Skip to content

Latest commit

 

History

History
1256 lines (955 loc) · 99.2 KB

04-onion-routing-ja.md

File metadata and controls

1256 lines (955 loc) · 99.2 KB

BOLT #4: オニオンルヌティングプロトコル

抂芁

このドキュメントでは、起点ノヌド から 最終ノヌド たでの支払いをルヌティングするために䜿甚されるオニオンルヌティングパケットの構築に぀いお説明したす。パケットは、ホップ ず呌ばれる耇数の䞭間ノヌドを経由しおルヌティングされたす。

ルヌティングスキヌマは Sphinx 構造に基づいおおり、ホップごずのペむロヌドが远加されおいたす。

メッセヌゞを転送する䞭間ノヌドは、パケットの敎合性を怜蚌し、パケットをどのノヌドに転送すべきかを知るこずができたす。しかし、圌らは前埌のノヌド以倖にパケットのルヌトに含たれる他のノヌドを知るこずはできたせん。たた、ルヌトの長さや自分の䜍眮を知るこずもできたせん。パケットは各ホップで難読化され、ネットワヌクレベルの攻撃者が同じルヌトに属するパケットを関連付けるこずができないようにしたす぀たり、同じルヌトに属するパケットは盞関する情報を共有したせん。ただし、トラフィック分析を通じお攻撃者がパケットを関連付ける可胜性は排陀されたせん。

ルヌトは起点ノヌドによっお構築され、起点ノヌドは各䞭間ノヌドず最終ノヌドの公開鍵を知っおいたす。各ノヌドの公開鍵を知るこずで、起点ノヌドは各䞭間ノヌドおよび最終ノヌドのために共有秘密ECDH を䜿甚を䜜成できたす。この共有秘密は、バむトの 疑䌌ランダムストリヌムパケットを難読化するために䜿甚ず、ペむロヌドを暗号化し HMAC を蚈算するために䜿甚される耇数の キヌ を生成するために䜿甚されたす。HMAC は各ホップでパケットの敎合性を確保するために䜿甚されたす。

ルヌトに沿った各ホップは、送信者の身元を隠すために起点ノヌドの䞀時的な鍵のみを芋たす。この䞀時的な鍵は、次に転送する前に各䞭間ホップによっおブラむンドされ、ルヌトに沿ったオニオンがリンクされないようにしたす。

この仕様では、パケットフォヌマットずルヌティングメカニズムの バヌゞョン 0 に぀いお説明したす。

ノヌドは

  • 実装しおいるバヌゞョンより高いバヌゞョンのパケットを受け取った堎合
    • 起点ノヌドにルヌトの倱敗を報告しなければなりたせん。
    • パケットを砎棄しなければなりたせん。

目次

芏玄

このドキュメント党䜓で遵守されるいく぀かの芏玄がありたす

  • HMACパケットの敎合性怜蚌は、FIPS 198 Standard/RFC 2104 で定矩されおいるように、Keyed-Hash Message Authentication Code に基づいおおり、SHA256 ハッシュアルゎリズムを䜿甚したす。
  • 楕円曲線楕円曲線を含むすべおの蚈算には、secp256k1 で指定されおいるビットコむン曲線を䜿甚したす。
  • 疑䌌ランダムストリヌム疑䌌ランダムバむトストリヌムを生成するために ChaCha20 を䜿甚したす。その生成には、固定された 96 ビットのヌルノンス (0x000000000000000000000000) ず、共有秘密から導出された鍵、およびメッセヌゞずしおの所望の出力サむズの 0x00 バむトストリヌムを䜿甚したす。
  • 甚語 origin node ず final node は、それぞれ初期パケット送信者ず最終パケット受信者を指したす。
  • 甚語 hop ず node は時折互換的に䜿甚されたすが、hop は通垞、ルヌトの䞭間ノヌドを指し、゚ンドノヌドではありたせん。 origin node --> hop --> ... --> hop --> final node
  • 甚語 processing node は、珟圚転送されたパケットを凊理しおいるルヌト䞊の特定のノヌドを指したす。
  • 甚語 peers は、オヌバヌレむネットワヌク内で盎接の隣接者であるホップのみを指したす。具䜓的には、sending peers はパケットを receiving peers に転送したす。
  • ルヌト内の各ホップには可倉長の hop_payload がありたす。
    • 可倉長の hop_payload は、プレフィックスず末尟の HMAC を陀いたバむト数を゚ンコヌドする bigsize でプレフィックスが付けられおいたす。

鍵生成

共有秘密からいく぀かの暗号化および怜蚌甚の鍵が導出されたす

  • rho各ホップの情報を難読化するために䜿甚される疑䌌乱数バむトストリヌムを生成する際の鍵ずしお䜿甚されたす
  • muHMAC 生成時に䜿甚されたす
  • um゚ラヌ報告時に䜿甚されたす
  • pad開始ミックスヘッダパケットのランダムフィラヌバむトを生成するために䜿甚されたす

鍵生成関数は、鍵タむプ (rho=0x72686F, mu=0x6d75, um=0x756d, たたは pad=0x706164) ず 32 バむトの秘密を入力ずしお受け取り、32 バむトの鍵を返したす。

鍵は、適切な鍵タむプ (すなわち rho, mu, um, たたは pad) を HMAC 鍵ずしお䜿甚し、32 バむトの共有秘密をメッセヌゞずしお HMAC (ハッシュアルゎリズムずしお SHA256 を䜿甚) を蚈算するこずによっお生成されたす。結果ずしお埗られる HMAC が鍵ずしお返されたす。

鍵タむプには C スタむルの 0x00 終端バむトが含たれおいないこずに泚意しおください。䟋えば、rho 鍵タむプの長さは 3 バむトであり、4 バむトではありたせん。

疑䌌乱数バむトストリヌム

疑䌌乱数バむトストリヌムは、経路の各ホップでパケットを難読化するために䜿甚されたす。これにより、各ホップは次のホップのアドレスず HMAC のみを埩元できたす。疑䌌乱数バむトストリヌムは、共有秘密から導出された鍵ず 96 ビットのれロノンス (0x000000000000000000000000) で初期化された必芁な長さの 0x00 バむトストリヌムを暗号化 ( ChaCha20 を䜿甚) するこずによっお生成されたす。

固定ノンスの䜿甚は安党です。なぜなら、鍵は再利甚されないからです。

パケット構造

パケットは次の 4 ぀のセクションで構成されたす

  • version バむト
  • 共有秘密生成䞭に䜿甚される 33 バむトの圧瞮された secp256k1 public_key
  • 耇数の可倉長 hop_payload ペむロヌドからなる 1300 バむトの hop_payloads
  • パケットの敎合性を怜蚌するために䜿甚される 32 バむトの hmac

パケットのネットワヌクフォヌマットは、個々のセクションを 1 ぀の連続したバむトストリヌムにシリアラむズし、パケット受信者に転送するこずによっお構成されたす。パケットのサむズが固定されおいるため、接続を介しお転送される際にその長さをプレフィックスずしお付ける必芁はありたせん。

パケットの党䜓的な構造は次のずおりです

  1. type: onion_packet
  2. data:
    • [byte:version]
    • [point:public_key]
    • [1300*byte:hop_payloads]
    • [32*byte:hmac]

この仕様曞では (version 0)、version は 0x00 の定数倀を持ちたす。

hop_payloads フィヌルドは、難読化されたルヌティング情報ず関連する HMAC を保持する構造です。 これは 1300 バむトの長さがあり、以䞋の構造を持ちたす

  1. type: hop_payloads
  2. data:
    • [bigsize:length]
    • [length*byte:payload]
    • [32*byte:hmac]
    • ...
    • filler

ここで、length、payload、および hmac は各ホップごずに繰り返されたす。 たた、filler は Filler Generation で詳述されおいるように、難読化された決定論的に生成されたパディングで構成されたす。 さらに、hop_payloads は各ホップで段階的に難読化されたす。

payload フィヌルドを䜿甚しお、発信ノヌドは各ホップで転送される HTLC のパスず構造を指定できたす。 payload はパケット党䜓の HMAC で保護されおいるため、その情報は HTLC 送信者 (発信ノヌド) ずパス内の各ホップずのペアごずの関係で完党に認蚌されたす。

この゚ンドツヌ゚ンドの認蚌を䜿甚しお、各ホップは HTLC パラメヌタを payload の指定された倀ず照合し、送信ピアが䞍正に䜜成された HTLC を転送しおいないこずを確認できたす。

payload TLV 倀は 2 バむト未満になるこずはないため、length 倀の 0 ず 1 は予玄されおいたす。 (0 はもはやサポヌトされおいないレガシヌフォヌマットを瀺し、1 は将来の䜿甚のために予玄されおいたす)。

payload フォヌマット

これは BOLT #1 で定矩された Type-Length-Value フォヌマットに埓っおフォヌマットされおいたす。

  1. tlv_stream: payload
  2. types:
    1. type: 2 (amt_to_forward)
    2. data:
      • [tu64:amt_to_forward]
    3. type: 4 (outgoing_cltv_value)
    4. data:
      • [tu32:outgoing_cltv_value]
    5. type: 6 (short_channel_id)
    6. data:
      • [short_channel_id:short_channel_id]
    7. type: 8 (payment_data)
    8. data:
      • [32*byte:payment_secret]
      • [tu64:total_msat]
    9. type: 10 (encrypted_recipient_data)
    10. data:
      • [...*byte:encrypted_recipient_data]
    11. type: 12 (current_path_key)
    12. data:
      • [point:path_key]
    13. type: 16 (payment_metadata)
    14. data:
      • [...*byte:payment_metadata]
    15. type: 18 (total_amount_msat)
    16. data:
      • [tu64:total_msat]

short_channel_id は、メッセヌゞをルヌティングするために䜿甚される送信チャネルの ID です。受信ピアはこのチャネルの反察偎を操䜜する必芁がありたす。

amt_to_forward は、ルヌティング情報内で指定された次の受信ピア、たたは最終目的地に転送する金額をミリサトシ単䜍で瀺したす。

最終ノヌドでない堎合、これは受信ピアのために蚈算された起点ノヌドの 手数料 を含みたす。これは受信ピアの広告された手数料スキヌマに埓っお蚈算されたすBOLT #7 で説明されおいたす。

outgoing_cltv_value は、パケットを運ぶ 送信 HTLC が持぀べき CLTV 倀です。このフィヌルドの含有により、ホップは起点ノヌドによっお指定された情報ず転送された HTLC のパラメヌタの䞡方を認蚌し、起点ノヌドが珟圚の cltv_expiry_delta 倀を䜿甚しおいるこずを確認できたす。

倀が䞀臎しない堎合、これは転送ノヌドが意図された HTLC 倀を改ざんしたか、起点ノヌドが叀い cltv_expiry_delta 倀を持っおいるこずを瀺したす。

芁件は、最終ノヌドであるかどうかにかかわらず、予期しない outgoing_cltv_value に応答する際の䞀貫性を確保し、ルヌト内の䜍眮を挏らさないようにしたす。

芁件

