通常Lightning Networkの決済では、支払先が予めインボイスを作成し、それを支払元に送ることで支払いがスタートする。このインボイスにはLNでマルチホップ決済をするにあたって、支払先のノードIDやコントラクトを構成する際に必要な情報(プリイメージのハッシュ、HTLCの有効期間など)が含まれる。これらの情報の伝達のため、基本的にLNではインボイスを使った支払いフローがデフォルトになっている。
ただ、Bitcoinのオンチェーントランザクションのように、相手のアドレスさえわかっていれば、相手と対話することなく支払元か直接支払するというユースケースも十分考えられる。
AMPを利用する方法
インボイスを必要としないSpontaneous Paymentについては、既にAMP(Atomic Multi Path Payments)をベースにしたアイディアがある。
従来のLNでは決済に使用するプリイメージは支払先が作成し、そのハッシュをインボイスに載せて支払元に伝達するが、Spontaneous Paymentでは、支払元がプリイメージを作成し、ルーティング含めた決済ではそのプリイメージのハッシュを使用する。そしてLNのオニオンルーティングを仕組みを利用して、プリイメージは支払先のみが復号できるように暗号化され、LNのルーティングパケットの最後のオニオンパケットにセットされ、支払先まで送信される。データを受信した支払先のノードは、プリイメージを復号し、そのプリイメージを利用して支払を受け取る。
この機能の自体は支払元と支払先のノードだけ、この仕組みに対応していればよく、中間ノードは通常のLN決済として認識する。
ECDHを利用する方法
このSpontaneous Paymentについて、ECDHを利用する方法が先日LNの開発者MLに新しいアイディアがポストされた↓
[Lightning-dev] ECDH for spontaneous payments and offline vending machines
このアイディアは、↑で発生する暗号化したプリイメージのルーティングをECDHを使うことで不要にしようというもの。
支払元から支払先へのLNのルーティングができるのであれば、両者がECDH(楕円曲線 Diffie-Hellman)によって導出できる共有シークレットを持つことを意味するため、それをプリイメージとして使えば、暗号化したプリイメージ自体をルーティングする必要はないというもの。
ECDHは楕円曲線を使って共通鍵を導出する仕組みで、アリスとボブがそれぞれ秘密鍵a
、b
と対応する公開鍵A = aG
、B = bG
を持ち、それぞれ相手の公開鍵を知っている場合、相手の公開鍵に自分の秘密鍵を乗算して出来た点は同じ点を指すという特性ががある。
共通鍵 = a * B = b * A
具体的には、支払先のノードのノードIDをN
(ノードID = 公開鍵)、支払元が支払の際に生成する一時鍵(ephemeral key)をk
とするとk * N
で新しい点が算出され、その点のx座標のハッシュをプリイメージとし、x座標のdoubleハッシュをペイメントハッシュとするというもの。
この場合、支払先のノードは自分がインボイスとして発行したものではないペイメントハッシュの支払を受け取ったら、自身のノードIDN
の秘密鍵n
とオニオンパケットにセットされている一時鍵k
の公開鍵(K = kG
とする)を使って共通鍵n + K
を計算し、そのx座標のdoubleハッシュと比較する。合致すれば対応する共有シークレットがその支払のプリイメージとなる。
既にChristian Deckerによるc-lightningで動作するPoCコードもある↓
GitHub - cdecker/lightning at stepan-pay
プリイメージ用に余計なオニオンパケットのデータを作らなくて良い分、ECDHの方がデータ量が少し少なくて済むのでシンプルで良いかもね。