Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Taproot

 Taproot

GBEC動画解説コンテンツのスライドです。
https://goblockchain.network/2020/02/bip341-taproot/

shigeyuki azuchi

February 25, 2020
Tweet

More Decks by shigeyuki azuchi

Other Decks in Technology

Transcript

  1. 1. Taprootとは?
 2. Taprootの仕組み
 3. マークルブランチで提供されるスクリプト 
 4. Key-Pathによるコインの使用
 5.

    Script-Pathによるコインの使用
 6. Script Interpreterの処理フロー
 7. 署名検証ルールの変更 
 8. Taprootにおける注意点
 9. まとめ
 1 今日話すこと
 Taproot

  2. BitcoinのUTXO作成時やUTXO使用時に公開する情報を最小限に抑えることで、Bitcoin Scriptのプライバシーや効率性を向上させる提案
 【BIP-341】https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
 
 【従来の送金】
 • 相手の公開鍵宛の支払い 
 ◦ P2PKH:OP_DUP

    OP_HASH160 <H(pubkey)> OP_EQUALVERIFY OP_CHECKSIG 
 ◦ P2WPKH:OP_0 <H(pubkey)>
 • 任意のスクリプトへの支払い 
 ◦ P2SH:OP_HASH160 <H(script)> OP_EQUAL 
 ◦ P2WSH:OP_0 <H(pubkey)>
 【Taprootの送金】
  Segwitのwitness version 1を利用
 OP_1 <pubkey(= witness program)> 
 
 2 Taprootとは?
 Taprootでは、公開鍵宛の支払いも、
 任意のスクリプト宛の支払いも、scriptPubkeyは 同じフォーマットになる。

  3. 3 Taprootの仕組み
 OP_1 <pubkey(= witness program)>
 Taprootのwitness programは32バイトの公開鍵(Q)
 
 Q

    = P + tG
 • P:公開鍵(Internal Key)
 ◦ 単一の支払先の公開鍵 
 ◦ マルチシグの集約公開鍵 
 A, B, C 3人の3-of-3のマルチシグを構成する場合、 P = PubA + PubB + PubC 
 ※ Key-Rogue攻撃などが考えられるため、 MuSigなどのプロトコルの利用を推奨 
  (https://goblockchain.network/2019/04/musig/ )
 • tG:スクリプト
 支払い条件となるスクリプトでマークルツリーを構成し、そのルートハッシュを rとするとtは、
 t = H TapTweak (P || r)
 

  4. スクリプトのアンロック条件が5つ( A, B, C, D, E)ある場合、各スクリプトをリーフノードして 
 マークルツリーを構成する。 H TapBranch

    やH TapTweak はタグ付きハッシュで、ハッシュ値の計算をする際に 
 それぞれ、”TapBranch”、”TapTweak”をタグとして付与することでコンテキストを明示している。 
 4 マークルブランチで提供されるスクリプト
 A
 B
 C
 D
 E
 AB = H TapBranch (A + B)
 CD = H TapBranch (C + D)
 CDE = H TapBranch (E + CD)
 ABCDE = H TapBranch (AB + CDE)
 t = H TapTweak (P + ABCDE)
 スクリプトで構成したマークルツリーの
 ルートハッシュをTaprootのscriptPubkeyに使用する
 リーフノードの値の計算は↓ 
 H TapLeaf (leaf version + Script A) 
 ※ leaf versionで、スクリプトを
 評価する際に適用するルールを指定。
 現在は0xc0固定で、BIP-342(TapScript)のルー ルが適用される。

  5. 5 Key-Pathを使ったコインのアンロック
 Q = P + tG ←のPを使ってコインをアンロックする場合
 
 公開鍵Qに対して有効な署名を提供することでアンロック可能


    • Pが単一のユーザーの公開鍵の場合 
 Pに対応する秘密鍵を xとすると(P = xG)、Q = (x + t)G。
 自身の秘密鍵xにtを加算した値がQの秘密鍵となるため、これを使って署名を作成する。 
 • Pが複数のユーザーの公開鍵からなる集約公開鍵の場合 
 各ユーザーが個別に生成した署名データと、 tを秘密鍵とした署名データを集約することで、 
 Qに対する有効な集約署名を作成する。 
 参考:https://goblockchain.network/2019/04/musig/ 
 ※ このようなマルチシグの場合、全ての参加者が同意すれば、スクリプトのアンロック条件を使用すること無く
  コインの使用が可能で、スクリプトが存在したことを誰も知ることはない。

  6. 6 Script-Pathを使ったコインのアンロック
 Q = P + tG ←のt(スクリプト)を使ってコインをアンロックする場合 
 


    tを生成したいずれかのリーフスクリプトを使ってコインをアンロック可能 
 
 A
 B
 C
 D
 E
 AB = H TapBranch (A + B)
 CD = H TapBranch (C + D)
 CDE = H TapBranch (E + CD)
 ABCDE = H TapBranch (AB + CDE)
 t = H TapTweak (P + ABCDE)
 B = H TapLeaf (Leaf version + Script B) 
 の条件を使ってコインをアンロックする場合、 
 • Script B
 • 点(公開鍵)P
 • Script Bがtを構成するリーフの1つであることを証明する 
 AおよびCDEのハッシュ値
 • Script Bをアンロック可能な要素 
 を提供することでコインがアンロック可能になる。 
 Leaf version(negation bit 含む)、Pおよび各ハッシュ値は 
 Control Blockと呼ばれる1つの要素としてスタック上にプッシュされる。 
 
 ※ 公開されるスクリプトは Bのみで、他のアンロック条件は公開される 
 ことがないため、アンロックに必要な公開情報を最小限に留めることが 
 でき、プライバシーの向上、チェーン上のスペースの節約になる。 
 ※ Control Blockにハッシュ値以外にPath(左右どちら)を表すデータが無いが、これはリーフ、内部ノード含め辞書順にソートされた 
 形でツリーが構成しているため。計算したノード値と Control Blockのハッシュ値の大小を比較して左右どちらのデータなのか判断している。 

  7. 7 Script Interpreterの処理フロー
 インタプリタは以下の手順で Taproot形式のscriptPubkeyを処理
 1. スタックからscriptPubkeyを抽出後、要素が空の場合エラー。
 2. スタック上に最低2つの要素がある場合、最後の要素の先頭バイトが0x50の場合、この要素はannex aと呼ばれ、


    スタックから削除される。
 ※ annex aは署名時のメッセージに含まれるが、現時点ではそれ以外何も作用しない。
 3. スタックに要素が1つだけ残っている場合は、Key-Pathを使用したアンロックとして処理される。
 a. 要素は署名として解釈され、公開鍵QとTaprootのメッセージダイジェストに対して有効か検証される。
 4. スタックに2つ以上の要素が残っている場合、Script-Pathを使用したアンロックとして処理される。
 a. 最後から2つめの要素が評価対象のスクリプト
 b. 最後の要素がControl Block = [Leaf version(1 byte) & negation bit, P(32 bytes), [hash values]]。
 c. Leaf versionを検証
 d. スクリプトとP、[hash values]からマークルツリーを復元しtを算出。
 e. negation bit & 1 == 1の場合Q = -Qとする。(QはP+tGでY座標を固定できないため) 
 f. 算出したtを使ってQ == P + tGを検証
 g. 残りのスタック要素を使ってスクリプトを評価
 
 Control Block
 Script B
 ...

  8. 8 署名検証ルールの変更
 hash type
 nVersion
 nLocktime
 全InputのOutPointのSHA256ハッシュ値 
 全Inputのコインの量のSHA256ハッシュ値 


    全InputのnSequenceのSHA256ハッシュ値 
 全アウトプットのSHA256ハッシュ値 
 該当Inputのspent type: 
 ext_flag(1) * 2 + annex_present 
 該当Inputが参照するUTXOのScriptPubkey 
 該当InputのOutPoint 
 該当Inputのコインの量 
 該当InputのnSequence 
 Tx内の該当Inputのインデックス 
 (annexのサイズ | annex)のSHA256値 
 対応するアウトプットのSHA256値 
 !ANYONECANPAY 
 !ANYONECANPAY 
 !ANYONECANPAY 
 !NONE, !SINGLE 
 ANYONECANPAY 
 ANYONECANPAY 
 ANYONECANPAY 
 !ANYONECANPAY 
 annexがある場合 
 SINGLE
 • 署名対象のメッセージダイジェストの計算方法がBIP-143から変わる 
 
 
 
 
 
 
 
 
 
 • Key-Pathを使用した署名検証 
 署名は64バイト(SIGHASH TYPE = 0x00=ALLと同様) or 65バイト(SIGHASH TYPEを含む) 
 UTXOのscriptPubkey にコミットするように 
 全Inputのコインの量にコミットするように 
 オフライン署名デバイスに手数料の嘘が付けない 
 SINGLE、NONEの場合nSequenceにコミットするように 
 Taproot固有データへのコミットメントが追加 
 ext_flagはメッセージの最後に拡張が追加されて ることを示すためのフラグ。 

  9. 9 Taprootの注意点
 • スクリプトを使用しない公開鍵宛の送金のみの場合は、使用できない Script-Pathを作成する。
 Q = P + H

    TapTweak (P)Gのようなアウトプットを作成するのが推奨される。 
 敵対者がM = M0 + tGを作成し、他のユーザーの公開鍵Aと集約したInternal Key P = A + Mを作成した場合、
 A + M0とPとして提供しtGでScript-Pathによるアンロックが可能になるため。
 • 公開鍵宛やマルチシグの送金など Key-Pathは使用せずScript-Pathのみをサポートするする場合、 
 Pは未知の離散対数を持つ公開鍵とする。 H = point(H(G)) = Gのハッシュ値をx座標とする点。
 • P2SHでラップして使うことはできない。 
 • annexは、将来の拡張用のフィールドで現在は無視される(が、トランザクションダイジェストの計算には使わ れる)ため、現時点ではセットしない方がいい。 
 • スクリプトからツリーを構成する際は必ずしも、 
 バランスの取れた二分木にする必要はなく、 
 条件の使用確率によったハフマンツリーを構成した方が効率的。 
 
 C
 A
 B
 t
 D
 E

  10. 10 まとめ
 • Taprootは、スクリプトのプライバシーと効率を上げるための拡張 
 ◦ 公開鍵への支払い、マルチシグへの支払い、スクリプトへの支払いの区別が無くなる。 
 • 多くのマルチパーティコントラクトのアンロック条件はマルチシグ

    or 別の条件なので、 
 ほとんどのコントラクトは Taprootにエンコードできる。 
 • スクリプトを使ってアンロックする場合も、公開される情報およびデータサイズは最小限。 
 • Leaf versionによる適用するスクリプトルールの選択や、 annexなどの拡張機能あり。 
 
 詳細な仕様については BIP-341を参照:
 • https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki 
 • https://techmedia-think.hatenablog.com/entry/2019/05/11/232625 (日本語訳)