Kunskapsbas: kvantbeständig kryptering

Nymchat tekniska whitepaper

Post-Quantum Key Agreement i Nymchat

Distribuera ML-KEM-768 offentliga nycklar över Nostr utan en katalog eller ett register, och så dem från en hemlighet som inget offentligt värde avslöjar.

Versionen 1.0 augusti 2026 Gäller för Nymchat 3.74+

Att lägga till en postkvantnyckelväxling till en budbärare är för det mesta inte ett kryptografiskt problem. De primitiva är standardiserade och biblioteken finns. Andra Denna artikel beskriver hur Nymchat svarar på det – varifrån den andra nyckeln kommer, hur den når de människor som behöver den, och vad gränssnittet får hävda om resultatet – och, i det sista avsnittet, vad det resultatet inte skyddar.

1Problemet är

Våra privata meddelanden är krypterade med NIP-44, som har två separerbara halvor. Den halva som scrambles den enkla texten - ChaCha20 med en HMAC-SHA256-tagg, nycklad genom HKDF (RFC 5869 Övrigt) - är inte meningsfullt hotad av en kvantdator; Grovers algoritm kostar en kvadratroots acceleration mot en symmetrisk nyckel, och 256 bitar absorberar det. Håller med på nyckeln är elliptisk kurva Diffie-Hellman över Sjuksköterska256k1Återställa en privat nyckel från sin offentliga motsvarighet retroaktivt avslöjar varje delad hemlighet som nyckeln någonsin producerat.

Hotet som detta skapar skjuts inte upp förrän en sådan maskin existerar. En motståndare med lagring kan spela in krypterad text idag och dekryptera den när kapaciteten anländer. Allt som skickas nu som fortfarande spelar roll då är redan komprometterat. Detta är det specifika angreppet som en post-kvantnyckelutbyte besegrar, och det är därför arbetet inte kan vänta på att maskinen ska byggas.

1.1 Frågan som denna artikel besvarar

Mildringsmetoden är väl förstådd: kör en postkvantnyckelencapsuleringsmekanism bredvid den klassiska utbytet, så att en angripare måste bryta båda för att läsa något.FIPS 204Detta väcker omedelbart ett distributionsproblem:

Frågan

Lägg till en post-quantum utbyte och du behöver en andra - hennes ML-KEM offentlig nyckel.

En npub är självinnehållande. Du kan skriva den på papper, läsa den högt eller skanna den från en skärm, och det är allt vem som helst behöver kryptera för dig. En ML-KEM-768 offentlig nyckel är 1,184 byte. Den kan inte läsas högt, den kommer inte att passa in i ett användarnamn, och den hör inte till en QR-kod förutom en identitet som bara är 32 byte.

Den svårare delen är att en andra nyckel ger tre olika problem, och resten av detta papper är till stor del ett svar på dem:

2Designbegränsningar

Fyra begränsningar formade svaret, och de utesluter de flesta av de uppenbara mönster innan någon kod skrivs.

  1. Så få hemligheter som möjligt. Våra användare bär redan exakt en hemlighet, nsec. Varje extra hemlighet är ett annat sätt att förlora din historia, och någon som vet hur man säkerhetskopierar en nsec kommer inte att veta hur man säkerhetskopierar något annat. avsnitt 3.1 visar att denna inte kan uppfyllas direkt - en postkvantnyckel som härrör från nsec ger inget postkvantskydd alls - så designen spenderar exakt en hemlighet och inte mer: ett enda stycke nyckelmaterial, genererat en gång per identitet, presenterat i samma form som nsec och på samma plats, så att vem som helst som vet hur man behåller en vet hur man behåller den andra. avsnitt 10.1 är ärlig om vad det fortfarande kostar.
  2. Ingen auktoritet Det finns ingen server som kan lita på att säga vilken nyckel tillhör vem.
  3. Flera enheter, en identitet Oavsett vilket nyckelmaterial som finns måste det hamna identiskt på alla, och de vägar som bär det där måste inte själva vara läsbara av motståndaren som funktionen försvarar mot.
  4. Inga förhandlingar alltså. Varje utbyte i bandet av “vilka siffror stöder du?” är en yta som en angripare kan klippa för att tvinga det svagare alternativet.