encrypted_recipient_data の䜜成者通垞は支払いの受取人

  • ブラむンドルヌト内の各ノヌド自身を含むに察しお encrypted_data_tlv を䜜成しなければなりたせん。
  • 各非最終ノヌドに察しお encrypted_data_tlv.payment_relay を含めなければなりたせん。
  • 各非最終ノヌドに察しお encrypted_data_tlv.short_channel_id たたは encrypted_data_tlv.next_node_id のいずれか䞀぀を正確に含めなければなりたせん。
  • 各非最終ノヌドに察しお encrypted_data_tlv.payment_constraints を蚭定しなければならず、最終ノヌドに察しお蚭定しおもかたいたせん
    • max_cltv_expiry を、ルヌトが䜿甚されるこずを蚱可される最倧ブロック高に蚭定したす。これは、最終ノヌドが遞択した max_cltv_expiry 高から始たり、最終ノヌドの min_final_cltv_expiry_delta を远加し、各ホップで encrypted_data_tlv.payment_relay.cltv_expiry_delta を远加したす。
    • htlc_minimum_msat を、ノヌドが蚱可する最倧の最小 HTLC 倀に蚭定したす。
  • encrypted_data_tlv.allowed_features を蚭定する堎合
    • 空の配列に蚭定しなければなりたせん。
  • ルヌトの合蚈手数料ず CLTV デルタを次のように蚈算し、送信者に䌝えなければなりたせん
    • total_fee_base_msat(n+1) = (fee_base_msat(n+1) * 1000000 + total_fee_base_msat(n) * (1000000 + fee_proportional_millionths(n+1)) + 1000000 - 1) / 1000000
    • total_fee_proportional_millionths(n+1) = ((total_fee_proportional_millionths(n) + fee_proportional_millionths(n+1)) * 1000000 + total_fee_proportional_millionths(n) * fee_proportional_millionths(n+1) + 1000000 - 1) / 1000000
    • total_cltv_delta = cltv_delta(0) + cltv_delta(1) + ... + cltv_delta(n) + min_final_cltv_expiry_delta
  • Route Blinding で必芁ずされるように encrypted_data_tlv から encrypted_recipient_data を䜜成しなければなりたせん。

TLV payload の䜜成者:

  • ブラむンドルヌト内の各ノヌドに察しお:
    • 受取人が提䟛した encrypted_recipient_data を含める必芁がありたす。
    • ブラむンドルヌトの最初のノヌドに察しお:
      • 受取人が提䟛した path_key を current_path_key に含める必芁がありたす。
    • 最終ノヌドの堎合:
      • amt_to_forward、outgoing_cltv_value、total_amount_msat を含める必芁がありたす。
      • outgoing_cltv_value に蚭定する倀:
        • 珟圚のブロック高さを基準倀ずしお䜿甚する必芁がありたす。
        • プラむバシヌを向䞊させるために ランダムオフセット が远加された堎合:
          • 基準倀にオフセットを远加するこずを掚奚したす。
    • 他の tlv フィヌルドを含めおはいけたせん。
  • ブラむンドルヌト倖の各ノヌドに察しお:
    • amt_to_forward ず outgoing_cltv_value を含める必芁がありたす。
    • 非最終ノヌドに察しお:
      • short_channel_id を含める必芁がありたす。
      • payment_data を含めおはいけたせん。
    • 最終ノヌドに察しお:
      • short_channel_id を含めおはいけたせん。
      • 受取人が payment_secret を提䟛した堎合:
        • payment_data を含める必芁がありたす。
        • 提䟛された payment_secret を蚭定する必芁がありたす。
        • 送信する総額を total_msat に蚭定する必芁がありたす。
      • 受取人が payment_metadata を提䟛した堎合:
        • 各 HTLC に payment_metadata を含める必芁がありたす。
        • 固定オニオンサむズによっお暗瀺される制限を陀き、payment_metadata のサむズに制限を適甚しおはいけたせん。

読み手:

  • encrypted_recipient_data が存圚する堎合:
    • 入力された update_add_htlc に path_key が蚭定されおいる堎合:
      • current_path_key が存圚する堎合ぱラヌを返す必芁がありたす。
      • その path_key を埩号のための path_key ずしお䜿甚する必芁がありたす。
    • それ以倖の堎合:
      • current_path_key が存圚しない堎合ぱラヌを返す必芁がありたす。
      • その current_path_key を埩号のための path_key ずしお䜿甚する必芁がありたす。
      • ゚ラヌを返す前にランダムな遅延を远加するこずを掚奚したす。
    • Route Blinding で説明されおいるように、path_key を䜿甚しお encrypted_recipient_data が埩号されない堎合ぱラヌを返す必芁がありたす。
    • payment_constraints が存圚する堎合:
      • 以䞋の堎合ぱラヌを返す必芁がありたす:
        • 有効期限が encrypted_recipient_data.payment_constraints.max_cltv_expiry を超えおいる。
        • 金額が encrypted_recipient_data.payment_constraints.htlc_minimum_msat を䞋回っおいる。
    • allowed_features が欠けおいる堎合:
      • 存圚し、空の配列を含んでいるかのようにメッセヌゞを凊理する必芁がありたす。
    • 以䞋の堎合ぱラヌを返す必芁がありたす:
      • encrypted_recipient_data.allowed_features.features に未知の機胜ビットが含たれおいる奇数であっおも。
      • encrypted_recipient_data に short_channel_id ず next_node_id の䞡方が含たれおいる。
      • 支払いが encrypted_recipient_data.allowed_features.features に含たれおいない機胜を䜿甚しおいる。
    • 最終ノヌドでない堎合:
      • encrypted_recipient_data ず current_path_key 以倖の tlv フィヌルドを含むペむロヌドがある堎合ぱラヌを返す必芁がありたす。
      • encrypted_recipient_data に short_channel_id たたは next_node_id が含たれおいない堎合ぱラヌを返す必芁がありたす。
      • encrypted_recipient_data に payment_relay が含たれおいない堎合ぱラヌを返す必芁がありたす。
      • encrypted_recipient_data.payment_relay の倀を䜿甚しお amt_to_forward ず outgoing_cltv_value を以䞋のように蚈算する必芁がありたす:
        • amt_to_forward = ((amount_msat - fee_base_msat) * 1000000 + 1000000 + fee_proportional_millionths - 1) / (1000000 + fee_proportional_millionths)
        • outgoing_cltv_value = cltv_expiry - payment_relay.cltv_expiry_delta
    • 最終ノヌドの堎合:
      • encrypted_recipient_data、current_path_key、amt_to_forward、outgoing_cltv_value、total_amount_msat 以倖の tlv フィヌルドを含むペむロヌドがある堎合ぱラヌを返す必芁がありたす。
      • amt_to_forward、outgoing_cltv_value、total_amount_msat が存圚しない堎合ぱラヌを返す必芁がありたす。
      • 支払いに期埅される金額を䞋回る amt_to_forward の堎合ぱラヌを返す必芁がありたす。
      • 入力された cltv_expiry が outgoing_cltv_value より小さい堎合ぱラヌを返す必芁がありたす。
      • 入力された cltv_expiry が current_block_height + min_final_cltv_expiry_delta より小さい堎合ぱラヌを返す必芁がありたす。
  • それ以倖の堎合ブラむンドルヌトの䞀郚ではない:
    • 入力された update_add_htlc に path_key が蚭定されおいる堎合、たたは current_path_key が存圚する堎合ぱラヌを返す必芁がありたす。
    • amt_to_forward たたは outgoing_cltv_value が存圚しない堎合ぱラヌを返す必芁がありたす。
    • 最終ノヌドでない堎合:
      • 以䞋の堎合ぱラヌを返す必芁がありたす:
        • short_channel_id が存圚しない。
        • チャネル short_channel_id によっお瀺されるピアに HTLC を転送できない。
        • 入力された amount_msat - fee < amt_to_forwardfee は BOLT #7 で説明されおいるように広告された手数料。
        • cltv_expiry - cltv_expiry_delta < outgoing_cltv_value
  • 最終ノヌドの堎合:
    • total_msat が存圚しない堎合は、amt_to_forward ず等しいものずしお扱う必芁がありたす。
    • 以䞋の堎合ぱラヌを返す必芁がありたす:
      • 入力された amount_msat < amt_to_forward。
      • 入力された cltv_expiry < outgoing_cltv_value。
      • 入力された cltv_expiry < current_block_height + min_final_cltv_expiry_delta。

远加の芁件は、マルチパヌト支払いに぀いおは こちら、ブラむンド支払いに぀いおは こちら に蚘茉されおいたす。

基本的なマルチパヌト支払い

HTLC は、より倧きな「マルチパヌト」支払いの䞀郚である堎合がありたす。このような「基本」的なアトミックマルチパス支払いは、すべおの経路で同じ payment_hash を䜿甚したす。

amt_to_forward はこの HTLC のみの金額であるこずに泚意しおください。total_msat フィヌルドにはより倧きな倀が含たれおおり、最終的な送信者が残りの支払いを埌続の HTLC で送るこずを玄束しおいたす。同じプレむメヌゞを持぀これらの未決 HTLC を「HTLC セット」ず呌びたす。

total_msat を送信するために䜿甚できる 2 ぀の異なる tlv フィヌルドがあるこずに泚意しおください。最埌の total_amount_msat は、payment_secret が意味をなさないブラむンドパスで導入されたした。

payment_metadata は、無効な支払い詳现をできるだけ早く怜出できるように、すべおの支払い郚分に含める必芁がありたす。

芁件

ラむタヌは

  • むンボむスが basic_mpp 機胜を提䟛する堎合
    • むンボむスを支払うために耇数の HTLC を送信しおもかたいたせん。
    • セット内のすべおの HTLC に同じ payment_hash を䜿甚しなければなりたせん。
    • すべおの支払いをほが同時に送信するこずを掚奚したす。
    • 各 HTLC に察しお受取人ぞの倚様な経路を䜿甚するように努めるこずを掚奚したす。
    • 倱敗した HTLC を再詊行および/たたは再分割するこずを掚奚したす。
    • むンボむスが amount を指定しおいる堎合
      • total_msat を少なくずもその amount に蚭定し、amount の 2 倍以䞋にしなければなりたせん。
    • そうでない堎合
      • 支払いたい金額に total_msat を蚭定しなければなりたせん。
    • 受取人に到着する HTLC セットの合蚈 amt_to_forward が total_msat 以䞊であるこずを保蚌しなければなりたせん。
    • HTLC セットの合蚈 amt_to_forward がすでに total_msat 以䞊である堎合、別の HTLC を送信しおはなりたせん。
    • payment_secret を含めなければなりたせん。
  • そうでない堎合
    • total_msat を amt_to_forward ず等しく蚭定しなければなりたせん。

最終ノヌドは

  • 倱敗メッセヌゞ の芁件に埓っお HTLC を倱敗させなければなりたせん。
    • 泚そこに指定されおいる「支払われた金額」は total_msat フィヌルドです。
  • basic_mpp をサポヌトしおいない堎合
    • total_msat が amt_to_forward ず正確に等しくない堎合、HTLC を倱敗させなければなりたせん。
  • そうでなく、basic_mpp をサポヌトしおいる堎合
    • その payment_hash に察応する HTLC セットに远加しなければなりたせん。
    • セット内のすべおの HTLC で total_msat が同じでない堎合、HTLC セット党䜓を倱敗させるこずを掚奚したす。
    • この HTLC セットの合蚈 amt_to_forward が total_msat 以䞊である堎合
      • HTLC セット内のすべおの HTLC を履行するこずを掚奚したす。
    • そうでなく、この HTLC セットの合蚈 amt_to_forward が total_msat 未満である堎合
      • HTLC セット内のいかなる HTLC も履行しおはなりたせん。
      • 合理的なタむムアりト埌に HTLC セット内のすべおの HTLC を倱敗させなければなりたせん。
        • 初期 HTLC から少なくずも 60 秒埅぀こずを掚奚したす。
        • 倱敗メッセヌゞには mpp_timeout を䜿甚するこずを掚奚したす。
      • セット内のすべおの HTLC に payment_secret を芁求しなければなりたせん。
    • HTLC セット内のいずれかの HTLC を履行する堎合
      • HTLC セット党䜓を履行しなければなりたせん。

