mirror of
https://github.com/lightning/bolts.git
synced 2024-11-19 01:50:03 +01:00
Merge pull request #1182 from rustyrussell/clarify-onions-part-2
Clarify onions part 2: a bit deeper rework
This commit is contained in:
commit
22b9c87453
@ -50,7 +50,8 @@ A node:
|
|||||||
* [Packet Structure](#packet-structure)
|
* [Packet Structure](#packet-structure)
|
||||||
* [Payload Format](#payload-format)
|
* [Payload Format](#payload-format)
|
||||||
* [Basic Multi-Part Payments](#basic-multi-part-payments)
|
* [Basic Multi-Part Payments](#basic-multi-part-payments)
|
||||||
* [Route Blinding](#route-blinding)
|
* [Route Blinding](#route-blinding)
|
||||||
|
* [Inside encrypted_recipient_data: encrypted_data_tlv](Inside-encrypted_recipient_data-encrypted_data_tlv)
|
||||||
* [Accepting and Forwarding a Payment](#accepting-and-forwarding-a-payment)
|
* [Accepting and Forwarding a Payment](#accepting-and-forwarding-a-payment)
|
||||||
* [Payload for the Last Node](#payload-for-the-last-node)
|
* [Payload for the Last Node](#payload-for-the-last-node)
|
||||||
* [Non-strict Forwarding](#non-strict-forwarding)
|
* [Non-strict Forwarding](#non-strict-forwarding)
|
||||||
@ -203,7 +204,7 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]
|
|||||||
* [`tu64`:`total_msat`]
|
* [`tu64`:`total_msat`]
|
||||||
1. type: 10 (`encrypted_recipient_data`)
|
1. type: 10 (`encrypted_recipient_data`)
|
||||||
2. data:
|
2. data:
|
||||||
* [`...*byte`:`encrypted_data`]
|
* [`...*byte`:`encrypted_recipient_data`]
|
||||||
1. type: 12 (`current_path_key`)
|
1. type: 12 (`current_path_key`)
|
||||||
2. data:
|
2. data:
|
||||||
* [`point`:`path_key`]
|
* [`point`:`path_key`]
|
||||||
@ -435,32 +436,166 @@ otherwise meets the amount criterion (eg. some other failure, or
|
|||||||
invoice timeout), however if it were to fulfill only some of them,
|
invoice timeout), however if it were to fulfill only some of them,
|
||||||
intermediary nodes could simply claim the remaining ones.
|
intermediary nodes could simply claim the remaining ones.
|
||||||
|
|
||||||
### Route Blinding
|
## Route Blinding
|
||||||
|
|
||||||
Nodes receiving onion packets may hide their identity from senders by
|
1. subtype: `blinded_path`
|
||||||
"blinding" an arbitrary amount of hops at the end of an onion path.
|
2. data:
|
||||||
|
* [`point`:`first_node_id`]
|
||||||
|
* [`point`:`first_path_key`]
|
||||||
|
* [`byte`:`num_hops`]
|
||||||
|
* [`num_hops*blinded_path_hop`:`path`]
|
||||||
|
|
||||||
When using route blinding, nodes find a route to themselves from a given
|
1. subtype: `blinded_path_hop`
|
||||||
"introduction node" and initial "path key". They then use ECDH with
|
2. data:
|
||||||
each node in that route to create a "blinded" node ID and an encrypted blob
|
* [`point`:`blinded_node_id`]
|
||||||
(`encrypted_data`) for each one of the blinded nodes.
|
* [`u16`:`enclen`]
|
||||||
|
* [`enclen*byte`:`encrypted_recipient_data`]
|
||||||
|
|
||||||
They communicate this blinded route and the encrypted blobs to the sender.
|
A blinded path consists of:
|
||||||
The sender finds a route to the introduction node and extends it with the
|
1. an initial introduction point (`first_node_id`)
|
||||||
blinded route provided by the recipient. The sender includes the encrypted
|
2. an initial key to share a secret with the first node_id (`first_path_key`)
|
||||||
blobs in the corresponding onion payloads: they allow nodes in the blinded
|
3. a series of tweaked node ids (`path.blinded_node_id`)
|
||||||
part of the route to "unblind" the next node and correctly forward the packet.
|
4. a series of binary blobs encrypted to the nodes (`path.encrypted_recipient_data`)
|
||||||
|
to tell them the next hop.
|
||||||
|
|
||||||
Note that there are two ways for the sender to reach the introduction
|
For example, Dave wants Alice to reach him via public node Bob then
|
||||||
point: one is to create a normal (unblinded) payment, and place the
|
Carol. He creates a chain of public keys ("path_keys") for Bob, Carol
|
||||||
initial blinding point in `current_path_key` along with the
|
and finally himself, so he can share a secret with each of them. These
|
||||||
`encrypted_data` in the onion payload for the introduction point to
|
keys are a simple chain, so each node can derive the next `path_key` without
|
||||||
start the blinded path. The second way is to create a blinded path to
|
having to be told explicitly.
|
||||||
the introduction point, set `next_path_key_override` inside the
|
|
||||||
`encrypted_data_tlv` on the hop prior to the introduction point to the
|
|
||||||
initial blinding point, and have it sent to the introduction node.
|
|
||||||
|
|
||||||
The `encrypted_data` is a TLV stream, encrypted for a given blinded node, that
|
From these shared secrets, Dave creates and encrypts three `encrypted_data_tlv`s:
|
||||||
|
1. encrypted_data_bob: For Bob to tell him to forward to Carol
|
||||||
|
2. encrypted_data_carol: For Carol to tell her to forward to him
|
||||||
|
3. encrypted_data_dave: For himself to indicate the path was used, and any metadata he wants.
|
||||||
|
|
||||||
|
To mask the node ids, he also derives three blinding factors from the
|
||||||
|
shared secrets, which turn Bob into Bob', Carol into Carol' and Dave
|
||||||
|
into Dave'.
|
||||||
|
|
||||||
|
So this is the `blinded_path` he hands to Alice.
|
||||||
|
|
||||||
|
1. `first_node_id`: Bob
|
||||||
|
2. `first_path_key`: the first path key for Bob
|
||||||
|
3. `path`: [Bob', encrypted_data_bob], [Carol', encrypted_data_carol], [Dave', encrypted_data_dave]
|
||||||
|
|
||||||
|
There are two different ways for Alice to construct an onion which gets to Bob (since he's probably not a direct peer of hers) which are described in the requirements below.
|
||||||
|
|
||||||
|
But after Bob the path is always the same: he will send Carol the `path_key` he derived, along with the onion. She will use the `path_key` to derive the tweak for the onion (which Alice encrypted for Carol' not Carol) so she can decrypt it, and also to derive the key to decrypt `encrypted_data_tlv` which will tell her to forward to Dave (and possibly additional restrictions Dave specified).
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
Note that the creator of the blinded path (i.e. the recipient) is creating it for the sender to use to create an onion, and for the intermediate nodes to read the instructions, hence there are two reader sections here.
|
||||||
|
|
||||||
|
The writer of a `blinded_path`:
|
||||||
|
|
||||||
|
- MUST create a viable path to itself ($`N_r`$) i.e. $`N_0 \rightarrow N_1 \rightarrow ... \rightarrow N_r`$.
|
||||||
|
- MUST set `first_node_id` to $`N_0`$
|
||||||
|
- MUST create a series of ECDH shared secrets for each node in the route using the following algorithm:
|
||||||
|
- $`e_0 \leftarrow \{0;1\}^{256}`$ ($`e_0`$ SHOULD be obtained via CSPRNG)
|
||||||
|
- $`E_0 = e_0 \cdot G`$
|
||||||
|
- For every node in the route:
|
||||||
|
- let $`N_i = k_i * G`$ be the `node_id` ($`k_i`$ is $`N_i`$'s private key)
|
||||||
|
- $`ss_i = SHA256(e_i * N_i) = SHA256(k_i * E_i)`$ (ECDH shared secret known only by $`N_r`$ and $`N_i`$)
|
||||||
|
- $`rho_i = HMAC256(\text{"rho"}, ss_i)`$ (key used to encrypt `encrypted_recipient_data` for $`N_i`$ by $`N_r`$)
|
||||||
|
- $`e_{i+1} = SHA256(E_i || ss_i) * e_i`$ (ephemeral private path key, only known by $`N_r`$)
|
||||||
|
- $`E_{i+1} = SHA256(E_i || ss_i) * E_i`$ (`path_key`. NB: $`N_i`$ MUST NOT learn $`e_i`$)
|
||||||
|
- MUST set `first_path_key` to $`E_0`$
|
||||||
|
- MUST create a series of blinded node IDs $`B_i`$ for each node using the following algorithm:
|
||||||
|
- $`B_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * N_i`$ (blinded `node_id` for $`N_i`$, private key known only by $`N_i`$)
|
||||||
|
- MUST set `blinded_node_id` for each `blinded_path_hop` in `path` to $`B_i`$
|
||||||
|
- MAY replace $`E_{i+1}`$ with a different value, but if it does:
|
||||||
|
- MUST set `encrypted_data_tlv[i].next_path_key_override` to $`E_{i+1}`$
|
||||||
|
- MAY store private data in `encrypted_data_tlv[r].path_id` to verify that the route is used in the right context and was created by them
|
||||||
|
- SHOULD add padding data to ensure all `encrypted_data_tlv[i]` have the same length
|
||||||
|
- MUST encrypt each `encrypted_data_tlv[i]` with ChaCha20-Poly1305 using the corresponding $`rho_i`$ key and an all-zero nonce to produce `encrypted_recipient_data[i]`
|
||||||
|
- MAY add additional "dummy" hops at the end of the path (which it will ignore on receipt) to obscure the path length.
|
||||||
|
|
||||||
|
The reader of the `blinded_path`:
|
||||||
|
- MUST prepend its own onion payloads to reach the `first_node_id`
|
||||||
|
- MUST include the corresponding `encrypted_recipient_data` in each onion payload within `path`
|
||||||
|
- For the first entry in `path`:
|
||||||
|
- if it is sending a payment:
|
||||||
|
- SHOULD create an unblinded onion payment to `first_node_id`, and include `first_path_key` as `current_path_key`.
|
||||||
|
- otherwise:
|
||||||
|
- MUST encrypt the first blinded path onion to the first `blinded_node_id`.
|
||||||
|
- MUST set `next_path_key_override` in the prior onion payload to `first_path_key`.
|
||||||
|
- For each successive entry in `path`:
|
||||||
|
- MUST encrypt the onion to the corresponding `blinded_node_id`.
|
||||||
|
|
||||||
|
The reader of the `encrypted_recipient_data`:
|
||||||
|
|
||||||
|
- MUST compute:
|
||||||
|
- $`ss_i = SHA256(k_i * E_i)`$ (standard ECDH)
|
||||||
|
- $`b_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * k_i`$
|
||||||
|
- $`rho_i = HMAC256(\text{"rho"}, ss_i)`$
|
||||||
|
- MUST decrypt the `encrypted_recipient_data` field using $`rho_i`$ as a key using ChaCha20-Poly1305 and an all-zero nonce key.
|
||||||
|
- If the `encrypted_recipient_data` field is missing, cannot be decrypted into an `encrypted_data_tlv` or contains unknown even fields:
|
||||||
|
- MUST return an error
|
||||||
|
- If the `encrypted_data_tlv` contains a `next_path_key_override`:
|
||||||
|
- MUST use it as the next `path_key`.
|
||||||
|
- Otherwise:
|
||||||
|
- MUST use $`E_{i+1} = SHA256(E_i || ss_i) * E_i`$ as the next `path_key`
|
||||||
|
- MUST forward the onion and include the next `path_key` in the lightning
|
||||||
|
message for the next node
|
||||||
|
- If it is the final recipient:
|
||||||
|
- MUST ignore the message if the `path_id` does not match the blinded route it
|
||||||
|
created for this purpose
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Route blinding is a lightweight technique to provide recipient anonymity.
|
||||||
|
It's more flexible than rendezvous routing because it simply replaces the public
|
||||||
|
keys of the nodes in the route with random public keys while letting senders
|
||||||
|
choose what data they put in the onion for each hop. Blinded routes are also
|
||||||
|
reusable in some cases (e.g. onion messages).
|
||||||
|
|
||||||
|
Each node in the blinded route needs to receive $`E_i`$ to be able to decrypt
|
||||||
|
the onion and the `encrypted_recipient_data` payload.
|
||||||
|
|
||||||
|
When concatenating two blinded routes generated by different nodes, the
|
||||||
|
last node of the first route needs to know the first `path_key` of the
|
||||||
|
second route: the `next_path_key_override` field must be used to transmit this
|
||||||
|
information. In theory this method could be used for payments (not just
|
||||||
|
onion messages), but we recommend using an unblinded path to reach the
|
||||||
|
`first_node_id` and using `current_path_key` there: this means that the
|
||||||
|
node can tell it is being used as an introductory point, but also does
|
||||||
|
not require blinded path support on the nodes to reach that point, and
|
||||||
|
gives meaningful errors on the unblinded part of the payment.
|
||||||
|
|
||||||
|
The final recipient must verify that the blinded route is used in the right
|
||||||
|
context (e.g. for a specific payment) and was created by them. Otherwise a
|
||||||
|
malicious sender could create different blinded routes to all the nodes that
|
||||||
|
they suspect could be the real recipient and try them until one accepts the
|
||||||
|
message. The recipient can protect against that by storing $`E_r`$ and the
|
||||||
|
context (e.g. a `payment_hash`), and verifying that they match when receiving
|
||||||
|
the onion. Otherwise, to avoid additional storage cost, it can put some private
|
||||||
|
context information in the `path_id` field (e.g. the `payment_preimage`) and
|
||||||
|
verify that when receiving the onion. Note that it's important to use private
|
||||||
|
information in that case, that senders cannot have access to.
|
||||||
|
|
||||||
|
Whenever the introduction point receives a failure from the blinded route, it
|
||||||
|
should add a random delay before forwarding the error. Failures are likely to
|
||||||
|
be probing attempts and message timing may help the attacker infer its distance
|
||||||
|
to the final recipient.
|
||||||
|
|
||||||
|
The `padding` field can be used to ensure that all `encrypted_recipient_data` have the
|
||||||
|
same length. It's particularly useful when adding dummy hops at the end of a
|
||||||
|
blinded route, to prevent the sender from figuring out which node is the final
|
||||||
|
recipient.
|
||||||
|
|
||||||
|
When route blinding is used for payments, the recipient specifies the fees and
|
||||||
|
expiry that blinded nodes should apply to the payment instead of letting the
|
||||||
|
sender configure them. The recipient also adds additional constraints to the
|
||||||
|
payments that can go through that route to protect against probing attacks that
|
||||||
|
would let malicious nodes unblind the identity of the blinded nodes. It should
|
||||||
|
set `payment_constraints.max_cltv_expiry` to restrict the lifetime of a blinded
|
||||||
|
route and reduce the risk that an intermediate node updates its fees and rejects
|
||||||
|
payments (which could be used to unblind nodes inside the route).
|
||||||
|
|
||||||
|
### Inside `encrypted_recipient_data`: `encrypted_data_tlv`
|
||||||
|
|
||||||
|
The `encrypted_recipient_data` is a TLV stream, encrypted for a given blinded node, that
|
||||||
may contain the following TLV fields:
|
may contain the following TLV fields:
|
||||||
|
|
||||||
1. `tlv_stream`: `encrypted_data_tlv`
|
1. `tlv_stream`: `encrypted_data_tlv`
|
||||||
@ -493,111 +628,12 @@ may contain the following TLV fields:
|
|||||||
2. data:
|
2. data:
|
||||||
* [`...*byte`:`features`]
|
* [`...*byte`:`features`]
|
||||||
|
|
||||||
#### Requirements
|
|
||||||
|
|
||||||
A recipient $`N_r`$ creating a blinded route $`N_0 \rightarrow N_1 \rightarrow ... \rightarrow N_r`$ to itself:
|
|
||||||
|
|
||||||
- MUST create a blinded node ID $`B_i`$ for each node using the following algorithm:
|
|
||||||
- $`e_0 \leftarrow \{0;1\}^{256}`$ ($`e_0`$ SHOULD be obtained via CSPRNG)
|
|
||||||
- $`E_0 = e_0 \cdot G`$
|
|
||||||
- For every node in the route:
|
|
||||||
- let $`N_i = k_i * G`$ be the `node_id` ($`k_i`$ is $`N_i`$'s private key)
|
|
||||||
- $`ss_i = SHA256(e_i * N_i) = SHA256(k_i * E_i)`$ (ECDH shared secret known only by $`N_r`$ and $`N_i`$)
|
|
||||||
- $`B_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * N_i`$ (blinded `node_id` for $`N_i`$, private key known only by $`N_i`$)
|
|
||||||
- $`rho_i = HMAC256(\text{"rho"}, ss_i)`$ (key used to encrypt the payload for $`N_i`$ by $`N_r`$)
|
|
||||||
- $`e_{i+1} = SHA256(E_i || ss_i) * e_i`$ (ephemeral private path key, only known by $`N_r`$)
|
|
||||||
- $`E_{i+1} = SHA256(E_i || ss_i) * E_i`$ (`path_key`. NB: $`N_i`$ MUST NOT learn $`e_i`$)
|
|
||||||
- MAY replace $`E_{i+1}`$ with a different value, but if it does:
|
|
||||||
- MUST set `encrypted_data_tlv[i].next_path_key_override` to $`E_{i+1}`$
|
|
||||||
- MAY store private data in `encrypted_data_tlv[r].path_id` to verify that the route is used in the right context and was created by them
|
|
||||||
- SHOULD add padding data to ensure all `encrypted_data_tlv[i]` have the same length
|
|
||||||
- MUST encrypt each `encrypted_data_tlv[i]` with ChaCha20-Poly1305 using the corresponding $`rho_i`$ key and an all-zero nonce to produce `encrypted_recipient_data[i]`
|
|
||||||
- MUST communicate the blinded node IDs $`B_i`$ and `encrypted_recipient_data[i]` to the sender
|
|
||||||
- MUST communicate the real node ID of the introduction point $`N_0`$ to the sender
|
|
||||||
- MUST communicate the first `path_key` $`E_0`$ to the sender
|
|
||||||
|
|
||||||
A reader:
|
|
||||||
|
|
||||||
- If it receives `path_key` ($`E_i`$) from the prior peer:
|
|
||||||
- MUST use $`b_i`$ instead of its private key $`k_i`$ to decrypt the onion.
|
|
||||||
Note that the node may instead tweak the onion ephemeral key with
|
|
||||||
$`HMAC256(\text{"blinded\_node\_id"}, ss_i)`$ which achieves the same result.
|
|
||||||
- Otherwise:
|
|
||||||
- MUST use $`k_i`$ to decrypt the onion, to extract `current_path_key` ($`E_i`$).
|
|
||||||
- MUST compute:
|
|
||||||
- $`ss_i = SHA256(k_i * E_i)`$ (standard ECDH)
|
|
||||||
- $`b_i = HMAC256(\text{"blinded\_node\_id"}, ss_i) * k_i`$
|
|
||||||
- $`rho_i = HMAC256(\text{"rho"}, ss_i)`$
|
|
||||||
- $`E_{i+1} = SHA256(E_i || ss_i) * E_i`$
|
|
||||||
- MUST decrypt the `encrypted_data` field using $`rho_i`$ and use the
|
|
||||||
decrypted fields to locate the next node
|
|
||||||
- If the `encrypted_data` field is missing or cannot be decrypted:
|
|
||||||
- MUST return an error
|
|
||||||
- If `encrypted_data` contains a `next_path_key_override`:
|
|
||||||
- MUST use it as the next `path_key` instead of $`E_{i+1}`$
|
|
||||||
- Otherwise:
|
|
||||||
- MUST use $`E_{i+1}`$ as the next `path_key`
|
|
||||||
- MUST forward the onion and include the next `path_key` in the lightning
|
|
||||||
message for the next node
|
|
||||||
|
|
||||||
The final recipient:
|
|
||||||
|
|
||||||
- MUST compute:
|
|
||||||
- $`ss_r = SHA256(k_r * E_r)`$ (standard ECDH)
|
|
||||||
- $`b_r = HMAC256(\text{"blinded\_node\_id"}, ss_r) * k_r`$
|
|
||||||
- $`rho_r = HMAC256(\text{"rho"}, ss_r)`$
|
|
||||||
- MUST decrypt the `encrypted_data` field using $`rho_r`$
|
|
||||||
- If the `encrypted_data` field is missing or cannot be decrypted:
|
|
||||||
- MUST return an error
|
|
||||||
- MUST ignore the message if the `path_id` does not match the blinded route it
|
|
||||||
created
|
|
||||||
|
|
||||||
#### Rationale
|
#### Rationale
|
||||||
|
|
||||||
Route blinding is a lightweight technique to provide recipient anonymity.
|
Encrypted recipient data is created by the final recipient to give to the
|
||||||
It's more flexible than rendezvous routing because it simply replaces the public
|
sender, containing instructions for the node on how to handle the message (it can also be created by the sender themselves: the node forwarding cannot tell). It's used
|
||||||
keys of the nodes in the route with random public keys while letting senders
|
in both payment onions and onion messages onions. See [Route Blinding](#route-blinding).
|
||||||
choose what data they put in the onion for each hop. Blinded routes are also
|
|
||||||
reusable in some cases (e.g. onion messages).
|
|
||||||
|
|
||||||
Each node in the blinded route needs to receive $`E_i`$ to be able to decrypt
|
|
||||||
the onion and the `encrypted_data` payload. Protocols that use route blinding
|
|
||||||
must specify how this value is propagated between nodes.
|
|
||||||
|
|
||||||
When concatenating two blinded routes generated by different nodes, the
|
|
||||||
last node of the first route needs to know the first `path_key` of the
|
|
||||||
second route: the `next_path_key_override` field must be used to transmit this
|
|
||||||
information.
|
|
||||||
|
|
||||||
The final recipient must verify that the blinded route is used in the right
|
|
||||||
context (e.g. for a specific payment) and was created by them. Otherwise a
|
|
||||||
malicious sender could create different blinded routes to all the nodes that
|
|
||||||
they suspect could be the real recipient and try them until one accepts the
|
|
||||||
message. The recipient can protect against that by storing $`E_r`$ and the
|
|
||||||
context (e.g. a `payment_hash`), and verifying that they match when receiving
|
|
||||||
the onion. Otherwise, to avoid additional storage cost, it can put some private
|
|
||||||
context information in the `path_id` field (e.g. the `payment_preimage`) and
|
|
||||||
verify that when receiving the onion. Note that it's important to use private
|
|
||||||
information in that case, that senders cannot have access to.
|
|
||||||
|
|
||||||
Whenever the introduction point receives a failure from the blinded route, it
|
|
||||||
should add a random delay before forwarding the error. Failures are likely to
|
|
||||||
be probing attempts and message timing may help the attacker infer its distance
|
|
||||||
to the final recipient.
|
|
||||||
|
|
||||||
The `padding` field can be used to ensure that all `encrypted_data` have the
|
|
||||||
same length. It's particularly useful when adding dummy hops at the end of a
|
|
||||||
blinded route, to prevent the sender from figuring out which node is the final
|
|
||||||
recipient.
|
|
||||||
|
|
||||||
When route blinding is used for payments, the recipient specifies the fees and
|
|
||||||
expiry that blinded nodes should apply to the payment instead of letting the
|
|
||||||
sender configure them. The recipient also adds additional constraints to the
|
|
||||||
payments that can go through that route to protect against probing attacks that
|
|
||||||
would let malicious nodes unblind the identity of the blinded nodes. It should
|
|
||||||
set `payment_constraints.max_cltv_expiry` to restrict the lifetime of a blinded
|
|
||||||
route and reduce the risk that an intermediate node updates its fees and rejects
|
|
||||||
payments (which could be used to unblind nodes inside the route).
|
|
||||||
|
|
||||||
# Accepting and Forwarding a Payment
|
# Accepting and Forwarding a Payment
|
||||||
|
|
||||||
@ -1459,7 +1495,7 @@ For consistency, all onion messages use [Route Blinding](#route-blinding).
|
|||||||
* `filler`
|
* `filler`
|
||||||
|
|
||||||
The `onionmsg_tlv` itself is a TLV: an intermediate node expects an
|
The `onionmsg_tlv` itself is a TLV: an intermediate node expects an
|
||||||
`encrypted_data` which it can decrypt into an `encrypted_data_tlv`
|
`encrypted_recipient_data` which it can decrypt into an `encrypted_data_tlv`
|
||||||
using the `path_key` which it is handed along with the onion message.
|
using the `path_key` which it is handed along with the onion message.
|
||||||
|
|
||||||
Field numbers 64 and above are reserved for payloads for the final
|
Field numbers 64 and above are reserved for payloads for the final
|
||||||
@ -1475,19 +1511,6 @@ even, of course!).
|
|||||||
2. data:
|
2. data:
|
||||||
* [`...*byte`:`encrypted_recipient_data`]
|
* [`...*byte`:`encrypted_recipient_data`]
|
||||||
|
|
||||||
1. subtype: `blinded_path`
|
|
||||||
2. data:
|
|
||||||
* [`point`:`first_node_id`]
|
|
||||||
* [`point`:`first_path_key`]
|
|
||||||
* [`byte`:`num_hops`]
|
|
||||||
* [`num_hops*onionmsg_hop`:`path`]
|
|
||||||
|
|
||||||
1. subtype: `onionmsg_hop`
|
|
||||||
2. data:
|
|
||||||
* [`point`:`blinded_node_id`]
|
|
||||||
* [`u16`:`enclen`]
|
|
||||||
* [`enclen*byte`:`encrypted_recipient_data`]
|
|
||||||
|
|
||||||
#### Requirements
|
#### Requirements
|
||||||
|
|
||||||
The creator of `encrypted_recipient_data` (usually, the recipient of the onion):
|
The creator of `encrypted_recipient_data` (usually, the recipient of the onion):
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
"unknown_tag_561": "123456"
|
"unknown_tag_561": "123456"
|
||||||
},
|
},
|
||||||
"encoded_tlvs": "011a0000000000000000000000000000000000000000000000000000020800000000000006c10a0800240000009627100c06000b69e505dc0e00fd023103123456",
|
"encoded_tlvs": "011a0000000000000000000000000000000000000000000000000000020800000000000006c10a0800240000009627100c06000b69e505dc0e00fd023103123456",
|
||||||
"ephemeral_privkey": "0202020202020202020202020202020202020202020202020202020202020202",
|
"path_privkey": "0202020202020202020202020202020202020202020202020202020202020202",
|
||||||
"ephemeral_pubkey": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
|
"path_key": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
|
||||||
"shared_secret": "76771bab0cc3d0de6e6f60147fd7c9c7249a5ced3d0612bdfaeec3b15452229d",
|
"shared_secret": "76771bab0cc3d0de6e6f60147fd7c9c7249a5ced3d0612bdfaeec3b15452229d",
|
||||||
"rho": "ba217b23c0978d84c4a19be8a9ff64bc1b40ed0d7ecf59521567a5b3a9a1dd48",
|
"rho": "ba217b23c0978d84c4a19be8a9ff64bc1b40ed0d7ecf59521567a5b3a9a1dd48",
|
||||||
"encrypted_data": "cd4100ff9c09ed28102b210ac73aa12d63e90852cebc496c49f57c49982088b49f2e70b99287fdee0aa58aa39913ab405813b999f66783aa2fe637b3cda91ffc0913c30324e2c6ce327e045183e4bffecb",
|
"encrypted_data": "cd4100ff9c09ed28102b210ac73aa12d63e90852cebc496c49f57c49982088b49f2e70b99287fdee0aa58aa39913ab405813b999f66783aa2fe637b3cda91ffc0913c30324e2c6ce327e045183e4bffecb",
|
||||||
@ -54,8 +54,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"encoded_tlvs": "020800000000000004510821031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f0a0800300000006401f40c06000b69c105dc0e00",
|
"encoded_tlvs": "020800000000000004510821031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f0a0800300000006401f40c06000b69c105dc0e00",
|
||||||
"ephemeral_privkey": "0a2aa791ac81265c139237b2b84564f6000b1d4d0e68d4b9cc97c5536c9b61c1",
|
"path_privkey": "0a2aa791ac81265c139237b2b84564f6000b1d4d0e68d4b9cc97c5536c9b61c1",
|
||||||
"ephemeral_pubkey": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0",
|
"path_key": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0",
|
||||||
"shared_secret": "dc91516ec6b530a3d641c01f29b36ed4dc29a74e063258278c0eeed50313d9b8",
|
"shared_secret": "dc91516ec6b530a3d641c01f29b36ed4dc29a74e063258278c0eeed50313d9b8",
|
||||||
"rho": "d1e62bae1a8e169da08e6204997b60b1a7971e0f246814c648125c35660f5416",
|
"rho": "d1e62bae1a8e169da08e6204997b60b1a7971e0f246814c648125c35660f5416",
|
||||||
"encrypted_data": "cc0f16524fd7f8bb0b1d8d40ad71709ef140174c76faa574cac401bb8992fef76c4d004aa485dd599ed1cf2715f57ff62da5aaec5d7b10d59b04d8a9d77e472b9b3ecc2179334e411be22fa4c02b467c7e",
|
"encrypted_data": "cc0f16524fd7f8bb0b1d8d40ad71709ef140174c76faa574cac401bb8992fef76c4d004aa485dd599ed1cf2715f57ff62da5aaec5d7b10d59b04d8a9d77e472b9b3ecc2179334e411be22fa4c02b467c7e",
|
||||||
@ -82,8 +82,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"encoded_tlvs": "01230000000000000000000000000000000000000000000000000000000000000000000000020800000000000002310a060090000000fa0c06000b699105dc0e00",
|
"encoded_tlvs": "01230000000000000000000000000000000000000000000000000000000000000000000000020800000000000002310a060090000000fa0c06000b699105dc0e00",
|
||||||
"ephemeral_privkey": "0101010101010101010101010101010101010101010101010101010101010101",
|
"path_privkey": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||||
"ephemeral_pubkey": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
"path_key": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||||
"shared_secret": "dc46f3d1d99a536300f17bc0512376cc24b9502c5d30144674bfaa4b923d9057",
|
"shared_secret": "dc46f3d1d99a536300f17bc0512376cc24b9502c5d30144674bfaa4b923d9057",
|
||||||
"rho": "393aa55d35c9e207a8f28180b81628a31dff558c84959cdc73130f8c321d6a06",
|
"rho": "393aa55d35c9e207a8f28180b81628a31dff558c84959cdc73130f8c321d6a06",
|
||||||
"encrypted_data": "0fa0a72cff3b64a3d6e1e4903cf8c8b0a17144aeb249dcb86561adee1f679ee8db3e561d9c43815fd4bcebf6f58c546da0cd8a9bf5cebd0d554802f6c0255e28e4a27343f761fe518cd897463187991105",
|
"encrypted_data": "0fa0a72cff3b64a3d6e1e4903cf8c8b0a17144aeb249dcb86561adee1f679ee8db3e561d9c43815fd4bcebf6f58c546da0cd8a9bf5cebd0d554802f6c0255e28e4a27343f761fe518cd897463187991105",
|
||||||
@ -106,8 +106,8 @@
|
|||||||
"unknown_tag_65535": "06c1"
|
"unknown_tag_65535": "06c1"
|
||||||
},
|
},
|
||||||
"encoded_tlvs": "011a00000000000000000000000000000000000000000000000000000604deadbeef0c06000b690105dc0e0f020000000000000000000000000000fdffff0206c1",
|
"encoded_tlvs": "011a00000000000000000000000000000000000000000000000000000604deadbeef0c06000b690105dc0e0f020000000000000000000000000000fdffff0206c1",
|
||||||
"ephemeral_privkey": "62e8bcd6b5f7affe29bec4f0515aab2eebd1ce848f4746a9638aa14e3024fb1b",
|
"path_privkey": "62e8bcd6b5f7affe29bec4f0515aab2eebd1ce848f4746a9638aa14e3024fb1b",
|
||||||
"ephemeral_pubkey": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a",
|
"path_key": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a",
|
||||||
"shared_secret": "352a706b194c2b6d0a04ba1f617383fb816dc5f8f9ac0b60dd19c9ae3b517289",
|
"shared_secret": "352a706b194c2b6d0a04ba1f617383fb816dc5f8f9ac0b60dd19c9ae3b517289",
|
||||||
"rho": "719d0307340b1c68b79865111f0de6e97b093a30bc603cebd1beb9eef116f2d8",
|
"rho": "719d0307340b1c68b79865111f0de6e97b093a30bc603cebd1beb9eef116f2d8",
|
||||||
"encrypted_data": "da1a7e5f7881219884beae6ae68971de73bab4c3055d9865b1afb60724a2e4d3f0489ad884f7f3f77149209f0df51efd6b276294a02e3949c7254fbc8b5cab58212d9a78983e1cf86fe218b30c4ca8f6d8",
|
"encrypted_data": "da1a7e5f7881219884beae6ae68971de73bab4c3055d9865b1afb60724a2e4d3f0489ad884f7f3f77149209f0df51efd6b276294a02e3949c7254fbc8b5cab58212d9a78983e1cf86fe218b30c4ca8f6d8",
|
||||||
@ -144,35 +144,35 @@
|
|||||||
{
|
{
|
||||||
"alias": "Bob",
|
"alias": "Bob",
|
||||||
"node_privkey": "4242424242424242424242424242424242424242424242424242424242424242",
|
"node_privkey": "4242424242424242424242424242424242424242424242424242424242424242",
|
||||||
"ephemeral_pubkey": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
|
"path_key": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
|
||||||
"blinded_privkey": "d12fec0332c3e9d224789a17ebd93595f37d37bd8ef8bd3d2e6ce50acb9e554f",
|
"blinded_privkey": "d12fec0332c3e9d224789a17ebd93595f37d37bd8ef8bd3d2e6ce50acb9e554f",
|
||||||
"decrypted_data": "011a0000000000000000000000000000000000000000000000000000020800000000000006c10a0800240000009627100c06000b69e505dc0e00fd023103123456",
|
"decrypted_data": "011a0000000000000000000000000000000000000000000000000000020800000000000006c10a0800240000009627100c06000b69e505dc0e00fd023103123456",
|
||||||
"next_ephemeral_pubkey": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0"
|
"next_path_key": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"alias": "Carol",
|
"alias": "Carol",
|
||||||
"node_privkey": "4343434343434343434343434343434343434343434343434343434343434343",
|
"node_privkey": "4343434343434343434343434343434343434343434343434343434343434343",
|
||||||
"ephemeral_pubkey": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0",
|
"path_key": "034e09f450a80c3d252b258aba0a61215bf60dda3b0dc78ffb0736ea1259dfd8a0",
|
||||||
"blinded_privkey": "bfa697fbbc8bbc43ca076e6dd60d306038a32af216b9dc6fc4e59e5ae28823c1",
|
"blinded_privkey": "bfa697fbbc8bbc43ca076e6dd60d306038a32af216b9dc6fc4e59e5ae28823c1",
|
||||||
"decrypted_data": "020800000000000004510821031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f0a0800300000006401f40c06000b69c105dc0e00",
|
"decrypted_data": "020800000000000004510821031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f0a0800300000006401f40c06000b69c105dc0e00",
|
||||||
"next_ephemeral_pubkey": "03af5ccc91851cb294e3a364ce63347709a08cdffa58c672e9a5c587ddd1bbca60",
|
"next_path_key": "03af5ccc91851cb294e3a364ce63347709a08cdffa58c672e9a5c587ddd1bbca60",
|
||||||
"next_ephemeral_pubkey_override": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f"
|
"next_path_key_override": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"alias": "Dave",
|
"alias": "Dave",
|
||||||
"node_privkey": "4444444444444444444444444444444444444444444444444444444444444444",
|
"node_privkey": "4444444444444444444444444444444444444444444444444444444444444444",
|
||||||
"ephemeral_pubkey": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
"path_key": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||||
"blinded_privkey": "cebc115c7fce4c295dc396dea6c79115b289b8ceeceea2ed61cf31428d88fc4e",
|
"blinded_privkey": "cebc115c7fce4c295dc396dea6c79115b289b8ceeceea2ed61cf31428d88fc4e",
|
||||||
"decrypted_data": "01230000000000000000000000000000000000000000000000000000000000000000000000020800000000000002310a060090000000fa0c06000b699105dc0e00",
|
"decrypted_data": "01230000000000000000000000000000000000000000000000000000000000000000000000020800000000000002310a060090000000fa0c06000b699105dc0e00",
|
||||||
"next_ephemeral_pubkey": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a"
|
"next_path_key": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"alias": "Eve",
|
"alias": "Eve",
|
||||||
"node_privkey": "4545454545454545454545454545454545454545454545454545454545454545",
|
"node_privkey": "4545454545454545454545454545454545454545454545454545454545454545",
|
||||||
"ephemeral_pubkey": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a",
|
"path_key": "03e09038ee76e50f444b19abf0a555e8697e035f62937168b80adf0931b31ce52a",
|
||||||
"blinded_privkey": "ff4e07da8d92838bedd019ce532eb990ed73b574e54a67862a1df81b40c0d2af",
|
"blinded_privkey": "ff4e07da8d92838bedd019ce532eb990ed73b574e54a67862a1df81b40c0d2af",
|
||||||
"decrypted_data": "011a00000000000000000000000000000000000000000000000000000604deadbeef0c06000b690105dc0e0f020000000000000000000000000000fdffff0206c1",
|
"decrypted_data": "011a00000000000000000000000000000000000000000000000000000604deadbeef0c06000b690105dc0e0f020000000000000000000000000000fdffff0206c1",
|
||||||
"next_ephemeral_pubkey": "038fc6859a402b96ce4998c537c823d6ab94d1598fca02c788ba5dd79fbae83589"
|
"next_path_key": "038fc6859a402b96ce4998c537c823d6ab94d1598fca02c788ba5dd79fbae83589"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user