此翻译是使用机器学习生成的,可能不是100%准确。 查看英文版本

后量子密码协议

Proposal 169
打开
Author zzz, orignal, drzed, eyedeekay
Created 2025-01-21
Last Updated 2026-02-23
Target Version 0.9.80

状态

协议/功能状态
Ratchet在 Java I2P 和 i2pd 中已完成
NTCP22026年第一季度测试版
SSU2即将开始实施,2026年第二三季度测试版
MLDSA SigTypes优先级较低,可能在2027年以后

概述

虽然对合适的后量子(PQ)密码学的研究和竞争已经进行了十年,但直到最近选择才变得明确。

我们在2022年开始研究PQ密码学的影响 zzz.i2p

TLS 标准在过去两年中增加了混合加密支持,由于 Chrome 和 Firefox 的支持,现在它被用于互联网上很大一部分加密流量 Cloudflare

NIST 最近最终确定并发布了后量子密码学的推荐算法 NIST 。几个常用的密码学库现在已经支持 NIST 标准,或将在不久的将来发布支持。

CloudflareNIST 都建议立即开始迁移。另请参见 2022 年 NSA PQ 常见问题解答 NSA 。I2P 应该在安全性和密码学方面保持领先地位。现在是实现推荐算法的时候了。利用我们灵活的加密类型和签名类型系统,我们将添加混合加密以及后量子和混合签名的类型。

目标

  • 选择抗量子算法
  • 在适当的 I2P 协议中添加纯量子和混合算法
  • 定义多个变体
  • 在实现、测试、分析和研究后选择最佳变体
  • 逐步添加支持并保持向后兼容性

非目标

  • 不要更改单向(Noise N)加密协议
  • 不要放弃SHA256,近期内不受PQ威胁
  • 此时不要选择最终首选变体

威胁模型

  • 位于 OBEP 或 IBGW 的 router,可能串通合作, 存储 garlic 消息以供后续解密(前向保密性)
  • 网络观察者 存储传输消息以供后续解密(前向保密性)
  • 网络参与者为 RI、LS、流传输、数据报 或其他结构伪造签名

受影响的协议

我们将修改以下协议,大致按照开发顺序排列。整体推出时间可能从2025年底到2027年中期。详情请参阅下面的优先级和推出部分。

协议/功能状态
混合 MLKEM Ratchet 和 LS2025年6月批准;2025年8月测试版;2025年11月发布
混合 MLKEM NTCP2已在实际网络测试,2026年2月批准;2026年5月测试版目标;2026年8月发布目标
混合 MLKEM SSU22026年2月批准;2026年8月测试版目标;2026年11月发布目标
MLDSA SigTypes 12-14提案稳定但可能要到2027年才最终确定
MLDSA Dests已在实际网络测试,需要网络升级以支持 floodfill
混合 SigTypes 15-17初步阶段
混合 Dests

设计

我们将支持 NIST FIPS 203 和 204 标准 FIPS 203 FIPS 204 ,这些标准基于但不兼容 CRYSTALS-Kyber 和 CRYSTALS-Dilithium(版本 3.1、3 及更早版本)。

密钥交换

我们将在以下协议中支持混合密钥交换:

协议Noise 类型仅支持 PQ?支持混合?
NTCP2XKnoyes
SSU2XKnoyes
RatchetIKnoyes
TBMNnono
NetDBNnono
PQ KEM 仅提供临时密钥,不直接支持静态密钥握手,如 Noise XK 和 IK。

Noise N 不使用双向密钥交换,因此不适用于混合加密。

因此,我们将仅支持混合加密,用于 NTCP2、SSU2 和 Ratchet。我们将按照 FIPS 203 中的定义来定义三种 ML-KEM 变体,总共 3 种新的加密类型。混合类型将仅与 X25519 结合定义。

新的加密类型包括:

TypeCode
MLKEM512_X255195
MLKEM768_X255196
MLKEM1024_X255197
开销将会很大。典型的消息1和消息2大小(对于XK和IK)目前约为100字节(在任何额外载荷之前)。根据算法的不同,这将增加8倍到15倍。

签名

我们将在以下结构中支持PQ和混合签名:

类型仅支持 PQ?支持混合?
RouterInfo
LeaseSet
Streaming SYN/SYNACK/Close
Repliable Datagrams
Datagram2 (prop. 163)
I2CP create session msg
SU3 文件
X.509 证书
Java keystores
因此我们将同时支持仅PQ和混合签名。我们将按照FIPS 204 定义三种ML-DSA变体、三种与Ed25519结合的混合变体,以及三种仅用于SU3文件的带预哈希的仅PQ变体,总共9种新的签名类型。混合类型将仅与Ed25519结合定义。我们将使用标准ML-DSA,而不是预哈希变体(HashML-DSA),除了SU3文件。

我们将使用"对冲"或随机化签名变体,而不是"确定性"变体,如 FIPS 204 第 3.4 节所定义。这确保了每个签名都是不同的,即使是对相同的数据签名,并提供了额外的侧信道攻击防护。有关算法选择(包括编码和上下文)的更多详细信息,请参见下面的实现说明部分。

新的签名类型包括:

类型代码
MLDSA4412
MLDSA6513
MLDSA8714
MLDSA44_EdDSA_SHA512_Ed2551915
MLDSA65_EdDSA_SHA512_Ed2551916
MLDSA87_EdDSA_SHA512_Ed2551917
MLDSA44ph18
MLDSA65ph19
MLDSA87ph20
X.509 证书和其他 DER 编码将使用 IETF draft 中定义的复合结构和 OID。

开销将会很大。典型的 Ed25519 目标和 router 身份大小为 391 字节。根据算法不同,这些将增加 3.5 倍到 6.8 倍。Ed25519 签名为 64 字节。根据算法不同,这些将增加 38 倍到 76 倍。典型的已签名 RouterInfo、LeaseSet、可回复数据报和已签名流消息大约为 1KB。根据算法不同,这些将增加 3 倍到 8 倍。

由于新的destination和router identity类型不包含填充,它们将无法被压缩。在传输过程中进行gzip压缩的destination和router identity的大小将增加12倍至38倍,具体取决于算法。

合法组合

对于目的地,新的签名类型在 leaseset 中支持所有加密类型。在密钥证书中将加密类型设置为 NONE (255)。