3En oberoende rotsekret

Belastningsbeslutet är att ML-KEM-dekapsuleringsnyckeln är sådd från nyckelmaterial som inget offentligt värde avslöjar.

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)

Roten presenteras för användaren som en nsec är: Bech32 Med det mänskligt läsbara prefixet nympqDärför läser den som nympq1…, visas bredvid nsec i identitetsskärmen bakom samma avslöja interaktion, kopierad med samma kontroll, aldrig loggat och aldrig skickat någonstans i klar.

Saltet är avsiktligt domän-separerat, så ingen annan hemlighet kan någonsin härleda samma nyckelpar. epoch motordrivna rotationer (avsnitt 9).

3.1 Varför nyckeln inte kan härledas från identitetsnyckeln

Den uppenbara designen är att så nyckelparet från den hemlighet som användaren redan har:

seed = HKDF(salt = "…", IKM = nsec)          // do not do this

Det är attraktivt av fyra skäl, alla verkliga: inget nytt att säkerhetskopiera, eftersom nsec redan är säkerhetskopiering; varje enhet som godkänner genom konstruktion, med inget synkroniseringsprotokoll att gå fel; en ersättningsbar annons per identitet är uppenbarligen korrekt, eftersom enheter inte kan vara oense om nyckeln; och nyckeln som existerar innan den någonsin publiceras, så en klient kan försegla något för sig själv i första hand.

Alla fyra fördelarna är värdelösa, av en anledning. Shors algoritm kör mot en publicerad npub ger nsec. Fröderivat är en offentlig algoritm över nsec. Så motståndaren som bryter den klassiska halvan rekonstruerar den postkvanthalva genom att köra samma HKDF som alla andra kör. Mot skörd-nu-decrypt-senare - det enda hotet att funktionen existerar för att stoppa - en nyckel härrör på detta sätt lägger ingenting till.

Regeln följer allt från

ML-KEM-dekapsuleringsnyckeln måste komma från entropin som varken kan härledas från nsec eller någonsin överförs under klassisk-endast kryptering.

En oberoende genererad hemlighet som sedan synkroniseras mellan en användares enheter inom ett vanligt NIP-44-meddelande är samma misslyckande med extra steg: en motståndare registrerar det meddelandet idag och återställer sin klassiska nyckel senare, och roten faller ut.

3.2 Få roten till användarens andra enheter

Begränsning 3 av avsnitt 2 - en identitet, flera enheter - kan inte tillfredsställas av aritmetik här, eftersom hela poängen är att nyckeln inte är en funktion av något som enheterna redan delar. nympq1… Koda sig själv.

Roten visas som nympq1… bredvid nsec, och en andra enhet accepterar den inbäddad i samma panel. Det är hela mekanismen. En enhet som inte har fått koden kan inte delta, vilket avsnitt 4.2 beskriver.

Regeln i avsnitt 3.1 säger att roten aldrig kan resa under klassisk-endast-kryptering, och varje mekanism som skulle göra detta automatiskt - synkronisera det genom en relä, omsluter det till identitetsnyckeln - bryter exakt det.

Formatet lämnar utrymme för en förpackad väg: en post kan bära en lista över förpackningar, var och en en AEAD blob under en nyckel som användaren kan reproducera på en annan enhet - en passkey PRF-utgång, till exempel. nympq1… Koden är det enda sättet att gå igenom. Avsnitt 10.1 anger vad det kostar.

Själva inspelningen lever i sin egen inställningskategori, nymchat-pq-rootÄven utan att bära några omslag gör det nödvändigt arbete: dess närvaro är hur en andra enhet lär sig att denna identitet redan har en rot, vilket är vad som stoppar den från att mynta en rival (avsnitt 3.3).

Designnot: den kategori som inte kan använda den nya nyckeln

