Scaling Bitcoin 2018のセッションの1つでもある、LNなどで利用されているペイメントチャネルネットワークの新しいプリミティブである「Multi-Hop Locks」について、以前一方向準同型関数を使った実装方法について書いたが↓
techmedia-think.hatenablog.com
Multi-Hop Locksには、一方向準同型関数を使用する方法以外に、
- SchnorrベースのScriptless Scripts
- ECDSAベースのScriptless Scripts
で実現する方法が定義されている。
今回は、現在のBitcoinでも利用可能なECDSAを使ったScriptless Scriptベースの実現方法についてみてみる。(ホワイトペーパーの内容を適当に脳内補間してるので誤解している可能性あり)
鍵生成フェーズ
各ユーザーが持つ秘密鍵をとし、対応する公開鍵をとする。
決済の経路間のユーザー=ペイメントチャネルを直接開いているユーザーは、相手と鍵生成プロトコルを使用して二者間の公開鍵を計算する。例えばは、はを計算し、はを計算することで共通の公開鍵を計算することができる。この公開鍵に対応する秘密鍵は、2人の秘密鍵を乗算したである。
ここで導出した共有鍵にコインをロックすることは、アンロックに2人の秘密の情報を必要とするという意味で、2-of-2のマルチシグへのコインのロックと同等のこととなる。
送信者から中間者、受信者の3人の場合、それぞれの秘密鍵を持っている場合、
- (送信者)と(中間者)の共有鍵は
- (中間者)と(受信者)の共有鍵は
※ 簡易的に同じ記載にしてるけど、中間者のは相手によって違う鍵になると思われる。
セットアップフェーズ
- LNで支払いを行う送信者は受信者までの数分(n)、ランダムに値をサンプリング()する。
- 続いて1〜nについてを計算する。なお、。
- 送信者は受信者までの各ユーザーに対して3つのアイテムを送信する。送信者から中間者、受信者の3人の場合、それぞれに送られるデータは
- (送信者)には
- (中間者)には
- (受信者)には
- 最後に受信者にのみ追加で、全てのサンプリング値を加算した()オープン鍵を送る。
ロックフェーズ
ロックフェーズは間で始まる。まず両者はECDSA署名に必要なランダムなnonceについて合意する。それぞれランダムにを選択し、それぞれ、を計算する。それぞれ計算した点を明らかにし、自分のnonceと組み合わせて共通のを計算する。
ここでRの計算に両者のnonceをGではなく、Yに乗算しているのがポイントになる。
まずはを無視して、二者の共有鍵に対する署名をLindellのプロトコルを使って計算する↓
techmedia-think.hatenablog.com
を無視したその署名データは
となる。当然この署名データにはが考慮されていないので、有効な署名ではない。有効な署名にするためにはの離散対数を使って、を計算すると、
と有効な署名が作成できる。
このの離散対数の知識が、受信者→送信者への経路でコインの入手と共に明らかになるデータになる。
つまり、2者間の共有鍵にロックされた資金の内、ペイメントチャネルのマルチホップ決済の送金分のコインを相手に送金するトランザクションを作成するが、そのトランザクションの署名で使用するRには、セットアップフェーズで送信者から配布されたが含まれ、この署名を有効なものにするためには、の離散対数の知識が必要になる。この離散対数が従来のLNのHTLCで扱われるシークレットの代替となる。
送信者から中間者、受信者の3人の場合、送信者から中間者、受信者の3人の場合、それぞれのnonceを選択した状態で、それぞれの間で作成されるRと署名データは以下のようになる。
(送信者)と(中間者)
であることから、この署名に対して必要なの離散対数は。
(中間者)と(受信者)
であることから、この署名に対して必要なの離散対数は。
リリースフェーズ
リリースフェーズでは、ロックフェーズでロックされたコインを入手するのに各チャネルでアンロック条件となっている離散対数を明らかにする。
送信者から中間者、受信者の3人の場合、受信者はオープン鍵とを持っているため、中間者からコインを貰う際の署名に使ったの離散対数をオープン鍵からを引くことで算出できる。この離散対数を中間者に対し明らかにすることで、コインを入手する。
中間者はの離散対数を知ったので、そこから予め知っているの値を引けば、の離散対数を算出でき、これを使って送信者から資金を入手する署名を完成させることができる。
途中の参加者が離散対数を相手に伝えることがなく、トランザクションをブロードキャストした場合も、ブロードキャストされたトランザクションで使われている署名値sを使ってs'・s-1を計算することで、自身がコインの入手に必要な離散対数を手に入れることができる。
注意点としては、ECDSAの署名(r, s)のsは-s mod q した場合でも有効で、これを許可すると成立しなくなるので、sは以下であるというLOW_Sルールが前提となる。 よく考えたら、sが変更されていた場合、もう1つのsの候補を計算すればいいだけなので、問題はなかった。
上記の方法を使えば、既存のBitcoinですぐにScriptlessなMulti-Hop LocksのLNコントラクトを実装することができるっぽい。ECDSA + Scriptlessということだったので、楕円曲線の操作がベースになるとは思ったけど、nonceのRを利用するのね。