对于 RouterIdentities,ElGamal 加密类型已被弃用。新的签名类型仅支持 X25519(类型 4)加密。新的加密类型将在 RouterAddresses 中指示。密钥证书中的加密类型将继续为类型 4。

需要新的加密算法

  • ML-KEM(原 CRYSTALS-Kyber)FIPS 203
  • ML-DSA(原 CRYSTALS-Dilithium)FIPS 204
  • SHA3-128(原 Keccak-256)FIPS 202 仅用于 SHAKE128
  • SHA3-256(原 Keccak-512)FIPS 202
  • SHAKE128 和 SHAKE256(SHA3-128 和 SHA3-256 的 XOF 扩展)FIPS 202

SHA3-256、SHAKE128 和 SHAKE256 的测试向量可在 NIST 获取。

请注意,Java bouncycastle 库支持上述所有功能。C++ 库支持在 OpenSSL 3.5 中提供 OpenSSL

替代方案

我们不会支持 FIPS 205 (Sphincs+),它比 ML-DSA 慢得多且占用空间大得多。我们不会支持即将推出的 FIPS206 (Falcon),它尚未标准化。我们不会支持 NTRU 或其他未被 NIST 标准化的后量子候选算法。

Rosenpass

有一些研究论文 探讨了将Wireguard (IK)适配为纯后量子密码学的方法,但该论文中仍有几个开放性问题。后来,这种方法被实现为Rosenpass Rosenpass 白皮书 ,用于后量子Wireguard。

Rosenpass 使用类似 Noise KK 的握手协议,采用预共享的 Classic McEliece 460896 静态密钥(每个 500 KB)和 Kyber-512(本质上是 MLKEM-512)临时密钥。由于 Classic McEliece 密文只有 188 字节,而 Kyber-512 公钥和密文都比较合理,两个握手消息都能放入标准 UDP MTU 中。来自 PQ KK 握手的输出共享密钥(osk)被用作标准 Wireguard IK 握手的输入预共享密钥(psk)。因此总共有两个完整的握手过程,一个是纯 PQ 的,另一个是纯 X25519 的。

我们无法通过任何这些方法来替换我们的XK和IK握手,因为:

  • 我们无法执行KK模式,Bob没有Alice的静态密钥
  • 500KB的静态密钥太大了
  • 我们不希望有额外的往返通信

白皮书中有很多有价值的信息,我们将审查它以获取想法和灵感。TODO。

规范

通用结构

按照以下方式更新通用结构文档 /docs/specs/common-structures/ 中的章节和表格:

PublicKey

新的公钥类型包括:

类型公钥长度起始版本用途
MLKEM512_X25519320.9.xx参见提案 169,仅用于 leaseSet,不用于 RI 或 destination
MLKEM768_X25519320.9.xx参见提案 169,仅用于 leaseSet,不用于 RI 或 destination
MLKEM1024_X25519320.9.xx参见提案 169,仅用于 leaseSet,不用于 RI 或 destination
MLKEM5128000.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
MLKEM76811840.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
MLKEM102415680.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
MLKEM512_CT7680.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
MLKEM768_CT10880.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
MLKEM1024_CT15680.9.xx参见提案 169,仅用于握手,不用于 leaseSet、RI 或 destination
NONE00.9.xx参见提案 169,仅用于具有 PQ 签名类型的 destination,不用于 RI 或 leaseSet
混合公钥是 X25519 密钥。KEM 公钥是从 Alice 发送给 Bob 的临时 PQ 密钥。编码和字节顺序在 FIPS 203 中定义。

MLKEM*_CT 密钥实际上并不是公钥,它们是在 Noise 握手中从 Bob 发送给 Alice 的"密文"。在此列出它们是为了完整性。

私钥

新的私钥类型有:

类型私钥长度版本用途
MLKEM512_X25519320.9.xx见提案169,仅用于 leaseSet,不用于 RI 或 Destination
MLKEM768_X25519320.9.xx见提案169,仅用于 leaseSet,不用于 RI 或 Destination
MLKEM1024_X25519320.9.xx见提案169,仅用于 leaseSet,不用于 RI 或 Destination
MLKEM51216320.9.xx见提案169,仅用于握手,不用于 leaseSet、RI 或 Destination
MLKEM76824000.9.xx见提案169,仅用于握手,不用于 leaseSet、RI 或 Destination
MLKEM102431680.9.xx见提案169,仅用于握手,不用于 leaseSet、RI 或 Destination
混合私钥是 X25519 密钥。KEM 私钥仅供 Alice 使用。KEM 编码和字节顺序在 FIPS 203 中定义。

SigningPublicKey

新的签名公钥类型包括:

类型长度(字节)起始版本用法
MLDSA4413120.9.xx见提案 169
MLDSA6519520.9.xx见提案 169
MLDSA8725920.9.xx见提案 169
MLDSA44_EdDSA_SHA512_Ed2551913440.9.xx见提案 169
MLDSA65_EdDSA_SHA512_Ed2551919840.9.xx见提案 169
MLDSA87_EdDSA_SHA512_Ed2551926240.9.xx见提案 169
MLDSA44ph13440.9.xx仅用于 SU3 文件,不用于 netDb 结构
MLDSA65ph19840.9.xx仅用于 SU3 文件,不用于 netDb 结构
MLDSA87ph26240.9.xx仅用于 SU3 文件,不用于 netDb 结构
混合签名公钥是 Ed25519 密钥后跟 PQ 密钥,如 IETF draft 中所述。编码和字节顺序在 FIPS 204 中定义。

SigningPrivateKey

新的签名私钥类型有:

类型长度(字节)起始版本用途
MLDSA4425600.9.xx参见提案 169
MLDSA6540320.9.xx参见提案 169
MLDSA8748960.9.xx参见提案 169
MLDSA44_EdDSA_SHA512_Ed2551925920.9.xx参见提案 169
MLDSA65_EdDSA_SHA512_Ed2551940640.9.xx参见提案 169
MLDSA87_EdDSA_SHA512_Ed2551949280.9.xx参见提案 169
MLDSA44ph25920.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
MLDSA65ph40640.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
MLDSA87ph49280.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
混合签名私钥是 Ed25519 密钥后跟 PQ 密钥,如 IETF draft 中所述。编码和字节顺序在 FIPS 204 中定义。

签名

新的签名类型包括:

类型长度(字节)起始版本用途
MLDSA4424200.9.xx参见提案 169
MLDSA6533090.9.xx参见提案 169
MLDSA8746270.9.xx参见提案 169
MLDSA44_EdDSA_SHA512_Ed2551924840.9.xx参见提案 169
MLDSA65_EdDSA_SHA512_Ed2551933730.9.xx参见提案 169
MLDSA87_EdDSA_SHA512_Ed2551946910.9.xx参见提案 169
MLDSA44ph24840.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
MLDSA65ph33730.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
MLDSA87ph46910.9.xx仅用于 SU3 文件,不用于 netDb 结构。参见提案 169
混合签名是 Ed25519 签名后跟 PQ 签名,如 IETF draft 中所述。混合签名通过验证两个签名来进行验证,如果任一签名失败则验证失败。编码和字节顺序在 FIPS 204 中定义。

密钥证书

新的签名公钥类型包括:

类型类型代码总公钥长度起始版本用途
MLDSA441213120.9.xx参见提案 169
MLDSA651319520.9.xx参见提案 169
MLDSA871425920.9.xx参见提案 169
MLDSA44_EdDSA_SHA512_Ed255191513440.9.xx参见提案 169
MLDSA65_EdDSA_SHA512_Ed255191619840.9.xx参见提案 169
MLDSA87_EdDSA_SHA512_Ed255191726240.9.xx参见提案 169
MLDSA44ph18n/a0.9.xx仅用于 SU3 文件
MLDSA65ph19n/a0.9.xx仅用于 SU3 文件
MLDSA87ph20n/a0.9.xx仅用于 SU3 文件
新的加密公钥类型包括:
类型类型代码总公钥长度起始版本用途
MLKEM512_X255195320.9.xx参见提案 169,仅用于 Leasesets,不适用于 RIs 或 Destinations
MLKEM768_X255196320.9.xx参见提案 169,仅用于 Leasesets,不适用于 RIs 或 Destinations
MLKEM1024_X255197320.9.xx参见提案 169,仅用于 Leasesets,不适用于 RIs 或 Destinations
NONE25500.9.xx参见提案 169
混合密钥类型绝不会包含在密钥证书中;只会包含在 leaseSet 中。

对于使用混合或PQ签名类型的目标,加密类型使用NONE(类型255),但没有加密密钥,整个384字节的主要部分用于签名密钥。

目标地址大小

以下是新 Destination 类型的长度。所有类型的加密类型都是 NONE(类型 255),加密密钥长度被视为 0。整个 384 字节部分用于签名公钥的第一部分。注意:这与 ECDSA_SHA512_P521 和 RSA 签名类型的规范不同,在那些类型中,我们在 destination 中保留了 256 字节的 ElGamal 密钥,即使它未被使用。

无填充。总长度为 7 + 总密钥长度。密钥证书长度为 4 + 额外密钥长度。

MLDSA44 的示例 1319 字节目标字节流:

skey[0:383] 5 (932 » 8) (932 & 0xff) 00 12 00 255 skey[384:1311]

类型类型代码总公钥长度主要部分超出部分总目标长度
MLDSA441213123849281319
MLDSA6513195238415681959
MLDSA8714259238422082599
MLDSA44_EdDSA_SHA512_Ed255191513443849601351
MLDSA65_EdDSA_SHA512_Ed2551916198438416001991
MLDSA87_EdDSA_SHA512_Ed2551917262438422402631

RouterIdent 大小

以下是新 Destination 类型的长度。所有类型的加密类型都是 X25519(类型 4)。X25519 公钥后面的整个 352 字节部分用于签名公钥的第一部分。无填充。总长度为 39 + 总密钥长度。密钥证书长度为 4 + 超出密钥长度。

MLDSA44 的示例 1351 字节 router 身份字节流:

enckey[0:31] skey[0:351] 5 (960 » 8) (960 & 0xff) 00 12 00 4 skey[352:1311]

类型类型代码总公钥长度主要多余总RouterIdent长度
MLDSA441213123529601351
MLDSA6513195235216001991
MLDSA8714259235222402631
MLDSA44_EdDSA_SHA512_Ed255191513443529921383
MLDSA65_EdDSA_SHA512_Ed2551916198435216322023
MLDSA87_EdDSA_SHA512_Ed2551917262435222722663

握手模式

握手使用 Noise Protocol 握手模式。

使用以下字母映射:

  • e = 一次性临时密钥
  • s = 静态密钥
  • p = 消息载荷
  • e1 = 一次性临时 PQ 密钥,从 Alice 发送到 Bob
  • ekem1 = KEM 密文,从 Bob 发送到 Alice

以下对 XK 和 IK 的修改用于混合前向保密 (hfs),如 Noise HFS spec 第 5 节所规定:

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 ->


  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 and ekem1 are encrypted. See pattern definitions below.
  NOTE: e1 and ekem1 are different sizes (unlike X25519)

e1 模式定义如下,如 Noise HFS spec 第 4 节所述:

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)

ekem1 模式的定义如下,如 Noise HFS spec 第4节所述:

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 握手密钥派生函数

问题

  • 我们是否应该更改握手哈希函数?请参见比较 。 SHA256不易受到后量子攻击,但如果我们确实想升级 哈希函数,现在是时候了,趁我们正在更改其他东西。 当前的IETF SSH提案IETF草案 是将MLKEM768 与SHA256一起使用,将MLKEM1024与SHA384一起使用。该提案包含 安全考虑的讨论。
  • 我们是否应该停止发送0-RTT棘轮数据(除了LS之外)?
  • 如果我们不发送0-RTT数据,我们是否应该将棘轮从IK切换到XK?

概述

本节适用于 IK 和 XK 协议。

混合握手在 Noise HFS 规范 中定义。第一条消息从 Alice 发送到 Bob,在消息载荷之前包含 e1(封装密钥)。这被视为额外的静态密钥;对其调用 EncryptAndHash()(作为 Alice)或 DecryptAndHash()(作为 Bob)。然后像往常一样处理消息载荷。

第二条消息,从 Bob 到 Alice,在消息载荷之前包含 ekem1,即密文。这被视为一个额外的静态密钥;对其调用 EncryptAndHash()(作为 Bob)或 DecryptAndHash()(作为 Alice)。然后,计算 kem_shared_key 并调用 MixKey(kem_shared_key)。接着按常规处理消息载荷。

定义的 ML-KEM 操作

我们定义以下函数,对应于 FIPS 203 中定义的加密构建块。