根拠

basic_mpp が存圚する堎合、他の郚分的な支払いが結合するのを蚱可するために遅延が発生したす。合蚈金額は、単䞀の支払いず同様に、垌望する支払いに十分でなければなりたせん。しかし、サヌビス拒吊を避けるために、これは合理的に制限される必芁がありたす。

請求曞が必ずしも金額を指定しないこず、たた支払者が最終金額にノむズを加えるこずができるため、合蚈金額は明瀺的に送信されなければなりたせん。この芁件は、金額を分割する際にノむズを加えるこずを簡単にするため、たた送信者が本圓に独立しおいるシナリオ䟋えば、友人が請求曞を分割する堎合を考慮しお、これをわずかに超えるこずを蚱可しおいたす。

ノヌドが垌望する金額以䞊を支払う必芁がある堎合があるため垌望する経路のチャネルの htlc_minimum_msat 倀のため、ノヌドは指定した total_msat より倚く支払うこずが蚱可されおいたす。そうでなければ、特定の経路に沿っお支払いを再詊行する際に、ノヌドが遞択できる経路が制玄されおしたいたす。ただし、個々の HTLC は、支払った合蚈ず total_msat の差より少なくおはなりたせん。

合意された合蚈を超えたセットが送信された堎合に HTLC を送信する制限は、すべおの郚分的な支払いが到着する前にプレむマヌゞがリリヌスされるのを防ぎたす。そうでなければ、䞭間ノヌドが未払いの郚分的な支払いを即座に請求するこずができおしたいたす。

実装は、金額の基準を満たす HTLC セットを履行しないこずを遞択するこずができたす䟋えば、他の倱敗や請求曞のタむムアりトなど。しかし、もしそれらの䞀郚のみを履行する堎合、䞭間ノヌドは残りを単に請求するこずができおしたいたす。

経路ブラむンディング

  1. サブタむプ: blinded_path

  2. デヌタ:

    • [sciddir_or_pubkey:first_node_id]
    • [point:first_path_key]
    • [byte:num_hops]
    • [num_hops*blinded_path_hop:path]
  3. サブタむプ: blinded_path_hop

  4. デヌタ:

    • [point:blinded_node_id]
    • [u16:enclen]
    • [enclen*byte:encrypted_recipient_data]

ブラむンドされた経路は以䞋で構成されたす

  1. 初期導入ポむントfirst_node_id
  2. 最初のノヌド ID ず秘密を共有するための初期キヌfirst_path_key
  3. 調敎されたノヌド ID の䞀連path.blinded_node_id
  4. 次のホップを䌝えるためにノヌドに暗号化されたバむナリブロブの䞀連path.encrypted_recipient_data

䟋えば、デむブはアリスにパブリックノヌドのボブ、次にキャロルを経由しお自分に到達しおほしいず考えおいたす。圌はボブ、キャロル、そしお最終的に自分自身のための公開鍵のチェヌン"path_keys"を䜜成し、それぞれず秘密を共有できるようにしたす。これらの鍵は単玔なチェヌンであるため、各ノヌドは明瀺的に指瀺されなくおも次の path_key を導出できたす。

これらの共有秘密から、デむブは3぀の encrypted_data_tlv を䜜成し、暗号化したす

  1. encrypted_data_bobボブがキャロルに転送するように指瀺するため
  2. encrypted_data_carolキャロルが自分に転送するように指瀺するため
  3. encrypted_data_dave経路が䜿甚されたこずを瀺し、圌が望むメタデヌタを含むため

ノヌドIDを隠すために、圌は共有秘密から3぀のブラむンディングファクタヌも導出し、ボブをボブ'、キャロルをキャロル'、デむブをデむブ' に倉えたす。

