「バグ」と言っても、勘違いによってセマンティクスを意図せず変更してしまったという話であって、脆弱性とかではないです。
前提
- 秘密鍵と公開鍵の組があるとする。
- ある取引があり、その中のある入力をとする。
- の中にと同じインデックスをもつ出力は存在しないとする。
- の親出力はでロックされているとする。
Pre-segwitの場合
の親出力をアンロックするためには、を用いて固定値0x00...01の署名を生成する必要がある1。にはこの入力と同じインデックスをもつ出力は存在しないという情報しかコミットされていない。したがってを手に入れた攻撃者は、出力数より入力数が多い取引を構築することによって、でロックされている任意の出力(の親出力以外も)を盗むことができる。
Segwitの場合
の親出力をアンロックするためには、を用いてoutpointをコミットした署名を生成する必要がある2。ゆえにこの署名は、少なくともoutpointで指定された出力をアンロックするためにしか使えない。
BIP-143の間違い
SegwitにおけるOP_CHECKSIGのアルゴリズムを規定したBIP-143には次のような記述がある3。
In the original algorithm, a
uint256of0x0000......0001is committed if the input index for aSINGLEsignature is greater than or equal to the number of outputs. In this BIP a0x0000......0000is committed, without changing the semantics.
著者は”without changing the semantics”と述べているが、上述したようにセマンティクスは変化してしまっている。