(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.

请注意,encap_key 和 ciphertext 都在 Noise 握手消息 1 和 2 的 ChaCha/Poly 块内进行了加密。它们将作为握手过程的一部分被解密。

kem_shared_key 通过 MixHash() 混合到链式密钥中。详情请参见下文。

Alice 密钥派生函数用于消息 1

对于 XK:在 ’es’ 消息模式之后和负载之前,添加:

或者

对于 IK:在 ’es’ 消息模式之后和 ’s’ 消息模式之前,添加:

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).

消息1的Bob密钥派生函数

对于 XK:在 ’es’ 消息模式之后和载荷之前,添加:

对于 IK:在 ’es’ 消息模式之后和 ’s’ 消息模式之前,添加:

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).

消息 2 的 Bob KDF

对于 XK:在 ’ee’ 消息模式之后和载荷之前,添加:

对于 IK:在 ’ee’ 消息模式之后和 ‘se’ 消息模式之前,添加:

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 for Message 2

在 ’ee’ 消息模式之后(以及在 IK 的 ‘ss’ 消息模式之前),添加:

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.

消息3的KDF(仅XK)

未更改

用于 split() 的 KDF

未更改

棘轮

按如下方式更新 ECIES-Ratchet 规范 /docs/specs/ecies/

Noise 标识符

  • “Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256”
  • “Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256”
  • “Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256”

1b) 新会话格式(带绑定)

变更:当前的 ratchet 在第一个 ChaCha 部分包含静态密钥,在第二部分包含有效载荷。使用 ML-KEM 后,现在有三个部分。第一部分包含加密的 PQ 公钥。第二部分包含静态密钥。第三部分包含有效载荷。

加密格式:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   New Session Ephemeral Public Key    |
  +             32 bytes                  +
  |     Encoded with Elligator2           |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +           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                  +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  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                  |
  +----+----+----+----+----+----+----+----+

解密格式:

Payload Part 1:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +       ML-KEM encap_key                +
  |                                       |
  +      (see table below for length)     +
  |                                       |
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 2:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +       X25519 Static Key               +
  |                                       |
  +      (32 bytes)                       +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 3:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |                                       |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

尺寸:

类型类型代码X长度消息1长度消息1加密长度消息1解密长度PQ密钥长度pl长度
X2551943296+pl64+plplpl
MLKEM512_X25519532912+pl880+pl800+pl800pl
MLKEM768_X255196321296+pl1360+pl1184+pl1184pl
MLKEM1024_X255197321680+pl1648+pl1568+pl1568pl
请注意,载荷必须包含一个DateTime块,因此最小载荷大小为7。最小消息1大小可以相应计算。

1g) 新会话回复格式

变更:当前的 ratchet 在第一个 ChaCha 部分有空载荷,载荷在第二部分中。使用 ML-KEM 后,现在有三个部分。第一部分包含加密的 PQ 密文。第二部分有空载荷。第三部分包含载荷。

加密格式:

  +----+----+----+----+----+----+----+----+
  |       Session Tag   8 bytes           |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Ephemeral Public Key           +
  |                                       |
  +            32 bytes                   +
  |     Encoded with Elligator2           |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  | ChaCha20 encrypted ML-KEM ciphertext  |
  +      (see table below for length)     +
  ~                                       ~
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +  (MAC) for ciphertext Section         +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +  (MAC) for key Section (no data)      +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |       ChaCha20 encrypted data         |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +         (MAC) for Payload Section     +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+

解密后的格式:

Payload Part 1:


  +----+----+----+----+----+----+----+----+
  |                                       |
  +       ML-KEM ciphertext               +
  |                                       |
  +      (see table below for length)     +
  |                                       |
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 2:

  empty

  Payload Part 3:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |                                       |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

大小:

类型类型代码Y长度消息2长度消息2加密长度消息2解密长度PQ CT长度可选长度
X2551943272+pl32+plplpl
MLKEM512_X25519532856+pl816+pl768+pl768pl
MLKEM768_X255196321176+pl1136+pl1088+pl1088pl
MLKEM1024_X255197321656+pl1616+pl1568+pl1568pl
请注意,虽然消息 2 通常会有非零载荷,但 ratchet 规范 /docs/specs/ecies/ 并不要求如此,因此最小载荷大小为 0。可以相应地计算消息 2 的最小大小。

NTCP2

按如下方式更新 NTCP2 规范 /docs/specs/ntcp2/

Noise 标识符

  • “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

变更:当前的 NTCP2 仅包含 ChaCha 部分中的选项。使用 ML-KEM 时,ChaCha 部分还将包含加密的 PQ 公钥。

为了让 PQ 和非 PQ 的 NTCP2 能够在同一个 router 地址和端口上得到支持,我们使用 X 值(X25519 临时公钥)的最高有效位来标记这是一个 PQ 连接。对于非 PQ 连接,这个位总是未设置的。

对于 Alice,在消息经过 Noise 加密之后,但在对 X 进行 AES 混淆之前,设置 X[31] |= 0x7f。

对于Bob,在对X进行AES去混淆后,测试X[31] & 0x80。如果该位被设置,则用X[31] &= 0x7f清除它,并通过Noise作为PQ连接进行解密。如果该位是清零的,则像往常一样通过Noise作为非PQ连接进行解密。

对于在不同 router 地址和端口上发布的 PQ NTCP2,这不是必需的。

有关更多信息,请参阅下面的已发布地址部分。

原始内容:

  +----+----+----+----+----+----+----+----+
  |        MS bit set to 1 and then       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted X         |
  +             (32 bytes)                +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   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 (options)          |
  +         32 bytes                      +
  |   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 current specification except add a second ChaChaPoly frame

未加密数据(未显示 Poly1305 认证标签):

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

注意:消息 1 选项块中的版本字段必须设置为 2,即使对于 PQ 连接也是如此。

大小:

类型类型代码X 长度消息 1 长度消息 1 加密长度消息 1 解密长度PQ 密钥长度可选长度
X2551943264+pad321616
MLKEM512_X25519532880+pad84881680016
MLKEM768_X255196321264+pad12321200118416
MLKEM1024_X255197321648+pad16161584156816
注意:类型代码仅供内部使用。router 将保持类型 4,并且支持情况将在 router 地址中指示。

2) SessionCreated

原始内容:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted Y         |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaChaPoly frame (MLKEM)            |
  +   Encrypted and authenticated data    +
  -      (see table below for length)     -
  +   k defined in KDF for message 2      +
  |   n = 0; see KDF for associated data  |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   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   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Same as current specification except add a second ChaChaPoly frame

