跳到主要内容
ecdsa.com

ML-DSA vs SLH-DSA:基于格还是基于哈希的后量子签名

ML-DSA 是通用的后量子签名:签名以千字节计,签名速度快。SLH-DSA 的安全性只依赖哈希函数,代价是 8~50 KB 的签名和缓慢的签名速度。

在 NIST 已标准化的后量子签名中,主要的选择就是 ML-DSA 与 SLH-DSA,两者都于2024年8月13日发布。ML-DSA(FIPS 204,源自 CRYSTALS-Dilithium)依赖结构化格;SLH-DSA(FIPS 205,源自 SPHINCS+)只依赖其哈希函数的安全性。两者在大小和速度上的特征差别极大,因此大多数系统会使用 ML-DSA,而在保守的安全假设值得付出代价的场合使用 SLH-DSA。

概览

ML-DSA(FIPS 204)SLH-DSA(FIPS 205)
安全假设Module-LWE 和 Module-SIS 格问题仅依赖 SHA-2 或 SHAKE 的性质
参数集ML-DSA-44、-65、-8712 个:SHA2 或 SHAKE × 128/192/256 × s(小型)或 f(快速)
安全类别2、3、51、3、5
公钥1,312 / 1,952 / 2,592 字节32 / 48 / 64 字节
签名2,420 / 3,309 / 4,627 字节7,856(128s)至 49,856 字节(256f)
私钥展开形式 2,560~4,896 字节,或 32 字节的种子64 / 96 / 128 字节
每秒签名次数(OpenSSL 3.6.5)约 3,900(44)、2,400(65)、2,050(87)约 7(SHA2-128s)、144(SHA2-128f)、3.5(SHA2-192s)
每秒验证次数约 20,800(44)、13,600(65)、8,500(87)约 7,400(SHA2-128s)、2,400(SHA2-128f)
每秒密钥生成次数约 22,000(44)约 55(128s)、3,400(128f)
签名随机性默认采用对冲式签名,允许确定性变体默认采用对冲式签名,允许确定性变体
上下文字符串最多 255 字节最多 255 字节
预哈希变体HashML-DSA(§5.4)HashSLH-DSA(§10.2.2)
X.509RFC 9881(id-ml-dsa-44 = 2.16.840.1.101.3.4.3.17 …)RFC 9909(id-slh-dsa-sha2-128s = …3.4.3.20 …)

速度用 openssl speed 在 Apple M4 Max 的单个核心上测得;OpenSSL 的 ML-DSA 是可移植的 C 代码,经过优化的实现签名速度要快好几倍。

安全假设

ML-DSA 是一种采用“带中止的 Fiat–Shamir”构造的格方案。它的安全性建立在模带误差学习(Module-LWE)和模短整数解(Module-SIS)问题之上:这两个问题已被研究了约二十年,经受住了经典攻击和量子攻击,但随着格基约减技术的进步,其具体的安全性估计仍在变化。NIST 选择的参数集相对这些估计留有余量。

SLH-DSA 用排列成超树(hypertree)的一次性和少次基于哈希的签名来构造签名。只要 SHA-256 或 SHAKE256 保持抗原像性及相关性质,SLH-DSA 就是安全的;它没有可供攻击的代数结构。这使它成为 NIST 标准化的签名中最保守的一种,也是万一格问题出现突破时天然的后备方案。与有状态的基于哈希的方案 LMS 和 XMSS 不同,它不需要维护状态:每个密钥最多可签名 2⁶⁴ 条消息。

实际的大小与速度

下面的脚本用 OpenSSL 3.6.5 以每种算法对同一条消息签名。

OpenSSL 3.6:后量子签名与经典签名的大小
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
printf 'firmware-2026.10.bin digest' > msg
for alg in ML-DSA-44 ML-DSA-65 SLH-DSA-SHA2-128s SLH-DSA-SHA2-128f ED25519; do
  openssl genpkey -algorithm "$alg" -out key.pem 2>/dev/null
  openssl pkeyutl -sign -rawin -inkey key.pem -in msg -out sig.bin 2>/dev/null
  openssl pkey -in key.pem -pubout -outform DER -out pub.der 2>/dev/null
  openssl pkey -in key.pem -pubout -out pub.pem 2>/dev/null
  if openssl pkeyutl -verify -rawin -pubin -inkey pub.pem -in msg -sigfile sig.bin >/dev/null 2>&1; then ok=yes; else ok=no; fi
  printf '%-18s public key (SPKI DER) %5s bytes, signature %6s bytes, verifies: %s\n' "$alg" \
    "$(wc -c < pub.der | tr -d ' ')" "$(wc -c < sig.bin | tr -d ' ')" "$ok"
