Diese Übersetzung wurde mittels maschinellem Lernen erstellt und ist möglicherweise nicht 100% korrekt. Englische Version anzeigen

PQ-Hybrid-NTCP2

Post-quanten-hybride Variante des NTCP2-Transportprotokolls unter Verwendung von ML-KEM

Status

Beta Q1 2026, Veröffentlichung Q2 2026

Übersicht

Dies ist die hybride post-quanten-sichere Variante des NTCP2-Transportprotokolls, wie sie in Vorschlag 169 entworfen wurde. Siehe diesen Vorschlag für zusätzlichen Hintergrund.

PQ Hybrid NTCP2 ist nur für dieselbe Adresse und denselben Port wie standardmäßiges NTCP2 definiert. Der Betrieb an einem anderen Port oder ohne Unterstützung für standardmäßiges NTCP2 ist nicht zulässig und wird dies mehrere Jahre lang auch nicht sein, bis standardmäßiges NTCP2 als veraltet gilt.

Diese Spezifikation beschreibt ausschließlich die Änderungen, die erforderlich sind, um NTCP2 um PQ-Hybrid zu erweitern. Für die Grundimplementierungsdetails siehe die NTCP2-Spezifikation.

Design

Wir unterstützen die NIST FIPS 203- und 204-Standards FIPS 203 FIPS 204 , die auf CRYSTALS-Kyber und CRYSTALS-Dilithium (Versionen 3.1, 3 und älter) basieren, aber NICHT kompatibel damit sind.

Schlüsselaustausch

PQ KEM bietet nur temporäre Schlüssel und unterstützt keine statischen Schlüssel-Handshakes wie Noise XK und IK direkt. Die Verschlüsselungstypen sind identisch mit denen im PQ Hybrid Ratchet und werden im Dokument zu gemeinsamen Strukturen /docs/specs/common-structures/ definiert, wie in FIPS 203 . Hybride Typen sind nur in Kombination mit X25519 definiert.

Die Verschlüsselungstypen sind:

TypeCodeNTCP2 Version
MLKEM512_X2551953
MLKEM768_X2551964
MLKEM1024_X2551975
### Zulässige Kombinationen

Die neuen Verschlüsselungstypen werden in den RouterAddresses angezeigt. Der Verschlüsselungstyp im Schlüsselzertifikat bleibt Typ 4.

Spezifikation

Handshake-Muster

Die Handshakes verwenden Noise Protocol Handshake-Muster.

Die folgende Buchstabenzuordnung wird verwendet:

  • e = einmaliger temporärer Schlüssel
  • s = statischer Schlüssel
  • p = Nachrichtennutzlast
  • e1 = einmaliger temporärer PQ-Schlüssel, gesendet von Alice an Bob
  • ekem1 = der KEM-Chiffretext, gesendet von Bob an Alice

Die folgenden Änderungen an XK und IK für die hybride Vorwärtsgeheimhaltung (hfs) entsprechen den Vorgaben aus Abschnitt 5 der Noise HFS-Spezifikation :

XK:                       XKhfs:
  <- s                      <- s
  ...                       ...
  -> e, es, p               -> e, es, e1, p
  <- e, ee, p               <- e, ee, ekem1, p
  -> s, se                  -> s, se
  <- p                      <- p
  p ->                      p ->


  e1 and ekem1 are encrypted. See pattern definitions below.
  NOTE: e1 and ekem1 are different sizes (unlike X25519)

Das e1-Muster ist wie folgt definiert, wie in Abschnitt 4 der Noise HFS-Spezifikation festgelegt:

For Alice:
  (encap_key, decap_key) = PQ_KEYGEN()

  // EncryptAndHash(encap_key)
  ciphertext = ENCRYPT(k, n, encap_key, ad)
  n++
  MixHash(ciphertext)

  For Bob:

  // DecryptAndHash(ciphertext)
  encap_key = DECRYPT(k, n, ciphertext, ad)
  n++
  MixHash(ciphertext)

Das ekem1-Muster ist wie folgt definiert, wie in Abschnitt 4 der Noise HFS-Spezifikation spezifiziert:

For Bob:

  (kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)

  // EncryptAndHash(kem_ciphertext)
  ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
  MixHash(ciphertext)

  // MixKey
  MixKey(kem_shared_key)


  For Alice:

  // DecryptAndHash(ciphertext)
  kem_ciphertext = DECRYPT(k, n, ciphertext, ad)
  MixHash(ciphertext)

  // MixKey
  kem_shared_key = DECAPS(kem_ciphertext, decap_key)
  MixKey(kem_shared_key)

Noise-Handshake-KDF

Übersicht

Der Hybrid-Handshake ist in der Noise HFS-Spezifikation definiert. Die erste Nachricht, von Alice an Bob, enthält e1, den Kapselungsschlüssel, vor dem Nachrichtennutzdaten. Dieser wird als zusätzlicher statischer Schlüssel behandelt; rufe EncryptAndHash() darauf auf (als Alice) oder DecryptAndHash() (als Bob). Danach werden die Nachrichtennutzdaten wie üblich verarbeitet.

Die zweite Nachricht von Bob an Alice enthält ekem1, den Chiffretext, vor der Nutzlast der Nachricht. Dies wird als zusätzlicher statischer Schlüssel behandelt; rufe EncryptAndHash() darauf auf (als Bob) bzw. DecryptAndHash() (als Alice). Danach wird der kem_shared_key berechnet und MixKey(kem_shared_key) aufgerufen. Anschließend wird die Nachrichtennutzlast wie üblich verarbeitet.

Definierte ML-KEM-Operationen

Wir definieren die folgenden Funktionen, die den verwendeten kryptografischen Bausteinen entsprechen, wie in FIPS 203 festgelegt.

(encap_key, decap_key) = PQ_KEYGEN()

Alice creates the encapsulation and decapsulation keys
The encapsulation key is sent in message 1.
encap_key and decap_key sizes vary based on ML-KEM variant.

(Chiffrat, kem_shared_key) = ENCAPS(encap_key)

Bob calculates the ciphertext and shared key,
using the ciphertext received in message 1.
The ciphertext is sent in message 2.
ciphertext size varies based on ML-KEM variant.
The kem_shared_key is always 32 bytes.

kem_shared_key = DECAPS(Ziffertext, decap_key)

Alice calculates the shared key,
using the ciphertext received in message 2.
The kem_shared_key is always 32 bytes.

Beachten Sie, dass sowohl der encap_key als auch der Ciphertext innerhalb der ChaCha/Poly-Blöcke in den Noise-Handshake-Nachrichten 1 und 2 verschlüsselt sind. Sie werden im Rahmen des Handshake-Prozesses entschlüsselt.

Der kem_shared_key wird mit MixHash() in den Verkettungsschlüssel eingemischt. Siehe unten für Details.

Alice-KDF für Nachricht 1

Nach dem ’es’-Nachrichtenmuster und vor der Nutzlast hinzufügen:

This is the "e1" message pattern:
  (encap_key, decap_key) = PQ_KEYGEN()

  // EncryptAndHash(encap_key)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  ciphertext = ENCRYPT(k, n, encap_key, ad)
  n++

  // MixHash(ciphertext)
  h = SHA256(h || ciphertext)


  End of "e1" message pattern.

  NOTE: For the next section (payload for XK or static key for IK),
  the keydata and chain key remain the same,
  and n now equals 1 (instead of 0 for non-hybrid).

Bob KDF für Nachricht 1

Nach dem ’es’-Nachrichtenmuster und vor der Nutzlast hinzufügen:

This is the "e1" message pattern:

  // DecryptAndHash(encap_key_section)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  encap_key = DECRYPT(k, n, encap_key_section, ad)
  n++

  // MixHash(encap_key_section)
  h = SHA256(h || encap_key_section)

  End of "e1" message pattern.

  NOTE: For the next section (payload for XK or static key for IK),
  the keydata and chain key remain the same,
  and n now equals 1 (instead of 0 for non-hybrid).

Bob-KDF für Nachricht 2

Für XK: Fügen Sie nach dem ’ee’-Nachrichtenmuster und vor der Nutzlast Folgendes hinzu:

This is the "ekem1" message pattern:

  (kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)

  // EncryptAndHash(kem_ciphertext)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)

  // MixHash(ciphertext)
  h = SHA256(h || ciphertext)

  // MixKey(kem_shared_key)
  keydata = HKDF(chainKey, kem_shared_key, "", 64)
  chainKey = keydata[0:31]

  End of "ekem1" message pattern.

  // AEAD parameters for payload section
  ... as in standard SSU2 ...
  k = keydata[32:63]
  ...

Alice-KDF für Nachricht 2

Fügen Sie nach dem Muster der Nachricht „ee“ Folgendes hinzu:

This is the "ekem1" message pattern:

  // DecryptAndHash(kem_ciphertext_section)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  kem_ciphertext = DECRYPT(k, n, kem_ciphertext_section, ad)

  // MixHash(kem_ciphertext_section)
  h = SHA256(h || kem_ciphertext_section)

  // MixKey(kem_shared_key)
  kem_shared_key = DECAPS(kem_ciphertext, decap_key)
  keydata = HKDF(chainKey, kem_shared_key, "", 64)
  chainKey = keydata[0:31]

  End of "ekem1" message pattern.

  // AEAD parameters for payload section
  ... as in standard SSU2 ...
  k = keydata[32:63]
  ...

KDF für Nachricht 3 (nur XK)

unchanged

KDF für split()

unchanged

Handshake-Details

Noise-Identifikatoren

  • „Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256“
  • „Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256“
  • „Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM1024_ChaChaPoly_SHA256“

1) SessionRequest

Änderungen: Das aktuelle NTCP2 enthält nur die Optionen in einem einzigen ChaCha-Abschnitt. Mit ML-KEM wird es einen neuen ChaCha-Abschnitt vor den Optionen geben, der den verschlüsselten Öffentlichen PQ-Schlüssel enthält.

Damit PQ- und Nicht-PQ-NTCP2-Verbindungen auf derselben Routeradresse und demselben Port unterstützt werden können, verwenden wir das höchstwertige Bit des X-Werts (X25519 ephemeraler öffentlicher Schlüssel), um anzugeben, dass es sich um eine PQ-Verbindung handelt. Dieses Bit ist für Nicht-PQ-Verbindungen immer deaktiviert.

Für Alice, nachdem die Nachricht durch Noise verschlüsselt wurde, aber vor der AES-Verfälschung von X, setze X[31] |= 0x7f.

Für Bob, nach der AES-Deobfuskation von X, teste X[31] & 0x80. Wenn das Bit gesetzt ist, lösche es mit X[31] &= 0x7f und entschlüssele via Noise als PQ-Verbindung. Wenn das Bit nicht gesetzt ist, entschlüssele via Noise wie üblich als Nicht-PQ-Verbindung.

Für PQ NTCP2, das auf einer anderen Routeradresse und einem anderen Port angeboten wird, ist dies nicht erforderlich.

Weitere Informationen finden Sie im Abschnitt „Veröffentlichte Adressen“ weiter unten.

Rohinhalte:

  +----+----+----+----+----+----+----+----+
  |        MS bit set to 1 and then       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted X         |
  +             (32 bytes)                +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaChaPoly encrypted data (MLKEM)   |
  +      (see table below for length)     +
  |   k defined in KDF for message 1      |
  +   n = 0                               +
  |   see KDF for associated data         |
  ~                                       ~
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   ChaCha20 encrypted data (options)   |
  +         16 bytes                      +
  |   k defined in KDF for message 1      |
  +   n = 1                               +
  |   see KDF for associated data         |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  ~         padding (optional)            ~
  |     length defined in options block   |
  +----+----+----+----+----+----+----+----+

  Same as current specification except add a second ChaChaPoly frame

Unverschlüsselte Daten (Poly1305-Authentifizierungstag nicht angezeigt):

  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                   X                   |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM encap_key            |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |               options                 |
  +              (16 bytes)               +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

Hinweis: Das Versionsfeld im Optionsblock der Nachricht 1 muss auch für PQ-Verbindungen auf 2 gesetzt werden.

Größen:

TypeType CodeX lenMsg 1 lenMsg 1 Enc lenMsg 1 Dec lenPQ key lenopt len
X2551943264+pad3216--16
MLKEM512_X25519532880+pad84881680016
MLKEM768_X255196321264+pad12321200118416
MLKEM1024_X255197321648+pad16161584156816
Hinweis: Typ-Codes sind nur für den internen Gebrauch. Router behalten den Typ 4, und die Unterstützung wird in den Router-Adressen angegeben.

2) SessionCreated

Änderungen: Das aktuelle NTCP2 enthält nur die Optionen in einem einzelnen ChaCha-Abschnitt. Mit ML-KEM wird ein neuer ChaCha-Abschnitt vor den Optionen hinzugefügt, der den verschlüsselten PQ-Ciphertext enthält.

Rohinhalte:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted Y         |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaCha20 encrypted data (MLKEM)     |
  -      (see table below for length)     -
  +   k defined in KDF for message 2      +
  |  (before mixKey)                      |
  +  n = 0; see KDF for associated data   +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaCha20 encrypted data (options)   |
  -           16 bytes                    -
  +   k defined in KDF for message 2      +
  |  (after mixKey)                       |
  +  n = 0; see KDF for associated data   +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Same as current specification except add a second ChaChaPoly frame

Unverschlüsselte Daten (Poly1305-Authentifizierungstag nicht angezeigt):

  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                  Y                    |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM Ciphertext           |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |               options                 |
  +              (16 bytes)               +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

Größen:

TypeType CodeY lenMsg 2 lenMsg 2 Enc lenMsg 2 Dec lenPQ CT lenopt len
X2551943264+pad3216--16
MLKEM512_X25519532848+pad81678476816
MLKEM768_X255196321136+pad11041104108816
MLKEM1024_X255197321616+pad15841584156816
Hinweis: Typ-Codes sind nur für den internen Gebrauch. Router behalten den Typ 4, und die Unterstützung wird in den Router-Adressen angegeben.

3) SessionConfirmed

Unverändert

Schlüsselableitungsfunktion (KDF) (für die Datenphase)

Unverändert

Veröffentlichte Adressen

Verwenden Sie in allen Fällen den NTCP2-Transportnamen wie gewohnt.

Verwenden Sie dieselbe Adresse/denselben Port wie bei nicht-PQ, nicht-firewalled. Nur eine PQ-Variante wird unterstützt. In der Router-Adresse veröffentlichen Sie v=2 (wie üblich) und den neuen Parameter pq=[3|4|5], um MLKEM 512/768/1024 anzugeben. Alice setzt das MSB des temporären Schlüssels (key[31] & 0x80) in der Sitzungsanfrage, um anzugeben, dass es sich um eine hybride Verbindung handelt. Siehe oben. Ältere Router werden den pq-Parameter ignorieren und wie gewohnt nicht-pq verbinden.

Unterschiedliche Adressen/Ports für nicht-PQ, oder nur PQ, nicht hinter einer Firewall, werden NICHT unterstützt. Dies wird nicht implementiert, bis nicht-PQ NTCP2 deaktiviert ist, was erst in mehreren Jahren der Fall sein wird. Wenn nicht-PQ deaktiviert ist, könnten mehrere PQ-Varianten unterstützt werden, jedoch nur eine pro Adresse. Sobald dies unterstützt wird, muss in der Routeradresse v=[3|4|5] veröffentlicht werden, um MLKEM 512/768/1024 anzugeben. Alice setzt das MSB des ephemeren Schlüssels nicht. Ältere Router prüfen den v-Parameter und überspringen diese Adresse als nicht unterstützte Variante.

Gefeuwalled-Adressen (keine IP veröffentlicht): In der Routeradresse v=2 veröffentlichen (wie üblich). Es ist nicht notwendig, einen pq-Parameter zu veröffentlichen.

Alice kann sich mit einem PQ-Bob über die PQ-Variante verbinden, die Bob veröffentlicht, unabhängig davon, ob Alice PQ-Unterstützung in ihren Router-Infos annonciert oder ob sie dieselbe Variante annonciert.