未加密数据(未显示 Poly1305 认证标签):

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

大小:

类型类型代码Y 长度消息 2 长度消息 2 加密长度消息 2 解密长度PQ CT 长度可选长度
X2551943264+pad321616
MLKEM512_X25519532848+pad81678476816
MLKEM768_X255196321136+pad11041104108816
MLKEM1024_X255197321616+pad15841584156816
注意:类型代码仅供内部使用。Router 将保持类型 4,支持情况将在 router 地址中指示。

3) SessionConfirmed

未更改

密钥派生函数 (KDF)(用于数据阶段)

未更改

已发布地址

在所有情况下,像往常一样使用 NTCP2 传输名称。

使用与非PQ、非防火墙相同的地址/端口。仅支持一种PQ变体。在router地址中,发布v=2(如常)和新参数pq=[3|4|5]来指示MLKEM 512/768/1024。Alice在会话请求中设置临时密钥的MSB(key[31] & 0x80)来指示这是一个混合连接。见上文。较旧的router将忽略pq参数并照常连接非pq。

不同地址/端口作为非PQ,或仅PQ、非防火墙模式不受支持。这将不会被实现,直到非PQ NTCP2被禁用,也就是几年后。当非PQ被禁用时,可能会支持多个PQ变体,但每个地址只支持一个。在router地址中,发布v=[3|4|5]来表示MLKEM 512/768/1024。Alice不设置临时密钥的MSB。较旧的router会检查v参数并跳过此地址,因为不受支持。

防火墙地址(未发布IP):在router地址中,发布v=2(如常)。无需发布pq参数。

Alice 可以使用 Bob 发布的 PQ 变体连接到 PQ Bob,无论 Alice 是否在她的 router 信息中宣传 pq 支持,或者她是否宣传相同的变体。

最大填充

在当前规范中,消息1和消息2被定义为具有"合理"数量的填充,建议范围为0-31字节,且未指定最大值。

Java I2P 为非 PQ 连接实现了最大 256 字节的填充,但这一点之前没有记录在文档中。

使用定义的消息大小作为最大填充量,也就是说,最大填充量将使消息大小翻倍,如下所示:

Message Max PaddingMLKEM-512MLKEM-768MLKEM-1024
Session Request88012641648
Session Created84811361616

SSU2

按以下方式更新 SSU2 规范 /docs/specs/ssu2/

噪声标识符

  • “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256”
  • “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256”

请注意,SSU2 不支持 MLKEM-1024,因为密钥过大,无法适配标准的 1500 字节数据报。

长标头

长头部为32字节。它在会话创建之前使用,用于Token Request、SessionRequest、SessionCreated和Retry。它也用于会话外的Peer Test和Hole Punch消息。

在以下消息中,将长头部中的 ver(版本)字段设置为 3 或 4,以指示 MLKEM-512 或 MLKEM-768。

  • (0) 会话请求
  • (1) 会话已创建
  • (9) 重试
  • (10) 令牌请求
  • (11) 打洞

在以下消息中,像往常一样将长报头中的 ver(版本)字段设置为 2,即使支持 MLKEM-512 或 MLKEM-768。如果对端支持,实现也可以将值设置为 3 或 4,但这不是必需的。实现应该接受任何 2-4 的值。

  • (7) 节点测试(会话外消息 5-7)

讨论:对于所有消息类型,将版本字段设置为 3 或 4 可能并非严格必要,但这样做有助于对不支持的后量子连接进行更早的故障检测。Token Request 和 Retry(类型 9 和 10)应该使用版本 3/4 以保持一致性。Hole Punch 消息(类型 11)可能不需要这种处理,但我们将遵循相同的模式以保持统一性。Peer Test 消息(类型 7)是会话外的,不表示启动会话的意图。

头部加密前:


  +----+----+----+----+----+----+----+----+
  |      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

短标头

未更改

SessionRequest (类型 0)

变更:当前的 SSU2 在 ChaCha 部分只包含区块数据。使用 ML-KEM 后,ChaCha 部分还将包含加密的后量子公钥。

用于欺骗保护的KDF更改:为了解决提案165 [Prop165]_ 中提出的问题,但采用不同的解决方案,我们修改了会话请求的KDF。这仅适用于PQ会话。非PQ会话的KDF保持不变。


// 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)

  ...

原始内容:

  +----+----+----+----+----+----+----+----+
  |  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)        +
  |                                       |
  +----+----+----+----+----+----+----+----+

未加密数据(未显示 Poly1305 认证标签):

  +----+----+----+----+----+----+----+----+
  |      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      |
  +----+----+----+----+----+----+----+----+

大小,不包括 IP 开销:

类型类型代码X 长度消息 1 长度消息 1 加密长度消息 1 解密长度PQ 密钥长度pl 长度
X2551943280+pl16+plplpl
MLKEM512_X25519532896+pl832+pl800+pl800pl
MLKEM768_X255196321280+pl1216+pl1184+pl1184pl
MLKEM1024_X255197不适用太大
注意:类型代码仅供内部使用。Router 将保持为类型 4,支持情况将在 router 地址中指示。

MLKEM768_X25519 的最小 MTU:IPv4 约为 1316,IPv6 约为 1336。

SessionCreated(类型 1)

变更:当前的 SSU2 在 ChaCha 部分仅包含块数据。使用 ML-KEM 后,ChaCha 部分还将包含加密的 PQ 公钥。

原始内容:

  +----+----+----+----+----+----+----+----+
  |  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)        +
  |                                       |
  +----+----+----+----+----+----+----+----+

未加密数据(未显示 Poly1305 认证标签):

  +----+----+----+----+----+----+----+----+
  |      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     |
  +----+----+----+----+----+----+----+----+

大小,不包括 IP 开销:

类型类型代码Y 长度消息 2 长度消息 2 加密长度消息 2 解密长度PQ CT 长度pl 长度
X2551943280+pl16+plplpl
MLKEM512_X25519532864+pl800+pl768+pl768pl
MLKEM768_X255196321184+pl1118+pl1088+pl1088pl
MLKEM1024_X255197n/a太大
注意:类型代码仅供内部使用。Router 将保持类型 4,支持情况将在 router 地址中指示。

MLKEM768_X25519 的最小 MTU:IPv4 约为 1316,IPv6 约为 1336。

