跳到主要内容
ecdsa.com

low-S 规范化

要求 ECDSA 签名的 s 值位于取值范围下半部分(s ≤ n/2)的规则,比特币和以太坊采用它来消除 ECDSA 固有的签名延展性。
其他写法low SLOW_Scanonical shigh-S

对于任何有效的 ECDSA 签名 (r, s),(r, n − s) 同样能通过验证:对 nonce 取负会翻转 s 的符号,而 k·G 与 −k·G 的 x 坐标相同。low-S 选取满足 s ≤ n/2 的那个代表;只要 s 较大,签名者就用 n − s 替换 s 来完成规范化。对 secp256k1 而言,n/2 向下取整为 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0。

Bitcoin Core 从 0.11.1 版(2015年)起只中继 low-S 签名,从 0.9.0 版起生成的就是 low-S 签名,BIP 146 记录了这一点;libsecp256k1 的验证器会拒绝 high-S。以太坊的 EIP-2(Homestead,2016年)规定 s 大于 n/2 的交易无效,但 ecrecover 预编译合约仍然接受 high-S 值,因此验证签名的合约必须自行强制执行这个上限。

通用的验证器(OpenSSL、WebCrypto、Java、Go)两种形式都接受,而 OpenSSL 等通用签名实现不做规范化,因此它们生成的签名约有一半在规范化之前无法通过 low-S 检查。EdDSA 要求 S 小于群的阶(RFC 8032 §5.1.7),从而避免了这个问题。

标准与参考资料

全部术语