在 ECDSA 中,签名者在 1…n−1 范围内选取 k,计算点 kG,并取其 x 坐标模 n 的值作为 r;然后计算 s = k⁻¹·(z + r·d) mod n,其中 z 是截断后的消息哈希,d 是私钥(FIPS 186-5 §6.4.1)。由于 s 同时是 k 和 d 的线性函数,只要得知单个签名的 k,就足以解出私钥:d = (s·k − z)·r⁻¹ mod n。因此,FIPS 186-5 §6.3 要求每次签名都使用全新的 k,并像保护密钥本身一样保护它。
重复使用同样致命,而且很容易被发现:同一密钥下 r 相同的两个签名可以算出 k = (z₁ − z₂)·(s₁ − s₂)⁻¹ mod n,进而算出 d。PlayStation 3 的签名密钥就是这样在2010年被提取出来的,许多区块链钱包也是这样被盗空的。nonce 甚至不必重复:每个签名只要有几位偏差或泄漏,收集到足够多的签名后,就能用格基约简求解隐藏数问题,从而恢复密钥。
现代库会根据私钥和消息哈希确定性地派生 k(RFC 6979,FIPS 186-5 §6.3.2 允许这种做法),或者使用对冲变体,在同样的派生过程中混入全新的随机性。EdDSA 把这一思路内置到算法中:Ed25519 的 nonce 是对私钥的一半与消息计算的 SHA-512(RFC 8032 §5.1.6)。nonce 重用检测工具会在一组签名中查找重复的 r 值。
在签名之外,“nonce”泛指任何只使用一次的值:AES-GCM 的 96 位 IV、OpenID Connect 的 nonce 声明、ACME 的 Replay-Nonce 头部。这些值需要的是唯一性和新鲜性,而不是保密性;签名中的 nonce 则不同寻常:既需要唯一和新鲜,也需要保密。