1
0
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:
Olaoluwa Osuntokun 2024-08-13 16:11:20 -07:00 committed by GitHub
commit 22b9c87453
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 180 additions and 157 deletions

View File

@ -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):

View File

@ -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,36 +144,36 @@
{ {
"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"
} }
] ]
} }
} }