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のプロトコルそのままでできるはず。