BIP: 146
Layer: Consensus (soft fork)
Title: Dealing with signature encoding malleability
Authors: Johnson Lau <jl2012@xbt.hk>
Pieter Wuille <pieter.wuille@gmail.com>
Status: Closed
Type: Specification
Assigned: 2016-08-16
License: PD
概要
本文書は、ECDSA 署名エンコーディングに起因する署名の展性を修正するため、ビットコインのトランザクション有効性規則に対する変更案を規定する。
動機
署名の展性とは、ネットワーク上の任意のリレーノードが、該当する秘密鍵へのアクセスなしに、トランザクション内の署名を変形できることを指す。segregated witness でないトランザクションでは、署名の展性によってtxidが変化し、未承認の子トランザクションが無効になる。segregated witness(BIP141)トランザクションのtxidは第三者によって展性を持たされることはないが、この展性の経路はwtxidを変化させ、コンパクトブロックリレー(BIP152)の効率を低下させる可能性がある。
Strict DER 署名(BIP66)の強制以降、ECDSA 署名における展性の既知の残存要因は 2 つある。
-
ECDSA 署名固有の展性:ECDSA 署名は、内部の数値 S の符号を反転させても(曲線位数を法として)無効化されないという性質上、本質的に展性を持つ。
-
検証失敗署名の展性:
OP_CHECKSIGまたはOP_CHECKMULTISIGでの検証に署名が失敗した場合、スタックにはFALSEが返され、スクリプト評価は継続する。検証失敗署名は、BIP66 に記載されたすべての規則に従う限り、任意の値を取り得る。
本文書は、前述の署名の展性を修正する新しい規則を規定する。
仕様
署名エンコーディングの展性を修正するため、以下の新規則を、segregated witness 化前のスクリプトと segregated witness のスクリプトの双方に適用する。
LOW_S
ECDSA 署名内の S 値は、曲線位数を 2 で割った値以下でなければならないとする(実質的にこの値を下半分の範囲に制限する)。ECDSA 検証が適用されるOP_CHECKSIGBIP141 で説明されている pay-to-witness-public-key-hash(P2WPKH)を含む、OP_CHECKSIGVERIFY、OP_CHECKMULTISIG、OP_CHECKMULTISIGVERIFYに渡されるすべての署名は、厳密な DER エンコーディング(BIP66 参照)のもとで、0x1から0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0まで(両端を含む)の S 値を用いなければならない(MUST)。
ECDSA 検証に渡される署名が Low S の値検査に通らず、かつ空のバイト配列でもない場合、スクリプト全体は直ちに false と評価される。
署名内の高い S 値は、S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - Sによって自明に置き換え可能である。
NULLFAIL
OP_CHECKSIGがスタックにFALSE値を返そうとする場合、該当する署名は空のバイト配列でなければならないとする。
OP_CHECKMULTISIGがスタックにFALSE値を返そうとする場合、このOP_CHECKMULTISIGに渡されるすべての署名は空のバイト配列でなければならないとする。署名検証の早期終了により一部署名の処理が省略された場合であっても同様である。
それ以外の場合、スクリプト全体は直ちに false と評価される。
例
以下の例は、LOW_S 規則と NULLFAIL 規則を組み合わせた結果である。参照実装クライアント v0.13.1 の実装詳細により、半分の曲線位数より大きい S 値を持つ一部の署名が LOW_S テストを通過してしまう場合がある点に注意されたい。ただし、そのような署名は明確に無効であり、後に NULLFAIL テストで失敗する。
表記:
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
以下のスクリプトは、従来はFALSEだったが、新規則のもとでは直ちに失敗する。
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 は「version bits」(BIP9 (https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki))により展開される。詳細は未定(TBD)。
ビットコインメインネットでは、BIP9 の starttime は未定(TBD)UTC の深夜(Epoch タイムスタンプ未定)、BIP9 の timeout は未定(TBD)UTC の深夜(Epoch タイムスタンプ未定)とする。
ビットコインテストネットでは、BIP9 の starttime は未定(TBD)UTC の深夜(Epoch タイムスタンプ未定)、BIP9 の timeout は未定(TBD)UTC の深夜(Epoch タイムスタンプ未定)とする。
互換性
参照実装クライアントは v0.9.0 以降、LOW_S に適合する署名を生成しており、LOW_S 規則は v0.11.1 以降、参照実装クライアントによりリレーポリシーとして強制されている。2016年8月時点で、この要件に違反するトランザクションがチェーンに追加されるケースは極めて少ない。実際に使用されているすべての scriptPubKey 種別について、非準拠署名は容易に準拠署名へ変換できるため、これらの要件による機能の喪失はない。
OP_CHECKSIGまたはOP_CHECKMULTISIGが失敗するスクリプトがチェーン上に現れることはまれである。NULLFAIL 規則は v0.13.1 以降、参照実装クライアントによりリレーポリシーとして強制されている。
利用者は、変則的なスクリプトを設計する際、これらの新規則に特段の注意を払わなければならない(MUST)。
実装
参照実装クライアント向けの実装は以下で入手できる。
https://github.com/bitcoin/bitcoin/blob/35fe0393f216aa6020fc929272118eade5628636/src/script/interpreter.cpp#L185
および
https://github.com/bitcoin/bitcoin/pull/8634
脚注
謝辞
本文書は、多くの人々からの意見が反映された以前の BIP62 (https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki) 提案から抽出されたものである。
著作権
本文書はパブリックドメインに置かれる。

