用語集 / ライトニングとレイヤー2
オニオンルーティング
別名はsphinxです。
- オニオンルーティングとは?
- オニオンルーティングとは、ライトニングネットワークが複数のホップを経て支払いを送る際に用いる階層化された暗号化のことで、各ノードには自身の転送に関する指示だけが渡され、それ以外は何も渡されません。
ライトニングネットワークの支払いはすべて固定長1,366バイトのパケットの中を通り、その層は1つずつ剥がされるため、転送するノードは直前のノードと直後のノードを知るだけで、それ以上は何も分かりません。パケットはどのホップでも同じサイズのままで、経路の長さとその中でのあなたの位置を隠します。中間にいる見知らぬ相手に対するプライバシーは強固ですが、両端のウォレットや取引所に対するプライバシーはそうではありません。
仕組み
オニオンルーティングは経路をホップごとに1層ずつ、逆順に包んで暗号化するため、最も外側の層を剥がすことがどのノードにとっても唯一の操作になります。
BOLT 4はこの構成をSphinxと呼び、ホップごとのペイロードで拡張しています。支払いが動き出す前に、あなたのウォレットは経路上のすべてのノードの公開鍵を把握し、それぞれに対してECDHを用いて共有秘密を導出します。共有秘密ごとに4つの鍵が得られます。rhoはパケットを難読化するバイト列を生成し、muは完全性HMACを計算し、umは戻り経路のエラーを認証し、padはフィラーを初期化します。そのバイト列は、96ビットのゼロnonceでゼロに対してChaCha20を実行したものです。ここで安全なのは、鍵が決して再利用されないからにほかなりません。
パケットは4つのフィールドを持ち、サイズは1つに固定されています。バージョンバイト(現在は0x00)、一時鍵として機能する33バイトの圧縮secp256k1点、1,300バイトのホップペイロード、そして32バイトのHMACです。すなわち回線上で1,366バイトとなり、長さのプレフィックスは不要です。
組み立ては後ろから進みます。1,300バイトの領域はChaCha20のストリームからのランダムなバイト列として始まり、最後のホップから最初のホップまで、各ホップについて右へシフトして場所を空け、はみ出した遠端は押し出されて捨てられます。253バイト未満のペイロードでは、シフト量はそのペイロードの長さに33を加えたもの、すなわち長さ1バイトと32バイトのHMACです。各シフトの後には、そのホップのrhoストリームとのXORが続き、それ以前の層が再び撹拌されます。
ホップが読み取るのは、型付きフィールドの短いリストです。型2はミリサトシ単位のamt_to_forward、型4はoutgoing_cltv_value、次に提示するHTLCに課す必要のあるタイムロック、型6は使用するチャネルを指定するshort_channel_idです。ただしノードは同じ相手への別のチャネルで代用することがあります。短いチャネルIDの代わりに、最終ノードは型8を受け取り、そこには32バイトの支払い秘密と合計金額が入っています。
もう1つの手順が、連続するパケットを関連付けられないようにします。各ホップは、次へ渡す前にブラインディング係数で一時鍵を調整するため、同じオニオンは通過する各リンク上で無関係なバイト列のように見えます。BOLT 4はこの限界について正直です。難読化は「does not preclude the possibility of packet association by an attacker via traffic analysis.」(攻撃者がトラフィック分析によってパケットを関連付ける可能性を排除するものではない)と述べています。
ビットコインを購入するときにこれが重要な理由
オニオンルーティングは、経路の中間にいる見知らぬ相手からあなたを守りますが、経路の両端にいる誰からも守りません。ライトニングネットワークのプライバシーについて最も誤解されているのはこの点です。
最初のホップは通常、あなたがすでに関係を持っているサービスであり、無作為な転送ノードよりもはるかに多くを見ています。当サイトのPhoenixレビューは、ACINQ自身のFAQを和らげずに引用しています。「The current version of Phoenix offers no advantage regarding privacy over existing, hosted, custodial wallets. We (ACINQ) know the final destination and amount of payments.」(現行版のPhoenixは、既存のホスト型カストディウォレットと比べてプライバシー上の利点を何ら提供しません。ACINQ自身は支払いの最終的な宛先と金額を把握しています)Phoenixはここで4.0の評価を得ており、真に自己管理型です。すなわち、12語のシードフレーズで守られた、携帯端末上の本物のノードです。カストディとプライバシーは別々の問題であり、Phoenixがうまく答えているのはそのうちの1つだけです。
受け取り側も同じです。Strikeは資金がアプリ内にある間はカストディ型で、本人確認を要求するため、自分のウォレットへのライトニングネットワーク経由の出金は、オニオンがいくつのホップを越えたとしても、金額、時刻、そして支払ったインボイスをStrikeに伝えます。Wallet of Satoshiは注意の状態を示し、ここで2.7の評価を得ています。その理由の一部は、同社が鍵を保有していることであり、同社はすでにカストディ型のライトニングネットワークサービスをEUから撤退させています。
したがって、オニオンルーティングをコンプライアンスの回避策と読まないでください。それは、国別ガイドのどの合法性の節があなたに当てはまるかを変えず、購入をそれを売った取引所から隠しもせず、あなたのウォレットの運営者が端点の1つである場合には何も与えません。それでも得られるものには価値があります。あなたが聞いたこともないルーティングノードは、誰が誰に支払うかのグラフを構築できず、あなたが送信者か別のホップかを判別できず、短い経路と長い経路を区別できません。
聞いたこともない2つのノードを通じてStrikeのインボイスを支払う
Strikeのインボイスをライトニングネットワークで支払うと、経路の各ノードが何を学び、何を学ばないかが分かります。
あなたのウォレットが4ノードの経路を選んだとします。自分のピア、2つの公開ルーティングノード、そしてStrikeです。パケットはStrikeから逆方向に組み立てられます。Strikeのペイロードには最終金額と支払い秘密が入ります。中間の各ペイロードには、下流の全員の手数料をまだ含むamt_to_forward、そのノードが広告する差分だけ減らしたoutgoing_cltv_value、使用するリンクのshort_channel_idが入ります。
2番目のルーティングノードは、ペイロードをちょうど1つ読み取ります。それは、前のノードがHTLCを渡したこと、そしてやや少ないHTLCを先へ提示しなければならないことを学びます。Strikeが終点にあることも、あなたが始点にいることも学ばず、経路が4ホップか8ホップかも判別できません。次へ渡す領域は、受け取ったのと同じ1,300バイトだからです。
そのノードに転送のための流動性がない場合、戻りパケットを組み立てます。自分のum鍵によるHMAC、失敗コード、失敗メッセージとパディングを合わせて少なくとも256バイトにするように選ばれたパディング、そしてその結果をammag鍵から得たストリームでXORしたものです。戻り経路上の各ホップはそれを再び難読化します。あなたのウォレットは層を剥がし、その後ループが27回実行されるまで復号を続けます。これはTLVペイロード形式が許す最長の経路であり、失敗したノードが試行の繰り返しのタイミングから自分の位置を割り出せないようにします。新しいノードは帰属データも添付します。すなわち4バイトに切り詰めたHMACを、最大20ホップの経路に対して210個、そして100ミリ秒単位の保持時間です。
オニオンルーティングvsブラインド経路
オニオンルーティングは支払いを運ぶノードから経路を隠し、ブラインド経路は支払う人から経路の末端部分を隠します。
通常のオニオンルーティングでは、共有秘密がそれらの鍵に対するECDHから得られるため、送信者がすべてのノードの実際の公開鍵を知っている必要があります。経路ブラインディングは最後の区間についてそれを逆転させます。受取人は調整済みのノードIDの連鎖を構築し、BOLT 4自身の例でBobをBob primeに、CarolをCarol primeに変え、次に送信者に導入点とホップごとに1つの暗号化ブロブを渡します。送信者は読めないブロブをオニオンで包みます。両者は競合せずに組み合わさります。BOLT 4はすべてのオニオンメッセージに経路ブラインディングを使うことを要求しており、オニオンメッセージは支払いのオニオンと同じパケット形式を使います。
オニオンルーティングvs HTLC
オニオンルーティングは指示を運び、HTLCはお金を運び、ライトニングネットワークの支払いには両方が必要です。それぞれが他方を検証するからです。
オニオンはホップにどこへどれだけ転送するかを伝えます。HTLCはチャネル上で実際に提示される条件付き支払いです。ペイロード領域は、送信者とそのホップだけが生成できるパケット全体のHMACで覆われているため、ノードは提示されたHTLCを自分向けに書かれたamt_to_forwardとoutgoing_cltv_valueと照合し、それらが一致しない場合には失敗させます。これにより、上流のノードが金額をこっそり削っていることが分かります。両者は切り離すこともできます。型513のオニオンメッセージは同じ構成でお金を運ばず、中間のホップからエラーが返ることは決してありません。