协议演进 / BIP/比特币改进提案 / BIP-340

BIP-340 secp256k1 的 Schnorr 签名

为 secp256k1 定义字节级完全确定的 64 字节 Schnorr 签名标准:32 字节 x-only 公钥、可批量验证,是 Taproot 的签名地基。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-340
标题Schnorr Signatures for secp256k1
作者Pieter Wuille <[email protected]>; Jonas Nick <[email protected]>; Tim Ruffing <[email protected]>
指定日期2020-01-19
讨论日期2018-07-06
层级未标注(签名规范)
类型Specification(规范类)
状态Deployed(已部署)
阅读版https://bips.dev/340
官方原文https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki

二、放在哪一族

签名方案族,是 Taproot 三件套的地基:BIP-340 定签名本身,BIP-341 定 SegWit v1 输出的花费规则,BIP-342 定脚本(Tapscript)里的签名验证语义。后两者的 Schnorr 验证都直接引用本文档的算法。

它接替的不是某一篇旧 BIP,而是比特币自创世以来使用的 ECDSA(配合 SHA256、同一条 secp256k1 曲线)。原文开宗明义:沿用同一条曲线与同一个哈希函数,既有的密钥生成机制(如 BIP-32 及其派生方案)全部保留,不引入对曲线与哈希函数的新安全假设。

下游应用包括:基于线性性质的多签与门限签名协议 MuSig2(BIP-327)、FROST,以及适配器签名(adaptor signatures)、盲签名等构造——这些在原文 Applications 一节都有专门论述。

三、它要解决什么

原文 Motivation 把 Schnorr 相对 ECDSA 的优势列为三条:

既然要新立标准,原文顺手把几个与 Schnorr 本身无关的问题一并解决:签名改用定长 64 字节编码(ECDSA 的 DER 编码变长、最长可达 72 字节);公钥只编 x 坐标、32 字节(现行压缩公钥是 33 字节);支持批量验证;最重要的是字节级完全定义——验证算法在每个字节上都没有歧义,保证没人能造出“对部分验证者有效、对另一部分无效”的签名。ECDSA 的 DER 解析当年定义不严,酿成过真实问题,最后要靠 BIP-66 打补丁,原文明确以此为戒。

四、规则本身

4.1 最终方案的形状

签名是 (R, s) 对:验证等式为 s⋅G = R + hash(R ‖ P ‖ m)⋅P,其中 P 为公钥点、m 为消息、G 为曲线基点。原文在两种变体中选了 (R, s) 而非 (e, s),关键理由是 (R, s) 变体支持批量验证,且不必为了缩短签名而使用短哈希——短哈希的碰撞在多方协作签名场景下会被恶意共签者利用。

三项关键设计:

4.2 编码

4.3 签名算法(默认)

原文给出的默认算法是确定性流程加一份“合成随机数”保险:把 32 字节辅助随机数据 a 经 BIP0340/aux 标签哈希后与私钥异或,再经 BIP0340/nonce 标签哈希(输入还包含公钥与消息)得到随机数材料,导出一次性值 k,并同样按 R 的 y 坐标奇偶规范化;挑战值 e 由 BIP0340/challenge 标签哈希算出,签名 s = k + e⋅d。输出前先自验一遍,验证失败即中止,以防计算错误泄露私钥信息。

要点有二:其一,随机性只是对侧信道与故障注入攻击的补充防线,方案的常规安全性质不依赖签名时随机数发生器的质量;其二,原文明确警告,默认算法(及任何确定性随机数生成方式)不能直接用于多签协议——MuSig2 等协议有自己的随机数要求,误用会不安全。其他产出合法签名的替代算法允许存在,但其随机数材料必须是全新、均匀随机且不可预测的,且不得跨签名方案复用同一私钥。

4.4 验证与批量验证

验证:由公钥 x 坐标经 lift_x 提升为 y 偶数的点 P;检查签名两半分别小于域大小 p 与曲线阶 n;算出挑战 e 与 R = s⋅G − e⋅P;当且仅当 R 非无穷远点、y 为偶数、且 x(R) 等于签名中的 r 时通过。

批量验证:多份签名可按随机系数线性组合后一次验证。全部合法时批量验证必然通过;只要有一份不合法,批量验证误放行的概率可忽略。系数由全部输入的哈希播种的密码学安全随机源确定性生成,以满足“批量结果不得与逐个验证实质不同”的字节级确定性要求。

4.5 消息长度与测试材料

现行规范接受任意长度的消息(早期修订曾限定恰为 32 字节,后已取消,变更记录在原文 Changelog);大消息出于性能考虑建议先预哈希。原文同时给出 CSV 格式的测试向量与纯 Python 参考实现(仅供演示,不可用于生产),以及应用消息的域分离(domain separation)最佳实践。

五、谁必须动

普通持币人:无直接动作。是否用上 Schnorr 签名,取决于钱包是否支持 Taproot 类输出;旧地址与旧交易分毫不变。

钱包与签名设备开发者:必须逐字节实现原文算法——公私钥规范化、标签哈希、随机数导出一步都不能自创;并用原文测试向量对拍。交互式多签场景不得套用默认签名算法的随机数生成。

全节点与验证者:在 BIP-341、BIP-342 的花费规则里调用本算法验签;可利用批量验证加速。

密码学协议开发者:MuSig2、门限签名、适配器签名等构造以本方案的线性与密钥前缀性质为前提,应按原文 Applications 一节的边界使用。

六、现在算不算数,以及一个常见误读

状态为 Deployed(已部署)。它已经作为 Taproot 的签名标准定稿:编码、签名、验证、批量验证全部字节级写死,并配有测试向量与参考实现,供各实现互操作。需要注意它自身的定位:BIP-340 是一份签名方案规范,本身不修改任何链上规则——真正在共识层启用它的是 BIP-341 与 BIP-342。

常见误读:

“BIP-340 之后,比特币把 ECDSA 淘汰了。”

不对。它新增了一套签名方案,而不是替换旧方案:存量输出类型(传统地址、SegWit v0 等)的 ECDSA 验证规则原封不动;Schnorr 签名只在 Taproot 花费中登场。同一条链上,两套签名体系按输出类型分工、长期并存。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。