3. SLH-DSA算法框架与参数集
SLH-DSA(Stateless Hash-Based Digital Signature Algorithm)是NIST后量子密码标准化中基于哈希的数字签名方案,其安全性仅依赖于底层哈希函数的抗碰撞性和抗原像性,不依赖任何数论困难问题。理解它的算法框架与参数集,是正确实现和评估该方案的前提。本节从三个核心函数出发,解析其内部结构,并说明标准参数集的构成逻辑与选择依据。
一、整体框架:三层结构
SLH-DSA的算法框架可以概括为“超树 + 少次签名 + 一次签名”的三层嵌套结构。最底层是WOTS+(Winternitz一次性签名),它只能安全地签一条消息;中间层是FORS(Few-Time Signature,少次签名),用于对消息摘要进行“压缩承诺”;最上层是Hypertree(超树),由多层Merkle树堆叠而成,把一次性公钥的验证路径逐层向上锚定到根公钥。
密钥生成阶段,算法自底向上构造超树:先生成最底层各棵子树的WOTS+密钥对,计算其叶节点,再逐层向上哈希得到各层树根,最终最顶层的树根即为公钥PK.root;私钥则由主种子SK.seed、伪随机函数种子SK.prf和公钥种子PK.seed组成。签名阶段,签名者对消息做两级哈希得到摘要,用FORS对摘要的前若干位签名,得到FORS公钥;再用超树中对应叶子的WOTS+私钥对“FORS公钥 + 树索引”签名,并附上从该叶子到根的各层认证路径。验证阶段则反向执行:用签名中的WOTS+签名重建叶节点,沿认证路径逐层哈希到根,与公钥比对;同时用FORS签名重建FORS公钥,校验摘要一致性。
二、标准参数集:哈希函数与安全级别的组合
FIPS 205 定义了 12 个参数集,由两个维度交叉组合而成。第一个维度是哈希函数族:SHA-256 与 SHAKE256。SHA-256 变体使用 SHA-256 配合预计算的简单哈希函数族,速度快、实现成熟;SHAKE256 变体使用 SHAKE256 作为可扩展输出函数,天然支持任意长度输出,适合需要灵活参数或硬件资源受限的场景。第二个维度是安全级别:128 位、192 位、256 位,分别对应 NIST 安全类别 1、3、5。
每个安全级别下又分为“s”(small,小签名)与“f”(fast,快速签名)两种优化取向。以 SHA-256 为例,参数集命名为 SLH-DSA-SHA2-128s、SLH-DSA-SHA2-128f、SLH-DSA-SHA2-192s、SLH-DSA-SHA2-192f、SLH-DSA-SHA2-256s、SLH-DSA-SHA2-256f;SHAKE256 变体同理命名为 SLH-DSA-SHAKE-128s 等。s 变体通过增大超树层数 d、减小每层高度 h,使签名更短但签名计算更慢;f 变体则相反,签名更快但签名体积更大。
| 参数集 | n(字节) | h(每层高度) | d(层数) | 签名长度(字节) | 公钥长度(字节) |
|---|---|---|---|---|---|
| SLH-DSA-SHA2-128s | 16 | 9 | 7 | 7856 | 32 |
| SLH-DSA-SHA2-128f | 16 | 3 | 22 | 17088 | 32 |
| SLH-DSA-SHA2-192s | 24 | 9 | 7 | 16224 | 48 |
| SLH-DSA-SHA2-192f | 24 | 3 | 22 | 35664 | 48 |
| SLH-DSA-SHA2-256s | 32 | 8 | 8 | 29792 | 64 |
| SLH-DSA-SHA2-256f | 32 | 4 | 17 | 49856 | 64 |
表中数值为 FIPS 205 标准规定的固定值,可直接用于实现时的缓冲区分配与长度校验。可以看到,安全级别越高,n 越大,签名长度随之增长;同一安全级别下,f 变体的签名长度约为 s 变体的 2 倍左右,但签名速度显著更快。
三、参数选择对性能与安全的影响
参数选择的核心矛盾在于签名体积、签名速度与验证速度之间的权衡。超树总高度 H = h × d 决定了需要签名的层数,也决定了签名中认证路径的总长度。增大 d 会减少每层认证路径的长度,从而缩短签名,但签名者需要为每一层计算 WOTS+ 签名,计算量随 d 线性增长;减小 d 则相反。这就是 s 与 f 两类变体的本质区别。
从安全角度看,n 直接决定哈希输出的字节数,进而决定抗碰撞安全强度(约为 n/2 位)和抗原像安全强度(约为 n 位)。128 位安全级别对应 n=16 字节,256 位对应 n=32 字节。需要特别注意的是,SLH-DSA 的安全归约对哈希函数有额外要求:FORS 和 WOTS+ 的安全性依赖于哈希函数在特定输入分布下的抗原像性,因此实现中必须严格使用标准规定的哈希函数族构造,不能随意替换为“看起来等价”的哈希。
四、实现要点与验证判据
实现 SLH-DSA 时,首先应根据所选参数集确定所有长度常量:n、h、d、FORS 的 k 与 a、WOTS+ 的 w 等。这些常量直接决定密钥、签名和中间缓冲区的布局。其次,密钥生成、签名、验证三个函数必须共享同一套地址结构(ADRS),用于在哈希调用中区分不同的树、层、链和哈希类型,地址编码错误是导致验证失败的最常见原因之一。
验证阶段的判据非常明确:用签名中的 WOTS+ 签名和认证路径重建出的根,必须与公钥中的 PK.root 逐字节相等;同时,用 FORS 签名重建的 FORS 公钥必须与 WOTS+ 签名所承诺的值一致。任一环节不匹配即判定签名无效。实现时应先做长度校验(签名长度必须等于参数集规定值),再做密码学验证,避免因缓冲区越界引发安全问题。
// 以 SLH-DSA-SHA2-128s 为例的长度常量(示例)
#define N 16 // 哈希输出字节数
#define H 9 // 每层树高
#define D 7 // 超树层数
#define SIG_LEN 7856 // 签名总长度
#define PK_LEN 32 // 公钥长度(2*N)
#define SK_LEN 64 // 私钥长度(4*N)
上述常量在实现中应作为编译期常量或配置项固化,并在签名与验证入口处做断言检查。对于需要支持多参数集的库,建议将参数集抽象为结构体,把 n、h、d、签名长度等字段集中管理,避免散落在各函数中的魔数导致维护错误。
综上,SLH-DSA 的框架可归纳为“FORS 压缩消息、WOTS+ 承诺叶节点、超树锚定到根”的三级结构;参数集则在哈希函数族、安全级别和 s/f 优化取向三个维度上展开。正确理解 h、d、n 三个核心参数的作用,是选择参数集、预估性能和分析安全边界的关键。