den nymchat-pq-root Kategori måste inte Den raden bär den enda kopian av roten, så att försegla den under en nyckel som härrör från roten är ett lås vars nyckel är inuti lådan: ingen enhet kunde någonsin öppna den, inklusive den som skrev den.

Varje annan inställningskategori kan och bör använda den root-deriverade nyckeln.Detta är det enda undantaget, och det är ett undantag om cirkularitet snarare än om styrka.

3.3 Generation och adoption

Vid uppstart, med en varaktig identitet, fungerar en klient i följande ordning:

  1. Leta efter en befintlig nymchat-pq-root och rekord.
  2. rekord hittades, och den här enheten kan lösa upp den - anta den och tillkännage denna identitet som postkvantförmåga.
  3. Inspelning hittad och den här enheten kan inte lösa upp den — inte generera en ny rot, och inte publicera någon annons alls. uppmana användaren att länka den här enheten genom att ange nympq1… kod från en enhet som redan har den.
  4. Inga rekord — generera en rot, publicera posten, tillkännage och visa nympq1… kod till användaren en gång så att de kan spara den.

Steg 3 är det steg som är lätt att få fel, och det är anledningen till att ordningen skrivs ner i stället för att lämnas till varje implementering.Två enheter som var och en bestämmer sig för att generera en rot producerar två oberoende rötter under en identitet, och det är misslyckandet denna ordning existerar för att förhindra.

4Kapacitetsanmälan

Den offentliga hälften av den härledda nyckelparen publiceras som en adressabel Nippe 01 händelse — typ 30078, taggad 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": [ ... ]
  }
}

Adressabel betyder att reläet håller en händelse per (kind, pubkey, d-tag), så en republik ersätter den tidigare annonsen på plats. Varje identitet har därför exakt en aktuell rekord, vilket är vad som gör &ldquo;look up Alice's key&rdquo; en enda otvetydig hämtning snarare än en lista att förena.

Undertecknandet är bindande. Händelsen är signerad av identitetsnyckeln, så påståendet &ldquo;denna ML-KEM-nyckel tillhör denna npub&rdquo; är exakt lika stark som npub själv.

Annonserna löper ut. En sjunde dag NIP-40 Utgångsdatumet, som återpubliceras var 24: e timme, registrerar ett uttalande om en klient som fortfarande körs i stället för en som brukade vara.

En missad annons läses precis som en som aldrig hade en nyckel: kamrater skickar vanlig NIP-44, som varje inloggning kan läsa, och klienten återupptar postkvantutbytet på sin nästa anslutning, när den återpubliceras. Så att vara tyst i mer än en vecka kostar skydd för meddelandena som skickas under gapet - de är klassiskt krypterade snarare än kvantmotståndskraftiga - och kostar inget annat.

Utan en överlever en post den nyckel den heter: en enhet som raderas, återställs eller har sin rot ersatt lämnar en stående instruktion att inkapslas till en nyckel ingen håller längre, och meddelanden som skickas under den går förlorade utan fel på vardera sidan.

Nyckelfältet heter dess format. Fältet är pk2, och siffran är en del av kontraktet snarare än dekoration: den namnger nyttolastformatet som nyckeln kan användas med. En läsare som inte känner igen fältet slutar &ldquo;Nymchat-klienten, ingen post-kvantnyckel&rdquo; och skickar vanlig NIP-44, som varje inloggning kan läsa. Det är den korrekta felriktningen, och det är värt att ange som en regel att formatnumreringen existerar för att genomdriva: ett oigenkänt kapacitetsanspråk måste kosta skydd, aldrig leverans. En nyckel som en peer inte kan använda är värre än ingen nyckel alls, eftersom meddelandet den producerar förloras utan fel på vardera sidan.

4.1 Frånvaro är meningsfullt och trevärderat

En subtil men viktig detalj: tillkännagivandet publiceras av varje Nymchat-klient, inte bara de som kan post-quantum, och nyckelfältet är valfritt.