Maximale Auffüllung

In der aktuellen Spezifikation ist für die Nachrichten 1 und 2 eine „angemessene“ Menge an Auffüllung (Padding) vorgesehen, wobei ein Bereich von 0–31 Bytes empfohlen wird, ohne dass ein Maximum festgelegt ist.

Bis API 0.9.68 (Release 2.11.0) implementierte Java I2P eine maximale Auffüllung von 256 Bytes für Nicht-PQ-Verbindungen, was jedoch zuvor nicht dokumentiert war. Ab API 0.9.69 (Release 2.12.0) implementiert Java I2P dieselbe maximale Auffüllung für Nicht-PQ-Verbindungen wie für MLKEM-512. Siehe Tabelle unten.

Verwenden Sie die definierte Nachrichtengröße als maximale Auffüllung, das heißt, die maximale Auffüllung verdoppelt die Nachrichtengröße für PQ-Verbindungen, wie folgt:

Message Max Paddingnon-PQ (thru 0.9.68)non-PQ (as of 0.9.69)MLKEM-512MLKEM-768MLKEM-1024
Session Request25688088012641648
Session Created25684884811361616
## Analyse der Overhead-Kosten

Schlüsselaustausch

Größenanstieg (Bytes):

TypePubkey (Msg 1)Ciphertext (Msg 2)
MLKEM512_X25519+816+784
MLKEM768_X25519+1200+1104
MLKEM1024_X25519+1584+1584
## Sicherheitsanalyse

Die NIST-Sicherheitskategorien sind in NIST-Präsentation , Folie 10, zusammengefasst. Vorläufige Kriterien: Unsere minimale NIST-Sicherheitskategorie sollte bei Hybridprotokollen 2 und bei reinen PQ-Protokollen 3 betragen.

CategoryAs Secure As
1AES128
2SHA256
3AES192
4SHA384
5AES256
### Handshakes

Dies sind alles hybride Protokolle. Implementierungen sollten MLKEM768 bevorzugen; MLKEM512 ist nicht sicher genug.

NIST-Sicherheitskategorien FIPS 203 :

AlgorithmSecurity Category
MLKEM5121
MLKEM7683
MLKEM10245
## Implementierungshinweise

Bibliotheksunterstützung

Die Bibliotheken Bouncycastle, BoringSSL und WolfSSL unterstützen jetzt MLKEM und MLDSA. Die Unterstützung durch OpenSSL wird im Release 3.5 am 8. April 2025 erfolgen OpenSSL .

Identifizierung eingehenden Datenverkehrs

Wir setzen das MSB des temporären Schlüssels (key[31] & 0x80) im Sitzungsanfragepaket, um anzugeben, dass es sich um eine hybride Verbindung handelt. Dies ermöglicht es uns, sowohl standardmäßiges NTCP als auch hybrides NTCP am selben Port zu betreiben. Für eingehende Verbindungen wird nur eine hybride Variante unterstützt und in der Routeradresse angekündigt. Zum Beispiel pq=3 oder pq=4.

Verschleierung

Als Alice, für eine PQ-Verbindung, vor der Verschleierung, setze X[31] |= 0x80. Dadurch wird X ein ungültiger X25519-Öffentlicher Schlüssel. Nach der Verschleierung wird AES-CBC diesen Wert randomisieren. Das MSB von X wird nach der Verschleierung zufällig sein.

Als Bob testen, ob (X[31] & 0x80) != 0 nach der De-Verfälschung gilt. Wenn ja, handelt es sich um eine PQ-Verbindung.

Die minimale Router-Version, die für NTCP2-PQ erforderlich ist, steht noch aus (TBD).

Hinweis: Typ-Codes sind nur für den internen Gebrauch. Router behalten den Typ 4, und die Unterstützung wird in den Router-Adressen angegeben.

Router-Kompatibilität

Transportnamen

Verwenden Sie in allen Fällen wie gewohnt den NTCP2-Transportnamen. Ältere Router werden den pq-Parameter ignorieren und wie üblich mit standardmäßigem NTCP2 eine Verbindung herstellen.

Referenzen

Was this page helpful?