techmedia-think.hatenablog.com
のECDSAの署名スキームを利用すると、
techmedia-think.hatenablog.com
コインのアンロック条件が、2-of-2のマルチシグ or その他の条件で構成されるTaprootをSchnorrを使わずにECDSAで実現できるのでは?と思い、プロトコルを考えてみた。
Taprootについて
Taprootの仕組みについてや↑の記事に書いたけど、基本的なコンセプトは、コインのアンロック条件がマルチシグ or 他の条件スクリプトで構成される場合、そのロックスクリプトをP2SHのようなスクリプトとして実現するのではなく、1つの公開鍵にして、ロックスクリプトの段階では、マルチシグやその他の条件の存在を隠すことができるというもの。
例えば以下のスクリプトは、アンロック条件が以下のいずれかになる。
- アリスとボブの2人の署名があればアンロック可能
- ロック時間経過したらボブの署名のみでアンロック可能
OP_IF 2 <A> <B> 2 OP_CHECKMULTISIG OP_ELSE <ロック時間> OP_CSV OP_DROP <B> OP_CHECKSIG OP_END
通常こういった条件はスクリプトにしてP2SHにするが、Taprootの場合
- アリスの公開鍵とボブの公開鍵を集約した新しい公開鍵
Cを作成する。 - その他の条件部分のスクリプトを
S =<ロック時間> OP_CSV OP_DROP <B> OP_CHECKSIGとする。 CとSを使って新しい公開鍵(楕円曲線上の点)P = C + H(C || S)Gを計算する。(Hはハッシュ関数で||は連結)- scriptPubkey
<taproot version> P宛にコインを送金する。
といった手順でロックスクリプトを構築しそこに送金する。
アンロックする方法は以下の2通りの方法がある。
アリスとボブの署名を使ってアンロックする場合
この場合、Pの公開鍵に対して有効な署名が提供すれば良い。Pはアリスとボブの公開鍵を集約して作った点Cに点H(C || S)Gを加算した点なので、アリスとボブの秘密鍵とH(C||S)を使ってSchnorr署名を作ればいい。
その他の条件(タイムロックされたスクリプト)を使ってアンロックする場合
この場合、CとSを明らかにして(スタックにプッシュして)、そこからPが計算できれば、Sのスクリプトを使ってコインをアンロックできるようになる。後はSの条件を満たす要素をスタックにプッシュしておけば良い。
ECDSAを使ったTaproot
Schnorrを使わずにECDSAを使って↑のTaprootを構築する場合、まずマルチシグを構成する公開鍵Cは、アリスの鍵ペアをP1 = x1 G、ボブの鍵ペアをP2 = x2 Gとし、両者それぞれ公開鍵P1、P2を相手に伝えている前提で、以下のようにCを求める。
- アリスが算出する場合は、
C = x1 * P2 - ボブが算出する場合は、
C = x2 * P1
こうやって計算したCは同じ楕円曲線上の点を指し、このCに対して有効な署名を作るには、アリスの秘密鍵x1とボブの秘密鍵x2を使った計算が必要になる。
この仕組み自体はYehuda Lindellが発表したプロトコルそのもの。
Cを算出したら、残りのロックスクリプトの作り方は↑のTaprootの作り方そのままで、スクリプトSとCを使ってP = C + H(C || S)Gを計算し、コインをロックする。
コインのアンロック方法
2つあるコインのアンロック方法の内、その他の条件(タイムロックされたスクリプト)を使ってコインをアンロックする場合、これも↑のTaprootと同じでOK。
マルチシグを使ってコインをアンロックする場合は、Yehuda Lindellのプロトコル↓
techmedia-think.hatenablog.com
に少し変更を加え、以下のようなプロトコルにする。
アリスとボブは上記の鍵ペアに加え、ランダムに選択したnonce (アリスは、ボブは
)をそれぞれ持つ。最後にアリスはボブにckey = Enc
(x1)を提供する。これはアリスのみが解読可能なx1のPaillier暗号。
- アリスとボブは、P1、P2、R1、R2とm'について合意する。ここでm'はLSB(H(m))。また、アリスとボブは安全のためP1、P2、R1、R2についてその秘密鍵を確かに持っていことを証明するための非対話型のゼロ知識を追加で交換する必要がある。
- アリスは
を計算し、ボブは
を計算する。それぞれ計算したRから同じx座標
を計算することができる。
- ボブは
と
を計算する。ここで
は巨大な乱数を表し、qは暗号操作中に使用される剰余を表す。続いてボブは
を計算する。この
はPaillier暗号の加法準同型演算を表す。 こうやって計算した
は、
となる。これをアリスに送る。
4.アリスはを復号して、s'を得る。続いて
を計算し、(r, s)をECDSA署名のアウトプットとする。
こうやってできたsは
となり、Taprootのコインのロック先Pに対して有効な署名になる。
Yehuda Lindellのプロトコルとの変更点は、ボブがを計算する際に、
を余計に加算している点で、これにより
CではなくPに対して有効な署名を作成する。
実際に検証したコードが(bitcoinrbとpaillierのgemが必要)↓
ECDSAの場合Schnorrのように鍵や署名自体に集約特性があるわけではなく、署名を構成するスキームを利用したアプローチなので、いずれにせよSchonrr導入のメリットは大きいと思うが、まぁECDSAでもできるんじゃない?と思い書いてみた。ちなみに同様のことをGraftrootで実現する場合は、Yehuda Lindellのプロトコルそのままでできるはず。