Develop with pleasure!

福岡でCloudとかBlockchainとか。

AMPを実現する3つのプロトコル

Lightning Networkにおいて、単一の経路ではキャパシティが不足し送金額に満たないが、複数の経路を使えば送金額を満たす場合に、複数の経路を使った支払いをアトミックに行うプロトコルがAtomic Multi-Path Payments(AMP)だ。

AMPのプロトコルとしては、以下の3つのプロトコルが提案されている。

プロトコルがどのようなものかというと

OG AMP

OG AMPはとOlaoluwa Osuntokun(@roasbeef)とConner Fromknechtが発表したAMP。

通常のLNの支払いでは受信者がプリイメージを生成し、そのハッシュをInvoiceで通知するが、OG AMPの場合、送信がベースプリイメージを生成する。AMPで使用する経路の数をnとすると、送信者はn個のシェアを生成し、それらの排他的論理和を計算してベースプリイメージを生成する。

ベースプリイメージ = s1 ^ s2 ^ .... ^ sn

続いて、各 {i \in }[1..n]をシーケンス番号とし、iとベースプリイメージを連結しハッシュした部分的なプリイメージ {r_i = H(BP || i)}を計算する。そしてi番目の経路の支払いで使用するハッシュ {h_i = H(r_i)}を計算する。

送信者は {h_i = H(r_i)}を各経路の支払いに使用し、支払いをスタートするが、受信者のHop Payloadの中にのみ {(ID, n, s_i)}を暗号化しておく(IDはAMPの支払いを識別するためのランダムな値)。

受信者は、上記AMPの部分的な支払いを複数の経路で受信すると、同じIDのデータをn個集める。n個揃うとその排他的論理和は取ればベースプリイメージBPが復元できる。BPが復元できたら、各部分的な支払いを受け取るために必要な {h_i}のプリイメージ {r_i}を計算することができ、この値を使って全経路のコインを受け取る。

各経路でベースプリイメージのシェアを配布することで、全経路分のシェアが集まらないとコインが受け取れないという意味で、複数の経路を使った支払いのアトミック性を担保する。

というのがOG AMPだが、元々LNではプリイメージを受信者が生成して、支払いが完了したらそのプリイメージが送信者に分かるという仕組みになっており、送信者にとってプリイメージは送信が正常に行われたことの暗号学的な証明になっていた。ところがOG AMPの場合、送信者がプリイメージを生成するため、この証明の仕組みが機能しなくなるという欠点がある。個人間送金などであれば問題ないけど企業間決済などのエンタープライズユースケースにおいてはこの証明を必要とするパターンも考えられる。

Base AMP

OG AMPの支払いの証明を課題を解決するため、Base AMPでは各支払いの経路で全て同じpayment_hashを利用する。

受信者がbasic_mppフィールドを含むオニオンパケットを受信した場合、受信ノードはBase AMPである可能性があると認識する。受信ノードは全ての経路の支払いが揃うまでプリイメージを明らかにしない。そのために、basic_mppのオニオンパケットを受け取った場合は他の経路のHTLCを受け取るまで60秒待つ。これは、悪意ある中間ノードが複数の経路にいた場合、片方の経路で入手したプリイメージを使って、別の経路の資金を入手するような可能性を阻止するため。OG AMPでは経路毎のpayment_hashが異なるのでこれを防げる。payment_hashが同じHTLCを集め、その送金額の合計がtotal_msatで指定された額になったら、同じタイミングでコインを受領する。

Base AMPの場合、全ての経路の支払いの受領タイミングのコントロールをアトミックに制限することはできず受信ノードの振る舞いに依存するが、送信者にとってのプリイメージの証明特性(Proof-of-Payment)は維持される。

High AMP

High AMPは、OG AMPの各支払経路で異なるハッシュを使うことによる複数のHTLCの相関関係を隠す効果と、Base AMPのProof of Payment特性の両方を実現するために研究されているプロトコル

どうやって実現するかというと、既存のHTLCのハッシュのプリイメージの交換部分を、楕円曲線上の点と(その秘密鍵である)スカラーに置き換える。

受信者は、秘密鍵となるスカラー {k_{par}}をランダムに選択し、対応する公開鍵=楕円曲線上の点 {K_{par} = k_{par}G}を計算し、Invoiceに記載する。この {K_{par}}を親公開鍵、 {k_{par}}を親秘密鍵とする。

秘密鍵 {k_{par}}に対して、各iの子鍵は {k_i = H(i || k_{par}G) + k_{par}}として導出できる。そして親公開鍵 {K_{par} = k_{par}G}に対して、各iの子公開鍵は {K_i = H(i || K_{par})G + K_{par} = k_iG}として計算できる(子鍵は部分的な支払いの経路分作られる)。

送信者は支払いに使用する経路の数分、 {K_i}を導出し、導出した各 {K_i}について対応する子秘密鍵 {k_i}の開示を必要とする条件付き支払いのHTLCを構成する。この場合HTLCの非タイムロック部分はScriptless Scriptで構成される(受取人がT = t * Gを提供し、有効な署名を作るとtが明らかになるパターン)。

こうして送信者→受信者への複数の経路の支払いが作成される。受信者は部分的な支払いを受信しても、すぐにそれを受け取るインセンティブはまだない。なぜなら、部分的な支払いの内、1つでも {k_i}を明らかにしてしまうと、送信者が {k_{par} = k_i - H(i || K_{par})}を計算することで親秘密鍵を入手し、それをもってProof of Paymentとして機能してしまうからだ。

そのため受取人はすべての経路の支払いを受信してから、コインの請求を行う。それによりすべての子秘密鍵が明らかになり、それのいずれかを使って送信者は親秘密鍵 {k_{par}}を抽出できる。

送信者は親秘密鍵 {k_{par}}を使ってデジタル署名を作成することでProof of Paymentを証明でき、かつ各部分的な支払いには異なる {K_i}が使われるため、複数の経路感の相関関係を隠すことも可能になる。

ただHigh AMPについてはBitcoinにSchnorr署名が実装される必要がある(まぁ最近の2P-ECDSAの研究から、ECDSAでも可能っぽいけど)。

というのが、OG AMP、Base AMP、High AMPの違い。BOLTのwikiを見る感じだとBOLT 1.1ではBaseとOGの両方が一応サポートされるっぽい。