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

BIP-66 严格 DER 签名

把签名必须采用严格 DER 编码写进共识有效性规则,使区块有效性不再依赖 OpenSSL 如何宽容地解析签名。本 BIP 目前处于已激活状态。

一、档案卡

档案卡
编号BIP-66
标题Strict DER signatures
作者Pieter Wuille <[email protected]>
指定日期2015-01-10
层级Consensus (soft fork)(共识(软分叉))
类型Specification(规范类)
状态Deployed(已激活)
阅读版https://bips.dev/66
官方原文https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki

二、放在哪一族

BIP-66 是共识收紧族的一份:它不新增功能,只把原本“事实上被容忍”的一类签名编码从有效集合里划出去,属于典型的软分叉——新规则只增加失败情形,不增加成功情形,原文的示例一节专门逐条核对了这一点。

内容上它是从先前的 BIP-62 提案中抽出的单项(原文致谢一节说明本文档 extracted from the previous BIP62 proposal);它与交易可塑性的关系也来自那一脉络:严格编码顺带减少了一类可塑性来源。部署上,它使用的双门槛切换机制后被 BIP-65 复用。

三、它要解决什么

比特币的参考实现当时依赖 OpenSSL 做签名验证,这等于让 OpenSSL 隐性地定义比特币的区块有效性规则。问题在于 OpenSSL 不是为“共识关键行为”设计的:它不保证不同版本之间逐 bug 兼容,它的改动已经实际影响过比特币软件。

签名编码是最要害的一处。长期以来 OpenSSL 的各个版本会宽容地接受偏离 DER 标准的各种编码并判为有效;当 OpenSSL 1.0.0p 与 1.0.1k 收紧这一行为时,结果是一些节点开始拒绝整条链。

BIP-66 的主张是反过来:把“有效签名恰好就是 DER 所规定的”写进比特币自己的有效性规则,使共识不再依赖 OpenSSL 的签名解析。原文说,这类改动是“若实现想把 OpenSSL 全部移出共识代码”所必需的。

四、规则本身

4.1 总规则

凡是传给 OP_CHECKSIG、OP_CHECKSIGVERIFY、OP_CHECKMULTISIG、OP_CHECKMULTISIGVERIFY 并要做 ECDSA 验证的签名,都必须使用严格 DER 编码。

这四个操作码都对栈上的公钥 / 签名对逐个做 ECDSA 验证。对其中每次验证:若签名未通过下述 IsValidSignatureEncoding 检查,整个脚本立即判为失败;若签名是合法 DER、但 ECDSA 验证本身不通过,则按原有行为继续(在某些情形下使操作码停止并向栈上压 false,但不立即使脚本失败),后续未轮到的签名也就不再被做编码检查。

空签名(长度为 0)不调用该检查函数——为的是给“故意无效的签名”保留一个简单、短小、可高效验证的编码。

4.2 严格 DER 的格式

比特币的签名字节串在 DER 签名之后还带 1 字节 sighash 标志,该标志不属于 DER 规范本身、不受本提案影响,但检查函数面对的是包含它的完整字节串。格式为:

0x30 [总长度] 0x02 [R 长度] [R] 0x02 [S 长度] [S] [sighash]

检查要点包括:

4.3 部署

复用 BIP-34 的双门槛切换机制,门槛相同,但对应 nVersion = 3:某高度 H 的区块为 nVersion = 3、且其前 1000 个区块中至少 750 个为 nVersion = 3 时,新规则对该区块生效;当前 1000 个区块中 950 个为 nVersion = 3 后,nVersion = 2 的区块变为无效,此后所有区块强制执行新规则。

4.4 兼容性

原文给出的部署底气是:严格 DER 要求自参考客户端 v0.8.0 起就已作为转发政策(relay policy)执行,到 2015 年 1 月被加进链上的违规交易已极少;且任何不合规签名都能平凡地转换成合规签名,这一要求没有功能损失。附带收益是减少交易可塑性(见 BIP-62)。

五、谁必须动

普通持币人:无直接变化。正常钱包产生的签名本就符合 DER。

钱包开发者:确保签名输出为严格 DER 编码——在参考客户端 v0.8.0 之后这已是转发政策层面的既有要求,本 BIP 只是把它提升为共识要求。

全节点与矿工:这是软分叉共识改动:升级节点按严格 DER 检查所有待验证签名,不合规的脚本直接失败,并参与 nVersion = 3 的版本门槛部署。

共识层:区块有效性从此由比特币自己的编码规则界定,不再随外部密码库的版本宽严而漂移。

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

状态为 Deployed,站点标注“已激活”。严格 DER 是现行共识规则的一部分。原文末尾另有一条披露:全网采用并执行本 BIP 之后,作者公开说明,严格 DER 签名间接解决了他此前发现的一个共识 bug。

常见误读:

“BIP-66 换了一种更安全的签名算法。”

不对。它动的不是 ECDSA 算法,也不是密钥或签名的值,而是签名的编码格式:同一条 (R, S) 签名,今后只许用 DER 规定的唯一严格写法上链。算法未变,变的只是“写法不规范即无效”。

七、延伸

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