SessionConfirmed (类型 2)

未更改

数据阶段的 KDF

未改变

中继和对等测试

以下区块包含版本字段。它们将保持版本2(为了与非PQ Bob兼容),并且不会为PQ更改为版本3/4。

  • 中继请求
  • 中继响应
  • 中继介绍
  • 对等测试

PQ 签名:Relay 块、Peer Test 块和 Peer Test 消息都包含签名。不幸的是,PQ 签名比 MTU 更大。目前没有机制可以将 Relay 或 Peer Test 块或消息分片到多个 UDP 数据包中。协议必须扩展以支持分片。这将在一个单独的待定提案中完成。在此完成之前,将不支持 Relay 和 Peer Test。

已发布地址

在所有情况下,像往常一样使用 SSU2 传输名称。不支持 MLKEM-1024。

使用与非PQ、非防火墙相同的地址/端口。支持一种或两种PQ变体。在router地址中,发布v=2(照常)和新参数pq=[3|4|3,4]来表示MLKEM 512/768/两者。较旧的router将忽略pq参数并照常连接非pq。

不支持与非PQ使用不同地址/端口,或仅PQ、非防火墙模式。这将不会实现,直到非PQ SSU2被禁用,即几年后。当非PQ被禁用时,支持一个或两个PQ变体。在router地址中,发布v=[3|4|3,4]以指示MLKEM 512/768/两者。较旧的router将检查v参数并跳过此地址,因为不受支持。

防火墙地址(不发布 IP):在 router 地址中,发布 v=2(如常)。防火墙地址中必须发布 pq 参数,以支持中继。

Alice 可以使用 Bob 发布的 PQ 变体连接到 PQ Bob,无论 Alice 是否在其 router 信息中宣告 pq 支持,或者她是否宣告相同的变体。

MTU

使用 MLKEM768 时请注意不要超过 MTU。SSU2 的最小 MTU 为 1280,这是消息 1 不含填充的大小。如果 Alice 或 Bob 的 MTU 为 1280,请不要在消息 1 中包含填充。

问题

我们可以在内部使用版本字段,对 MLKEM512 使用版本 3,对 MLKEM768 使用版本 4。

对于消息1和消息2,MLKEM768会使数据包大小超过1280的最小MTU。如果MTU太低,可能就不支持该连接。

对于消息1和消息2,MLKEM1024会使数据包大小超过1500字节的最大MTU限制。这将需要对消息1和消息2进行分片处理,这会带来很大的复杂性。可能不会采用这种方案。

中继和对等测试:见上文

流媒体

TODO: 是否有更高效的方式来定义签名/验证以避免复制签名?

SU3 文件

待办事项

IETF 草案 第 8.1 节不允许在 X.509 证书中使用 HashML-DSA,也不为 HashML-DSA 分配 OID,这是因为实现复杂性和安全性降低的缘故。

对于 SU3 文件的纯 PQ 签名,请使用 IETF 草案 中为证书定义的非预哈希变体 OID。我们不定义 SU3 文件的混合签名,因为我们可能需要对文件进行两次哈希(尽管 HashML-DSA 和 X2559 使用相同的哈希函数 SHA512)。此外,在 X.509 证书中连接两个密钥和签名将完全不符合标准。

请注意,我们不允许使用 Ed25519 签名 SU3 文件,虽然我们已经定义了 Ed25519ph 签名,但我们从未就其 OID 达成一致,也从未使用过它。

SU3 文件不允许使用普通的签名类型;请使用 ph(预哈希)变体。

其他规格

新的最大 Destination 大小将是 2599(base 64 中为 3468)。

更新其他提供 Destination 大小指导的文档,包括:

  • SAMv3
  • Bittorrent
  • 开发者指南
  • 命名 / 地址簿 / 跳转服务器
  • 其他文档

开销分析

密钥交换

大小增加(字节):

TypePubkey (Msg 1)Cipertext (Msg 2)
MLKEM512_X25519+816+784
MLKEM768_X25519+1200+1104
MLKEM1024_X25519+1584+1584
速度:

根据 Cloudflare 报告的速度:

类型相对速度
X25519 DH/keygen基准
MLKEM512快2.25倍
MLKEM768快1.5倍
MLKEM10241倍(相同)
XK4倍 DH(keygen + 3 DH)
MLKEM512_X255194倍 DH + 2倍 PQ(keygen + enc/dec)= 4.9倍 DH = 慢22%
MLKEM768_X255194倍 DH + 2倍 PQ(keygen + enc/dec)= 5.3倍 DH = 慢32%
MLKEM1024_X255194倍 DH + 2倍 PQ(keygen + enc/dec)= 6倍 DH = 慢50%
Java 中的初步测试结果:
类型相对 DH/encapsDH/decapskeygen
X25519基准基准基准
MLKEM512快29倍快22倍快17倍
MLKEM768快17倍快14倍快9倍
MLKEM1024快12倍快10倍快6倍

签名

大小:

典型的密钥、签名、RIdent、Dest 大小或大小增量(包含 Ed25519 作为参考),假设 RI 使用 X25519 加密类型。列出了 Router Info、LeaseSet、可回复数据报以及两个流传输(SYN 和 SYN ACK)数据包各自的增加大小。当前的 Destination 和 Leasesets 包含重复填充,在传输过程中可压缩。新类型不包含填充且无法压缩,导致传输中的大小增量要高得多。请参见上述设计部分。

类型公钥签名密钥+签名RIdentDestRInfoLS/Streaming/Datagram (每条消息)
EdDSA_SHA512_Ed25519326496391391baselinebaseline
MLDSA4413122420373213511319+3316+3284
MLDSA6519523309526119911959+5668+5636
MLDSA8725924627721926312599+7072+7040
MLDSA44_EdDSA_SHA512_Ed2551913442484382813831351+3412+3380
MLDSA65_EdDSA_SHA512_Ed2551919843373535720231991+5668+5636
MLDSA87_EdDSA_SHA512_Ed2551926244691731526632631+7488+7456
速度:

Cloudflare 报告的速度:

类型相对速度标识验证
EdDSA_SHA512_Ed25519基准线基准线
MLDSA44慢5倍快2倍
MLDSA65??????
MLDSA87??????
Java 中的初步测试结果:
类型相对签名速度验证密钥生成
EdDSA_SHA512_Ed25519基准基准基准
MLDSA444.6倍慢1.7倍快2.6倍快
MLDSA658.1倍慢相同1.5倍快
MLDSA8711.1倍慢1.5倍慢相同

