Newer
Older
===================================
Post-Quantum Crypto Protocols
===================================
.. meta::
:author: zzz
:created: 2025-01-21
:thread: http://zzz.i2p/topics/3294
:status: Open
:target: 0.9.80
.. contents::
Overview
========
While research and competition for suitable post-quantum (PQ)
have not become clear until recently.
We started looking at the implications of PQ crypto
in 2022 [FORUM]_.
TLS standards added hybrid encryption support in the last two years and it now
is used for a significant portion of encrypted traffic on the internet
due to support in Chrome and Firefox [CLOUDFLARE]_.
NIST recently finalized and published the recommended algorithms
for post-quantum cryptography [NIST-PQ]_.
Several common cryptography libraries now support the NIST standards
or will be releasing support in the near future.
Both [CLOUDFLARE]_ and [NIST-PQ]_ recommend that migration start immediately.
See also the 2022 NSA PQ FAQ [NSA-PQ]_.
I2P should be a leader in security and cryptography.
Now is the time to implement the recommended algorithms.
Using our flexible crypto type and signature type system,
we will add types for hybrid crypto, and for PQ and hybrid signatures.
Goals
=====
- Select PQ-resistant algorithms
- Add PQ-only and hybrid algorithms to I2P protocols where appropriate
- Select best variants after implementation, testing, analysis, and research
- Add support incrementally and with backward compatibility
Non-Goals
=========
- Don't change one-way (Noise N) encryption protocols
Threat Model
============
- Routers at the OBEP or IBGW, possibly colluding,
storing garlic messages for later decryption (forward secrecy)
- Network observers
storing transport messages for later decryption (forward secrecy)
- Network participants forging signatures for RI, LS, streaming, datagrams,
or other structures
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Design
======
We will support the NIST FIPS 203 and 204 standards [FIPS203]_ [FIPS204]_
which are based on, but NOT compatible with,
CRYSTALS-Kyber and CRYSTALS-Dilithium (versions 3.1, 3, and older).
Key Exchange
-------------
We will support key exchange in the following protocols:
======= ========== ============== ===============
Proto Noise Type Support PQ? Support Hybrid?
======= ========== ============== ===============
NTCP2 XK no yes
SSU2 XK no yes
Ratchet IK no yes
TBM N no no
NetDB N no no
======= ========== ============== ===============
PQ KEM provides ephemeral keys only, and does not directly support
static-key handshakes such as Noise XK and IK.
While there is some recent research [PQ-WIREGUARD]_ on adapting Wireguard (IK)
for pure PQ crypto, there are several open questions, and
this approach is unproven.
Noise N does not use a two-way key exchange and so it is not suitable
for hybrid encryption.
So we will support hybrid encryption only, for NTCP2, SSU2, and Ratchet.
We will define the three ML-KEM variants as in [FIPS203]_,
for 3 new encryption types total.
Hybrid types will only be defined in combination with X25519.
================ ====
Type Code
================ ====
MLKEM512_X25519 5
MLKEM768_X25519 6
MLKEM1024_X25519 7
================ ====
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
Overhead will be substantial. Typical message 1 and 2 sizes (for XK and IK)
are currently around 100 bytes (before any additional payload).
This will increase by 8x to 15x depending on algorithm.
Signatures
-----------
We will support PQ and hybrid signatures in the following structures:
========================== ============== ===============
Type Support PQ? Support Hybrid?
========================== ============== ===============
RouterInfo yes yes
LeaseSet yes yes
Streaming SYN/SYNACK/Close yes yes
Repliable Datagrams yes yes
I2CP create session msg yes yes
SU3 files yes yes
X.509 certificates yes yes
Java keystores yes yes
========================== ============== ===============
So we will support both PQ-only and hybrid signatures.
We will define the three ML-DSA variants as in [FIPS204]_,
for 6 new signature types total.
Hybrid types will only be defined in combination with Ed25519.
We will use the standard ML-DSA, NOT the pre-hash variants (HashML-DSA).
============================ ====
Type Code
============================ ====
MLDSA44_EdDSA_SHA512_Ed25519 12
MLDSA65_EdDSA_SHA512_Ed25519 13
MLDSA87_EdDSA_SHA512_Ed25519 14
MLDSA44 15
MLDSA65 16
MLDSA87 17
============================ ====
X.509 certificates and other DER encodings will use the
composite structures and OIDs defined in [COMPOSITE-SIGS]_.
Overhead will be substantial. Typical Ed25519 destination and router identity
sizes are 391 bytes.
These will increase by 3.5x to 6.8x depending on algorithm.
Ed25519 signatures are 64 bytes.
These will increase by 38x to 76x depending on algorithm.
Typical signed RouterInfo, LeaseSet, repliable datagrams, and signed streaming messages are about 1KB.
These will increase by 3x to 8x depending on algorithm.
As the new destination and router identity types will not contain padding,
they will not be compressible. Sizes of destinations and router identities
that are gzipped in-transit will increase by 12x - 38x depending on algorithm.
TODO: Add RSA4096 hybrid types for su3?
For Destinations, the new signature types are supported with all encryption
types in the leaseset. Set the encryption type in the key certificate to NULL (255).
For RouterIdentities, ElGamal encryption type is deprecated.
The new signature types are supported with X25519 (type 4) encryption only.
The new encryption types will be indicated in the RouterAddresses.
The encryption type in the key certificate will continue to be type 4.
New Crypto Required
-------------------
- ML-KEM (formerly CRYSTALS-Kyber) [FIPS203]_
- ML-DSA (formerly CRYSTALS-Dilithium) [FIPS204]_
- SHA3-128 (formerly Keccak-256) [FIPS202]_ Used only for SHAKE128
- SHA3-256 (formerly Keccak-512) [FIPS202]_
- SHAKE128 and SHAKE256 (XOF extensions to SHA3-128 and SHA3-256) [FIPS202]_
Test vectors for SHA3-256, SHAKE128, and SHAKE256 are at [NIST-VECTORS]_.
Note that the Java bouncycastle library supports all the above.
Alternatives
-------------
We will not support [FIPS205]_ (Sphincs+), it is much much slower and bigger than ML-DSA.
We will not support the upcoming FIPS206 (Falcon), it is not yet standardized.
We will not support NTRU or other PQ candidates that were not standardized by NIST.
Specification
=============
Common Structures
-----------------
PublicKey
================ ================= ====== =====
Type Public Key Length Since Usage
================ ================= ====== =====
MLKEM512_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM512 800 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM768 1184 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM1024 1568 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
NULL 0 0.9.xx See proposal 169, for destinations with PQ sig types only, not for RIs or Leasesets
================ ================= ====== =====
Hybrid public keys are the X25519 key.
KEM public keys are the ephemeral PQ key sent from Alice to Bob.
PrivateKey
================ ================== ====== =====
Type Private Key Length Since Usage
================ ================== ====== =====
MLKEM512_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM512 1632 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM768 2400 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM1024 3168 0.9.xx See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
================ ================== ====== =====
Hybrid private keys are the X25519 key followed by the PQ key.
KEM private keys are the ciphertext sent from Bob to Alice.
SigningPublicKey
============================ ============== ====== =====
Type Length (bytes) Since Usage
============================ ============== ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 1344 0.9.xx See proposal 169
MLDSA65_EdDSA_SHA512_Ed25519 1984 0.9.xx See proposal 169
MLDSA87_EdDSA_SHA512_Ed25519 2624 0.9.xx See proposal 169
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
MLDSA44 1312 0.9.xx See proposal 169
MLDSA65 1952 0.9.xx See proposal 169
MLDSA87 2592 0.9.xx See proposal 169
============================ ============== ====== =====
Hybrid signing public keys are the Ed25519 key followed by the PQ key.
SigningPrivateKey
`````````````````
============================ ============== ====== =====
Type Length (bytes) Since Usage
============================ ============== ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 2592 0.9.xx See proposal 169
MLDSA65_EdDSA_SHA512_Ed25519 4064 0.9.xx See proposal 169
MLDSA87_EdDSA_SHA512_Ed25519 4928 0.9.xx See proposal 169
MLDSA44 2560 0.9.xx See proposal 169
MLDSA65 4032 0.9.xx See proposal 169
MLDSA87 4896 0.9.xx See proposal 169
============================ ============== ====== =====
Hybrid signing private keys are the Ed25519 key followed by the PQ key.
Signature
``````````
============================ ============== ====== =====
Type Length (bytes) Since Usage
============================ ============== ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 2484 0.9.xx See proposal 169
MLDSA65_EdDSA_SHA512_Ed25519 3373 0.9.xx See proposal 169
MLDSA87_EdDSA_SHA512_Ed25519 4691 0.9.xx See proposal 169
MLDSA65 3309 0.9.xx See proposal 169
MLDSA87 4647 0.9.xx See proposal 169
============================ ============== ====== =====
Hybrid signatures are the Ed25519 signature followed by the PQ signature.
Hybrid signatures are verified by verifying both signatures, and failing
if either one fails.
Key Certificates
````````````````
The defined Signing Public Key types are:
============================ =========== ======================= ====== =====
Type Type Code Total Public Key Length Since Usage
============================ =========== ======================= ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 12 1344 0.9.xx See proposal 169
MLDSA65_EdDSA_SHA512_Ed25519 13 1984 0.9.xx See proposal 169
MLDSA87_EdDSA_SHA512_Ed25519 14 2624 0.9.xx See proposal 169
MLDSA44 15 1312 0.9.xx See proposal 169
MLDSA65 16 1952 0.9.xx See proposal 169
MLDSA87 17 2592 0.9.xx See proposal 169
============================ =========== ======================= ====== =====
The defined Crypto Public Key types are:
================ =========== ======================= ====== =====
Type Type Code Total Public Key Length Since Usage
================ =========== ======================= ====== =====
MLKEM512_X25519 5 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519 6 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519 7 32 0.9.xx See proposal 169, for Leasesets only, not for RIs or Destinations
================ =========== ======================= ====== =====
Hybrid key types are NEVER included in key certificates; only in leasesets.
entire 384-byte main section is for the signing key.
Destination sizes
``````````````````
Here are lengths for the new Destination types.
Enc type for all is NULL (type 255) and the encryption key length is treated as 0.
The entire 384-byte section is used for the first part of the signing public key.
NOTE: This is different than the spec for the ECDSA_SHA512_P521
and the RSA signature types, where we maintained the 256-byte ElGamal
key in the destination even though it was unused.
No padding.
Total length is 7 + total key length.
Key certificate length is 4 + excess key length.
Example 1319-byte destination byte stream for MLDSA44:
skey[0:383] 5 (932 >> 8) (932 & 0xff) 00 12 00 255 skey[384:1311]
============================ =========== ======================= ====== ====== =====
Type Type Code Total Public Key Length Main Excess Total Dest Length
============================ =========== ======================= ====== ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 12 1344 384 960 1351
MLDSA65_EdDSA_SHA512_Ed25519 13 1984 384 1600 1991
MLDSA87_EdDSA_SHA512_Ed25519 14 2624 384 2240 2631
MLDSA44 15 1312 384 928 1319
MLDSA65 16 1952 384 1568 1959
MLDSA87 17 2592 384 2208 2599
============================ =========== ======================= ====== ====== =====
RouterIdent sizes
``````````````````
Here are lengths for the new Destination types.
The entire 352-byte section after the X28819 public key is used for the first part of the signing public key.
No padding.
Total length is 39 + total key length.
Key certificate length is 4 + excess key length.
Example 1351-byte router identity byte stream for MLDSA44:
enckey[0:31] skey[0:351] 5 (960 >> 8) (960 & 0xff) 00 12 00 4 skey[352:1311]
============================ =========== ======================= ====== ====== =====
Type Type Code Total Public Key Length Main Excess Total RouterIdent Length
============================ =========== ======================= ====== ====== =====
MLDSA44_EdDSA_SHA512_Ed25519 12 1344 352 992 1383
MLDSA65_EdDSA_SHA512_Ed25519 13 1984 352 1632 2023
MLDSA87_EdDSA_SHA512_Ed25519 14 2624 352 2272 2663
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
MLDSA44 15 1312 352 960 1351
MLDSA65 16 1952 352 1600 1991
MLDSA87 17 2592 352 2240 2631
============================ =========== ======================= ====== ====== =====
Handshake Patterns
------------------
Handshakes use [Noise]_ handshake patterns.
The following letter mapping is used:
- e = one-time ephemeral key
- s = static key
- p = message payload
- e1 = one-time ephemeral PQ key, sent from Alice to Bob
- ekem1 = the KEM ciphertext, sent from Bob to Alice
The following modifications to XK and IK for hybrid forward secrecy (hfs) are:
.. raw:: html
{% highlight lang='dataspec' %}
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 is encrypted together with the message 1 payload p
ekem1 is encrypted together with the message 2 payload p
IK: IKhfs:
<- s <- s
... ...
-> e, es, s, ss, p -> e, es, e1, s, ss, p
<- tag, e, ee, se, p <- tag, e, ee, ekem1, se, p
<- p <- p
p -> p ->
e1 is encrypted together with the message 1 alice static key s
ekem1 is encrypted with the message 2 ee DH result state FIXME
{% endhighlight %}
Noise Handshake KDF
---------------------
The KEM 32-byte shared secret is combined or mixHash()ed or HKDF()ed into the
final Noise shared secret, before split(), for a final 32-byte shared secret.
Not concatenated with the DH shared secret for a 64-byte final shared secret,
which is what TLS does [TLS-HYBRID]_.
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
Defined ML-KEM Operations
`````````````````````````
We define the following functions corresponding to the cryptographic building blocks used
as defined in [FIPS203]_.
(encap_key, decap_key) = 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.
(cihpertext, 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.
Note that both the encap_key and the ciphertext are encrypted inside ChaCha/Poly
blocks in the Noise handshake messages 1 and 2.
They will be decrypted as part of the handshake process.
The kem_shared_key is combined with the X25519 DH shared key to
create a shared session key.
See below for details.
Alice KDF for Message 1
`````````````````````````
(encap_key, decap_key) = KEYGEN()
Bob KDF for Message 2
`````````````````````````
(cihpertext, kem_shared_key) = ENCAPS(encap_key)
Alice KDF for Message 2
`````````````````````````
kem_shared_key = DECAPS(ciphertext, decap_key)
Alice/Bob KDF for split()
`````````````````````````
see below
Ratchet
---------
Noise identifiers:
- "Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256"
- "Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256"
- "Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256"
1b) New session format (with binding)
`````````````````````````````````````
Changes: Current ratchet contained only the static key in the first ChaCha section.
With ML-KEM, the first ChaCha section will also contain the encrypted PQ public key.
Encrypted format:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| |
+ +
| New Session Ephemeral Public Key |
+ 32 bytes +
| Encoded with Elligator2 |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) for Static Key Section +
| 16 bytes |
+----+----+----+----+----+----+----+----+
| |
+ Payload Section +
| ChaCha20 encrypted data |
~ ~
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) for Payload Section +
| 16 bytes |
+----+----+----+----+----+----+----+----+
{% endhighlight %}
Decrypted format:
.. raw:: html
| |
+ (see table below for length) +
| |
~ ~
| |
+----+----+----+----+----+----+----+----+
| |
+ X25519 Static Key +
| |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
Payload Part 2:
+----+----+----+----+----+----+----+----+
| |
+ Payload Section +
| |
~ ~
| |
+ +
| |
+----+----+----+----+----+----+----+----+
Sizes:
================ ========= ===== ========= ============= ============= ========== =======
Type Type Code X len Msg 1 len Msg 1 Enc len Msg 1 Dec len PQ key len pl len
================ ========= ===== ========= ============= ============= ========== =======
X25519 4 32 96+pl 64+pl pl -- pl
MLKEM512_X25519 5 32 896+pl 864+pl 800+pl 800 pl
MLKEM768_X25519 6 32 1280+pl 1344+pl 1184+pl 1184 pl
MLKEM1024_X25519 7 32 1664+pl 1632+pl 1568+pl 1568 pl
================ ========= ===== ========= ============= ============= ========== =======
1g) New Session Reply format
````````````````````````````
Changes: Current ratchet has an empty payload for the first ChaCha section.
With ML-KEM, the first ChaCha section will contain the encrypted PQ ciphertext.
Encrypted format:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| Session Tag 8 bytes |
+----+----+----+----+----+----+----+----+
| |
+ Ephemeral Public Key +
| |
+ 32 bytes +
| Encoded with Elligator2 |
+ +
| |
+----+----+----+----+----+----+----+----+
+ (see table below for length) +
~ ~
+ +
| |
+----+----+----+----+----+----+----+----+
| 16 bytes |
+----+----+----+----+----+----+----+----+
| |
+ Payload Section +
| ChaCha20 encrypted data |
~ ~
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) for Payload Section +
| 16 bytes |
+----+----+----+----+----+----+----+----+
{% endhighlight %}
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
Payload Part 1:
+----+----+----+----+----+----+----+----+
| |
+ ML-KEM ciphertext +
| |
+ (see table below for length) +
| |
~ ~
| |
+----+----+----+----+----+----+----+----+
Payload Part 2:
+----+----+----+----+----+----+----+----+
| |
+ Payload Section +
| |
~ ~
| |
+ +
| |
+----+----+----+----+----+----+----+----+
{% endhighlight %}
Sizes:
================ ========= ===== ========= ============= ============= ========== =======
Type Type Code Y len Msg 2 len Msg 2 Enc len Msg 2 Dec len PQ CT len opt len
================ ========= ===== ========= ============= ============= ========== =======
X25519 4 32 72+pl 32+pl pl -- pl
MLKEM512_X25519 5 32 840+pl 800+pl 768+pl 768 pl
MLKEM768_X25519 6 32 1160+pl 1120+pl 1088+pl 1088 pl
MLKEM1024_X25519 7 32 1640+pl 1600+pl 1568+pl 1568 pl
================ ========= ===== ========= ============= ============= ========== =======
KDF for Payload Section Encrypted Contents
``````````````````````````````````````````
.. raw:: html
{% highlight lang='text' %}
// split()
keydata = HKDF(chainKey, ZEROLEN, "", 64)
TODO
k_ab = keydata[0:31]
k_ba = keydata[32:63]
rest unchanged
{% endhighlight %}
NTCP2
------
Noise identifiers:
- "Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256"
- "Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256"
- "Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM1024_ChaChaPoly_SHA256"
Changes: Current NTCP2 contains only the options in the ChaCha section.
With ML-KEM, the ChaCha section will also contain the encrypted PQ public key.
Raw contents:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaChaPoly frame |
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
| k defined in KDF for message 1 |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
~ padding (optional) ~
| length defined in options block |
+----+----+----+----+----+----+----+----+
Same as before except ChaChaPoly frame is bigger
{% endhighlight %}
Unencrypted data (Poly1305 authentication tag not shown):
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
+ (see table below for length) +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
{% endhighlight %}
Sizes:
================ ========= ===== ========= ============= ============= ========== =======
Type Type Code X len Msg 1 len Msg 1 Enc len Msg 1 Dec len PQ key len opt len
================ ========= ===== ========= ============= ============= ========== =======
X25519 4 32 64+pad 32 16 -- 16
MLKEM512_X25519 5 32 864+pad 832 816 800 16
MLKEM768_X25519 6 32 1248+pad 1216 1200 1184 16
MLKEM1024_X25519 7 32 1632+pad 1600 1584 1568 16
================ ========= ===== ========= ============= ============= ========== =======
Note: Type codes are for internal use only. Routers will remain type 4,
and support will be indicated in the router addresses.
Changes: Current NTCP2 contains only the options in the ChaCha section.
With ML-KEM, the ChaCha section will also contain the encrypted PQ public key.
Raw contents:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaChaPoly frame |
+ Encrypted and authenticated data +
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
+ k defined in KDF for message 2 +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Same as before except ChaChaPoly frame is bigger
{% endhighlight %}
Unencrypted data (Poly1305 auth tag not shown):
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ML-KEM Ciphertext |
+ (see table below for length) +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
{% endhighlight %}
Sizes:
================ ========= ===== ========= ============= ============= ========== =======
Type Type Code Y len Msg 2 len Msg 2 Enc len Msg 2 Dec len PQ CT len opt len
================ ========= ===== ========= ============= ============= ========== =======
X25519 4 32 64+pad 32 16 -- 16
MLKEM512_X25519 5 32 832+pad 800 784 768 16
MLKEM768_X25519 6 32 1120+pad 1088 1104 1088 16
MLKEM1024_X25519 7 32 1600+pad 1568 1584 1568 16
================ ========= ===== ========= ============= ============= ========== =======
Note: Type codes are for internal use only. Routers will remain type 4,
and support will be indicated in the router addresses.
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
3) SessionConfirmed
```````````````````
Unchanged
Key Derivation Function (KDF) (for data phase)
``````````````````````````````````````````````
The data phase uses a zero-length associated data input.
The KDF generates two cipher keys k_ab and k_ba from the chaining key ck,
using HMAC-SHA256(key, data) as defined in [RFC-2104]_.
This is the Split() function, exactly as defined in the Noise spec.
.. raw:: html
{% highlight lang='text' %}
ck = from handshake phase
// k_ab, k_ba = HKDF(ck, zerolen)
// ask_master = HKDF(ck, zerolen, info="ask")
// zerolen is a zero-length byte array
temp_key = HMAC-SHA256(ck, zerolen)
TODO
remainder unchanged
{% endhighlight %}
SSU2
----
Noise identifiers:
- "Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256"
- "Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256"
- "Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM1024_ChaChaPoly_SHA256"
Long Header
`````````````
The long header is 32 bytes. It is used before a session is created, for Token Request, SessionRequest, SessionCreated, and Retry.
It is also used for out-of-session Peer Test and Hole Punch messages.
Before header encryption:
.. raw:: html