Develop with pleasure!

福岡でCloudとかBlockchainとか。

MoneroでスクリプトレスなPayment Channelを実現するためのDLSAGリング署名スキーム Part2

Part1でDLSAGの仕組みについて整理したので↓

techmedia-think.hatenablog.com

続いて、DLSAGを利用して、Payment Channel Networkを構築する際に必要な構成要素を順番に見ていく。

MoneroでPayment Channel

上記のDual-Keyアウトプットを使った払い戻しトランザクションを使ってMoneroでPayment Channelを構築する。

Dual-Keyは↑のDLSAGの提案で新しく出てきた概念で、現状のMoneroでは各アウトプットには送信先として公開鍵が1つだけ指定できるが、Dual-Keyでは2つ公開鍵が指定できるようになり、さらにタイムロックを制御するフラグtがセットされた以下のような3つの要素で構成されるようになる。

(アリスの公開鍵、ボブの公開鍵、t)

tはチェーン上のブロック高をセットでき、

  • t = 0の場合は、このアウトプットをいつでもアリスの公開鍵に対応した秘密鍵で署名すれば使用できる
  • tが0でない場合、ブロックチェーン上のブロック高がtを超えると、2つめのボブの公開鍵に対応した秘密鍵で署名して使用できるようになる

という性質を持つ。

チャネルのオープン

アリスがMoneroのDual-Key {(pk_{A,0}, pk_{A,1})}にγ XMR保持していて、ボブとの間にPayment Channelを作成したい場合、↑のDual-Keyを使ってチャネルを開く。

f:id:techmedia-think:20190716144242j:plain