done
cd / && rm -rf "$dir"
输出
ML-DSA-44          public key (SPKI DER)  1334 bytes, signature   2420 bytes, verifies: yes
ML-DSA-65          public key (SPKI DER)  1974 bytes, signature   3309 bytes, verifies: yes
SLH-DSA-SHA2-128s  public key (SPKI DER)    50 bytes, signature   7856 bytes, verifies: yes
SLH-DSA-SHA2-128f  public key (SPKI DER)    50 bytes, signature  17088 bytes, verifies: yes
ED25519            public key (SPKI DER)    44 bytes, signature     64 bytes, verifies: yes

两者的特征恰好相反。ML-DSA 的公钥和签名都以千字节计,每秒可签名数千次。SLH-DSA 的公钥极小(与 Ed25519 的一样小),但签名有 8~50 KB,而且在这台机器上,小型的 s 参数集每次签名约需 137 毫秒(f 参数集以签名大小翻倍为代价,换来约 20 倍的签名速度)。两者的验证都很快。对于证书链或 TLS 握手,ML-DSA 可行而 SLH-DSA 不可行;对于每次发布只签名一次、每次启动都要验证的固件镜像,SLH-DSA 的开销无关紧要,其极小的公钥也能放进启动 ROM。

运维细节

  • 对冲签名(hedged signing)。两项标准默认都会把新鲜的随机数与从密钥派生的值混合,并允许在没有随机数生成器的平台上使用确定性变体;验证方无法区分两者。
  • 上下文。两者都会把最多 255 字节的上下文字符串绑定到每个签名中,协议应利用它区分不同用途。
  • 纯签名与预哈希变体。HashML-DSA 和 HashSLH-DSA 对摘要签名,并把哈希算法的 OID 绑定进去;它们是独立的算法,拥有各自的 OID,FIPS 204 建议一个密钥只用于两者之一。
  • 私钥格式。ML-DSA 密钥可以存储为 32 字节的种子,RFC 9881 的 seed 和 both 编码都允许这样做;如果一方只接受展开后的密钥,就会出现互操作问题。
  • 硬件与 FIPS 验证。支持 ML-DSA 和 SLH-DSA 的已验证模块从2024年起陆续出现;具体支持哪些参数集,以模块的证书为准。

如何选择

  • 私有 PKI、内部 mTLS、文档和代码签名:ML-DSA-65(或 44)。
  • 固件、安全启动、硬件信任根:SLH-DSA-128s 或 192s;如果你能管理签名者的状态,也可以选用 CNSA 2.0 针对这一场景强制要求的有状态方案 LMS 和 XMSS。
  • 需要保存数十年的长期归档和根证书:SLH-DSA,也可以与 ML-DSA 搭配组成双重签名。
  • 大批量签名(令牌、交易、日志):ML-DSA;SLH-DSA 跟不上。
  • 带宽受限的协议:两者都不小;ML-DSA-44 是目前已标准化方案中最小的,FN-DSA(FIPS 206 草案)的目标更小。
  • 公共 WebPKI 的 TLS:目前浏览器两者都不接受;过渡的整体情况参见 ML-DSA vs ECDSA。

迁移说明

  1. 按有效期和签名量盘点签名用途:长期有效且很少签名的制品适合用 SLH-DSA,其余都用 ML-DSA。
  2. 选择实现了最终标准的库版本:OpenSSL 3.5 或更高版本(2025年4月),Java 版 Bouncy Castle 1.79 或更高版本(标准化的私钥编码需要 1.81),ML-DSA 可用 Go 1.27 的 crypto/mldsa。标准化之前的 Dilithium 和 SPHINCS+ 的输出与之不兼容。
  3. 为大小做好规划:提高证书、令牌和签名字段的大小上限;ML-DSA-65 证书约为 5.5 KB(参见配套的对比文章),SLH-DSA 签名则可能超出常见的头部或记录大小限制。
  4. 过渡期间考虑混合方案:ML-DSA 加 ECDSA 或 EdDSA 的复合证书(IETF 草案)或双重签名,可以让经典验证方继续正常工作。
  5. 在协议规范中固定上下文字符串和变体(纯签名或预哈希),使所有实现保持一致。

参考资料

全部对比