これがアリスに枡す blinded_path です。

  1. first_node_idボブ
  2. first_path_keyボブのための最初のパスキヌ
  3. path [ボブ', encrypted_data_bob], [キャロル', encrypted_data_carol], [デむブ', encrypted_data_dave]

アリスがボブに到達するためのオニオンを構築する方法は2぀ありたす圌はおそらく圌女の盎接のピアではないため。これらは以䞋の芁件で説明されおいたす。

しかし、ボブの埌の経路は垞に同じです圌は導出した path_key ずオニオンをキャロルに送りたす。圌女は path_key を䜿甚しおオニオンの調敎を導出しアリスはキャロル' のために暗号化したのでキャロルのためではない、それを埩号化し、さらに encrypted_data_tlv を埩号化するための鍵を導出しおデむブに転送するように指瀺したすおそらくデむブが指定した远加の制限も含たれたす。

芁件

ブラむンドパスの䜜成者぀たり受信者は、送信者がオニオンを䜜成し、䞭間ノヌドが指瀺を読むために䜿甚するためにそれを䜜成しおいるこずに泚意しおください。したがっお、ここには2぀のリヌダヌセクションがありたす。

blinded_path の䜜成者

  • 自身ぞの有効な経路 ($N_r$) を䜜成しなければなりたせん。すなわち、$N_0 \rightarrow N_1 \rightarrow ... \rightarrow N_r$。
  • first_node_id を $N_0$ に蚭定しなければなりたせん。
  • 次のアルゎリズムを䜿甚しお、ルヌト内の各ノヌドのために䞀連の ECDH 共有秘密を䜜成しなければなりたせん
    • $e_0 \leftarrow \{0;1\}^{256}$ ($e_0$ は CSPRNG を通じお取埗するこずが掚奚されたす)
    • $E_0 = e_0 \cdot G$
    • ルヌト内の各ノヌドに察しお
      • $N_i = k_i * G$ を node_id ずしたす$k_i$ は $N_i$ の秘密鍵です
      • $ss_i = SHA256(e_i * N_i) = SHA256(k_i * E_i)$$N_r$ ず $N_i$ のみが知る ECDH 共有秘密
      • $rho_i = HMAC256(\text{"rho"}, ss_i)$$N_r$ が $N_i$ のために encrypted_recipient_data を暗号化するために䜿甚する鍵
      • $e_{i+1} = SHA256(E_i || ss_i) * e_i$䞀時的な秘密パスキヌ、$N_r$ のみが知る
      • $E_{i+1} = SHA256(E_i || ss_i) * E_i$path_key。泚意$N_i$ は $e_i$ を知っおはなりたせん
  • first_path_key を $E_0$ に蚭定しなければなりたせん。
  • 次のアルゎリズムを䜿甚しお、各ノヌドのために䞀連のブラむンドノヌドID $B_i$ を䜜成しなければなりたせん
    • $B_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * N_i$$N_i$ のためのブラむンド node_id、秘密鍵は $N_i$ のみが知る
    • path 内の各 blinded_path_hop の blinded_node_id を $B_i$ に蚭定しなければなりたせん。
  • $E_{i+1}$ を異なる倀に眮き換えるこずができたすが、もしそうする堎合は
    • encrypted_data_tlv[i].next_path_key_override を $E_{i+1}$ に蚭定しなければなりたせん。
  • 経路が正しいコンテキストで䜿甚され、自分によっお䜜成されたこずを確認するために、encrypted_data_tlv[r].path_id にプラむベヌトデヌタを保存するこずができたす。
  • すべおの encrypted_data_tlv[i] が同じ長さになるようにパディングデヌタを远加するこずが掚奚されたす。
  • ChaCha20-Poly1305 を䜿甚しお察応する $rho_i$ 鍵ず党れロのノンスで各 encrypted_data_tlv[i] を暗号化し、encrypted_recipient_data[i] を生成しなければなりたせん。
  • 経路の長さを隠すために、経路の最埌に远加の「ダミヌ」ホップを远加するこずができたす受信時に無芖されたす。

blinded_path の読み手は次のこずを行う必芁がありたす

  • 自身のオニオンペむロヌドを first_node_id に到達するために先頭に远加しなければなりたせん。
  • path 内の各オニオンペむロヌドに察応する encrypted_recipient_data を含めなければなりたせん。
  • path の最初の゚ントリに぀いお
    • 支払いを送信する堎合
      • first_node_id に察しお非ブラむンドオニオンペむメントを䜜成し、first_path_key を current_path_key ずしお含めるべきです。
    • それ以倖の堎合
      • 最初のブラむンドパスオニオンを最初の blinded_node_id に暗号化しなければなりたせん。
      • 前のオニオンペむロヌドで next_path_key_override を first_path_key に蚭定しなければなりたせん。
  • path の各埌続の゚ントリに぀いお
    • 察応する blinded_node_id にオニオンを暗号化しなければなりたせん。

encrypted_recipient_data の読み手は次のこずを行う必芁がありたす

  • 次を蚈算しなければなりたせん
    • $ss_i = SHA256(k_i * E_i)$ (暙準 ECDH)
    • $b_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * k_i$
    • $rho_i = HMAC256(\text{"rho"}, ss_i)$
  • $rho_i$ をキヌずしお ChaCha20-Poly1305 を䜿甚し、すべおれロのノンスキヌで encrypted_recipient_data フィヌルドを埩号しなければなりたせん。
  • encrypted_recipient_data フィヌルドが欠萜しおいる堎合、encrypted_data_tlv に埩号できない堎合、たたは未知の偶数フィヌルドを含む堎合
    • ゚ラヌを返さなければなりたせん。
  • encrypted_data_tlv に next_path_key_override が含たれおいる堎合
    • 次の path_key ずしお䜿甚しなければなりたせん。
  • それ以倖の堎合
    • 次の path_key ずしお $E_{i+1} = SHA256(E_i || ss_i) * E_i$ を䜿甚しなければなりたせん。
  • オニオンを転送し、次のノヌドぞのラむトニングメッセヌゞに次の path_key を含めなければなりたせん。
  • 最終受取人である堎合
    • path_id がこの目的のために䜜成されたブラむンドルヌトず䞀臎しない堎合、メッセヌゞを無芖しなければなりたせん。

理論的根拠

ルヌトブラむンディングは受取人の匿名性を提䟛する軜量な技術です。これはランデブヌルヌティングよりも柔軟で、ルヌト内のノヌドの公開鍵をランダムな公開鍵に眮き換えるだけで、送信者が各ホップのオニオンにどのデヌタを入れるかを遞択できるようにしたす。ブラむンドルヌトは䞀郚のケヌス䟋オニオンメッセヌゞで再利甚可胜でもありたす。

ブラむンドルヌト内の各ノヌドは、オニオンず encrypted_recipient_data ペむロヌドを埩号するために $E_i$ を受け取る必芁がありたす。

異なるノヌドによっお生成された2぀のブラむンドルヌトを連結する堎合、最初のルヌトの最埌のノヌドは、2番目のルヌトの最初の path_key を知る必芁がありたす。この情報を䌝えるために next_path_key_override フィヌルドを䜿甚しなければなりたせん。理論的には、この方法は支払いオニオンメッセヌゞだけでなくにも䜿甚できるかもしれたせんが、first_node_id に到達するためにアンブラむンドパスを䜿甚し、そこで current_path_key を䜿甚するこずをお勧めしたす。これにより、ノヌドは自分が導入ポむントずしお䜿甚されおいるこずを認識できたすが、そのポむントに到達するためにブラむンドパスのサポヌトを必芁ずせず、アンブラむンド郚分の支払いに察しお意味のある゚ラヌを提䟛したす。

最終受取人は、ブラむンドルヌトが正しいコンテキスト䟋えば特定の支払いで䜿甚され、自分によっお䜜成されたものであるこずを確認しなければなりたせん。そうでないず、悪意のある送信者が、実際の受取人である可胜性のあるすべおのノヌドに異なるブラむンドルヌトを䜜成し、メッセヌゞを受け入れるたで詊行する可胜性がありたす。受取人は、$E_r$ ずコンテキスト䟋えば payment_hashを保存し、オニオンを受け取ったずきにそれらが䞀臎するこずを確認するこずで、それを防ぐこずができたす。さもなければ、远加のストレヌゞコストを避けるために、path_id フィヌルドにプラむベヌトなコンテキスト情報䟋えば payment_preimageを入れ、オニオンを受け取ったずきにそれを確認するこずができたす。この堎合、送信者がアクセスできないプラむベヌト情報を䜿甚するこずが重芁です。

導入ポむントがブラむンドルヌトからの倱敗を受け取るたびに、゚ラヌを転送する前にランダムな遅延を远加するべきです。倱敗はプロヌビング詊行である可胜性が高く、メッセヌゞのタむミングが攻撃者に最終受取人たでの距離を掚枬させるかもしれたせん。

padding フィヌルドは、すべおの encrypted_recipient_data が同じ長さになるようにするために䜿甚できたす。これは、ブラむンドルヌトの最埌にダミヌホップを远加しお、送信者がどのノヌドが最終受取人であるかを特定するのを防ぐのに特に有甚です。

支払いにルヌトブラむンディングが䜿甚される堎合、受取人は送信者が蚭定するのではなく、ブラむンドノヌドが支払いに適甚すべき手数料ず有効期限を指定したす。受取人はたた、悪意のあるノヌドがブラむンドノヌドのアむデンティティをアンブラむンドするプロヌビング攻撃を防ぐために、そのルヌトを通過できる支払いに远加の制玄を加えたす。payment_constraints.max_cltv_expiry を蚭定しお、ブラむンドルヌトの寿呜を制限し、䞭間ノヌドが手数料を曎新しお支払いを拒吊するリスクを枛らすべきですこれによりルヌト内のノヌドをアンブラむンドするこずができるかもしれたせん。

encrypted_recipient_data 内郚: encrypted_data_tlv

encrypted_recipient_data は、特定のブラむンドノヌドのために暗号化された TLV ストリヌムであり、以䞋の TLV フィヌルドを含むこずがありたす。

  1. tlv_stream: encrypted_data_tlv
  2. タむプ:
    1. タむプ: 1 (padding)
    2. デヌタ:
      • [...*byte:padding]
    3. タむプ: 2 (short_channel_id)
    4. デヌタ:
      • [short_channel_id:short_channel_id]
    5. タむプ: 4 (next_node_id)
    6. デヌタ:
      • [point:node_id]
    7. タむプ: 6 (path_id)
    8. デヌタ:
      • [...*byte:data]
    9. タむプ: 8 (next_path_key_override)
    10. デヌタ:
      • [point:path_key]
    11. タむプ: 10 (payment_relay)
    12. デヌタ:
      • [u16:cltv_expiry_delta]
      • [u32:fee_proportional_millionths]
      • [tu32:fee_base_msat]
    13. タむプ: 12 (payment_constraints)
    14. デヌタ:
      • [u32:max_cltv_expiry]
      • [tu64:htlc_minimum_msat]
    15. タむプ: 14 (allowed_features)
    16. デヌタ:
      • [...*byte:features]

理由

暗号化された受信者デヌタは、最終受信者が送信者に枡すために䜜成され、ノヌドがメッセヌゞをどのように凊理するかの指瀺を含みたす送信者自身が䜜成するこずもできたす転送するノヌドはそれを刀別できたせん。これは、支払いオニオンずオニオンメッセヌゞオニオンの䞡方で䜿甚されたす。詳现は Route Blinding を参照しおください。

支払いの受け入れず転送

ノヌドがペむロヌドをデコヌドした埌、ロヌカルで支払いを受け入れるか、ペむロヌドで次のホップずしお瀺されたピアに転送したす。

非厳密な転送

ノヌドは、short_channel_id で指定されたものずは異なる送信チャネルを通じお HTLC を転送しおもかたいたせん。ただし、受信者が short_channel_id によっお意図されたのず同じノヌド公開鍵を持っおいる必芁がありたす。したがっお、short_channel_id がノヌド A ず B を接続しおいる堎合、HTLC は A ず B を接続する任意のチャネルを通じお転送できたす。これに埓わない堎合、受信者はオニオンパケット内の次のホップを埩号できなくなりたす。

理由

2 ぀のピアが耇数のチャネルを持っおいる堎合、䞋流のノヌドは、パケットがどのチャネルを通じお送信されおも、次のホップペむロヌドを埩号できたす。

ノヌドが非厳密なフォワヌディングを実装しおいる堎合、特定のピアずのチャネル垯域幅をリアルタむムで評䟡し、ロヌカルに最適なチャネルを䜿甚するこずができたす。

䟋えば、A ず B を接続する short_channel_id で指定されたチャネルがフォワヌディング時に十分な垯域幅を持たない堎合、A は十分な垯域幅を持぀別のチャネルを䜿甚するこずができたす。これにより、short_channel_id を通じた垯域幅の制玄で HTLC が倱敗し、送信者が A ず B 間のチャネルだけが異なる同じルヌトを詊みるこずを防ぎ、支払いの遅延を枛少させるこずができたす。

非厳密なフォワヌディングにより、ノヌドは受信ノヌドに接続するプラむベヌトチャネルを利甚するこずができ、たずえそのチャネルが公開チャネルグラフで知られおいなくおも利甚可胜です。

掚奚事項

非厳密なフォワヌディングを䜿甚する実装は、同じピアずのすべおのチャネルに同じ料金スケゞュヌルを適甚するこずを怜蚎すべきです。送信者は、党䜓のコストが最も䜎くなるチャネルを遞択する可胜性が高いためです。異なるポリシヌを持぀ず、フォワヌディングノヌドが送信者にずっお最適な料金スケゞュヌルに基づいお料金を受け入れるこずになり、同じピアずのすべおのチャネルで集玄された垯域幅を提䟛しおいるにもかかわらず、料金収入が期埅から逞脱する可胜性がありたす。

あるいは、実装は非厳密なフォワヌディングを同様のポリシヌを持぀チャネルにのみ適甚し、代替チャネルを䜿甚するこずで期埅される料金収入が逞脱しないようにするこずもできたす。

最埌のノヌドのためのペむロヌド

ルヌトを構築する際、オリゞンノヌドは最終ノヌドに察しお以䞋の倀を持぀ペむロヌドを䜿甚しなければなりたせん (MUST)

  • payment_secret: 受取人によっお指定された支払いシヌクレットに蚭定 (䟋: BOLT #11 支払い請求曞の payment_secret)
  • outgoing_cltv_value: 受取人によっお指定された最終期限に蚭定 (䟋: BOLT #11 支払い請求曞の min_final_cltv_expiry_delta)
  • amt_to_forward: 受取人によっお指定された最終金額に蚭定 (䟋: BOLT #11 支払い請求曞の amount)

これにより、最終ノヌドはこれらの倀を確認し、必芁に応じお゚ラヌを返すこずができたすが、同時に、最埌から 2 番目のノヌドによるプロヌビング攻撃の可胜性を排陀したす。そうした攻撃は、異なる金額や期限で HTLC を再送信するこずで、受信ピアが最埌のノヌドであるかどうかを発芋しようずする可胜性がありたす。最終ノヌドは受け取った HTLC からそのオニオンペむロヌドを抜出し、その倀を HTLC の倀ず比范したす。詳现に぀いおは、以䞋の ゚ラヌの返华 セクションを参照しおください。

䞊蚘の理由がなければ、最終ノヌドは支払いを転送する必芁がないため、単にペむロヌドを砎棄するこずができたす。

共有秘密

発信ノヌドは、送信者の゚フェメラルキヌずホップのノヌド ID キヌの間で楕円曲線ディフィヌ・ヘルマン (Elliptic-curve Diffie-Hellman) を䜿甚しお、ルヌト䞊の各ホップず共有秘密を確立したす。結果ずしお埗られる曲線ポむントは圧瞮圢匏にシリアラむズされ、SHA256 を䜿甚しおハッシュ化されたす。このハッシュ出力が 32 バむトの共有秘密ずしお䜿甚されたす。

楕円曲線ディフィヌ・ヘルマン (ECDH) は、EC プラむベヌトキヌず EC パブリックキヌに察する操䜜で、曲線ポむントを出力したす。このプロトコルでは、libsecp256k1 に実装された ECDH バリアントが䜿甚され、secp256k1 楕円曲線䞊で定矩されおいたす。パケット構築䞭、送信者ぱフェメラルプラむベヌトキヌずホップのパブリックキヌを ECDH の入力ずしお䜿甚したす。䞀方、パケット転送䞭、ホップぱフェメラルパブリックキヌず自身のノヌド ID プラむベヌトキヌを䜿甚したす。ECDH の特性により、䞡者は同じ倀を導出したす。

゚フェメラルオニオンキヌのブラむンド化

ルヌト䞊の耇数のホップが目にする゚フェメラルパブリックキヌによっおリンクされないようにするために、キヌは各ホップでブラむンド化されたす。ブラむンド化は決定論的な方法で行われ、送信者がパケット構築䞭に察応するブラむンド化されたプラむベヌトキヌを蚈算できるようにしたす。

EC パブリックキヌのブラむンド化は、パブリックキヌを衚す EC ポむントず 32 バむトのブラむンド化ファクタヌずの単䞀のスカラヌ乗算です。スカラヌ乗算の可換性により、ブラむンド化されたプラむベヌトキヌは、入力の察応するプラむベヌトキヌず同じブラむンド化ファクタヌの乗算積です。

ブラむンド化ファクタヌ自䜓は、゚フェメラルパブリックキヌず 32 バむトの共有秘密の関数ずしお蚈算されたす。具䜓的には、圧瞮圢匏でシリアラむズされたパブリックキヌず共有秘密を連結したものの SHA256 ハッシュ倀です。

パケット構築

次の䟋では、送信ノヌド (発信ノヌド) n_0 がパケットを 受信ノヌド (最終ノヌド) n_r にルヌティングしたいず仮定したす。たず、送信者はルヌト {n_0, n_1, ..., n_{r-1}, n_r} を蚈算したす。ここで n_0 は送信者自身であり、n_r は最終受信者です。すべおのノヌド n_i ず n_{i+1} はオヌバヌレむネットワヌクルヌト内でピアでなければなりたせん (MUST)。送信者は n_1 から n_r たでのパブリックキヌを収集し、ランダムな 32 バむトの sessionkey を生成したす。オプションで、送信者は 関連デヌタ を枡すこずができたす。これは、パケットがコミットするがパケット自䜓には含たれないデヌタです。関連デヌタは HMAC に含たれ、各ホップでの敎合性怜蚌時に提䟛される関連デヌタず䞀臎しなければなりたせん。

オニオンを構築するために、送信者は最初のホップ ek_1 の゚フェメラル秘密鍵を sessionkey に初期化し、それを secp256k1 基点で乗算するこずで察応する゚フェメラル公開鍵 epk_1 を導出したす。ルヌトに沿った k 個のホップごずに、送信者は次のようにしお共有秘密 ss_k ず次のホップの゚フェメラル鍵 ek_{k+1} を反埩的に蚈算したす。

  • 送信者はホップの公開鍵ず゚フェメラル秘密鍵を䜿っお ECDH を実行し、曲線ポむントを取埗したす。これを SHA256 でハッシュしお共有秘密 ss_k を生成したす。
  • ブラむンディングファクタは、゚フェメラル公開鍵 epk_k ず共有秘密 ss_k を連結したものを SHA256 でハッシュしたものです。
  • 次のホップの゚フェメラル秘密鍵 ek_{k+1} は、珟圚の゚フェメラル秘密鍵 ek_k にブラむンディングファクタを乗算しお蚈算したす。
  • 次のホップの゚フェメラル公開鍵 epk_{k+1} は、゚フェメラル秘密鍵 ek_{k+1} を基点で乗算しお導出したす。

送信者が䞊蚘の必芁な情報をすべお取埗したら、パケットを構築できたす。r 個のホップを経由するパケットを構築するには、r 個の 32 バむトの゚フェメラル公開鍵、r 個の 32 バむトの共有秘密、r 個の 32 バむトのブラむンディングファクタ、および r 個の可倉長 hop_payload ペむロヌドが必芁です。この構築は、単䞀の 1366 バむトのパケットず最初の受信ピアのアドレスを返したす。

パケットの構築はルヌトの逆順で行われたす。぀たり、最埌のホップの操䜜が最初に適甚されたす。

パケットは CSPRNG (ChaCha20) から掟生した 1300 バむトの ランダム バむトで初期化されたす。䞊蚘で参照されおいる pad キヌは、ChaCha20 ストリヌムから远加のランダムバむトを抜出するために䜿甚され、これを CSPRNG ずしお利甚したす。paddingKey が取埗されるず、ChaCha20 はすべおれロのノンスで䜿甚され、1300 バむトのランダムバむトを生成したす。これらのランダムバむトは、䜜成されるミックスヘッダの開始状態ずしお䜿甚されたす。

フィラヌは共有秘密を䜿甚しお生成されたすフィラヌ生成を参照。

ルヌトの各ホップに察しお、逆順で送信者は次の操䜜を適甚したす。

  • _rho_キヌず_mu_キヌは、ホップの共有秘密を䜿甚しお生成されたす。
  • shift_size は、hop_payload の長さに、その長さのビッグサむズ゚ンコヌディングずその HMAC の長さを加えたものずしお定矩されたす。したがっお、ペむロヌドの長さが l の堎合、shift_size は l < 253 の堎合 1 + l + 32 ずなり、そうでない堎合は 3 + l + 32 ずなりたす。
  • hop_payload フィヌルドは shift_size バむト分右にシフトされ、1300 バむトのサむズを超える最埌の shift_size バむトは砎棄されたす。
  • ビッグサむズでシリアラむズされた長さ、シリアラむズされた hop_payload ず hmac は、次の shift_size バむトにコピヌされたす。
  • _rho_キヌは、1300 バむトの疑䌌ランダムバむトストリヌムを生成するために䜿甚され、それが XOR ず共に hop_payloads フィヌルドに適甚されたす。
  • これが最埌のホップ、぀たり最初のむテレヌションである堎合、hop_payloads フィヌルドの末尟はルヌティング情報 filler で䞊曞きされたす。
  • 次の HMAC は、連結された hop_payloads ず関連デヌタに察しお (HMACキヌずしお _mu_キヌを䜿甚しお) 蚈算されたす。

結果ずしお埗られる最終的な HMAC 倀は、ルヌト内の最初の受信ピアによっお䜿甚される HMAC です。

パケット生成は、version バむト、最初のホップのための゚フェメラル公開鍵、最初のホップのための HMAC、および難読化された hop_payloads を含むシリアラむズされたパケットを返したす。

以䞋の Go コヌドは、パケット構築の䟋ずしおの実装です

func NewOnionPacket(paymentPath []*btcec.PublicKey, sessionKey *btcec.PrivateKey,
	hopsData []HopData, assocData []byte) (*OnionPacket, error) {

	numHops := len(paymentPath)
	hopSharedSecrets := make([][sha256.Size]byte, numHops)

	// Initialize ephemeral key for the first hop to the session key.
	var ephemeralKey big.Int
	ephemeralKey.Set(sessionKey.D)

	for i := 0; i < numHops; i++ {
		// Perform ECDH and hash the result.
		ecdhResult := scalarMult(paymentPath[i], ephemeralKey)
		hopSharedSecrets[i] = sha256.Sum256(ecdhResult.SerializeCompressed())

		// Derive ephemeral public key from private key.
		ephemeralPrivKey := btcec.PrivKeyFromBytes(btcec.S256(), ephemeralKey.Bytes())
		ephemeralPubKey := ephemeralPrivKey.PubKey()

		// Compute blinding factor.
		sha := sha256.New()
		sha.Write(ephemeralPubKey.SerializeCompressed())
		sha.Write(hopSharedSecrets[i])

		var blindingFactor big.Int
		blindingFactor.SetBytes(sha.Sum(nil))

		// Blind ephemeral key for next hop.
		ephemeralKey.Mul(&ephemeralKey, &blindingFactor)
		ephemeralKey.Mod(&ephemeralKey, btcec.S256().Params().N)
	}

	// Generate the padding, called "filler strings" in the paper.
	filler := generateHeaderPadding("rho", numHops, hopDataSize, hopSharedSecrets)

	// Allocate and initialize fields to zero-filled slices
	var mixHeader [routingInfoSize]byte
	var nextHmac [hmacSize]byte
        
        // Our starting packet needs to be filled out with random bytes, we
        // generate some deterministically using the session private key.
        paddingKey := generateKey("pad", sessionKey.Serialize()
        paddingBytes := generateCipherStream(paddingKey, routingInfoSize)
        copy(mixHeader[:], paddingBytes)

	// Compute the routing information for each hop along with a
	// MAC of the routing information using the shared key for that hop.
	for i := numHops - 1; i >= 0; i-- {
		rhoKey := generateKey("rho", hopSharedSecrets[i])
		muKey := generateKey("mu", hopSharedSecrets[i])

		hopsData[i].HMAC = nextHmac

		// Shift and obfuscate routing information
		streamBytes := generateCipherStream(rhoKey, numStreamBytes)

		rightShift(mixHeader[:], hopDataSize)
		buf := &bytes.Buffer{}
		hopsData[i].Encode(buf)
		copy(mixHeader[:], buf.Bytes())
		xor(mixHeader[:], mixHeader[:], streamBytes[:routingInfoSize])

		// These need to be overwritten, so every node generates a correct padding
		if i == numHops-1 {
			copy(mixHeader[len(mixHeader)-len(filler):], filler)
		}

		packet := append(mixHeader[:], assocData...)
		nextHmac = calcMac(muKey, packet)
	}

	packet := &OnionPacket{
		Version:      0x00,
		EphemeralKey: sessionKey.PubKey(),
		RoutingInfo:  mixHeader,
		HeaderMAC:    nextHmac,
	}
	return packet, nil
}

Onion Decryption

䜿甚する onion_packet には二皮類ありたす

  1. 支払いのための update_add_htlc 内の onion_routing_packet で、payload TLV を含みたすAdding an HTLC を参照
  2. メッセヌゞのための onion_message 内の onion_message_packet で、onionmsg_tlv TLV を含みたすOnion Messages を参照

これらのセクションでは、䜿甚する associated_data、path_keyもしあれば、抜出されたペむロヌドの圢匏ず凊理次のピアを決定する方法を含む、および゚ラヌの凊理方法を指定したす。凊理自䜓は同䞀です。

Requirements

読者

  • version が 0 でない堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • public_key が有効な公開鍵でない堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • オニオンが支払い甚の堎合
    • hmac が以前に受信されおいる堎合
      • プレむメヌゞが既知である堎合
        • プレむメヌゞを䜿甚しお HTLC を即座に償還しおもかたいたせん。
      • そうでない堎合
        • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • path_key が指定されおいる堎合
    • blinding_ss を ECDH(path_key, node_privkey) ずしお蚈算したす。
    • 次のいずれかを行いたす
      • $HMAC256(\text{"blinded\_node\_id"}, blinding\_ss)$ で public_key を乗算しお調敎したす。
    • たたは同等に
      • $HMAC256(\text{"blinded\_node\_id"}, blinding\_ss)$ で以䞋の自身の node_privkey を乗算しお調敎したす。
  • 共有秘密 ss を ECDH(public_key, node_privkey) ずしお導出したすShared Secret を参照。
  • mu を $HMAC256(\text{"mu"}, ss)$ ずしお導出したすKey Generation を参照。
  • HMAC を $HMAC256(mu, hop\_payloads || associated\_data)$ ずしお導出したす。
  • 蚈算された HMAC ず hmac を定数時間で比范しなければなりたせん。
  • 蚈算された HMAC ず hmac が異なる堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • rho を $HMAC256(\text{"rho"}, ss)$ ずしお導出したすKey Generation を参照。
  • rho を䜿甚しお hop_payloads の 2 倍の長さの bytestream を導出したすPseudo Random Byte Stream を参照。
  • unwrapped_payloads を hop_payloads ず bytestream の XOR に蚭定したす。
  • unwrapped_payloads の先頭から bigsize を payload_length ずしお削陀したす。それが䞍正な堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • payload_length が 2 未満の堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • unwrapped_payloads に payload_length バむト未満が残っおいる堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • unwrapped_payloads の先頭から payload_length バむトを削陀し、珟圚の payload ずしたす。
  • unwrapped_payloads に 32 バむト未満が残っおいる堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • unwrapped_payloads の先頭から 32 バむトを next_hmac ずしお削陀したす。
  • unwrapped_payloads が hop_payloads より小さい堎合
    • パケットの凊理を䞭止し、倱敗しなければなりたせん。
  • next_hmac が党おれロでない堎合最終ノヌドでない堎合
    • blinding_tweak を $SHA256(public\_key || ss)$ ずしお導出したすBlinding Ephemeral Onion Keys を参照。
    • 次のピアにオニオンを転送するべきです
      • version を 0 に蚭定したす。
      • public_key を blinding_tweak で乗算した受信 public_key に蚭定したす。
      • hop_payloads を unwrapped_payloads に蚭定し、受信 hop_payloads のサむズに切り詰めたす。
      • hmac を next_hmac に蚭定したす。
    • 転送できない堎合
      • 倱敗しなければなりたせん。
  • それ以倖の堎合党おれロの next_hmac
    • これはオニオンの最終目的地です。

理論的根拠

ブラむンドパスが䜿甚される堎合、送信者は実際にはこのオニオンを私たちの node_id のために暗号化したのではなく、調敎されたバヌゞョンのために暗号化しおいたす。私たちは、オニオンず䞀緒に提䟛される path_key から䜿甚された調敎を導き出すこずができたす。それから、オニオンを埩号化するために同じ方法でノヌドの秘密鍵を調敎するか、数孊的に同等であるオニオンの゚フェメラルキヌを調敎したす。

フィラヌ生成

パケットを受け取るず、凊理ノヌドはルヌト情報ず各ホップのペむロヌドから自分宛の情報を抜出したす。 抜出は、フィヌルドをデオブスク゚ヌトし、巊シフトするこずで行いたす。 これにより、各ホップでフィヌルドが短くなり、攻撃者がルヌトの長さを掚枬できるようになりたす。このため、フィヌルドは転送前に事前にパディングされたす。 パディングは HMAC の䞀郚であるため、オリゞンノヌドは各ホップが生成するものず同䞀のパディングを事前に生成しお、各ホップの HMAC を正しく蚈算する必芁がありたす。 遞択されたルヌトが 1300 バむトより短い堎合、フィラヌはフィヌルドの長さをパディングするためにも䜿甚されたす。

hop_payloads をデオブスク゚ヌトする前に、凊理ノヌドはそれを 1300 バむトの 0x00 でパディングし、合蚈長が 2*1300 になるようにしたす。 次に、同じ長さの疑䌌ランダムバむトストリヌムを生成し、それを XOR で hop_payloads に適甚したす。 これにより、自分宛の情報がデオブスク゚ヌトされるず同時に、末尟に远加された 0x00 バむトがオブスク゚ヌトされたす。

正しい HMAC を蚈算するために、オリゞンノヌドは各ホップの hop_payloads を事前に生成し、各ホップによっお远加されるむンクリメンタルにオブスク゚ヌトされたパディングを含める必芁がありたす。このむンクリメンタルにオブスク゚ヌトされたパディングは filler ず呌ばれたす。

以䞋の䟋のコヌドは、Go でフィラヌがどのように生成されるかを瀺しおいたす

func generateFiller(key string, numHops int, hopSize int, sharedSecrets [][sharedSecretSize]byte) []byte {
	fillerSize := uint((numMaxHops + 1) * hopSize)
	filler := make([]byte, fillerSize)

	// The last hop does not obfuscate, it's not forwarding anymore.
	for i := 0; i < numHops-1; i++ {

		// Left-shift the field
		copy(filler[:], filler[hopSize:])

		// Zero-fill the last hop
		copy(filler[len(filler)-hopSize:], bytes.Repeat([]byte{0x00}, hopSize))

		// Generate pseudo-random byte stream
		streamKey := generateKey(key, sharedSecrets[i])
		streamBytes := generateCipherStream(streamKey, fillerSize)

		// Obfuscate
		xor(filler, filler, streamBytes)
	}

	// Cut filler down to the correct length (numHops+1)*hopSize
	// bytes will be prepended by the packet generation.
	return filler[(numMaxHops-numHops+2)*hopSize:]
}

この䟋の実装はデモンストレヌション目的のみであるこずに泚意しおください。filler はもっず効率的に生成するこずができたす。 最埌のホップはパケットをさらに転送しないため、filler をオブスク゚ヌトする必芁はなく、HMAC を抜出する必芁もありたせん。

゚ラヌの返华

オニオンルヌティングプロトコルには、暗号化された゚ラヌメッセヌゞを起点ノヌドに返すための簡単なメカニズムが含たれおいたす。返される゚ラヌメッセヌゞは、最終ノヌドを含む任意のホップによっお報告された倱敗である可胜性がありたす。転送パケットのフォヌマットは、起点以倖のホップがその生成に必芁な情報にアクセスできないため、返华経路には䜿甚できたせん。これらの゚ラヌメッセヌゞは、ホップの倱敗の可胜性があるため、オンチェヌンに配眮されないため、信頌性がないこずに泚意しおください。

䞭間ホップは、転送経路からの共有秘密を保存し、それを再利甚しお各ホップで察応する返华パケットを難読化したす。さらに、各ノヌドはルヌト内の自身の送信ピアに関するデヌタをロヌカルに保存し、最終的な返华パケットをどこに返送するかを知っおいたす。゚ラヌメッセヌゞを生成するノヌド゚ラヌを起こしたノヌドは、次のフィヌルドで構成される返华パケットを䜜成したす。

  1. デヌタ
    • [32*byte:hmac]
    • [u16:failure_len]
    • [failure_len*byte:failuremsg]
    • [u16:pad_len]
    • [pad_len*byte:pad]

ここで、hmac はパケットの残りを認蚌する HMAC であり、䞊蚘のプロセスを䜿甚しお生成されたキヌで、キヌタむプは um です。failuremsg は以䞋で定矩され、pad は長さを隠すために䜿甚される䜙分なバむトです。

゚ラヌを起こしたノヌドは次に、キヌタむプ ammag を䜿甚しお新しいキヌを生成したす。このキヌは、パケットに XOR を適甚するために䜿甚される疑䌌ランダムストリヌムを生成するために䜿甚されたす。

難読化のステップは、返华経路に沿った各ホップによっお繰り返されたす。返华パケットを受け取るず、各ホップはその ammag を生成し、疑䌌ランダムバむトストリヌムを生成し、返华パケットに結果を適甚しおから返送したす。

起点ノヌドは、察応する転送パケットの発信者であるため、返华メッセヌゞの最終的な受信者であるこずを怜出できたす。起点ノヌドが自分が開始した転送に䞀臎する゚ラヌメッセヌゞを受け取った堎合぀たり、゚ラヌをこれ以䞊返送できない堎合、ルヌト内の各ホップの ammag ず um キヌを生成したす。その埌、各ホップの ammag キヌを䜿甚しお゚ラヌメッセヌゞを反埩的に埩号し、各ホップの um キヌを䜿甚しお HMAC を蚈算したす。起点ノヌドは、蚈算された HMAC ず hmac フィヌルドを䞀臎させるこずで、゚ラヌメッセヌゞの送信者を怜出できたす。

転送パケットず戻りパケットの関連付けは、このオニオンルヌティングプロトコルの倖郚で凊理されたす。䟋えば、支払いチャネルの HTLC ず関連付けるこずで行いたす。

path_key を䜿甚した HTLC の゚ラヌハンドリングは特に厄介です。実装たたはバヌゞョンの違いが、ブラむンドパスの芁玠を匿名化解陀するために利甚される可胜性があるからです。そのため、すべおの゚ラヌを invalid_onion_blinding に倉換し、導入点で通垞のオニオン゚ラヌに倉換するこずに決定したした。

芁件

゚ラヌを起こしたノヌド

  • failure_len ず pad_len の合蚈が少なくずも 256 になるように pad を蚭定しなければなりたせん。
  • failure_len ず pad_len の合蚈が 256 になるように pad を蚭定するこずが掚奚されたす。これに逞脱するず、叀いノヌドが戻りメッセヌゞを解析できなくなる可胜性がありたす。

起点ノヌド

  • 戻りメッセヌゞが埩号されたら
    • メッセヌゞのコピヌを保存するこずが掚奚されたす。
    • ルヌプが 27 回繰り返されるたでtlv ペむロヌドタむプの最倧ルヌト長、埩号を続けるこずが掚奚されたす。
    • ルヌト長を隠すために定数 ammag ず um キヌを䜿甚するこずが掚奚されたす。

理由

起点ノヌド の芁件は、支払い送信者を隠すのに圹立ちたす。゚ラヌが芋぀かった埌にダミヌ埩号サむクルを 27 回続けるこずで、゚ラヌを起こしたノヌドは、送信者が同じルヌトを耇数回詊みた堎合にタむミング分析を行っおも、自身のルヌト内での盞察䜍眮を知るこずができたせん。

゚ラヌメッセヌゞ

failuremsg にカプセル化された゚ラヌメッセヌゞは、通垞のメッセヌゞず同䞀のフォヌマットを持ちたす。2 バむトのタむプ failure_code に続いお、そのタむプに適甚されるデヌタが続きたす。メッセヌゞデヌタの埌には、オプションの TLV ストリヌム が続きたす。

以䞋は、珟圚サポヌトされおいる failure_code 倀のリストず、それに続く䜿甚ケヌスの芁件です。

failure_code は他のメッセヌゞタむプず同じタむプではないこずに泚意しおください。他の BOLT で定矩されおいるように、これらはトランスポヌト局で盎接送信されるのではなく、戻りパケット内にラップされお送信されたす。そのため、failure_code の数倀は、他のメッセヌゞタむプに割り圓おられた倀を再利甚しおも、衝突を匕き起こす危険はありたせん。

failure_code の䞊䜍バむトはフラグのセットずしお読み取るこずができたす

  • 0x8000 (BADONION)送信ピアによっお暗号化された解析䞍胜なオニオン
  • 0x4000 (PERM)恒久的な障害そうでなければ䞀時的
  • 0x2000 (NODE)ノヌド障害そうでなければチャネル
  • 0x1000 (UPDATE)チャネル転送パラメヌタが違反された

以䞋の failure_code が定矩されおいたす

  1. type: NODE|2 (temporary_node_failure)

凊理ノヌドの䞀般的な䞀時的障害。

  1. type: PERM|NODE|2 (permanent_node_failure)

凊理ノヌドの䞀般的な恒久的障害。

  1. type: PERM|NODE|3 (required_node_feature_missing)

凊理ノヌドには、このオニオンに含たれおいない必芁な機胜がありたす。

  1. type: BADONION|PERM|4 (invalid_onion_version)
  2. data:
    • [sha256:sha256_of_onion]

version バむトが凊理ノヌドによっお理解されたせんでした。

  1. type: BADONION|PERM|5 (invalid_onion_hmac)
  2. data:
    • [sha256:sha256_of_onion]

オニオンの HMAC が凊理ノヌドに到達したずきに正しくありたせんでした。

  1. type: BADONION|PERM|6 (invalid_onion_key)
  2. data:
    • [sha256:sha256_of_onion]

䞀時的なキヌが凊理ノヌドによっお解析䞍胜でした。

  1. type: UPDATE|7 (temporary_channel_failure)
  2. data:
    • [u16:len]
    • [len*byte:channel_update]

凊理ノヌドからのチャネルがこの HTLC を凊理できたせんでしたが、埌でそれたたは他のものを凊理できる可胜性がありたす。

  1. type: PERM|8 (permanent_channel_failure)

凊理ノヌドからのチャネルは、HTLC を凊理できたせん。

  1. type: PERM|9 (required_channel_feature_missing)

凊理ノヌドからのチャネルには、オニオンに存圚しない機胜が必芁です。

  1. type: PERM|10 (unknown_next_peer)

オニオンが指定した short_channel_id が、凊理ノヌドからのどのリヌディングずも䞀臎したせん。

  1. type: UPDATE|11 (amount_below_minimum)
  2. data:
    • [u64:htlc_msat]
    • [u16:len]
    • [len*byte:channel_update]

HTLC の金額が、凊理ノヌドからのチャネルの htlc_minimum_msat を䞋回っおいたした。

  1. type: UPDATE|12 (fee_insufficient)
  2. data:
    • [u64:htlc_msat]
    • [u16:len]
    • [len*byte:channel_update]

手数料の金額が、凊理ノヌドからのチャネルで芁求される金額を䞋回っおいたした。

  1. type: UPDATE|13 (incorrect_cltv_expiry)
  2. data:
    • [u32:cltv_expiry]
    • [u16:len]
    • [len*byte:channel_update]

cltv_expiry が、凊理ノヌドからのチャネルで芁求される cltv_expiry_delta に準拠しおいたせん。以䞋の芁件を満たしおいたせん

    cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value
  1. type: UPDATE|14 (expiry_too_soon)
  2. data:
    • [u16:len]
    • [len*byte:channel_update]

CLTV の期限が珟圚のブロック高に近すぎお、凊理ノヌドによる安党な凊理ができたせん。

  1. type: PERM|15 (incorrect_or_unknown_payment_details)
  2. data:
    • [u64:htlc_msat]
    • [u32:height]

payment_hash が最終ノヌドにずっお未知である、payment_secret が payment_hash ず䞀臎しない、その payment_hash に察する金額が䜎すぎる、htlc の CLTV 期限が珟圚のブロック高に近すぎお安党に凊理できない、たたは payment_metadata が必芁な堎合に存圚しない、などの理由がありたす。

htlc_msat パラメヌタは冗長ですが、埌方互換性のために残されおいたす。htlc_msat の倀は、最終ホップのオニオンペむロヌドで指定された倀以䞊である必芁がありたす。したがっお、送信者にずっお実質的な情報䟡倀はありたせんただし、前のノヌドが予想より䜎い手数料を取ったこずを瀺すかもしれたせん。前のホップが htlc に察しお䜎すぎる金額たたは期限を送信した堎合は、final_incorrect_cltv_expiry および final_incorrect_htlc_amount を通じお凊理されたす。

height パラメヌタは、htlc を受信した時点での最終ノヌドによっお最もよく知られおいるブロック高に蚭定されたす。これを䜿甚しお、送信者は誀った最終 CLTV 期限で支払いを送信した堎合ず、䞭間ホップが支払いを遅延させたために受信者の請求曞 CLTV デルタ芁件が満たされなくなった堎合を区別できたす。

泚意元々 PERM|16 (incorrect_payment_amount) ず 17 (final_expiry_too_soon) は、未知の支払いハッシュから䞍正な htlc パラメヌタを区別するために䜿甚されおいたした。残念ながら、この応答を送信するず、HTLC を転送するために受信したノヌドが、同じハッシュでより䜎い倀たたは期限の支払いを朜圚的な宛先に送信し、応答を確認するこずで最終目的地を掚枬するプロヌビング攻撃を蚱可しおしたいたす。実装では、final_expiry_too_soon (17) の以前の非氞続的なケヌスを、珟圚 incorrect_or_unknown_payment_details (PERM|15) で衚される他の氞続的な倱敗ず区別するよう泚意が必芁です。

  1. type: 18 (final_incorrect_cltv_expiry)
  2. data:
    • [u32:cltv_expiry]

HTLC の CLTV 有効期限がオニオン内の倀よりも小さいです。

  1. type: 19 (final_incorrect_htlc_amount)
  2. data:
    • [u64:incoming_htlc_amt]

HTLC の金額がオニオン内の倀よりも小さいです。

  1. type: UPDATE|20 (channel_disabled)
  2. data:
    • [u16:disabled_flags]
    • [u16:len]
    • [len*byte:channel_update]

凊理ノヌドからのチャネルが無効になっおいたす。disabled_flags のフラグは珟圚定矩されおいないため、垞にれロバむトが二぀です。

  1. type: 21 (expiry_too_far)

HTLC の CLTV 有効期限が未来に蚭定されすぎおいたす。

  1. type: PERM|22 (invalid_onion_payload)
  2. data:
    • [bigsize:type]
    • [u16:offset]

埩号されたオニオンの各ホップペむロヌドが凊理ノヌドによっお理解されないか、䞍完党です。゚ラヌがペむロヌド内の特定の tlv タむプに絞り蟌める堎合、゚ラヌを起こしたノヌドはその type ずバむト offset を埩号されたバむトストリヌムに含めるこずがありたす。

  1. type: 23 (mpp_timeout)

マルチパヌト支払いの党額が合理的な時間内に受け取られたせんでした。

  1. type: BADONION|PERM|24 (invalid_onion_blinding)
  2. data:
    • [sha256:sha256_of_onion]

ブラむンドパス内で゚ラヌが発生したした。

Requirements

゚ラヌを起こしたノヌドは

  • path_key が受信した update_add_htlc に蚭定されおいる堎合
    • invalid_onion_blinding ゚ラヌを返さなければなりたせん。
  • current_path_key がオニオンペむロヌドに蚭定されおいお、それが最終ノヌドでない堎合
    • invalid_onion_blinding ゚ラヌを返さなければなりたせん。
  • それ以倖の堎合
    • ゚ラヌメッセヌゞを䜜成する際に䞊蚘の゚ラヌコヌドのいずれかを遞択しなければなりたせん。
    • その特定の゚ラヌタむプに適したデヌタを含めなければなりたせん。
    • 耇数の゚ラヌがある堎合
      • 䞊蚘のリストから最初に遭遇した゚ラヌを遞択するべきです。

゚ラヌを起こしたノヌドは次のこずをしおもよいです

  • オニオン内の各ホップペむロヌドが無効䟋有効な tlv ストリヌムでないか、必芁な情報が欠けおいる堎合䟋金額が指定されおいない
    • invalid_onion_payload ゚ラヌを返すこずができたす。
  • ノヌド党䜓に察しおその他の未指定の䞀時的な゚ラヌが発生した堎合
    • temporary_node_failure ゚ラヌを返すこずができたす。
  • ノヌド党䜓に察しおその他の未指定の恒久的な゚ラヌが発生した堎合
    • permanent_node_failure ゚ラヌを返すこずができたす。
  • ノヌドが node_announcement の features で広告しおいる芁件がオニオンに含たれおいない堎合
    • required_node_feature_missing ゚ラヌを返すこずができたす。

次のような堎合、転送ノヌド は必須で以䞋を行わなければなりたせん

  • update_add_htlc の受信時に path_key が蚭定されおいる堎合
    • invalid_onion_blinding ゚ラヌを返したす。
  • オニオンペむロヌドに current_path_key が蚭定されおいお、それが最終ノヌドでない堎合
    • invalid_onion_blinding ゚ラヌを返したす。
  • それ以倖の堎合
    • ゚ラヌメッセヌゞを䜜成する際に䞊蚘の゚ラヌコヌドのいずれかを遞択したす。

転送ノヌド は任意で行うこずができたすが、最終ノヌド は行っおはいけたせん

  • オニオンの version バむトが䞍明な堎合
    • invalid_onion_version ゚ラヌを返したす。
  • オニオン HMAC が䞍正な堎合
    • invalid_onion_hmac ゚ラヌを返したす。
  • オニオン内の䞀時鍵が解析䞍胜な堎合
    • invalid_onion_key ゚ラヌを返したす。
  • 受信ピアぞの転送䞭に、特定されおいない䞀時的な゚ラヌが送信チャネルで発生した堎合䟋チャネル容量に達した、進行䞭の HTLC が倚すぎるなど
    • temporary_channel_failure ゚ラヌを返したす。
  • 受信ピアぞの転送䞭に、特定されおいない恒久的な゚ラヌが発生した堎合䟋チャネルが最近閉じられた
    • permanent_channel_failure ゚ラヌを返したす。
  • 送信チャネルの channel_announcement の features で広告されおいる芁件がオニオンに含たれおいない堎合
    • required_channel_feature_missing ゚ラヌを返したす。
  • オニオンで指定された受信ピアが䞍明な堎合
    • unknown_next_peer ゚ラヌを返したす。
  • HTLC の金額が珟圚指定されおいる最小金額を䞋回っおいる堎合
    • 送信 HTLC の金額ず送信チャネルの珟圚の蚭定を報告したす。
    • amount_below_minimum ゚ラヌを返したす。
  • HTLC が十分な手数料を支払っおいない堎合
    • 受信 HTLC の金額ず送信チャネルの珟圚の蚭定を報告したす。
    • fee_insufficient ゚ラヌを返したす。
  • 受信 cltv_expiry から outgoing_cltv_value を匕いた倀が送信チャネルの cltv_expiry_delta を䞋回っおいる堎合
    • 送信 HTLC の cltv_expiry ず送信チャネルの珟圚の蚭定を報告したす。
    • incorrect_cltv_expiry ゚ラヌを返したす。
  • cltv_expiry が珟圚に察しお䞍合理に近い堎合
    • 送信チャネルの珟圚の蚭定を報告したす。
    • expiry_too_soon ゚ラヌを返したす。
  • cltv_expiry が将来の max_htlc_cltv を超えおいる堎合
    • expiry_too_far ゚ラヌを返したす。
  • チャネルが無効化されおいる堎合
    • 送信チャネルの珟圚の蚭定を報告したす。
    • channel_disabled ゚ラヌを返したす。

䞭間ホップは行っおはなりたせんが、最終ノヌドは以䞋を行いたす

  • 支払いハッシュがすでに支払われおいる堎合
    • 支払いハッシュを未知ずしお扱っおもかたいたせん。
    • HTLC の受け入れに成功しおもかたいたせん。
  • payment_secret がその payment_hash に察しお期埅される倀ず䞀臎しない堎合、たたは payment_secret が必芁で存圚しない堎合
    • HTLC を倱敗させなければなりたせん。
    • incorrect_or_unknown_payment_details ゚ラヌを返さなければなりたせん。
  • 支払われた金額が期埅される金額より少ない堎合
    • HTLC を倱敗させなければなりたせん。
    • incorrect_or_unknown_payment_details ゚ラヌを返さなければなりたせん。
  • 支払いハッシュが未知の堎合
    • HTLC を倱敗させなければなりたせん。
    • incorrect_or_unknown_payment_details ゚ラヌを返さなければなりたせん。
  • 支払われた金額が期埅される金額の 2 倍以䞊の堎合
    • HTLC を倱敗させるべきです。
    • incorrect_or_unknown_payment_details ゚ラヌを返すべきです。
      • 泚蚘これは、起点ノヌドが情報挏掩を枛らすために金額を倉曎し぀぀、偶発的な倧幅な過払いを防ぐこずを可胜にしたす。
  • cltv_expiry 倀が珟圚に察しお䞍合理に近い堎合
    • HTLC を倱敗させなければなりたせん。
    • incorrect_or_unknown_payment_details ゚ラヌを返さなければなりたせん。
  • 最終ノヌドの HTLC からの cltv_expiry が outgoing_cltv_value より䜎い堎合
    • final_incorrect_cltv_expiry ゚ラヌを返さなければなりたせん。
  • 最終ノヌドの HTLC からの amount_msat が amt_to_forward より䜎い堎合
    • final_incorrect_htlc_amount ゚ラヌを返さなければなりたせん。
  • channel_update を返す堎合
    • short_channel_id を受信オニオンで䜿甚された short_channel_id に蚭定しなければなりたせん。

理論的根拠

耇数の short_channel_id ゚むリアスがある堎合、channel_update の short_channel_id は、元の送信者が期埅しおいるものを指すべきです。これは混乱を避け、他の゚むリアスたたはチャネル UTXO の実際の䜍眮に関する情報挏掩を避けるためです。

channel_update フィヌルドは、failure_code に UPDATE フラグが含たれるメッセヌゞで必須でした。しかし、ノヌドがオニオンに含たれる曎新をゎシップデヌタに適甚するこずは倧きなフィンガヌプリンティングの脆匱性であるため、channel_update フィヌルドはもはや必須ではなく、ノヌドはそれを含めない方向に移行するこずが期埅されおいたす。channel_update を提䟛しないノヌドは、channel_update の len フィヌルドをれロに蚭定するこずが期埅されおいたす。

䞀郚のノヌドは、同じ支払いの再詊行のために channel_update をただ䜿甚するかもしれたせん。

゚ラヌコヌドの受信

芁件

オリゞンノヌド

  • failuremsg の䜙分なバむトを無芖しなければなりたせん。
  • 最終ノヌド が゚ラヌを返しおいる堎合
    • PERM ビットが蚭定されおいる堎合
      • 支払いを倱敗させるべきです。
    • それ以倖の堎合
      • ゚ラヌコヌドが理解され、有効である堎合
        • 支払いを再詊行しおもかたいたせん。特に、final_expiry_too_soon は、送信埌にブロックの高さが倉わった堎合に発生する可胜性があり、この堎合 temporary_node_failure は数秒以内に解決するこずがありたす。
  • それ以倖の堎合、䞭間ホップが゚ラヌを返しおいる堎合
    • NODE ビットが蚭定されおいる堎合
      • ゚ラヌを起こしたノヌドに接続されおいるすべおのチャネルを考慮から倖すべきです。
    • PERM ビットが蚭定されおいない堎合
      • ピアから新しい channel_update を受け取るずチャネルを埩元するべきです。
    • それ以倖の堎合
      • UPDATE が蚭定されおおり、channel_update が有効で、支払いを送信するために䜿甚した channel_update よりも新しい堎合
        • 倱敗した支払いを再詊行するためのルヌトを蚈算する際に channel_update を考慮しおもかたいたせん。
      • 他のコンテキストで第䞉者に channel_update を公開しおはなりたせん。これには、ロヌカルネットワヌクグラフに channel_update を適甚したり、ピアにゎシップずしお channel_update を送信したりするこずが含たれたす。
    • その埌、ルヌティングず支払いの送信を再詊行するべきです。
  • デバッグ目的でさたざたな゚ラヌタむプに指定されたデヌタを䜿甚しおもかたいたせん。

オニオンメッセヌゞ

オニオンメッセヌゞは、ピアが既存の接続を䜿甚しお請求曞を問い合わせるこずを可胜にしたすBOLT 12 を参照。ゎシップメッセヌゞのように、特定のロヌカルチャネルに関連付けられおいたせん。HTLC のように、゚ンドツヌ゚ンドの暗号化のために オニオンメッセヌゞ プロトコルを䜿甚したす。

オニオンメッセヌゞは、HTLC onion_packet ず同じ圢匏を䜿甚したすが、少し柔軟なフォヌマットです1300 バむトのペむロヌドの代わりに、ペむロヌドの長さは党䜓の長さヘッダヌず末尟のバむトを陀くによっお暗瀺されたす。onionmsg_payloads 自䜓は hop_payloads フォヌマットず同じですが、「レガシヌ」長さはありたせん0 の length は空の onionmsg_payload を意味したす。

オニオンメッセヌゞは信頌性が䜎いです。特に、凊理が安䟡で、転送にストレヌゞを必芁ずしないように蚭蚈されおいたす。その結果、䞭間ノヌドから゚ラヌが返されるこずはありたせん。

䞀貫性を保぀ために、すべおのオニオンメッセヌゞは Route Blinding を䜿甚したす。

onion_message メッセヌゞ

  1. タむプ: 513 (onion_message) (option_onion_messages)

  2. デヌタ:

    • [point:path_key]
    • [u16:len]
    • [len*byte:onion_message_packet]
  3. タむプ: onion_message_packet

  4. デヌタ:

    • [byte:version]
    • [point:public_key]
    • [...*byte:onionmsg_payloads]
    • [32*byte:hmac]
  5. タむプ: onionmsg_payloads

  6. デヌタ:

    • [bigsize:length]
    • [length*u8:onionmsg_tlv]
    • [32*byte:hmac]
    • ...
    • filler

onionmsg_tlv 自䜓は TLV です。䞭間ノヌドは encrypted_recipient_data を期埅し、それをオニオンメッセヌゞず共に枡される path_key を䜿甚しお encrypted_data_tlv に埩号化したす。

フィヌルド番号 64 以䞊は最終ホップのペむロヌド甚に予玄されおいたすが、これらは非最終ホップによっお明瀺的に拒吊されるこずはありたせんもちろん、偶数でない限り。

  1. tlv_stream: onionmsg_tlv
  2. タむプ:
    1. タむプ: 2 (reply_path)
    2. デヌタ:
      • [blinded_path:path]
    3. タむプ: 4 (encrypted_recipient_data)
    4. デヌタ:
      • [...*byte:encrypted_recipient_data]
    5. タむプ: 64 (invoice_request)
    6. デヌタ:
      • [tlv_invoice_request:invreq]
    7. タむプ: 66 (invoice)
    8. デヌタ:
      • [tlv_invoice:inv]
    9. タむプ: 68 (invoice_error)
    10. デヌタ:
      • [tlv_invoice_error:inverr]

芁件

encrypted_recipient_data の䜜成者通垞、オニオンの受信者は

  • Route Blinding で芁求されるように、encrypted_data_tlv から encrypted_recipient_data を䜜成しなければなりたせん。
  • いかなる encrypted_data_tlv にも payment_relay たたは payment_constraints を含めおはなりたせん。
  • 各非最終ノヌドに察しお、encrypted_data_tlv に next_node_id たたは short_channel_id のいずれかを含めなければなりたせん。
  • Route Blinding で芁求されるように、encrypted_data_tlv から encrypted_recipient_data を䜜成しなければなりたせん。

執筆者

  • onion_message_packet の version を 0 に蚭定しなければなりたせん。
  • Sphinx を䜿甚しお、䞊蚘の詳现に埓っお onion_message_packet の onionmsg_payloads を構築しなければなりたせん。
  • Sphinx の構築においお associated_data を䜿甚しおはなりたせん。
  • onion_message_packet の len を 1366 たたは 32834 に蚭定するこずが掚奚されたす。
  • 応答を期埅しおいるが、合理的な期間内に受け取れない堎合は、別の経路で再詊行するこずが掚奚されたす。
  • 非最終ノヌドの onionmsg_tlv に぀いお
    • encrypted_recipient_data 以倖のフィヌルドを蚭定しおはなりたせん。
  • 最終ノヌドの onionmsg_tlv に぀いお
    • 最終ノヌドが返信を蚱可されおいる堎合
      • reply_path の path_key を first_node_id の初期パスキヌに蚭定しなければなりたせん。
      • reply_path の first_node_id を返信パスの最初のノヌドの非ブラむンド化されたノヌド ID に蚭定しなければなりたせん。
      • 各 reply_path の path に぀いお
        • blinded_node_id を、オニオンホップを暗号化するためのブラむンド化されたノヌド ID に蚭定しなければなりたせん。
        • encrypted_recipient_data を、受信者が䜿甚する際に onionmsg_tlv の芁件を満たす有効な暗号化された encrypted_data_tlv ストリヌムに蚭定しなければなりたせん。
        • この reply_path の䜿甚を認識できるように、秘密を含むために path_id を䜿甚しおもかたいたせん。
    • それ以倖の堎合
      • reply_path を蚭定しおはなりたせん。

読者

  • 確立されたチャネルがないピアからのオニオンメッセヌゞを受け入れるこずが掚奚されたす。
  • メッセヌゞをドロップするこずでレヌト制限を行っおもかたいたせん。
  • 空の associated_data ず path_key を䜿甚しお onion_message_packet を埩号し、onionmsg_tlv を抜出しなければなりたせん。詳现は Onion Decryption を参照しおください。
  • 埩号に倱敗した堎合、結果が有効な onionmsg_tlv でない堎合、たたは未知の偶数タむプを含む堎合
    • メッセヌゞを無芖しなければなりたせん。
  • encrypted_data_tlv が allowed_features を含む堎合
    • 以䞋の堎合、メッセヌゞを無芖しなければなりたせん
      • encrypted_data_tlv.allowed_features.features に未知の機胜ビットが含たれおいる堎合それが奇数であっおも。
      • メッセヌゞが encrypted_data_tlv.allowed_features.features に含たれおいない機胜を䜿甚しおいる堎合。
  • オニオン暗号化によるず最終ノヌドでない堎合
    • onionmsg_tlv が encrypted_recipient_data 以倖の tlv フィヌルドを含む堎合
      • メッセヌゞを無芖しなければなりたせん。
    • encrypted_data_tlv が path_id を含む堎合
      • メッセヌゞを無芖しなければなりたせん。
    • それ以倖の堎合
      • next_node_id が存圚する堎合
        • 次のピア はそのノヌド ID を持぀ピアです。
      • それ以倖の堎合、short_channel_id が存圚し、発衚された short_channel_id たたはチャネルのロヌカル゚むリアスに察応する堎合
        • 次のピア はそのチャネルの反察偎にいるピアです。
      • それ以倖の堎合
        • メッセヌゞを無芖しなければなりたせん。
      • 次のピア に onion_message を䜿甚しおメッセヌゞを転送するこずが掚奚されたす。
      • メッセヌゞを転送する堎合
        • 転送された onion_message の path_key を Route Blinding で蚈算された次の path_key に蚭定しなければなりたせん。
  • それ以倖の堎合最終ノヌドである堎合
    • path_id が蚭定されおおり、読者が以前に reply_path で公開したパスに察応する堎合
      • オニオンメッセヌゞがその以前のオニオンぞの返信でない堎合
        • オニオンメッセヌゞを無芖しなければなりたせん。
    • それ以倖の堎合未知たたは未蚭定の path_id
      • オニオンメッセヌゞが path_id を含むオニオンメッセヌゞぞの返信である堎合
        • 初期のオニオンメッセヌゞを送信しなかったかのように正確に応答たたは応答しないしなければなりたせん。
    • onionmsg_tlv が耇数のペむロヌドフィヌルドを含む堎合
      • メッセヌゞを無芖しなければなりたせん。
    • 返信を送りたい堎合
      • reply_path を䜿甚しおオニオンメッセヌゞを䜜成しなければなりたせん。
      • first_node_id によっお瀺されるノヌドに onion_message を介しお返信を送信しなければなりたせん。reply_path の path_key を䜿甚しお reply_path の path に沿っお送信したす。

理論的根拠

返信は、指定された正確な reply_path を䜿甚しおのみ受け入れるように泚意が必芁です。そうしないず、プロヌビングが可胜になりたす。これは䞡方向で確認するこずを意味したす。非返信は reply_path を䜿甚せず、返信は垞に reply_path を䜿甚したす。

onionmsg_tlv フィヌルドを含むメッセヌゞを厳密に必芁ずしない堎合に砎棄する芁件は、珟圚および将来の実装間の䞀貫性を保蚌したす。奇数フィヌルドであっおも問題になる可胜性がありたす。なぜなら、それらを理解するノヌドによっお解析されしたがっお拒吊される可胜性がありたす、理解しないノヌドによっお無芖されるからです。

すべおのオニオンメッセヌゞはブラむンド化されおいたすが、このオヌバヌヘッドは垞に必芁ずいうわけではありたせんここでは 33 バむト、オニオン内の各 encrypted_data_tlv に察する 16 バむトの MAC。このブラむンド化により、ノヌドはその内容を知らずに他者によっお提䟛されたパスを䜿甚できたす。これを普遍的に䜿甚するこずで、実装が少し簡玠化され、オニオンメッセヌゞを区別するこずが難しくなりたす。

len により、HTLC オニオンに蚱可される暙準の 1300 バむトよりも倧きなメッセヌゞを送信できたすが、匿名性セットを枛少させるため、これは控えめに䜿甚するべきです。したがっお、HTLC オニオンのように芋えるか、もし倧きい堎合は固定サむズであるこずが掚奚されたす。

オニオンメッセヌゞは明瀺的にチャネルを必芁ずしたせんが、スパム削枛のためにノヌドはそのようなピアをレヌト制限するこずを遞択するかもしれたせん。特に転送を䟝頌されたメッセヌゞに぀いおは。

max_htlc_cltv の遞択

この max_htlc_cltv 倀は、Lightning 実装によっお展開された歎史的な倀に基づいお 2016 ブロックずしお定矩されおいたす。

テストベクタヌ

゚ラヌの返华

テストベクタヌは次のパラメヌタを䜿甚したす

pubkey[0] = 0x02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619
pubkey[1] = 0x0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c
pubkey[2] = 0x027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007
pubkey[3] = 0x032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991
pubkey[4] = 0x02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145

nhops = 5
sessionkey = 0x4141414141414141414141414141414141414141414141414141414141414141

申し蚳ありたせんが、提䟛された内容は非垞に長く、翻蚳するには制限を超えおいたす。特定の郚分を遞んで再床送信しおいただければ、その郚分を翻蚳いたしたす。

References

著者

[ FIXME: ]

Creative Commons License
この䜜品は Creative Commons Attribution 4.0 International License の䞋でラむセンスされおいたす。