observeratMedelSkicka beteende
Anmälan med nyckel Nymchat, post-quantum förmåga Hybrid
Annons, ingen nyckel alls Nymchat, klassisk endast - post-quantum off, eller en enhet som ännu inte är kopplad till identitetsroten Klassiska NIP-17
Inget meddelande Okänd klient. Kan vara någon användare av Nostr eller Bitchat Klassisk, plus en kompatibilitetslåda

En nyckellös tillkännagivande är ett undertecknat uttalande att avsändaren kör Nymchat, vilket gör att sändningsvägen hoppar över en spekulativ korsprotokollförpackning som den annars skulle behöva inkludera för alla som den inte kan identifiera.

4.2 En enhet som inte kan öppna roten förblir tyst

Annonsen är ersättningsbar: en händelse per identitet, sista skriv vinner.Det är vad som gör en enskild inspelningsdesign fungerar, och det är också vad som gör en länkad enhet farlig om den publicerar.En enhet som tillkännagav en nyckel som den hade myntat för sig själv skulle störa den verkliga inspelningen och skicka varje peer till kryptering under en nyckel som de andra enheterna inte kan öppna.

Så en enhet som vet en rot existerar men inte kan öppna den publicerar ingen annons alls. Den är inte trasig och den är inte låst ut ur appen: den läser fortfarande varje meddelande som den har nycklarna för och skickar fortfarande klassiskt, samtidigt som användaren uppmanas att länka den.

5Upptäckten och beslutet att skicka

Klienter lär sig peer-nycklar på två sätt. En stående prenumeration täcker de personer som en användare faktiskt motsvarar – öppna konversationer och gruppmedlemmar – så deras meddelanden kommer som vanliga händelser. För en peer-möte för första gången körs en engångsfråga vid sändningstid, begränsad till 2,5 sekunder; om det inte löser, går meddelandet klassiskt, vilket är det beteende som existerade innan post-kvantum tillsattes snarare än ett nytt misslyckande läge.

En användare som länkar en ny enhet, eller som flyttar från en webbläsartilläggsloggning till en lokal nyckel, blir post-kvant-kapabel mitt i konversationen, och en permanent cached &ldquo;no&rdquo; skulle hålla dem på klassisk kryptering för annonsens liv.

5.1 Varför det inte finns någon nedgraderad attack

Rutningsbeslutet reduceras till en enda fråga:

pq = (we hold a signed, unexpired ML-KEM key for this recipient)

Det finns ingen förhandlingsförmåga, ingen lista över algoritmer som stöds och inget fält som en angripare kan klara av för att tvinga en svagare väg. är Misslyckandet med en borttagen eller återhållen annons är att meddelandet går klassiskt - status quo före den här funktionen - snarare än att ett hybridmeddelande nedgraderas till något falskt.

Den motsatta håller också och betyder mer: en kund skickar hybrid endast När det håller en nyckel, och håller nyckeln är bevis mottagaren kan avkapslas.Det finns inget tillstånd där ett meddelande skickas post-kvant till någon som inte kan läsa det.

6Hybrid konstruktion

En oförändrad NIP-44-krypteringstext är det inre skiktet, och ML-KEM nycklar en yttre AEAD runt den:

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)

Båda hemligheterna måste fortfarande återvinnas för att läsa meddelandet: det yttre skiktet ger endast en NIP-44-krypteringstext, och öppningen som behöver den klassiska ECDH. En kvantmotståndare som bryter secp256k1 får den inre nyckeln och fortfarande möter ML-KEM; en paus av ML-KEM skär bort det yttre skiktet och lämnar NIP-44 stående.

Mottagarens ML-KEM-nyckel är långlivad, men varje meddelande bär en oberoende krypteringstext och därmed en oberoende krypteringstext. kem_ssDet är vad som gör att härledningen av nonce snarare än slumpmässigt låter: ChaCha20-Poly1305 Övrigt är bruten genom att återanvända ett (nyckel, nonce) par, och här är nyckeln själv ny för varje meddelande, så inget par kan upprepa.

6.1 Varför lagren förblir separata