安全分析

NIST安全类别在NIST演示文稿 第10页中进行了总结。初步标准:对于混合协议,我们的最低NIST安全类别应为2级,对于仅PQ的协议应为3级。

类别安全级别等同于
1AES128
2SHA256
3AES192
4SHA384
5AES256

握手

这些都是混合协议。实现应该优先选择 MLKEM768;MLKEM512 的安全性不够。

NIST 安全类别 FIPS 203

算法安全类别
MLKEM5121
MLKEM7683
MLKEM10245

签名

该提案定义了混合签名类型和仅PQ签名类型。MLDSA44混合签名比MLDSA65仅PQ签名更可取。MLDSA65和MLDSA87的密钥和签名大小对我们来说可能太大了,至少在一开始是这样。

NIST 安全类别 FIPS 204

算法安全类别
MLDSA442
MLKEM673
MLKEM875

类型偏好设置

虽然我们将定义并实现3种加密类型和9种签名类型,但我们计划在开发过程中测量性能,并进一步分析增加的结构大小所带来的影响。我们还将继续研究并监控其他项目和协议的发展动态。

经过一年或更长时间的开发后,我们将尝试为每个用例确定首选类型或默认选项。选择时需要在带宽、CPU和预估安全级别之间进行权衡。并非所有类型都适用或允许用于所有用例。

初步偏好设置如下,可能会有变更:

加密算法:MLKEM768_X25519

签名:MLDSA44_EdDSA_SHA512_Ed25519

初步限制如下,可能会有变更:

加密:SSU2 不允许使用 MLKEM1024_X25519

签名:MLDSA87和混合变体可能过大;MLDSA65和混合变体可能也过大

实现说明

库支持

Bouncycastle、BoringSSL 和 WolfSSL 库现在都支持 MLKEM 和 MLDSA。OpenSSL 的支持将在 2025 年 4 月 8 日发布的 3.5 版本中提供 OpenSSL

Java I2P 改编的 southernstorm.com Noise 库包含了对混合握手的初步支持,但我们将其作为未使用的代码移除了;我们将需要重新添加它并更新以匹配 Noise HFS 规范

签名变体

我们将使用"对冲"或随机化签名变体,而不是"确定性"变体,如 FIPS 204 第 3.4 节所定义。这确保每个签名都是不同的,即使对相同数据进行签名也是如此,并提供额外的侧信道攻击保护。虽然 FIPS 204 规定"对冲"变体是默认选项,但在各种库中这可能是也可能不是这样。实现者必须确保在签名时使用"对冲"变体。

我们使用标准的签名过程(称为纯 ML-DSA 签名生成),该过程在内部将消息编码为 0x00 || len(ctx) || ctx || message,其中 ctx 是大小为 0x00..0xFF 的可选值。我们没有使用任何可选上下文。len(ctx) == 0。此过程在 FIPS 204 算法 2 步骤 10 和算法 3 步骤 5 中定义。注意,某些已发布的测试向量可能需要设置一种模式,在该模式下消息不进行编码。

可靠性

大小增加将导致 NetDB 存储、流式握手和其他消息的 tunnel 分片大幅增加。请检查性能和可靠性变化。

结构大小

查找并检查任何限制 router info 和 leaseSet 字节大小的代码。

NetDB

审查并可能减少在内存或磁盘中存储的最大 LS/RI 数量,以限制存储增长。提高 floodfill 的最低带宽要求?

棘轮

共享 Tunnel

基于消息1(新会话消息)的长度检查,应该可以在相同tunnel上自动分类/检测多个协议。以MLKEM512_X25519为例,消息1的长度比当前ratchet协议大816字节,最小消息1大小(仅包含DateTime载荷)为919字节。当前ratchet的大多数消息1载荷都小于816字节,因此可以将它们分类为非混合ratchet。大消息可能是POST请求,这种情况比较少见。

因此推荐的策略是:

  • 如果消息1小于919字节,则为当前的ratchet协议。
  • 如果消息1大于或等于919字节,则可能是MLKEM512_X25519。 先尝试MLKEM512_X25519,如果失败,再尝试当前的ratchet协议。

这应该允许我们在同一个目标上有效地支持标准 ratchet 和混合 ratchet,就像我们之前在同一个目标上支持 ElGamal 和 ratchet 一样。因此,我们可以比不能为同一目标支持双协议的情况下更快地迁移到 MLKEM 混合协议,因为我们可以为现有目标添加 MLKEM 支持。

必需支持的组合有:

  • X25519 + MLKEM512
  • X25519 + MLKEM768
  • X25519 + MLKEM1024

以下组合可能比较复杂,不是必须支持的,但可能会支持,这取决于具体实现:

  • 多个 MLKEM
  • ElG + 一个或多个 MLKEM
  • X25519 + 一个或多个 MLKEM
  • ElG + X25519 + 一个或多个 MLKEM

我们可能不会尝试在同一个目标上支持多个 MLKEM 算法(例如,MLKEM512_X25519 和 MLKEM_768_X25519)。只选择一个;但是,这取决于我们选择首选的 MLKEM 变体,以便 HTTP 客户端 tunnel 可以使用。依赖于具体实现。

我们可能会尝试在同一个目标上支持三种算法(例如 X25519、MLKEM512_X25519 和 MLKEM769_X25519)。分类和重试策略可能过于复杂。配置和配置界面可能过于复杂。这取决于具体实现。

我们很可能不会尝试在同一个目标上同时支持 ElGamal 和混合算法。ElGamal 已经过时,而且仅支持 ElGamal + 混合算法(没有 X25519)意义不大。此外,ElGamal 和混合新会话消息都很大,因此分类策略通常必须尝试两种解密方式,这会很低效。具体实现取决于实现方。

客户端可以在相同的 tunnel 上为 X25519 和混合协议使用相同或不同的 X25519 静态密钥,这取决于具体实现。

前向保密性

ECIES规范允许在新会话消息载荷中包含Garlic消息,这使得可以实现0-RTT传输初始流数据包(通常是HTTP GET)以及客户端的leaseset。然而,新会话消息载荷不具备前向保密性。由于本提案强调增强ratchet的前向保密性,实现可能会或应该推迟包含流载荷或完整流消息,直到第一个现有会话消息。这将以牺牲0-RTT传输为代价。策略也可能取决于流量类型或tunnel类型,或者例如GET与POST的区别。具体实现可自行决定。

