forked from I2P_Developers/i2p.www
prop. 169 updates
big fixup of MLKEM sections after getting unit test working
This commit is contained in:
@ -5,7 +5,7 @@ Post-Quantum Crypto Protocols
|
||||
:author: zzz
|
||||
:created: 2025-01-21
|
||||
:thread: http://zzz.i2p/topics/3294
|
||||
:lastupdated: 2025-03-06
|
||||
:lastupdated: 2025-03-10
|
||||
:status: Open
|
||||
:target: 0.9.80
|
||||
|
||||
@ -502,6 +502,60 @@ XK: XKhfs:
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
The e1 pattern is defined as follows, as specified in [Noise-Hybrid]_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
For Alice:
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// EncryptAndHash(encap_key)
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
For Bob:
|
||||
|
||||
// DecryptAndHash(ciphertext)
|
||||
encap_key = DECRYPT(k, n, ciphertext, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
The ekem1 pattern is defined as follows, as specified in [Noise-Hybrid]_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
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)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -529,7 +583,7 @@ 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()
|
||||
(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.
|
||||
@ -550,8 +604,7 @@ 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.
|
||||
The kem_shared_key is mixed into the chaining key with MixHash().
|
||||
See below for details.
|
||||
|
||||
|
||||
@ -568,17 +621,17 @@ For IK: After the 'es' message pattern and before the 's' message pattern, add:
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
(encap_key, decap_key) = KEYGEN()
|
||||
|
||||
// MixHash(encap_key)
|
||||
// Save for Payload section KDF
|
||||
h = SHA256(h || encap_key)
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
|
||||
// MixHash(ciphertext)
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
@ -599,15 +652,14 @@ For IK: After the 'es' message pattern and before the 's' message pattern, add:
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
|
||||
// MixHash(encap_key)
|
||||
// Save for Payload section KDF
|
||||
h = SHA256(h || encap_key)
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
encap_key = DECRYPT(k, n, encap_key_section, ad)
|
||||
|
||||
// MixHash(encap_key_section)
|
||||
h = SHA256(h || encap_key_section)
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
@ -628,23 +680,20 @@ For IK: After the 'ee' message pattern and before the 'se' message pattern, add:
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
// MixHash(ciphertext)
|
||||
// Save for Payload section KDF
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
(ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
//[chainKey, k] = MixKey(sharedSecret)
|
||||
// ChaChaPoly parameters to encrypt/decrypt
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
(kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
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.
|
||||
|
||||
@ -661,23 +710,19 @@ After the 'ee' message pattern (and before the 'ss' message pattern for IK), add
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
// MixHash(ciphertext)
|
||||
// Save for Payload section KDF
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
kem_shared_key = DECAPS(ciphertext, decap_key)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
//[chainKey, k] = MixKey(sharedSecret)
|
||||
// ChaChaPoly parameters to encrypt/decrypt
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, flags/static key section, ad)
|
||||
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.
|
||||
|
||||
@ -708,8 +753,12 @@ Noise identifiers
|
||||
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.
|
||||
Changes: Current ratchet contained the static key in the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ public key.
|
||||
The second section contains the static key.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
@ -727,10 +776,22 @@ Encrypted format:
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key and X25519 Static Key+
|
||||
+ ML-KEM encap_key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for encap_key Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ 32 bytes +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
@ -761,7 +822,6 @@ Decrypted format:
|
||||
{% highlight lang='dataspec' %}
|
||||
Payload Part 1:
|
||||
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key +
|
||||
@ -770,6 +830,10 @@ Payload Part 1:
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
@ -780,7 +844,7 @@ Payload Part 1:
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
@ -800,17 +864,21 @@ 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
|
||||
MLKEM512_X25519 5 32 912+pl 880+pl 800+pl 800 pl
|
||||
MLKEM768_X25519 6 32 1296+pl 1360+pl 1184+pl 1184 pl
|
||||
MLKEM1024_X25519 7 32 1680+pl 1648+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.
|
||||
Changes: Current ratchet has an empty payload for the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ ciphertext.
|
||||
The second section has an empty payload.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
@ -838,7 +906,11 @@ Encrypted format:
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Key Section +
|
||||
+ (MAC) for ciphertext Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for key Section (no data) +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
@ -877,6 +949,10 @@ Payload Part 1:
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
empty
|
||||
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
@ -895,9 +971,9 @@ 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
|
||||
MLKEM512_X25519 5 32 856+pl 816+pl 768+pl 768 pl
|
||||
MLKEM768_X25519 6 32 1176+pl 1136+pl 1088+pl 1088 pl
|
||||
MLKEM1024_X25519 7 32 1656+pl 1616+pl 1568+pl 1568 pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
|
||||
@ -938,10 +1014,17 @@ Raw contents:
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| ChaChaPoly frame (MLKEM) |
|
||||
+ (see table below for length) +
|
||||
| k defined in KDF for message 1 |
|
||||
+ n = 0 +
|
||||
| see KDF for associated data |
|
||||
~ n = 0 ~
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| ChaChaPoly frame |
|
||||
+ (see table below for length) +
|
||||
| ChaChaPoly frame (options) |
|
||||
+ 32 bytes +
|
||||
| k defined in KDF for message 1 |
|
||||
+ n = 0 +
|
||||
| see KDF for associated data |
|
||||
@ -951,7 +1034,7 @@ Raw contents:
|
||||
| length defined in options block |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Same as before except ChaChaPoly frame is bigger
|
||||
Same as before except add a second ChaChaPoly frame
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
@ -995,9 +1078,9 @@ 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
|
||||
MLKEM512_X25519 5 32 880+pad 848 816 800 16
|
||||
MLKEM768_X25519 6 32 1264+pad 1232 1200 1184 16
|
||||
MLKEM1024_X25519 7 32 1648+pad 1616 1584 1568 16
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note: Type codes are for internal use only. Routers will remain type 4,
|
||||
@ -1025,7 +1108,7 @@ Raw contents:
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| ChaChaPoly frame |
|
||||
| ChaChaPoly frame (MLKEM) |
|
||||
+ Encrypted and authenticated data +
|
||||
- (see table below for length) -
|
||||
+ k defined in KDF for message 2 +
|
||||
@ -1033,6 +1116,14 @@ Raw contents:
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| ChaChaPoly frame (options) |
|
||||
+ Encrypted and authenticated data +
|
||||
- 32 bytes -
|
||||
+ k defined in KDF for message 2 +
|
||||
| n = 0; see KDF for associated data |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| unencrypted authenticated |
|
||||
+ padding (optional) +
|
||||
| length defined in options block |
|
||||
@ -1040,7 +1131,7 @@ Raw contents:
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Same as before except ChaChaPoly frame is bigger
|
||||
Same as before except add a second ChaChaPoly frame
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
@ -1081,9 +1172,9 @@ 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
|
||||
MLKEM512_X25519 5 32 848+pad 816 784 768 16
|
||||
MLKEM768_X25519 6 32 1136+pad 1104 1104 1088 16
|
||||
MLKEM1024_X25519 7 32 1616+pad 1584 1584 1568 16
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note: Type codes are for internal use only. Routers will remain type 4,
|
||||
@ -1190,7 +1281,15 @@ Raw contents:
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| ChaCha20 encrypted data |
|
||||
| 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 +
|
||||
@ -1244,8 +1343,8 @@ Sizes, not including IP overhead:
|
||||
Type Type Code X len Msg 1 len Msg 1 Enc len Msg 1 Dec len PQ key len pl len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 80+pl 16+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 880+pl 816+pl 800+pl 800 pl
|
||||
MLKEM768_X25519 6 32 1264+pl 1200+pl 1184+pl 1184 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 too big
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
@ -1253,7 +1352,7 @@ Note: Type codes are for internal use only. Routers will remain type 4,
|
||||
and support will be indicated in the router addresses.
|
||||
|
||||
Minimum MTU for MLKEM768_X25519:
|
||||
About 1300 for IPv4 and 1320 for IPv6.
|
||||
About 1316 for IPv4 and 1336 for IPv6.
|
||||
|
||||
|
||||
|
||||
@ -1285,7 +1384,15 @@ Raw contents:
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| ChaCha20 data |
|
||||
| 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 +
|
||||
@ -1340,8 +1447,8 @@ Sizes, not including IP overhead:
|
||||
Type Type Code Y len Msg 2 len Msg 2 Enc len Msg 2 Dec len PQ CT len pl len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 80+pl 16+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 848+pl 784+pl 768+pl 768 pl
|
||||
MLKEM768_X25519 6 32 1168+pl 1102+pl 1088+pl 1088 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 too big
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
@ -1349,7 +1456,7 @@ Note: Type codes are for internal use only. Routers will remain type 4,
|
||||
and support will be indicated in the router addresses.
|
||||
|
||||
Minimum MTU for MLKEM768_X25519:
|
||||
About 1300 for IPv4 and 1320 for IPv6.
|
||||
About 1316 for IPv4 and 1336 for IPv6.
|
||||
|
||||
|
||||
SessionConfirmed (Type 2)
|
||||
@ -1437,9 +1544,9 @@ Size increase (bytes):
|
||||
================ ============== =============
|
||||
Type Pubkey (Msg 1) Cipertext (Msg 2)
|
||||
================ ============== =============
|
||||
MLKEM512_X25519 +800 +768
|
||||
MLKEM768_X25519 +1184 +1088
|
||||
MLKEM1024_X25519 +1568 +1568
|
||||
MLKEM512_X25519 +816 +784
|
||||
MLKEM768_X25519 +1200 +1104
|
||||
MLKEM1024_X25519 +1584 +1584
|
||||
================ ============== =============
|
||||
|
||||
Speed:
|
||||
@ -1579,6 +1686,7 @@ Library Support
|
||||
|
||||
Bouncycastle, BoringSSL, and WolfSSL libraries support MLKEM and MLDSA now.
|
||||
OpenSSL support will be in their 3.5 release scheduled for April 8, 2025 [OPENSSL]_.
|
||||
3.5-alpha will be availabe March 11, 2025.
|
||||
|
||||
The southernstorm.com Noise library adapted by Java I2P contained preliminary support for
|
||||
hybrid handshakes, but we removed it as unused; we will have to add it back
|
||||
|
Reference in New Issue
Block a user