Status
Beta Q2 2026, Veröffentlichung Q3 2026
Übersicht
Dies ist die hybride post-quantengesicherte Variante des SSU2-Transportprotokolls, wie sie in Proposal 169 entworfen wurde. Weitere Hintergrundinformationen sind in diesem Proposal zu finden.
PQ Hybrid SSU2 ist nur auf derselben Adresse und demselben Port wie Standard-SSU2 definiert. Der Betrieb auf einem anderen Port oder ohne Standard-SSU2-Unterstützung ist nicht zulässig und wird es auch für mehrere Jahre nicht sein, bis Standard-SSU2 abgekündigt wird.
Diese Spezifikation dokumentiert ausschließlich die Änderungen, die am Standard-SSU2 erforderlich sind, um PQ Hybrid zu unterstützen. Die grundlegenden Implementierungsdetails sind der SSU2-Spezifikation zu entnehmen.
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, jedoch NICHT mit diesen kompatibel sind.
Schlüsselaustausch
PQ KEM bietet ausschließlich ephemere Schlüssel und unterstützt keine statischen Schlüssel-Handshakes wie Noise XK und IK. Die Verschlüsselungstypen sind dieselben wie im PQ Hybrid Ratchet und werden im Dokument für gemeinsame Strukturen /docs/specs/common-structures/ definiert; wie in FIPS 203 sind Hybrid-Typen nur in Kombination mit X25519 definiert.
Die Verschlüsselungstypen sind:
| Type | Code | SSU2 Version |
|---|---|---|
| MLKEM512_X25519 | 5 | 3 |
| MLKEM768_X25519 | 6 | 4 |
Die neuen Verschlüsselungstypen werden in den RouterAddresses angegeben. Der Verschlüsselungstyp im Key-Zertifikat bleibt weiterhin Typ 4.
Spezifikation
Handshake-Muster
Handshakes verwenden Noise Protocol -Handshake-Muster.
Die folgende Buchstabenzuordnung wird verwendet:
- e = einmaliger ephemerer Schlüssel
- s = statischer Schlüssel
- p = Nachrichtennutzlast
- e1 = einmaliger ephemerer PQ-Schlüssel, von Alice an Bob gesendet
- ekem1 = der KEM-Chiffretext, von Bob an Alice gesendet
Die folgenden Modifikationen an XK und IK für hybride Vorwärtsgeheimhaltung (hfs) sind wie in Noise HFS spec Abschnitt 5 spezifiziert:
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 Noise HFS spec Abschnitt 4 angegeben:
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 Noise HFS spec Abschnitt 4 angegeben:
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 hybride Handshake ist in der Noise HFS spec
definiert. Die erste Nachricht von Alice an Bob enthält e1, den Kapselungsschlüssel (encapsulation key), vor der Nachrichtennutzlast. Dieser wird als zusätzlicher statischer Schlüssel behandelt; rufe darauf EncryptAndHash() (als Alice) bzw. DecryptAndHash() (als Bob) auf. Anschließend wird die Nachrichtennutzlast wie gewohnt verarbeitet.
Die zweite Nachricht, von Bob an Alice, enthält ekem1, den Chiffretext, vor der Nachrichtennutzlast. Dieser wird als zusätzlicher statischer Schlüssel behandelt; rufen Sie darauf EncryptAndHash() (als Bob) oder DecryptAndHash() (als Alice) auf. Berechnen Sie dann den kem_shared_key und rufen Sie MixKey(kem_shared_key) auf. Anschließend wird die Nachrichtennutzlast wie gewohnt verarbeitet.
Definierte ML-KEM-Operationen
Wir definieren die folgenden Funktionen, die den kryptografischen Bausteinen entsprechen, wie sie in FIPS 203 festgelegt sind.
(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.
(ciphertext, 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(ciphertext, 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 in ChaCha/Poly-Blöcken innerhalb der 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. Weitere Details siehe unten.
Alice KDF für Nachricht 1
Nach dem ’es’-Nachrichtenmuster und vor der Nutzlast einfü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 einfü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: Nach dem ’ee’ Nachrichtenmuster und vor der Nutzlast, füge 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.
Alice KDF für Nachricht 2
Nach dem ’ee’-Nachrichtenmuster hinzufügen:
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.
KDF für Nachricht 3
unverändert
KDF für split()
unverändert
Handshake-Details
Noise-Bezeichner
- “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256”
- “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256”
Beachten Sie, dass MLKEM-1024 für SSU2 NICHT unterstützt wird, da die Schlüssel zu groß sind, um in ein Standard-1500-Byte-Datagramm zu passen.
Langer Header
Der lange Header ist 32 Byte groß. Er wird verwendet, bevor eine Session erstellt wurde, für Token Request, SessionRequest, SessionCreated und Retry. Er wird außerdem für Peer Test- und Hole Punch-Nachrichten außerhalb einer Session verwendet.
Setzen Sie in den folgenden Nachrichten das Feld ver (Version) im langen Header auf 3 oder 4, um MLKEM-512 bzw. MLKEM-768 anzugeben.
- (0) Sitzungsanfrage
- (1) Sitzung erstellt
- (9) Wiederholen
- (10) Token-Anfrage
- (11) Hole Punch
In den folgenden Nachrichten ist das ver-Feld (Version) im langen Header wie üblich auf 2 zu setzen, auch wenn MLKEM-512 oder MLKEM-768 unterstützt wird. Implementierungen können den Wert auch auf 3 oder 4 setzen, wenn die Gegenseite dies unterstützt, jedoch ist dies nicht zwingend erforderlich. Implementierungen sollten jeden Wert von 2 bis 4 akzeptieren.
- (7) Peer Test (Nachrichten außerhalb der Sitzung 5–7)
Diskussion: Das Setzen des Versionsfelds auf 3 oder 4 ist möglicherweise nicht für alle Nachrichtentypen zwingend erforderlich, erleichtert jedoch die frühere Fehlererkennung bei nicht unterstützten Post-Quantum-Verbindungen. Token Request und Retry (Typen 9 und 10) sollten aus Konsistenzgründen die Versionen 3/4 verwenden. Hole Punch-Nachrichten (Typ 11) erfordern diese Behandlung möglicherweise nicht, wir werden jedoch zur Einheitlichkeit dasselbe Muster befolgen. Peer Test-Nachrichten (Typ 7) befinden sich außerhalb einer Sitzung und signalisieren keine Absicht, eine Sitzung einzuleiten.
Vor der Header-Verschlüsselung:
+----+----+----+----+----+----+----+----+
| Destination Connection ID |
+----+----+----+----+----+----+----+----+
| Packet Number |type| ver| id |flag|
+----+----+----+----+----+----+----+----+
| Source Connection ID |
+----+----+----+----+----+----+----+----+
| Token |
+----+----+----+----+----+----+----+----+
Destination Connection ID :: 8 bytes, unsigned big endian integer
Packet Number :: 4 bytes, unsigned big endian integer
type :: The message type = 0, 1, 7, 9, 10, or 11
ver :: The protocol version = 2, 3, or 4 for non-PQ, MLKEM512, MLKEM768
id :: 1 byte, the network ID (currently 2, except for test networks)
flag :: 1 byte, unused, set to 0 for future compatibility
Source Connection ID :: 8 bytes, unsigned big endian integer
Token :: 8 bytes, unsigned big endian integer
Kurzer Header
unverändert
SessionRequest (Typ 0)
Änderungen: Das aktuelle SSU2 enthält im ChaCha-Abschnitt nur die Block-Daten. Mit ML-KEM wird der ChaCha-Abschnitt zusätzlich den verschlüsselten öffentlichen PQ-Schlüssel enthalten.
KDF-Änderung zum Schutz vor Spoofing: Um die in Proposal 165 [Prop165]_ aufgeworfenen Probleme zu lösen, jedoch mit einem anderen Ansatz, modifizieren wir die KDF für Session Request. Dies gilt ausschließlich für PQ-Sessions. Die KDF für Nicht-PQ-Sessions bleibt unverändert.
// End of KDF for initial chain key (unchanged)
// Bob static key
// MixHash(bpk)
h = SHA256(h || bpk);
// Start of KDF for session request
// NEW for PQ only
// bhash = Bob router hash (32 bytes)
// MixHash(bhash)
h = SHA256(h || bhash);
// Rest of KDF for session request, unchanged, as in SSU2 spec
// MixHash(header)
h = SHA256(h || header)
...
Roher Inhalt:
+----+----+----+----+----+----+----+----+
| Long Header bytes 0-15, ChaCha20 |
+ encrypted with Bob intro key +
| See Header Encryption KDF |
+----+----+----+----+----+----+----+----+
| Long Header bytes 16-31, ChaCha20 |
+ encrypted with Bob intro key n=0 +
| |
+----+----+----+----+----+----+----+----+
| |
+ X, ChaCha20 encrypted +
| with Bob intro key n=0 |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaCha20 encrypted data (MLKEM) |
+ (length varies) +
| k defined in KDF for Session Request |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaCha20 encrypted data (payload) |
+ (length varies) +
| k defined in KDF for Session Request |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| |
+ Poly1305 MAC (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
Unverschlüsselte Daten (Poly1305-Authentifizierungs-Tag nicht dargestellt):
+----+----+----+----+----+----+----+----+
| Destination Connection ID |
+----+----+----+----+----+----+----+----+
| Packet Number |type| ver| id |flag|
+----+----+----+----+----+----+----+----+
| Source Connection ID |
+----+----+----+----+----+----+----+----+
| Token |
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ML-KEM encap_key |
+ (see table below for length) +
| |
+----+----+----+----+----+----+----+----+
| Noise payload (block data) |
+ (length varies) +
| see below for allowed blocks |
+----+----+----+----+----+----+----+----+
Größen, ohne IP-Overhead:
| Typ | Typ-Code | X Länge | Nachricht 1 Länge | Nachricht 1 Verschlüsselte Länge | Nachricht 1 Entschlüsselte Länge | PQ-Schlüssellänge | pl Länge |
|---|---|---|---|---|---|---|---|
| X25519 | 4 | 32 | 80+pl | 16+pl | pl | – | pl |
| MLKEM512_X25519 | 5 | 32 | 896+pl | 832+pl | 800+pl | 800 | pl |
| MLKEM768_X25519 | 6 | 32 | 1280+pl | 1216+pl | 1184+pl | 1184 | pl |
| MLKEM1024_X25519 | 7 | n/a | zu groß | ||||
| Hinweis: Typ-Codes sind nur für den internen Gebrauch bestimmt. Router bleiben vom Typ 4, und die Unterstützung wird in den Router-Adressen angegeben. |
Minimale MTU für MLKEM768_X25519: 1318 für IPv4 und 1338 für IPv6. Siehe unten.
SessionCreated (Typ 1)
Änderungen: Das aktuelle SSU2 enthält im ChaCha-Abschnitt nur die Block-Daten. Mit ML-KEM wird der ChaCha-Abschnitt zusätzlich den verschlüsselten öffentlichen PQ-Schlüssel enthalten.
Roher Inhalt:
+----+----+----+----+----+----+----+----+
| Long Header bytes 0-15, ChaCha20 |
+ encrypted with Bob intro key and +
| derived key, see Header Encryption KDF|
+----+----+----+----+----+----+----+----+
| Long Header bytes 16-31, ChaCha20 |
+ encrypted with derived key n=0 +
| See Header Encryption KDF |
+----+----+----+----+----+----+----+----+
| |
+ Y, ChaCha20 encrypted +
| with derived key n=0 |
+ (32 bytes) +
| See Header Encryption KDF |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaCha20 data (MLKEM) |
+ Encrypted and authenticated data +
| length varies |
+ k defined in KDF for Session Created +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaCha20 data (payload) |
+ Encrypted and authenticated data +
| length varies |
+ k defined in KDF for Session Created +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Poly1305 MAC (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
Unverschlüsselte Daten (Poly1305-Authentifizierungs-Tag nicht angezeigt):
+----+----+----+----+----+----+----+----+
| Destination Connection ID |
+----+----+----+----+----+----+----+----+
| Packet Number |type| ver| id |flag|
+----+----+----+----+----+----+----+----+
| Source Connection ID |
+----+----+----+----+----+----+----+----+
| Token |
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ML-KEM Ciphertext |
+ (see table below for length) +
| |
+----+----+----+----+----+----+----+----+
| Noise payload (block data) |
+ (length varies) +
| see below for allowed blocks |
+----+----+----+----+----+----+----+----+
Größen, ohne IP-Overhead:
| Typ | Typcode | Y-Länge | Msg 2-Länge | Msg 2 Enc-Länge | Msg 2 Dec-Länge | PQ CT-Länge | pl-Länge |
|---|---|---|---|---|---|---|---|
| X25519 | 4 | 32 | 80+pl | 16+pl | pl | – | pl |
| MLKEM512_X25519 | 5 | 32 | 864+pl | 800+pl | 768+pl | 768 | pl |
| MLKEM768_X25519 | 6 | 32 | 1184+pl | 1118+pl | 1088+pl | 1088 | pl |
| MLKEM1024_X25519 | 7 | n/a | zu groß | ||||
| Hinweis: Typ-Codes sind nur für den internen Gebrauch bestimmt. Router bleiben vom Typ 4, und die Unterstützung wird in den Router-Adressen angegeben. |
Minimale MTU für MLKEM768_X25519: 1318 für IPv4 und 1338 für IPv6. Siehe unten.
SessionConfirmed (Typ 2)
unverändert
KDF für die Datenphase
unverändert
Relay und Peer-Test
Die folgenden Blöcke enthalten Versionsfelder. Sie bleiben bei Version 2 (zur Kompatibilität mit einem Nicht-PQ-Bob) und werden für PQ nicht auf Version 3/4 geändert.
- Relay Request
- Relay Response
- Relay Intro
- Peer Test
PQ-Signaturen: Relay-Blöcke, Peer-Test-Blöcke und Peer-Test-Nachrichten enthalten alle Signaturen. Leider sind PQ-Signaturen größer als die MTU. Es gibt derzeit keinen Mechanismus, um Relay- oder Peer-Test-Blöcke bzw. -Nachrichten über mehrere UDP-Pakete zu fragmentieren. Das Protokoll muss erweitert werden, um Fragmentierung zu unterstützen. Dies wird in einem separaten, noch zu erstellenden Vorschlag behandelt. Bis dessen Fertigstellung werden Relay und Peer Test nicht unterstützt.
Veröffentlichte Adressen
Verwenden Sie in allen Fällen den SSU2-Transportnamen wie gewohnt. MLKEM-1024 wird nicht unterstützt.
Verwende dieselbe Adresse/denselben Port wie bei nicht-PQ, nicht-firewalled. Eine oder beide PQ-Varianten werden unterstützt. Veröffentliche in der Router-Adresse v=2 (wie üblich) sowie den neuen Parameter pq=[3|4|3,4|4,3], um MLKEM 512/768/beide anzugeben. Router mit einer MTU unterhalb des unten angegebenen Minimums dürfen keinen „pq"-Parameter veröffentlichen, der „4" enthält. Veröffentliche 4,3, um eine Präferenz für MLKEM-768 anzugeben, oder 3,4 für eine Präferenz für MLKEM-512. Die tatsächlich verwendete Version liegt im Ermessen des Initiators, und die angegebene Präferenz wird möglicherweise nicht berücksichtigt. Router mit einer MTU unterhalb des unten angegebenen Minimums dürfen keine Verbindung über MLKEM768 herstellen. Ältere Router ignorieren den pq-Parameter und verbinden sich wie gewohnt ohne PQ.
Verschiedene Adressen/Ports wie bei Nicht-PQ, oder PQ-only ohne Firewall werden NICHT unterstützt. Dies wird nicht implementiert, bis nicht-PQ SSU2 deaktiviert wird, was noch mehrere Jahre dauern wird. Wenn nicht-PQ deaktiviert ist, werden eine oder beide PQ-Varianten unterstützt. Veröffentlichen Sie in der router-Adresse v=[3|4|3,4|4,3], um MLKEM 512/768/beides anzugeben. Ältere router werden den v-Parameter prüfen und diese Adresse als nicht unterstützt überspringen.
Firewalled-Adressen (keine IP veröffentlicht): Veröffentlichen Sie in der Router-Adresse v=2 (wie gewohnt). Der pq-Parameter MUSS in Firewalled-Adressen veröffentlicht werden, um Relay zu unterstützen.
Alice kann sich mit einem PQ-fähigen Bob über die von Bob veröffentlichte PQ-Variante verbinden, unabhängig davon, ob Alice in ihren Router-Informationen PQ-Unterstützung ankündigt oder ob sie dieselbe Variante bewirbt.
MTU
Achten Sie darauf, die MTU bei MLKEM768 nicht zu überschreiten. Die minimale MTU für MLKEM768_X25519 beträgt 1318 für IPv4 und 1338 für IPv6 (ausgehend von einer minimalen Nutzlast von 10 Bytes mit einem DateTime- und einem Padding- oder RelayTagRequest-Block). Die minimale MTU für SSU2 im Allgemeinen beträgt 1280, daher können nicht alle Peers MLKEM768 verwenden. Veröffentlichen oder verwenden Sie MLKEM768 nicht, wenn die tatsächliche MTU geringer als das Minimum ist – weder lokal noch gemäß der vom Peer angegebenen MTU. Achten Sie darauf, die Padding-Größe nicht so zu wählen, dass Nachricht 1 oder 2 die lokale oder entfernte MTU überschreiten würde.
Overhead-Analyse
Schlüsselaustausch
Größenzunahme (Bytes):
| Type | Pubkey (Msg 1) | Ciphertext (Msg 2) |
|---|---|---|
| MLKEM512_X25519 | +816 | +784 |
| MLKEM768_X25519 | +1200 | +1104 |
Die NIST-Sicherheitskategorien sind in NIST-Präsentation Folie 10 zusammengefasst. Vorläufige Kriterien: Unsere minimale NIST-Sicherheitskategorie sollte 2 für hybride Protokolle und 3 für reine Post-Quanten-Protokolle (PQ-only) sein.
| Category | As Secure As |
|---|---|
| 1 | AES128 |
| 2 | SHA256 |
| 3 | AES192 |
| 4 | SHA384 |
| 5 | AES256 |
Dies sind alles hybride Protokolle. Implementierungen sollten MLKEM768 bevorzugen; MLKEM512 ist nicht sicher genug.
NIST-Sicherheitskategorien FIPS 203 :
| Algorithm | Security Category |
|---|---|
| MLKEM512 | 1 |
| MLKEM768 | 3 |
Bibliotheksunterstützung
Die Bibliotheken Bouncycastle, BoringSSL und WolfSSL unterstützen MLKEM und MLDSA bereits jetzt. OpenSSL-Unterstützung ist für deren Version 3.5 am 8. April 2025 geplant OpenSSL .
Identifizierung des eingehenden Datenverkehrs
Wir setzen das MSB (Most Significant Bit) des ephemeren Schlüssels (key[31] & 0x80) in der Session-Request, um anzuzeigen, dass es sich um eine Hybrid-Verbindung handelt. Dies ermöglicht es uns, sowohl Standard-NTCP als auch Hybrid-NTCP auf demselben Port zu betreiben. Für eingehende Verbindungen wird nur eine Hybrid-Variante unterstützt und in der router-Adresse bekanntgegeben. Zum Beispiel pq=3 oder pq=4.
Verschleierung
Als Alice, für eine PQ-Verbindung, vor der Verschleierung, setze X[31] |= 0x80. Dies macht X zu einem ungültigen X25519-Public-Key. Nach der Verschleierung wird AES-CBC ihn randomisieren. Das MSB von X wird nach der Verschleierung zufällig sein.
Als Bob prüfen, ob (X[31] & 0x80) != 0 nach der De-Verschleierung gilt. Falls ja, handelt es sich um eine PQ-Verbindung.
Die mindestens erforderliche Router-Version für NTCP2-PQ ist noch festzulegen.
Hinweis: Typ-Codes sind nur für den internen Gebrauch bestimmt. Router bleiben vom Typ 4, und die Unterstützung wird in den Router-Adressen angegeben.
Router-Kompatibilität
Transportbezeichnungen
Verwende in allen Fällen wie gewohnt den NTCP2-Transportnamen. Ältere Router ignorieren den pq-Parameter und verbinden sich wie üblich über Standard-NTCP2.