Develop with pleasure!

福岡でCloudとかBlockchainとか。

CTVを利用したDLCプロトコルのパフォーマンス改善

先月Lloyd Fournierにより提案された、現在提案中のBIP-119のCTV(OP_CHECKTEMPLATEVERIIFY)を使うとDLCのパフォーマンスが大幅に向上するという内容についてみてみる↓

https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019808.html

DLCとは?

DLC(Discreet Log Contracts)はBitcoinでオラクルを利用したコントラクトを実現するプロトコル

もともとBitcoinには任意のメッセージに対して署名検証を行うようなopcodeはないため、本来オラクルを利用したコントラクトは作れないが、Schnorr署名やAdaptor Signatureを利用することで、これを可能にしたのがDLC

簡単に説明すると、あるイベントの結果を発表するオラクルが存在する。このオラクルの公開鍵 {P = xG}は事前に公開されている。そしてイベント毎にオラクルはその結果の情報に署名して署名値を公開する。ただ、事前に署名に使用するPublic nonce  {R = kG}は公開しておく。Pはオラクルにつき1つだが、Rはイベント毎に作られる。

このオラクルが公開する結果を元にして、資金を決済したい2人は、オラクルが公開したRを使って、結果の取り得る値の数分、以下の証明ポイントを計算する。

 {S_i = R + H(R || X || 結果_i) P}

そしてこのSの候補セットを使って、 {結果_i}に応じて資金を分配する(契約を実行する)Contract Execution Transaction(CET)を作成する(例えば、 {結果_i}がXであれば1BTCをAに残りをBに、Yであれば1BTCをBに残りをAに送るというような)。

この時、CETのアウトプットの資金は、 {賭けたユーザーの公開鍵 + S_i}にロックされる。

イベントが終わると、オラクルは、対象となる {結果_i}について、Public nonce Rに対応するnonce kを使ってSchnorr署名 {s_i = k + H(R || X || 結果_i) x}を計算し、署名データを公開する。

この {s_i}は、予め賭けの参加者が計算した証明ポイント {S_i}秘密鍵になるため、 {s_i}が分かれば、資金をロックした {i賭けたユーザーの公開鍵 + S_i}について、自分の秘密鍵と合わせてアンロックすることができる。

詳細な仕組みについては、以前のブログ記事GBEC動画を参照。

Adaptor Signature版

↑はオリジナルのDLCプロトコルだけど、CETでAdaptor Signatureを利用するパターンが現在の主流になっている。

オリジナルのプロトコルでは、CETのアウトプットのロック条件に証明ポイントを使用していたけど、Adaptor Signatureを使う場合、CETのアウトプットは、イベントの結果による両者の残高が単純に反映されたものになる。そしてCETのインプットの署名にAdaptor Signatureを利用する。

インプットは参加者の2-of-2のマルチシグになっているので、これをインプットとして、結果のパターン分両者の残高を反映したCETを作成する。そして各CETに対して証明ポイント {S_i}を補助ポイントとしてAdaptor Signatureを生成し、交換する。この場合、オラクルが結果の {s_i}を公開すると、そのデータを使ってAdaptor Signatureを有効な署名に変換することができる。つまり、オラクルが公開した結果に対応した {CET_i}のみが有効な署名を得られることになる。

DLCの課題

↑のようにしてBitcoinでもオラクルを利用したコントラクトを構築できるが、DLCプロトコルの参加者は、

  • 結果の取り得る数分の証明ポイントの計算
  • CETの数分のアダプター署名の計算と検証

をしなければならない。結果の取り得る値が数件なら特に問題になるようなことはないけど、例えばBTC/USD価格のようなものが対象の場合、何千、何万というオーダーの証明ポイントおよびCETを作成しなければならず、参加者が通信するデータ量もそれに応じて増加する。特にCETの数分のAdaptor Signatureの演算はコスト高になる。

また、複数のオラクルを用いる場合や、複数のオラクルの閾値を利用するようなケースでは、さらに大幅に計算量が増える。

CTVを使ったパフォーマンス改善

↑の課題をCTVを利用することで改善しようというのが今回の提案。

これまで各CET毎にAdaptor Signatureを作成していたけど、代わりに結果の数分の以下のようなTapleafのスクリプトにコインをロックする。

<CET-hash_i> CHECKTEMPLATEVERIFY <証明ポイント> CHECKSIG

ここで、<CET-hash_i> {結果_i}の場合に、その結果に応じた各ユーザーの残高を反映した {CET_i}トランザクションから生成したハッシュ値。証明ポイントに対して有効な秘密鍵は、オラクルが公開した署名データから得られる。

つまりオラクルが公開した値により対象の結果のTapleafの署名検証をパスするが、CHECKTEMPLATEVERIFYにより、このコインは予め定められたCETトランザクションでしか使えないという制約を付けている。

この結果、Adaptor Signature作成時に必要な楕円曲線の演算を、ハッシュ計算に置き換えることができ、計算コストが大幅に削減される。事前の証明ポイントの計算しないといけないのは変わらないので、CTVによるパフォーマンス改善がAdaptor Signature版の場合ということかな?

また、複数のオラクルを使用する場合やオラクルの閾値を使用する場合も、以下のように簡単に実現できる。

<CET-hash> CHECKTEMPLATEVERIFY
<オラクル1の証明ポイント> CHECKSIG
<オラクル2の証明ポイント> CHECKSIGADD
<オラクル3の証明ポイント> CHECKSIGADD
2 EQUAL

CTVを使う場合のトレードオフ

これまでのDLCプロトコルは、Bitcoinスクリプト機能を使うものではなく、暗号技術を組み合わせたScriptlessな構造だったけど、↑のようにCTVを使うと、非協調ケースの場合にCETをブロードキャストすると、それがDLCトランザクションであることが識別できてしまう。また、CTVで検証するハッシュ分や、そのTapleafまでのマークルパスなどデータサイズが少し増えることになる。