首页
学习
活动
专区
工具
TVP
发布

BIP146 解决签名编码的延展性“翻译”

综述

本提案描述了改变比特币交易的验证规则,来修正与 ECDSA 签名编码有关的交易延展性。

动机

签名延展性指的是:网络中的任何中继节点,不需要获取对应交易的私钥, 而修改该交易签名的能力。对于非 SW 交易,签名延展性将改变 txid ,将使所有未确认的子交易失效。即使 SW 交易( BIP141 )的 txid 是非第三方延展的,但这种延展性的 vector 仍然将改变 wtxid ,并且可能降低紧凑型区块的中继效率(BIP152)。

自从严格的 DER 签名实施后,ECDSA 签名中还有两个已知的延展性来源:

ECDSA 自身的签名延展性:ECDSA 签名是自身具有延展性,因为内部S 的负值(模曲线顺序)不会使签名无效。

无效签名的延展性:如果采用OP_CHECKSIG或OP_CHECKMULTISIG的签名验证失败,一个 false 将被返回到栈上,并且脚本验证将继续执行。无效签名可以使用任何值,只要这些值遵循 BIP66 中描述的所有规则。

本提案定义了新的规则来修正上述提到的延展性。

规则

为了修正签名编码的延展性,接下来的新规则被应用到当下的隔离验证和隔离验证脚本。

LOW_S

新规则要求ECDSA签名内的S的值最大是曲线半径除以2(实际上将该值限制在其下半部分范围内)。每个使用了OP_CHECKSIG1 , OP_CHECKSIGVERIFY , OP_CHECKMULTISIG , OP_CHECKMULTISIGVERIFY操作码的签名,同时该签名采用了 ECDSA 验证,则必须使用一个介于 0x1 和0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,并且采用严格 DER 编码的 S 值。

如果传递给 ECDSA 验证的签名没有通过 LOW_S 检查,并且是一个非空的字节数组,则整个脚本评估立即失败。

在签名中一个高 S 值可以平滑的被S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S替换。

NULLFAIL

如果一个 OP_CHECKSIG 试图向栈上返回一个 false 值,那我们要求对应的签名必须是一个空的字节数组。

如果一个 OP_CHECKMULTISIG 试图向栈上返回一个 false,我们要求传输到 OP_CHECKMULTISIG 的所有签名必须是空的字节数组,即使由于过早的签名验证中断而可能导致一些签名处理被跳过。

否则,整个脚本评估立即失败。

示例

接下来的示例由LOW_S和NULLFAIL2规则组成。

符号:

CO :curve order = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141

HCO:half curve order = CO / 2 = 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0

P1, P2:valid, serialized, public keys

S1L, S2L :valid low S value signatures using respective keys P1 and P2 (1 ≤ S ≤ HCO)

S1H, S2H :signatures with high S value (otherwise valid) using respective keys P1 and P2 (HCO < S < CO)

F :any BIP66-compliant non-empty byte array but not a valid signature

这些脚本像以前一样返回TRUE至栈上:

S1L P1 CHECKSIG

0 S1L S2L 2 P1 P2 2 CHECKMULTISIG

这些脚本像以前一样返回FALSE至栈上:

0 P1 CHECKSIG

0 0 0 2 P1 P2 2 CHECKMULTISIG

在新规则执行后,先前的TRUE脚本将立即失败

S1H P1 CHECKSIG

0 S1H S2L 2 P1 P2 2 CHECKMULTISIG

0 S1L S2H 2 P1 P2 2 CHECKMULTISIG

0 S1H S2H 2 P1 P2 2 CHECKMULTISIG

在新规则执行后,先前的TRUE脚本将立即失败

F P1 CHECKSIG

0 S2L S1L 2 P1 P2 2 CHECKMULTISIG

0 S1L F 2 P1 P2 2 CHECKMULTISIG

0 F S2L 2 P1 P2 2 CHECKMULTISIG

0 S1L 0 2 P1 P2 2 CHECKMULTISIG

0 0 S2L 2 P1 P2 2 CHECKMULTISIG

0 F 0 2 P1 P2 2 CHECKMULTISIG

0 0 F 2 P1 P2 2 CHECKMULTISIG

部署:

该 BIP 将通过 BIP9 (版本位)进行部署。

比特币主网络中,BIP9 的开始时间是: midnight TBD UTC (纪元时间戳 TBD ),BIP 的结束时间是: midnight TBD UTC (纪元时间戳 TBD )。

比特币测试网络中,BIP9 的开始时间是: midnight TBD UTC (纪元时间戳 TBD),BIP 的结束时间是: midnight TBD UTC (纪元时间戳 TBD )。

兼容性

从 V0.9.0,客户端已产生了 LOW_S 兼容性脚本,并且从 V0.11.1 客户端开始,LOW_S 规则已经作为中继策略被强制执行。截止 2016 年 8 月,违反上述规则的交易很少被添加至主链中。对于实际使用的所有 scriptPubKey 类型,非兼容性的签名可以平滑的被转换为兼容性,所以这些新规则并没有任何导致任何功能的丢失。

使用OP_CHECKSIGorOP_CHECKMULTISIG失败的脚本很少出现在主链上。从 V0.13.1 客户端开始,NULLFAIL 规则已经作为中继政策被强制执行。

当设计新脚本时,用户必须注意这些新规则。

实施

参考客户端的实现可以在下述网址获得:

https://github.com/bitcoin/bitcoin/blob/35fe0393f216aa6020fc929272118eade5628636/src/script/interpreter.cpp#L185

and

https://github.com/bitcoin/bitcoin/pull/8634

脚注

P2WPKH 的交易在 BIP141 中描述

请注意由于 v0.13.1 客户端中具体实现的细节,一些使用高 S 值的签名通过了LOW_S 检测。然而,这些签名肯定是无效的,由随后的 NULLFAIL 检测失败。

引用

https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki

本文由翻译,转载无需授权。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180111G0MCWM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券