טעלעפאָנירן Whitepaper
פּוסט-קוואַנטימ Key Agreement אין Nymchat
דיסטרינג ML-KEM-768 public keys over Nostr without a directory or a register, and sowing them out of a secret that no public value exposes.
אַוועקלייגן אַ פּוסט-קוואַנאַם קוואַם קוואַם אַוועקלייגן צו אַ messenger is mostly not a cryptography problem. The primitives are standardized and the libraries exist. The hard part is that every participant now needs a 2 און דעם אַרטיקל באַריכט ווי נימצעטע ענטפער צו דעם - ווי די שוך קוואָן באקומען, ווי עס געפירט די מענטשן וואָס זײַנען עס, און וואָס דער אינטרס איז געפירט צו פאָרויסזאָגן וועגן די רעזולטאטן - און, אין די לעצטע סאַטעס, וואָס דעם רעזולטאט לא באַריכט.
דער בלאַט איז מאַשין איבערגעזעצט פֿאַר קאַנוויניאַנס. דער ענגלישער אָריגינעל איז די ווערסיע וואָס אַפּלייז.
1די בעיה
אונדזער פּריוואַט הודעות זענען encrypted with ניפּ-44דער שוואַבלע איז דער שוואַבלע טקסט — ChaCha20 מיט אַ HMAC-SHA256 טאג, קוואַבלע דורך און HKDF (דערגרייכט 5869) — איז לא סמינטיקלי גענוג דורך אַ קוואנטיש קאָמפּיוטער; Grover's algorithm costs a square-root accelerup against a symmetric key, and 256 bits absorbs that. ענטפער אויף די מפתח איז די דיליפּטיש-קוריוו Diffie-Hellman over. אַוועקלייגן 256K1און די אלגורימט פון Shor פעלט די דיסקריקט לוגאַרימט אַפּראָוט. recovering one private key from its public counterpart retroactively exposes every shared secret that key ever produced.
די איום איז געבוירן אין דערפאַרונג אַרויף צו אַ אַזאַ מאַשין קיוואַסט. אַ אויבן מיט סאַגרייטינג קענען רעקאָרד אַקיפאָרד טקסט היום און דיסקיפאָד עס ווען דערפאַרונג גענומען. יעדער אַזאַ שרייַבן איצט אַזאַ שאַוועלעד אז איז אַוואַפאָדעד.
1.1 The question this paper answers
די מאַקסימום טעלעפאָנירן איז די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן פון די מאַקסימום טעלעפאָנירן (און 203 געסטאון דעריבער איז א בעיה:
אַפּענדינג אַ פּוסט-קוואַנאַם אַוועקלייגן און איר זקוקן אַ שניה — זיין ML-KEM ציבור מפתח. Where does that key live, and how get it before you can send her anything?
איר קענען שרייַבן עס אויף פּאַפּיר, לערנען עס רעכט, אָדער סאַנסן עס פון אַ סקאָרן, און עס איז אַלע יעדער דאַרפֿן צו קראָפייד צו איר. A ML-KEM-768 public key is 1,184 bytes. It cannot be read out loud, it will not fit in a username, and it does not belong in a QR code besides an identity that is only 32 bytes.
די צופרידן פּרייַז איז אַז אַ שוך קלייַז bring three distinct problems, and the rest of this paper is largely a answer to them:
- אפשר איז א תחליף. אַ קלייַן אין אַ מאָל קענען לערנען אין אַ מאָל איז די גאַנץ אַז אַ אַטראַפאָר אַוועקלייגן פֿאַר זייער. Section 4 binds it to the identity with a signature, which settles this one outright.
- עס איז געפונען אין די מכשירים של משתמשים. די אותו חשבון אויף אַ טעלעפאָנירן און אַ נאַטפאָנירן האָבן צו פאָרויסזאָגן אותו קייַן, אָדער הודעות געפונען צו איינער cannot be opened on the other.
- אפשר איז א אבוד. די ציבור מפתח איז געפירט פון אַ סוד, so what actually has to survive is that secret — and by construction nothing else reconstructs it. Section 10.1 states clearly what that costs, because this one is not solved as much as paid for.
2מעגלעך מעגלעך
ארבעה טרעפענדינגס געפונען די תשובה, און זיי יקספּלאָד רוב פון די אַוואַבאַל דיזיינז אַוואַסט אַוואַסט אַוואַסט אַוואַסט קיין קוד איז געפירט.
- יעדער איינער כפי יכולתו. יעדער אַפּערדינג סענטימעטער איז א אנדערע וועג צו באַקומען דיין היסטוראַ, און מישהו וואָס קענען באַקומען אַ נאַסע סענטימעטער וועט ניט באַקומען אַ אַפּערייטינג אַ נאַסע. Section 3.1 מראה דעם אַפּערייטינג אין אַפּערייטינג אַפּער-קוואַנמימעטער - אַ פּוסט-קוואַנמימעטער קוואַם פון די נאַסע באַקומען אין אַפּער-קוואַנמיע באַקומען אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג — so the design spends exactly one secret and no more: a single piece of key material, generated once per identity, presented in the same shape as the nsec and in the same place, so that anyone who knows how to keep one knows how to keep the other.
- אין אַלט. אין אַ סערער וואָס קענען זיין סערייטאַד צו זען וואָס קליי שייך צו מי. Any such server becomes the point at which messages can be redirected.
- פילע גאַנץ, א יחיד אידיטואיציה. אַ נוסטר אַדמיניטעט איז געניצט פון עטלעכע קליימאַנץ באָצוואַנץ. יעדער קריטימאַטור געניצט וועט געניצט אַדמיניד אויף אַלע די קליימאַנץ, and the paths that carry it there must not themselves be readable by the opponent the feature is defending against.
- אין די משא ומתן. יעדער in-band exchange of “which ciphers do you support?” is a surface an attacker can strip to force the weaker option.
3און דער סוד איז
די בלאַט-נעלונג דעצאָלונג איז אַז די ML-KEM decapsulation key איז זרעוודיק פון קריטימאַטור אַז קיין ציבור ערך געפונען. Each identity gets one root secret, generated once:
pqRoot = 32 bytes from a CSPRNG, generated ONCE per identity
seed = HKDF-Expand(
HKDF-Extract(salt = "nym-pq-root-v2", IKM = pqRoot),
info = "mlkem768/epoch/" || epoch,
64 bytes)
(ek, dk) = ML-KEM-768.KeyGen(seed)
די root איז דערגרייכט צו די ניצערס ווי אַ nsec איז: און 32 און מיך [חלילה, נישט מיך - איך מיין די רעכטע].
nympqאון איך בין איך nympq1…, געפונען ביידן די nsec אין די אַדמיניסטראַטיש סקרעדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדדד
דער סאַל איז דומיין-פרייַדעד אויף ענין, so no other secret can ever derive the same keypair. epoch אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן (Section 9)
3.1 Why the key can't be derived from the identity key
די אַוואַוויד פּלאַן איז צו זרעו די קשייפּאַר פון די סוד די ניצערס האָבן:
seed = HKDF(salt = "…", IKM = nsec) // do not do this
עס איז אַטראַקטיוו פֿאַר ארבעה סיבות, אַלע זיי זענען ריאלי: אין נייַעס צו אַוועקלייגן, because the nsec already is the backup; יעדער דיזיינז אַוועקלייגן דורך בויגן, אין אַ סינכאָניזיישאַן פּוטאָקאָוטאָקאַל צו גאַנץ; אַ אַוועקלייגן אַוועקלייגן אַוועקלייגן per identity being obviously correct, because devices can not disagree about the key; and the key existing before it is ever published, so a client can seal something to himself at first run.
די אַלגאָריכטע פון Shor איז אַלגאָריכטע פון אַ פאָריוואַט נפּוב אַדווינג די nsec. The seed derivation is a public algorithm over the nsec. So the opponent who breaks the classical half reconstructs the post-quantum half by running the same HKDF that everyone else runs. Against harvest-now-decrypt-later — the one threat the feature exists to stop — a key derived this way adds nothing at all.
די ML-KEM decapsulation key must come from entropy that is neither derivable from the nsec nor ever transmitted under classic-only encryption.
די צוויי טעג פון דעם רעקאָרל מיינט ווי די ערשטער. A independently generated secret that is then synchronized between a user's devices within an ordinary NIP-44 message is the same failure with additional steps: an opponent records that message today and recovers its classic key later, and the root falls out.
3.2 באַקומען די root צו די user's other devices
3 פון Section 2 - איינער אַדמיניטעט, מער דיזייגן - cannot be satisfied by arithmetic here, because the whole point is that the key is not a function of anything the devices already share. It has to be satisfied by transport instead, and there is exactly one path: the user moves the device. nympq1… קודיע לעצמך
דער רוּחַ איז געווען nympq1… און דעריבער, איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך האָב איך
מאַנוואַלי טראַנסעראַנט איז אַ קאָנטייליע פעלד אין אַ ערשטער צעד. The rule in Section 3.1 says the root may never travel under classic-only encryption, and every mechanism that would make this automatic — syncing it through a relay, wrapping it to the identity key — violates exactly that.
די פורמט לייענען שטעלן פֿאַר אַ אַוועקלייגן פעלד: אַ רעקאָרד קענען געניצט אַ רשימה פון אַוועקלייגן, יעדער אַ AEAD בלוב אונטער אַ קלייַן וואָס ניצערס קענען רעפּראָדירן אויף אַ אנדערע פּליייז — אַ passkey PRF output, for example.Nothing ships one today, and until something does, the nympq1… עס איז א טעמפּעראַטור פון 10.1.1 און עס איז א טעמפּעראַטור פון 10.1.
דער רעקאָרד איז באקומען א קטגוריה, nymchat-pq-rootאפילו געניצט אין אַוועקלייגן עס מיינט נדרש אַרבעט: Its presence is how a second device learns that this identity already has a root, which is what stops it minting a rival one (Section 3.3).
און nymchat-pq-root די קטגוריה נישט דער רייַך געניצט די יחיד קאַפּיע פון די שורש, so sealing it under a key derived from the root is a lock whose key is inside the box: no device could ever open it, including the one who wrote it. It is sealed classically — NIP-44 to itself — or not at all. This is the one place the design accepts classical-only protection, and it can afford to: the line carries no root today, only the fact that one exists.
יעדער אנדערע קאַטעגאָריז קענען און וועט נוצן די root-derived key.This is the single exception, and it is an exception about circularity rather than about strength.
3.3 דורות און אַוועקלייגן
אויף באָוט, holding a durable identity, a client works in this order:
- נישט א קיים
nymchat-pq-rootאון שיא. - די רעקאָרד געפירט, און דעם מכשיר קענען אַוועקלייגן עס דעריבער, איר קענען באַקומען די Post-Quantum Capability.
- די רעקאָרד געפירט, און דעם מכשיר cannot unwrap it. - אין געגרינדעט אַ נייַ שורט, און ניט געגרינדעט קיין אַוועקלייגן אין די זאך.
nympq1…עס איז געווען א מכשיר שעבר. - אין די שיא — געגרינדעט אַ root, באַקומען די רעקאָרד, אַוועקלייגן, און זען די
nympq1…איר קענען באַקומען אַ קאָד צו באַקומען.
3 איז די צעד וואָס איז קל צו באַקומען טעות, און עס איז די סיבה די אָרדינג איז געפֿונען אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ
4היפּש א קאמיע
די ציבור half of the derived keypair is published as an addressable.
אַוועק 01
אַוועקלייגן אַוועקלייגן — kind 30078, tagged nym-pq:
{
"kind": 30078,
"tags": [
["d", "nym-pq"],
["t", "nym-pq"],
["expiration", "<unix seconds>"]
],
"content": {
"v": 2,
"alg": "mlkem768",
"nym": 1,
"epoch": 0,
"pk2": "<base64url ML-KEM-768 encapsulation key>",
"exp": <unix seconds>,
"devices": [ ... ]
}
}
אַדראַבלאַבלע מיינט די ראַייל באַקומען אַ אַוועקלייגן פּער (kind, pubkey, d-tag), so a republish replaces the previous announcement in place. Each identity therefore has exactly one current record, which is what makes Alice's key” a single unambiguous fetch rather than a list to reconcile.
עס איז א מחייב. עס איז געגרינדעט דורך די אַדמיניטעט קייַן, so the claim “this ML-KEM key belongs to this npub” is exactly as strong as the npub itself. Replacing a different encapsulation key requires forging a secp256k1 signature. A attacker who can do that doesn’t need to bother with the KEM.
דערגרייכט די הודעות. און שבע ימים ניפּ-40 די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע פון די רעקאָרדאַציע.
אַ מאָלאָפּד אַוועקלייגן איז געניצט די ספּעציעל ווי אַ געניצט אין אַ קויל: peers send ordinary NIP-44, which every login can read, and the client resumes the post-quantum exchange on its next connection, when it republishes.So going quiet for longer than a week costs protection for the messages sent during the gap — they are classically encrypted rather than quantum-resistant — and costs nothing else. Delivery is unaffected, nothing already received becomes unreadable, and no action is needed on return.
דער אַסמימטריאַ איז די סיבה צו די יקספּערייטינג אין אַ קאַנסאַל פון עס. אין איינער, אַ רעקאָם ענטפערד די קלייַך וואָס ער געגרינדעט: אַ דיוואַטע וואָס איז געגרינדעט, ראַסטאַד, אָדער האט זייַן רויט געגרינדעט לייענען אַ סטאַינג יקספּעראַלד צו יקספּעראַלד צו אַ קלייַך וואָס אין אַראָפּ באַקומען, און הודעות געגרינדעט אונטער עס זענען אנגעקומען אין אַ שגיאה אויף קיין צד. Seven days bordes that window, and lets relays drop the record themselves rather than relying on clients to notice.
דער פעלד מפתח איז געגרינדעט צו זיין פורמט. עס איז pk2, and the digit is part of the contract rather than decoration: it names the payload format the key may be used with. A reader who does not recognize the field concludes “Nymchat client, no post-quantum key” and sends ordinary NIP-44, which every login can read. That is the correct failure direction, and it is worth stating as a rule the format numbering exists to enforce: an unrecognized capability claim must cost protection, never delivery. A key a peer cannot use is worse than no key at all, because the message it produces is lost with no error on either side.
4.1 אַפּערייטינג איז געשמאנט, און טרייליוואַטיד
אַ סענטימאַל but important detail: The announcement is published by every Nymchat client, not only post-quantum-capable ones, and the key field is optional. That yields three distinguishable states rather than two:
| ענטפער | מיטל | געפירט Behavior |
|---|---|---|
| אַוועקלייגן מיט אַ מפתח | אַוועקלייגן, אַוועקלייגן אַוועקלייגן אַוועקלייגן | און היבריד |
| דעריבער אין מפתח | Nymchat, classical only — post-quantum off, אָדער אַ פּלייינג אין דיזענדינג צו די אַדמיניטעט פון | דערגרייכט NIP-17 |
| אין אַוועק | עס קענען זיין קיין ניצן. | קלאסיש, פלוס אַ קאַמפּאַסיביע וואַלפּ |
A keyless announcement is a signed statement that the sender runs Nymchat, which allows the send path skip a speculative cross-protocol wrap it would otherwise have to include for anyone it cannot identify.
4.2 אַ מכשיר וואָס cannot open the root remains silent
די אַוועקלייגן איז אַפּערייטינג: one event per identity, last write wins. That's what makes the single-record design work, and it's also what makes a unlinked device dangerous if it publishes. A device that announced a key it had minted for itself would clobber the real record and send every peer to encrypting under a key that other devices can't open.
אז אַ מכשיר וואָס זען אַ שורע קיים, אָבער קענען אין אַוועקלייגן עס, אַפּלייסינג קיין אַוועקלייגן אין אַלע.It is not broken and it is not locked out of the application: it still reads every message it has the keys for and still sends classically, while prompting the user to link it. Silence is the correct behavior for a device that cannot speak for the identity.
5דערגרייכט און די החלטה
די קלייאַנץ לערנען פּייערז' קווייַז פון צוויי וועג. A standing subscription covers the people a user actually corresponds with — open conversations and group members — so their announcements arrive as ordinary events. For a peer meeting for the first time, a one-shot query runs at send time, limited to 2.5 seconds; if it does not resolve, the message goes classical, which is the behavior that existed before post-quantum was added rather than a new failure mode.
A user who links a new device, or who moves from a browser-extension login to a local key, becomes post-quantum capable mid-conversation, and a permanently cached “no” would keep them on classic encryption for the life of the announcement.
5.1 Why there is no downgrade attack
די רעקאָרדינג דעצאָלונג איז געפירט צו אַ יחיד שאלה:
pq = (we hold a signed, unexpired ML-KEM key for this recipient)
אין אַ קאַמפּאַניעס קאַמפּאַניעס, אין אַ רשימה פון תומכים-אלגאָרימטס, און אין אַ פעלד אַ אַראָפּערייער קענען קלייז צו ינקריכט אַ שוטעטער. איז The failure mode of a stripped or withheld announcement is that the message goes classic — the status quo before this feature — rather than that a hybrid message is downgraded to something forgiveable.
די קאַנטראָווז אויך באַקומען און מער אינפֿאָרמאַציע: A client sends hybrid רק און מיך [חלילה, נישט מיך - איך מיין די רעכטע] אויך נישט!
6היברידיד בויגן
Nymchat doesn't replace NIP-44. It wraps it. A unmodified NIP-44 ciphertext is the inner layer, און ML-KEM keys an external AEAD around it:
inner = nip44_encrypt(plaintext, conversation_key(sender, recipient))
info = "nymchat-pq2" || sender_secp_pk || recip_secp_pk || kem_ct || recip_kem_pk
prk = HKDF-Extract(salt = "nymchat-pq2-v1", IKM = kem_ss)
key = HKDF-Expand(prk, info || "key", 32)
nonce = HKDF-Expand(prk, info || "nonce", 12)
outer = ChaCha20-Poly1305(key, nonce, plaintext = inner, aad = info)
payload = "pq2." || base64url(kem_ct) || "." || base64url(outer)
שתי סודעס האָבן עדיין צו באַקומען צו באַקומען צו לייענען די אָפּשאַצונג: די יבערבליק באַקומען רק אַ NIP-44 ספיפרקט, און אַוועקלייגן וואָס באַקומען די קלאסיש ECDH. A quantum opponent who breaks secp256k1 gets the inner key and still faces ML-KEM; a break of ML-KEM strips the outer layer and leaves NIP-44 standing.
kem_ssאין די אַפּערייטינג פון אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינג אַפּערייטינגkem_ct,recip_kem_pkאון צוויי אידיטישטיווע קלייז זענען געפונען אין ווי אַפּענדיקטאַד דאַטן, so the outer layer is committed to the exact transcript that produced it. Splicing a encryption text on another sender's identity fails authentication rather than decrypting.
דער רייַבן פון די רייַבן ML-KEM key is long-lived, but each message carries an independent encryption text and therefore an independent encryption key.
kem_ssאון זייער זייער מינדערוויכטיג, און זייער מינדערוויכטיג.
אַוועקלייגן20-Poly1305
כ'האף די ווען (מיטן דרייווער) זאלן מארך ימים זיין.
6.1 Why the layers stay separate
די אלטראַטיאָן איז צו מיקסן די שני סענטימעטער אין אַ יחיד קאַנטראָאַל קייַן און האַלטן אַז צו NIP-44:
ck = HKDF-Extract(salt = "…",
IKM = ecdh_x || kem_ss || …) // do not do this
עס איז געווען א טעמפּעראַטור, און עס איז א טעמפּעראַטור:
ecdh_xעס איז געווען א באקאנטע טעלעפאָנירן (ניפּ-07און זייער זייער מינדערוויכטיג.ניפּ-46עס פעלט NIP-44 אויף די צאָלן פון די צאָלן און האַלטן back a encryption text, which is the whole point of holding the key somewhere the application cannot reach.
די מיקסן פון די ספּעציעלס אַוועקלייגן יעדער לינינג אַז באַקומען די אידיטישטיווע קלייַן אין אַ סאַגענער, וואָס איז צוזאָגן די מערסט באַשטימען ניצערס, און קיין כומע פון אַרבעט אויף די קלייַן אַוועקלייגן קענען לערנען עס. Layering removes the dependency: NIP-44 remains whole and is produced by whatever holds the identity key, signer included, while the KEM half is computed from the recovery code the client holds directly.
די ML-KEM ciphertext איז 1,088 בייטס און ריד אויף יעדער עצה, base64url-coded to 1,451 characters; the external AEAD adds a 16-byte Poly1305 tag and expands the NIP-44 payload it wraps by a third. A 50-character message grows from 176 bytes to 1,712, and a 2,000-character one from 2,820 to 5,238. The floor is approximately 1.5 KB per message regardless of how short the message is, which is the price of encapsulating fresher every time rather than reusing a shared secret.
6.2 אַפּערייטינג אַוועקלייגן
און pq2. prefix makes deployment incremental: עס איז self-describing, so a client chooses the decryption path by inspecting the payload rather than by trusting a tag or remembering what a peer supports. A reader that does not recognize a prefix fails to open that payload rather than mis-reading it, and messages sealed before either side could do post-quantum stay readable as ordinary NIP-44 without no migration.
ML-KEM decapsulation is designed to never fail: given a malformed ciphertext, the Fujisaki-Okamoto transform returns a deterministic pseudo-random secret rather than an error. A wrong key therefore does not surface at the KEM layer at all — it surfaces as a HMAC failure inside NIP-44, which is the same way a wrong classical key surfaces. Callers treat both identically, so the failure carries no distinguishing signal. It is also what makes Section 9.1's candidate list workable: a client tries each key in turn and lets NIP-44 say which one was right.
6.3 די צוויי שוואַרדס פון די גאַנץ
A ניפּ-17 די מסר איז א ניפּ-59 דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער, דעריבער.
אַ חותם אַלאָגינגער באַקומען רק די פעלטער שורה. The seal is produced by the signer as ordinary NIP-44 — the application never sees the key that makes it — so it cannot be hybridized in place. This costs nothing against the attack in question: the seal is reachable only through the wrap, and the wrap is what a recorder stores. A opponent holding recorded traffic must break ML-KEM before a seal is even visible to attack.
7געגרינדעט מיט די חלקיש דיסקרייטינג
און מיך [חלילה, נישט מיך - איך מיין די רעכטע] אויך נישט!
דערגרייכט דעם אַ אַוועקלייגן פּראָבלעמאַטיאָן אַז אַ נייַוויע ימפּלאַניזיישאַן באַקומען טעות. If eight of ten members receive a hybrid copy, the message is נישט א אויבן זײַנען זײַנען אַ קלאסיש קאַפּיע פון אַ קליינטקס אַז איז אַדמיניד אין די עשרה, so the message is protected only if יעדער און קופ.
Nymchat thus tracks per-message coverage during the fan-out — the count is only knowable while the wraps are being built — and the badge reports “quantum-resistant to 8 of 10 members” instead of claiming the message is protected. באַקומען און דעריבער, איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך האָבּ איך
7.1 וואָס די שרייַבן מודיע
עס איז געווען א אמת על הודעהאין די עקספּעראַמאַנץ פון דעם מיך:
- יעדער קאַפּיע פון דעם קלאַנטעקס איז אַ היברידיד.
- פּריסיוולי: עטלעכע קאַפּינעס פון אַ גאַנץ אָנזאָג געפֿונען קלאסיש. Drawed degraded rather than full, because one classical copy of a plaintext identical in all of them is all an opponent needs.
- קלאסיש איז צוגעשטעלט פּאַרטייק ווי אין אַ בודג, because an absent indicator is ambiguous between “unprotected”, “broken”, and “this build lacks the feature”.
די ענטפער איז געגרינדעט ווען די אָנזאָג איז געגרינדעט אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָפּ אַראָ
The group rules above stack on top of this rather than replacing it: a group message is fully protected only when each member's copy was, and a received group message with no coverage count shows partial.
8געגרינדעט צו עצמך
פילע טעג פון אַ קליינט אַלאָגן זענען קענדיקטעד צו די ניצערס אַדמיניטעט: סינכענדיד אַפּעראַמאַנץ, די קאַנסאַטיאָן רשימה, גאַנץ קייַז, און די פּאָליע ארקיע. These carry more about a user than most single messages do, so leaving them classic would make them the weakest stored artifact regardless of how carefully the messages themselves were sealed. They use the same hybrid, encapsulated to the user's own root-derived key — with one exception described in Section 3.2, the nymchat-pq-root עס איז געווען א מפתח שלא יכולתו לייצר.
A settings blob or an archive row sits in one place for years, which is exactly the shape of thing a harvest-now-decrypt-later opponent collects — much more than any single message, which is at least ephemeral in the user’s own mind.
אַ קאָמפּאַניטיישאַן רעגירונג די פורמט דאָ אין די קליי. A self-addressed copy must be readable by יעדער די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַפּערייטינג פון די אַ
עס איז אַ מעניינט יקספּעראַמאַנץ, אין אַ יקספּעראַמאַנץ, און עס איז די סיבה צו באַקומען אַ יקספּעראַמאַנץ פֿאַר לינקן אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּעראַמאַנץ אַפּ
A device running a browser extension or a remote signer (NIP-46) holds no nsec to derive from, but it does hold the recovery code, and under the layered construction of Section 6.1 which is all the post-quantum half needs: the signer produces the NIP-44 layer as it always has, and the client keys the outer layer itself.
9און רוט
און epoch ס'איז דא א באקאנטע אויסדרוק being able to rotate without new key material. Incrementing it yields a fresh keypair from the same root and a republished announcement; peers pick up the new key from the replaceable record. Rotation therefore does not ask the user to write anything down a second time: the root is generated once per identity and the epoch does the turn.
9.1 Old epochs are kept, און nothing is re-encrypted.
אַ קליינע בויען אַ דיסקיפאָנירן קאַנדיקטאַץ פון די נאַך עקספּעראַן אַפּראָוטערז פון די נאַך עקספּער − 3, so a message sealed shortly before a rotation still opens against the keypair that was current when it was sent.
עס איז עס וואָס מאַכן רוטאַציע אַוואַטיוו צו באַקומען אין אַלע: אָן עס, יעדער רוטאַציע וועט אַפּראָדז אַוואַטיוו יעדער וואָס איז אין פעלט. יעדער עס איז אַוואַטיוו אַוואַטיוו אַוואַטיוו אַוואַטיוו אַוואַטיוו אַוואַטיוו, because a message the user can no longer open is strictly worse for them than one whose protection cannot be improved retroactively (Section 10.5).
10איך בין אין שמירה
אַ פּאַפּיר וואָס רק רשימה וואָס אַ פּלאַן באַשטימען איז אין באַשטימען אַ סיסטעם, און overstating a security property in an interface is worse than omitting it.The following are outside what this construction defends.
10.1 The root is a second secret, and losing it is unrecoverable.
עס איז די פּרייַז פון די פּלאַן. The constraint in Section 2 that a user should have exactly one thing to keep cannot be met: the nsec alone does not reconstruct the post-quantum key, because the whole point is that no public value and no other secret exposes it. If no device holds the root and none of Section 3.2's wraps can be opened, material sealed to the root-derived key is not recoverable.
מיט ידניע טרעפן די יחיד פעלד, דעם איז מער ווי עס קענען ערשטער לייענען. nympq1… קודיע אַפּעראַטור האט די ספּעציעל אַ קאַפּיע פון עס, אויף אַ דיזיינז, און פּרייַבן אַז די דיזיינז פּרייַב יעדער פּוסט-קוואנטע הודעה, אַפּעראַטור blob and archive row sealed to it.
nsec אין די מעשה, עס איז די מעשה שעליו כל מעשה.
יעדער אַוועקלייגן פּרייַז אַוועקלייגן ווייַטער, יעדער אַוועקלייגן פּרייַז אַוועקלייגן אַוועקלייגן אַ אַוועקלייגן פּרייַז אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן אַוועקלייגן
10.2 אַנטייטינג, ווי דיסקרייטינג פון די סודיות
כל חתימה אין נוסטר איז Schnorr איבער secp256k1, און וואָס איז אין טעמע כאן. אַ ענגליע מיט אַ קוואטן קאָמפּיוטער קענען פאָרויסזאָגן חתימות און פאַפאָנירן אַ ניצערס אין ריאאַל טיימז. וואָס די היברידיד קיוו אַוועקלייגן געבאָגן איז יקספּער-וואָרד-דקאָריפּט-זען: אַ יקספּעראַטור רעגיסטרינג טרעפליקס היום cannot read it later. It does not make a message unforgivable against an opponent who already has the machine. This distinction is carried into the applications deliberately — the padlock indicator reports authentication, the shield reports confidentiality, and they are separate glyphs because a message can
די בינדונג צווישן אַ npub און אַ ML-KEM key is a secp256k1 signature, so an opponent who can forge those can replace a key of their own. Confidentiality against a future opponent is not the same as authenticity against one.
10.3 אַוועקלייגן
און מיך [חלילה, נישט מיך - איך מיין די רעכטע] אויך נישט! p עס איז געפונען אַז אַ געגנט קיים, Its size, or when a relay received it. Traffic analysis is not addressed by any part of this design.
10.4 דער Offline mesh
Nymchat's Bluetooth mesh transport is a separate protocol with its own handshake, and it is not covered by this work.
10.5 מייַכן אַרויף צו
די סיפאָרטקס געגרינדעט בעשאַס יעדער צד איז still classic remains classic permanently. It already exists and cannot be re-sealed. Protection begins at the message where both sides held post-quantum keys, not at the moment the feature was switched on.
11אַפּעראַמאַנץ
| געפירט | למה אין |
|---|---|
| דערגרייכט די Post-Quantum Key פון די Identity Key. | די דריוואַטינג איז אַ פאַביע אַלגאָרגיטם איבער די nsec, און אַ קוואַנאַמי אַדוואַסטער באַקומען די nsec פון די פּיפּאָפּאַד פּיפּאָב, so breaking the classic half hands over the post-quantum half with it. It solved every distribution problem in this paper and defended against nobody. |
| באַזייַבן די root צו די ניצערס פון אנדערע מכשירים דורך NIP-44 | א שורש געפירט אונטער קלאסיש-only encryption is recoverable by anyone who recorded that message and breaks its key later, which is the opponent the root exists to stop. |
| אַ נייַווערינג ML-KEM keypair on each device | ס'איז דא א באקאנטע אויסדרוק being able to use a different decapsulation key, and one replaceable announcement per identity cannot carry them all. Peers would encrypt to which key was published last, and every other device would be unable to read the result. |
| געפירט מיט אַ PIN | די פּינע איז וועגן 13 bits און אַ אַלפאָנינגער באַקומען די אַוועקלייגן רייַך. Offering it beside two 256-bit paths would misrepresent what the weakest wrap is worth. |
| דערגרייכט די npub צו באַקומען די שני מפתח. | 1,184 בייטס איז אין אַ שאַרדינג אַדמינירן, און עס וועט געפונען יעדער יקספּענדינג ניצן פון נוסטר קאַלינע פון אַ אַדרעס וואָס איז דעפאַניטיד ווי 32 בייטס. |
| ער איז א Key Directory Service. | עס איז געווען א באקאנטע רעקאָרדינג, און מי שיענה צו די רעקאָרדינג איז א באקאנטע רעקאָרדינג. |
| באַקומען צו כל הודעה | אין די מאָל: The sender needs the געוועהן אין דער ערשטע מסר, און אין דער ערשטע מסר. |
| אַוועקלייגן אַוועקלייגן capacity | געפונען אַ אַדוואַגראַדיד געפונען. An attacker who can strip a capability flag forces the classic path. |
| אין די קלאסיש, אין די קלאסיש | דערגרייכט די ענטפער פון אַנאַליזיישאַן פון secp256k1 אין אַוואָם אַ מער צעיר פּרימיטיוו. A hybrid fails only if ביידע אין די |
12לייענען די Parity
Nymchat ships two independent implementations of this construction — one in JavaScript for the web application, one in Dart for the mobile applications, including a from-cratch ML-KEM-768 port. צוויי ימפּלאַניזיישאַנז פון די איין פּרימיטיוו איז אָרגאַלי אַ ימפּלאַניזיישאַן, אַזוי זיי זענען פּינענדיד אַדוואַנט אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו אַדוואַטיוו.
The Dart ML-KEM implementation is validated against the official
דעריבער ACVP
געגרינדעט מיט אַפּעראַטור (ML-KEM-*-FIPS203) — 25 key-generation, 25 encapsulation און 10 decapsulation cases, run as their own suite. These are the vectors NIST publishes to validate an implementation, so passing them is evidence the port is correct, not merely evidence that the two clients agree with each other. מעל די אַזאַ, אַ שייַבן פיקסע פון טסט וויקטאָרס — זרע דריוואַציע, encapsulation, both payload formats, and complete gift wraps — is generated from the JavaScript reference and checked by both test suites. The root secret extends that fixture rather than replacing it: root to seed, root to keypair, the root's public fingerprint, and the derived key, nonce and associated data of the outer layer are vectors of their own, so the two clients cannot disagree about what a
nympq1… אַ דיוויגנעס אין יעדער אַפּלאַמאַניישאַן מייַנעמען די בויען אַוועקלייגן ווי אַ פּראָדוקציע פון אַ הודעה אַז די אנדערע קלייאַנאַז אין אַפּערייטינג.
די אַפּראָדס איז שוואַך געניצט צווישן דיס. עס איז די שייַכן אַ אַפּראָדס “זה איז די root I hold” from “This is a different one”, and a client that could not reproduce another client's fingerprint would read a perfectly good record as no record at all — and then, following Section 3.3, mint a second root and split the identity.
עס איז און open source. געפירט דורך AGPL-3.0. The cryptographic core described here is
js/nym-crypto.js און js/modules/pq.js אויף די אינטרנט, און
lib/core/crypto/ און lib/features/identity/pq_registry.dart אויף די Mobile Clients.
פֿאַר די קערטער, לא טכנישע הסבר, זען די דערינערונג פון Quantum-Resistant Encryption.