アリスはγ XMRをDual-Key {(pk_{AB}, pk_{A'})}に送金するデポジットトランザクション(dtx)を作成し、ブロック高lにロックするよう設定する。

Moneroにおける2-of-2のマルチシグは、アリスとボブがそれぞれその秘密鍵のシェアを持つ公開鍵 {pk_{AB}}で実現する。この公開鍵に対応する秘密鍵 {sk_{AB}}は、アリスが持つ秘密鍵 {[sk_{AB}]_A}とボブが持つ秘密鍵 {[sk_{AB}]_B}を加算したもの {sk_{AB} = [sk_{AB}]_A + [sk_{AB}]_B}となる。つまり、コインを公開鍵 {pk_{AB}}に送金することで、両者の秘密鍵の情報がなければ署名を完成させられない=使えない2-of-2のマルチシグへのロックとなる。

こうして、ボブが {pk_{AB}}にロックされたコインの使用に協力しない場合、アリスはチェーンのブロックがlを超えると別の払い戻しトランザクションを作ること無く、自分の資金のコントロールを取り戻すことができる。一方、ボブがオフチェーンで {pk_{AB}}からコインを受け取った場合、チェーン上でブロック高lに達するまでに最も金額の高いものをオンチェーンにプットする必要がある。

このデポジットトランザクションのアウトプットを使用する方法は以下の2つ。

  • アリスとボブが協力して {pk_{AB}}に対して有効な署名を作る
  • チェーンのブロック高がlを超えたら、アリスの {pk_{A'}}に対して有効な署名を作る

このことから、このPayment Channelは以下の特性を持つ。

  • ブロック高lを超えるとアリスによる払い戻しが可能であることから、有効期間付きのPayment Channelであること。
  • 一度もオフチェーン決済をしない場合( {pk_{AB}}に対して有効なアリスの署名をボブに送っていない場合)、ブロック高lを超えるとアリスしかコインを取り扱えないので払い戻し用にトランザクションをブロードキャストする必要なく、コインはアリスの所有物となる。

オフチェーン決済

↑でセットアップしたPayment Channelを使ってオフチェーン決済をする。アリスはγ'をボブに送金するオフチェーントランザクション(otx)を作成する。このトランザクションのインプットは↑のDual-Key {(pk_{AB}, pk_{A'})}で、アウトプットはボブのDual-Keyアドレス {(pk_{B,0}, pk_{B,1})}と、お釣りγ-γ'を送るアリスのDual-Key {(pk_{A,0}, pk_{A,1})}。このトランザクションotxを有効なトランザクションにするためには、アリスとボブが協力して署名する必要がある。

が、このPayment Channelの要は、アリスだけがotxに署名し、署名のシェアとなる {[σ]_A}をボブに送る。この時点でボブはブロック高lが来る前に、署名を完成させトランザクションをブロードキャストすることでγ'を入手できる状態になる。その後は、ブロック高lが訪れるまでは、γ'より高い残高のオフチェーン決済トランザクションを受け取ることができる。

この時の署名プロセスが↓の2OF2RSSIGNプロトコル(青字の部分は除く)

f:id:techmedia-think:20190711165015p:plain
2OF2RSSIGN(pkAB, [skAB]A, [skAB]B, tx) プロトコルの定義

このプロトコルの結果、アリスとボブはそれぞれの署名 {[σ]_A} {[σ]_B}を入手するので、それを結合して最終的な署名 {σ = ([s_0]_A + [s_0]_B, s_1, ..., s_{n-1}, h_0, (J_A + J_B))}を完成させる。

署名のシェアの検証

また、署名プロトコルにおいて重要なのが、それぞれが出力する署名のシェアが正しいものかの検証だ。アリスが {[σ]_B}を受け取り、それが有効な署名σのシェアかどうか検証したい場合、 {[σ]_B}から {[s_0]_B}をピックアップし、 {([s_0] + [s_0]B)G = (R_A + R_B) - h_{n-1}pk_{AB,b}}が成立するか検証する。ここで {R_A = [s'_0]_A G} {R_B = [s'_0]_B G}である。

Channelのクローズ

Channelのクローズには2パターンある。

  • ボブが最新のotxに自分の署名 {[σ]_B}を計算し、アリスの {[σ]_A}と組み合わせて最終的な署名を完成させブロードキャストする。
  • タイムロックlを過ぎてもボブがotxをブロードキャストしない場合、アリスがdtxのDual-Keyのタイムロック側の条件を使ったトランザクションを作成、ブロードキャストし資金を取り戻す。

※ クローズ処理やオフチェーン決済を見て分かるが、どのオフチェーントランザクションをブロードキャストしたとしても、チェーン上に記録されたものが有効で、ペナルティや最新の残高の反映を強制させる仕組みがないため、これはあくまで一方向のPayment Channelっぽい。

Moneroの条件付き支払い

条件付き支払いは、ハッシュのプリイメージや離散対数問題の解を入手するなど暗号問題に対する解を提供できる場合にのみ有効になる支払いだ。この条件付き支払いはAtomic SwapやPayment Channel Networkなどで利用される。

グループ要素Y = yG、XMRの量γおよびタイムアウトtで定義される 以下のようなDiscrete-log Timelock Contract (DTLC)を考える。

  1. ボブがt日前にyG = Yとなるような値yを生成した場合、アリスはボブにγXMR支払う。
  2. tが経過するとアリスはγXMRを取り戻す。

アリスとボブの間のPayment Channelを開く際に作成したDualアドレス {(pk_AB, pk_A)}において、この条件付き支払いを行う場合、アリスとボブは条件Yで、2OF2RSSIGNCONDプロトコル(上図の青字の部分が加わる)を使ってctxに署名する。この時、 {Y = yg} {Y^* = ympk_{AB,1}}

このプロトコルの要は、アリスとボブが協力して署名を完成させるが、もう1人ボブにyを教えるユーザーがいる。これは別のコインのチェーンと交換する場合にはアリスだったり、マルチホップ決済の場合はボブより先の受領者だったりする。アリスは ([{s'_0}]_A, [sk_AB]_A)をボブは ([{s'_0}]_B, [sk_AB]_B)を、そして3人目のユーザは(y, Y)を提供する。アリスとボブがそれぞれ {[σ]_A}および {[σ]_B}を提供しても、最終的な署名を完成させるためにはtの値が必要だ。

そのため、2OF2RSSIGNCONDプロトコル実行後、ボブはアリスに自分の署名のシェア {[σ]_B}を渡し、アリスはその有効性を検証した後、自分の署名のシェア {[σ]_A}を返信する。この順の交換で、値yが明らかになっていて、ブロック高のロックlに達していない場合にのみctxが公開されることを保証する。

ボブがctxで自分のXMRを請求する場合、ボブは {[s'_0]_A + [s'_0]_B + y}を含む署名σを提供する必要がある。そのためボブはyを知っている場合のみこれを行える。この署名が公開されると、アリスは既に {[σ]_A}および {[σ]_B}を知っているのでσからtを計算できる。

重要なのはyとYがチェーン上に現れないということで、第三者がチェーンを監視しても、同じ条件を使う別のトランザクションと結びつけることはできない。このトランザクションは条件なしのMoneroトランザクションと変わらないため、暗号通貨MoneroのFungibilityに貢献する。

MoneroのPayment Channel Network

アリスが、アリス⇔ボブ⇔キャロル⇔デイブという形式の開かれたPayment Channel Networkの経路を使ってデイブへのオフチェーン支払いをする場合、支払は以下の3つのフェーズで行われる。

  1. 最初にデイブは条件 {(Y = yG, Y^{*} = ympk^{1}_{CD})}を作成する。条件 {(Y, Y^{*})}をアリスに伝える。
  2. アリスは条件 {(Y, Y^{*})}を使ってボブへの条件付き支払いを作成し、ボブは同じ条件を使ってキャロルへの条件付き支払いを作成し、キャロルも同条件を使ってデイブへの条件付き支払いを作成する。
  3. 最後にデイブはyをキャロルに公開し、キャロルからコインを受け取る。次にキャロルはボブに、ボブはアリスにyを公開してそれぞれコインを入手する。

と基本は↑のような手順を踏むが、全てのユーザーで同じ条件(Y, Y^*)は使用できない(計算に使うGは全ユーザー共通だけど各 {Y^*_i}の値などは異なる)。この問題に対応するため、各ユーザーペアは支払いの受取人を彼らの共有アドレスの払い戻しアドレスにアウトプットの識別子を掛けたもの(つまり、 {m_{AB}pk_A}で、 {pk_A}はペア {(pk_{AB}, pk_A)}の払い戻しアドレス)に転送する通信ラウンドを追加する。この値を受け取ると、受信者は各ユーザーについてペア {(Y, Y^*_i)}を両方の条件値が期待通りに功徳されている事実のゼロ知識証明と共に計算する。最後に、受信者はこれらの条件をゼロ知識証明と一緒に支払いのパスに送り返すという処理が加わる。

ここで、条件付き支払いを設定する前に、各ユーザーは入金の条件が出金の条件と同じ値yに基づいて構築されていることを検証するため、受信者が作成したゼロ知識証明を検証する必要がある。ゼロ知識スキームの健全性は、デイブがその証明をずるし、その状態で他のユーザーが正しいと検証できないようにすることが重要で、そうでなければ、デイブへの支払いは行われるが、同じyが使えず中継ユーザーがコインを失う状況ができるかもしれない。

この条件部分はMulti Hop Locks↓を利用して、最初に送金者がセットアップするようになるのかも?

techmedia-think.hatenablog.com

所感

↑がDLSAGを利用した条件付き支払いやPayment Channelの構成方法だけど、やっぱりかなり複雑ね。あと以下の制約もあるので、まだBitcoinのLNほど柔軟に決済とまではいかず、課題は残る。

  • DLSAGはまだMoneroでは利用可能ではなく、まだ具体的なデプロイ計画は無い?
  • Dual-Keyを使ってセットアップしたPayment Channelは有効期間付きである。
  • ペナルティや最新の残高を反映するような制約はついていないため、基本的に一方向の決済となるっぽい。

ただスクリプトシステムが無いかつ、リング署名スキームを採用しているプラットフォームで実現するという意味では意味のある提案だと思う。