Alternativet är att blanda båda hemligheterna i en enda konversationsnyckel och skicka den till NIP-44:

ck = HKDF-Extract(salt = "…",
                  IKM  = ecdh_x || kem_ss || …)          // do not do this

Denna konstruktion låter som kryptografi. Den har ett strukturellt problem: den behöver ecdh_x, den råa x-koordinaten av ECDH-utgången, som nyckelmaterial - och en webbläsartillägg (NIP-07) eller en fjärrsignatur (NIP-46Det utför NIP-44 på ringerens vägnar och ger tillbaka en krypterad text, vilket är hela punkten att hålla nyckeln någonstans där applikationen inte kan nå.

Att blanda hemligheterna utesluter därför varje inloggning som håller identitetsnyckeln i en signerare, det vill säga de mest noggranna användarna, och ingen mängd arbete på nyckelderivationen kan ändra det. Layering tar bort beroendet: NIP-44 förblir hel och produceras av vad som håller identitetsnyckeln, signer ingår, medan KEM hälften beräknas från återhämtningskoden som klienten innehar direkt.

Kostnaden är bandbredd, och det är inte litet. ML-KEM-krypteringstexten är 1 088 bytes och körs på varje meddelande, bas64url-kodad till 1 451 tecken; den yttre AEAD lägger till en 16-byte Poly1305-tagg och expanderar NIP-44: s nyttolast den omsluter med en tredjedel. Ett 50-tecken meddelande växer från 176 bytes till 1 712 och ett 2000-tecken från 2 820 till 5 238. Golvet är ungefär 1,5 KB per meddelande oavsett hur kort meddelandet är, vilket är priset på att inkapslas nyligen varje gång snarare än att återanvända en delad hemlighet.

6.2 Självbeskrivande payloads

den pq2. Prefixet gör utplaceringen incrementell: det är självbeskrivande, så en klient väljer dekrypteringsvägen genom att inspektera nyttolasten snarare än genom att lita på en tagg eller komma ihåg vad en peer stöder.En läsare som inte känner igen ett prefix misslyckas med att öppna den nyttolasten snarare än att felläsa den, och meddelanden förseglade före vardera sidan kunde göra post-kvantet läsbart som vanlig NIP-44 utan migrering.

Implicit avslag

ML-KEM-dekapsuleringen är utformad för att aldrig misslyckas: med tanke på en felformad krypterad text returnerar Fujisaki-Okamoto-transformationen en deterministisk pseudo-slumpmässig hemlighet snarare än ett fel. En felaktig nyckel dyker därför inte upp på KEM-skiktet alls – den dyker upp som ett HMAC-fel inuti NIP-44, vilket är samma sätt som en felaktig klassisk nyckel ytor. Callers behandlar båda på samma sätt, så misslyckandet bär ingen särskiljande signal. Det är också vad som gör kandidatlistan i avsnitt 9.1 fungerande: en klient försöker varje nyckel i sin tur och låter NIP-44 säga vilken som var rätt.

6.3 Båda skikten av presentförpackningen

A NIP-17 Ett privat meddelande är a NIP-59 presentförpackning: ett osignerat rykte, förseglat under avsändarens identitetsnyckel (typ 13), sedan förpackat under en kastnyckel som genereras per meddelande (typ 1059).

A hybrid NIP-59 gift wrap: the rumor sealed under the sender's key, that seal wrapped under a per-message ephemeral key, both layers carrying a NIP-44 ciphertext inside a post-quantum AEAD. kind 1059 — wrap  ·  signed by a per-message ephemeral key content = pq2.<kem_ct>.<aead>   inner = NIP-44(eph, recip)   outer key = ML-KEM(recip) kind 13 — seal  ·  signed by the sender's identity key content = pq2.<kem_ct>.<aead>   inner = NIP-44(sender, recip)   outer key = ML-KEM(recip) rumor — unsigned the message: kind, content, tags, author pubkey unsigned on purpose — a signature would be portable proof
Båda krypteringsskikten är hybrida, var och en med en oberoende ML-KEM-encapsulation. Det yttre skiktet är nycklat till en kastbar hemlighet, så omslaget avslöjar inte avsändaren.

En signeringslogg får endast det yttre lagret. Stämpeln produceras av signeraren som vanlig NIP-44 – applikationen ser aldrig nyckeln som gör den – så den kan inte hybridiseras på plats. Detta kostar ingenting mot angreppet i fråga: stämpeln är endast tillgänglig genom omslaget, och omslaget är vad en inspelare lagrar. En motståndare som håller inspelad trafik måste bryta ML-KEM innan en stämpel är ens synlig för att attackera.

7Gruppmeddelanden och partiell täckning

Ett gruppmeddelande är inte en enkrypterad text. Det är samma enkrypterade text som skickas ut till varje medlem, varje kopia inkapslad till den medlemmens egna ML-KEM-nyckel.

Detta skapar ett bokföringsproblem som en naiv implementering får fel. Om åtta av tio medlemmar får en hybridkopia, är meddelandet inte En motståndare behöver en klassisk kopia av en vanlig text som är identisk i alla tio, så meddelandet skyddas endast om varje Kopia är .

Nymchat spårar därför per-meddelande täckning under fan-out - antalet är bara känt medan omslag byggs - och badget rapporterar &ldquo;quantum-resistent till 8 av 10 medlemmar&rdquo; snarare än att hävda att meddelandet är skyddat. mottagna gruppmeddelande (endast avsändaren räknar fan-out), gränssnittet rapporterar partiellt snarare än fullständigt skydd.

7.1 Vad skölden rapporterar

Skölden säger sanningen om Meddelande, inte om programvaran som skickade den:

Dömningen registreras när meddelandet förseglas snarare än återberäknas från vad en peer annonserar senare.Cypertext som redan existerar kan inte bli bättre skyddad än det var, och ett gränssnitt som återskapade gamla meddelanden på styrkan av en ny annons skulle hävda något falskt om bytes på en relä.

Gruppreglerna ovan stack på toppen av detta i stället för att ersätta det: ett gruppmeddelande är helt skyddat endast när varje medlems kopia var, och ett mottagit gruppmeddelande utan täckning räknas delvis.

8Kopior riktade till dig själv

Flera saker som en klient lagrar är krypterade till användarens egen identitet: synkroniserade inställningar, konversationslistan, gruppnycklar och meddelandearkivet. Dessa bär mer om en användare än de flesta enskilda meddelanden gör, så att lämna dem klassiska skulle göra dem till det svagaste lagrade artefaktet oavsett hur noggrant meddelandena själva förseglades. De använder samma hybrid, inkapslad till användarens egna roterade nyckel - med ett undantag som beskrivs i avsnitt 3.2, nymchat-pq-root kategorin själv, som inte kan förseglas under en nyckel som bara den kan producera.

En inställningsblob eller en arkivrad sitter på ett ställe i åratal, vilket är exakt den form av sak en skörd-nu-dekrypterad-senare motståndare samlar - mycket mer än något enda meddelande, vilket är åtminstone efemeral i användarens eget sinne.

En begränsning styr formatet här snarare än nyckeln. En självadresserad kopia måste vara läsbar av varje enheten på kontot, så varje enhet annonserar vad den kan öppna i listan som dess meddelande bär, och kontot skriver bara vad de alla kan läsa.

En begränsning värd att nämna

En enhet som har identiteten men inte roten kan inte öppna något förseglat till den roterade nyckeln, inklusive dess egna inställningar.Det är en avsiktlig konsekvens, inte en övervakning, och det är därför avsnitt 3.3 har en sådan enhetspruta för länkning i stället för att mynta en ny rot: en andra rot skulle inte göra bloben läsbar, det skulle bara dela identitetsnyckelmaterialet i två.Tills användaren länkar det, fortsätter enheten att fungera – den läser vad den har nycklarna för och skickar klassiskt.

En enhet som driver en webbläsartillägg eller en fjärrsignatur (NIP-46) har ingen nsec att härleda från, men den håller återhämtningskoden, och under den lagerbyggda konstruktionen av avsnitt 6.1 som är allt den post-kvanthalva behöver: signaturen producerar NIP-44-skiktet som det alltid har, och klienten nycklar det yttre skiktet självt.

9roterande

den epoch Counter i härledningen är vad som gör rotation möjligt utan nytt nyckelmaterial. Incrementering det ger ett nytt nyckelpar från samma rotation och en återpublicerad annons; kamrater plocka upp den nya nyckeln från den ersättbara posten.

9.1 Gamla epoker bevaras, och ingenting återkrypteras

En klient bygger dekrypteringskandidater från den aktuella epoken ner till epoken &minus; 3, så ett meddelande förseglat strax före en rotation öppnas fortfarande mot nyckelparet som var aktuellt när det skickades.

Det fönstret är det som gör rotation säker att göra alls: utan det skulle varje rotation stryka vad som redan var i flygning. Allt redan förseglat förblir läsbart för identitets liv, eftersom ett meddelande som användaren inte längre kan öppna är strängt värre för dem än ett vars skydd inte kan förbättras retroaktivt (avsnitt 10.5).

10Vad detta inte skyddar

Ett papper som bara listar vad en design uppnår beskriver inte ett system, och att överskatta en säkerhetsegenskap i ett gränssnitt är värre än att utelämna det.

10.1 Roten är en andra hemlighet, och att förlora den är oåterkallelig

Detta är designens verkliga pris. Begränsningen i avsnitt 2 att en användare ska ha exakt en sak att hålla kan inte uppfyllas: nsec ensam rekonstruerar inte postkvantnyckeln, eftersom hela poängen är att inget offentligt värde och ingen annan hemlighet avslöjar den. Om ingen enhet håller roten och ingen av avsnitt 3.2: s omslag kan öppnas, är materialet förseglat till roten-derivatnyckeln inte återvinnbart.

Med manuell överföring den enda vägen, är detta skarpare än det kan först läsa. nympq1… kod någonstans har exakt en kopia av det, på en enhet, och förlorar den enheten förlorar varje post-quantum meddelande, inställningar blob och arkiv rad förseglad till den. nsec Det hjälper inte; det är den egenskap som hela designen vilar på.

En angripare attackerar den billigaste vägen tillgänglig, så ett schema är värt vad dess svagaste återhämtningsväg är värt - en minnesvärd passfras, till exempel, skulle sätta hela saken på vad passfrasen är värd, och den inslagna raden är exakt det artefakt som en skörd-nu-dekrypterad-senare motståndare samlar och maler offline på fritid.

10.2 Autentisering, som skiljer sig från konfidentialitet

Varje signatur i Nostr är Schnorr över secp256k1, och det är oförändrat här. En motståndare med en kvantdator kunde förfalska signaturer och låtsas vara en användare i realtid. Vad den hybridnyckelväxeln besegrar är skörd-nu-dekryptering-senare: en angripare som registrerar trafik idag kan inte läsa det senare. Det gör inte ett meddelande oförlåtligt mot en motståndare som redan har maskinen. Denna skillnad transporteras till applikationerna avsiktligt - padlockindikator rapporterar autentisering, skölden rapporterar konfidentialitet, och de är separata glyfer eftersom ett meddelande kan ha en utan den andra.

Bindningen mellan en npub och en ML-KEM-nyckel är en secp256k1-signatur, så en motståndare som kan förfalska dem kan ersätta en egen nyckel.

10.3 Metadata

Gift wrapping döljer avsändaren, mottagaren bortom en enda p taggen, typen och tidsstämpeln för det inre meddelandet. Det döljer inte att en händelse existerar, dess storlek eller när en relä mottog den.

10.4 Den offline mesh

Nymchats Bluetooth mesh transport är ett separat protokoll med sitt eget handslag, och det täcks inte av detta arbete.

10.5 Redan skickade meddelanden

Ciphertext inspelad medan båda sidorna fortfarande var klassiska förblir klassiska permanent. Det finns redan och kan inte återstängas. Skydd börjar vid meddelandet där båda sidorna höll post-kvantnycklar, inte vid det ögonblick funktionen var påslagen.

11Alternativ som övervägs

tillnärmningVarför inte
Hämta postkvantnyckeln från identitetsnyckeln Avvisad. Derivationen är en offentlig algoritm över nsec, och en kvantmotståndare återställer nsec från den publicerade npub, så bryter den klassiska halvan händer över den post-kvanthalva med det.
Skicka roten till användarens andra enheter via NIP-44 En rot som överförs under klassisk-endast kryptering kan återvinnas av någon som registrerade det meddelandet och bryter dess nyckel senare, vilket är motståndaren roten existerar för att stoppa.
Ett separat genererat ML-KEM-tangentpar på varje enhet Avvisad. Enheter skulle hålla olika avkapslingsnycklar, och en utbytbar annons per identitet kan inte bära dem alla. Peers skulle kryptera till vilken nyckel som publicerades senast, och varje annan enhet skulle inte kunna läsa resultatet.
Wrap roten under en PIN En fyrsiffrig PIN-kod är ungefär 13 bitar mot en offline-angripare som håller den förpackade raden.
Utöka npub för att bära båda nycklarna 1,184 bytes är inte en delbar identifierare, och det skulle bryta varje befintlig Nostr-klients analys av en adress som definieras som 32 bytes.
En nyckeldirektörstjänst Återinför den auktoritet som nätverket existerar för att undvika.Den som svarar på sökningen bestämmer vem som kan läsa meddelandet.
Anslut nyckeln till varje meddelande löser ingenting: sändaren behöver mottagarens nyckel före det första meddelandet, vilket är exakt fallet med inget tidigare meddelande att bära det.
In-band förhandlingsförmåga Skapar en nedgraderad yta En angripare som kan ta bort en förmåga flagga tvingar den klassiska vägen.
Endast postkvant, ingen klassisk fot Avvisar decennier av analys av secp256k1 i utbyte mot en mycket yngre primitiv. både är fallet.

12Genomförandeparitet

Nymchat levererar två oberoende implementeringar av denna konstruktion - en i JavaScript för webbapplikationen, en i Dart för mobila applikationer, inklusive en från början ML-KEM-768-port.

Dart ML-KEM-implementeringen valideras mot den officiella Nästa ACVP Kända svarstester för ML-KEM-768 (ML-KEM-*-FIPS203) — 25 nyckelgenerering, 25 inkapsling och 10 decapsulation fall, körs som sin egen uppsättning. Dessa är de vektorer som NIST publicerar för att validera en implementering, så att passera dem är bevis på att porten är korrekt, inte bara bevis på att de två klienterna är överens med varandra. Dessutom genereras en delad fixture av testvektorer – fröderivation, inkapsling, både nyttolastformat och kompletta presentförpackningar – från JavaScript-referensen och kontrolleras av båda testpaketen. Root-hemligheten utökar den fixture istället för att ersätta den: rot till frö, rot till nyckelpar, rotens offentliga fingeravtryck, och den härledda nyckeln, nonce och associerade data i det yttre lagret är deras egna vektorer nympq1… En avvikelse i var och en av implementationerna misslyckas med att bygga istället för att producera ett meddelande som den andra klienten inte kan öppna.

Det är vad som säger en enhet &ldquo;detta är roten jag håller&rdquo; från &ldquo;detta är en annan en&rdquo;, och en klient som inte kunde reproducera en annan kunds fingeravtryck skulle läsa en perfekt bra post som ingen post alls - och sedan, efter avsnitt 3.3, mynta en andra rot och dela identiteten.

Nymchat är Öppen källa under AGPL-3.0. Den kryptografiska kärnan som beskrivs här är js/nym-crypto.js och js/modules/pq.js på webbsidan, och lib/core/crypto/ med lib/features/identity/pq_registry.dart för mobila kunder.

För en kortare, icke-teknisk förklaring, se Kunskapsbassida om kvantbeständig kryptering.