新会话大小

在同一目标上使用MLKEM、MLDSA或两者都使用,将显著增加新会话消息的大小,如上所述。这可能会大幅降低新会话消息通过tunnel传递的可靠性,因为消息必须被分片为多个1024字节的tunnel消息。传递成功率与分片数量成指数关系。实现可以使用各种策略来限制消息大小,但会以牺牲0-RTT传递为代价。具体取决于实现。

NTCP2

我们在会话请求中设置临时密钥的最高位(key[31] & 0x80)来表示这是一个混合连接。这允许我们在同一端口上同时运行标准 NTCP 和混合 NTCP。只支持一种混合变体,并在 router 地址中公告。例如,v=2,3 或 v=2,4 或 v=2,5。

混淆

作为 Alice,对于 PQ 连接,在混淆之前,设置 X[31] |= 0x80。这使得 X 成为一个无效的 X25519 公钥。混淆后,AES-CBC 会将其随机化。混淆后 X 的最高有效位将是随机的。

作为 Bob,在去混淆后测试 (X[31] & 0x80) != 0。如果是这样,则这是一个 PQ 连接。

NTCP2-PQ 所需的最低 router 版本待定。

注意:类型代码仅供内部使用。Router将保持为类型4,支持将在router地址中指示。

SSU2

我们在长头部中使用版本字段,对于 MLKEM512 设置为 3,对于 MLKEM768 设置为 4。地址中使用 v=2,3,4 就足够了。

检查并验证 SSU2 能够处理跨多个数据包(6-8个?)分片的 MLDSA 签名 RI。

注意:类型代码仅供内部使用。Router将保持为类型4,支持情况将在router地址中指示。

Router 兼容性

传输名称

在所有情况下,请照常使用 NTCP2 和 SSU2 传输名称。

Router 加密类型

我们有几个备选方案需要考虑:

Type 5/6/7 Router

不推荐。仅使用上面列出的与 router 类型匹配的新传输协议。旧版 router 无法连接、构建 tunnel 或发送 netDb 消息。需要几个发布周期来调试并确保支持,然后才能默认启用。相比下面的替代方案,可能会将推出时间延长一年或更多。

Type 4 Router

推荐。由于 PQ 不影响 X25519 静态密钥或 N 握手协议,我们可以让 router 保持类型 4,只是公布新的传输方式。旧版本的 router 仍然可以连接、构建 tunnel 通过,或向其发送 netDb 消息。

建议

推荐在 Ratchet、NTCP2 和 SSU2 中使用 MLKEM-768,因为它在安全性和密钥长度之间提供了最佳平衡。

Router 签名类型

类型 12-17 Router

较旧的router会验证RI,因此无法连接、通过其构建tunnel或向其发送netDb消息。在默认启用之前,需要经过多个发布周期来调试和确保支持。这将面临与enc. type 5/6/7推出相同的问题;相比上面列出的type 4 enc. type推出替代方案,可能会将推出时间延长一年或更久。

无替代方案。

LS 加密类型

类型 5-7 LS 密钥

这些可能存在于带有较旧类型 4 X25519 密钥的 LS 中。较旧的 router 会忽略未知的密钥。

目标节点可以支持多种密钥类型,但只能通过对消息1使用每个密钥进行试解密来实现。可以通过维护每个密钥成功解密的计数,并优先尝试使用最多的密钥来减轻开销。Java I2P在同一目标节点上使用ElGamal+X25519时采用了这种策略。

目标签名类型

Type 12-17 目标

Router 会验证 leaseSet 签名,因此无法连接或接收类型 12-17 目标的 leaseSet。需要经过几个发布周期来调试并确保支持后才能默认启用。

没有替代方案。

优先级和发布

最有价值的数据是端到端流量,使用棘轮加密进行加密。作为tunnel跳跃之间的外部观察者,这些数据被额外加密两次,分别使用tunnel加密和传输加密。作为OBEP和IBGW之间的外部观察者,数据只被额外加密一次,使用传输加密。作为OBEP或IBGW参与者,棘轮是唯一的加密方式。然而,由于tunnel是单向的,要捕获棘轮握手中的两个消息需要串通的router,除非tunnel是在同一个router上构建OBEP和IBGW。

目前最令人担忧的后量子威胁模型是今天存储流量,然后在很多很多年后进行解密(前向保密)。混合方法可以防护这种威胁。

PQ威胁模型中,在合理时间内(比如几个月)破解认证密钥,然后冒充认证或近实时解密,这种情况还很遥远?那时我们才需要迁移到PQC静态密钥。

因此,最早的PQ威胁模型是OBEP/IBGW存储流量以供后续解密。我们应该首先实现混合棘轮。

Ratchet 是最高优先级。传输层次之。签名是最低优先级。

签名推广也将比加密推广晚一年或更长时间,因为不可能实现向后兼容。此外,MLDSA 在行业中的采用将由 CA/Browser Forum 和证书颁发机构标准化。CA 首先需要硬件安全模块 (HSM) 支持,但目前尚不可用 CA/Browser Forum 。我们预期 CA/Browser Forum 将推动关于特定参数选择的决策,包括是否支持或要求复合签名 IETF draft

里程碑目标时间
Ratchet beta2025年底
选择最佳加密类型2026年初
NTCP2 beta2026年初
SSU2 beta2026年中
Ratchet 生产版2026年中
Ratchet 默认2026年底
签名 beta2026年底
NTCP2 生产版2026年底
SSU2 生产版2027年初
选择最佳签名类型2027年初
NTCP2 默认2027年初
SSU2 默认2027年中
签名生产版2027年中

迁移

如果我们无法在同一个 tunnel 上同时支持新旧 ratchet 协议,迁移将会变得困难得多。

我们应该能够像处理 X25519 那样,依次尝试不同的方法,这一点有待验证。

问题

  • Noise Hash 选择 - 继续使用 SHA256 还是升级? SHA256 应该在未来 20-30 年内都是安全的,不会受到量子计算威胁, 参见 NIST 演示文稿NCCOE 演示文稿 。 如果 SHA256 被破解,我们会面临更严重的问题 (netDb)。
  • NTCP2 独立端口,独立 router 地址
  • SSU2 中继 / 对等测试
  • SSU2 版本字段
  • SSU2 router 地址版本

参考资料