1
0
mirror of https://github.com/lightning/bolts.git synced 2024-11-19 10:00:04 +01:00
lightning-bolts/proposals/route-blinding.md
xiaolou86 9f55ccdfee
Fix typos (#1130)
* BOLT 04: fix typos
* proposals: fix typos
2024-01-30 06:54:54 +01:00

619 lines
34 KiB
Markdown

# Route Blinding
## Table of Contents
* [Proposal](#proposal)
* [Introduction](#introduction)
* [Overview](#overview)
* [Notations](#notations)
* [Requirements](#requirements)
* [Encrypted data](#encrypted-data)
* [Creating a blinded route](#creating-a-blinded-route)
* [Sending to a blinded route](#sending-to-a-blinded-route)
* [Receiving from a blinded route](#receiving-from-a-blinded-route)
* [Blinded payments](#blinded-payments)
* [Attacks](#attacks)
* [Unblinding channels with payment probing](#unblinding-channels-with-payment-probing)
* [Unblinding nodes after restart](#unblinding-nodes-after-restart)
* [Tips and Tricks](#tips-and-tricks)
* [Recipient pays fees](#recipient-pays-fees)
* [Dummy hops](#dummy-hops)
* [Wallets and unannounced channels](#wallets-and-unannounced-channels)
* [Blinded route selection](#blinded-route-selection)
* [Blinded trampoline route](#blinded-trampoline-route)
* [FAQ](#faq)
* [Why not use rendezvous](#why-not-use-rendezvous)
* [Why not use HORNET](#why-not-use-hornet)
## Proposal
### Introduction
Route blinding is a lightweight technique to provide recipient anonymity by blinding an arbitrary
amount of hops at the end of an onion path. 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).
The downside compared to rendezvous is that senders have more leeway to probe by changing various
variables, so the scheme needs to explicitly defend against probing attacks and may provide less
privacy against some classes of attacks.
Some use-cases where route blinding is useful include:
* Sender and recipient anonymity for onion messages
* Recipient anonymity for Bolt 12 offers
* Recipient anonymity when receiving payments
* Using unannounced channels in invoices without revealing them
* Forcing a payment to go through a specific set of intermediaries that can witness the payment
### Overview
At a high level, route blinding works by having the recipient choose an _introduction point_ and a
route to itself from that introduction point. The recipient then blinds each node and channel along
that route with ECDH. The recipient sends details about the blinded route and some cryptographic
material to the sender (via a Bolt 11 invoice or Bolt 12 offer), which lets the sender build an
onion with enough information to allow nodes in the blinded route to incrementally unblind the next
node in the route.
This scheme requires all the nodes in the blinded route and the sender to activate support for the
feature. It needs a big enough share of the network to support it to provide meaningful privacy
guarantees.
### Notations
* A node `N(i)`'s `node_id` is defined as: `N(i) = k(i) * G` (`k(i)` is the node's private key).
* Blinded `node_id`s are defined as: `B(i) = b(i) * G` (`b(i)` is the blinding factor).
* Sphinx ephemeral public keys are defined as: `E(i) = e(i) * G`.
### Requirements
A node `N(r)` wants to provide a blinded route `N(0) -> N(1) -> ... -> N(r)` that must be used
to receive onions.
* Intermediate nodes in the blinded route MUST NOT learn the `node_id` or `scid` of other
intermediate nodes except for their immediate predecessor or successor.
* Intermediate nodes in the blinded route MUST NOT learn their distance to the recipient `N(r)`.
* Senders MUST NOT learn the real `node_id` and `scid` of the blinded intermediate hops after the
introduction point `N(0)`.
* If `N(r)` creates multiple blinded routes to itself, senders MUST NOT be able to tell that these
routes lead to the same recipient (unless of course this information is leaked by higher layers
of the protocol, such as using the same `payment_hash` or being generated for the same offer).
### Encrypted data
Route blinding introduces a new TLV field to the onion `tlv_payload`: the `encrypted_data`.
This field is used to carry data coming from the builder of the route that cannot be modified by
the sender. It needs to contain enough data to let intermediate nodes locate the next node in the
route (usually a `node_id` or `scid`), and may be extended with additional data in the future. It
uses ChaCha20-Poly1305 as AEAD scheme.
1. type: 10 (`encrypted_data`)
2. data:
* [`...*byte`:`encrypted_data`]
Once decrypted, the content of this encrypted payload is a TLV stream.
### Creating a blinded route
`N(r)` performs the following steps to create a blinded route:
```text
Initialization:
e(0) <- {0;1}^256
E(0) = e(0) * G
Blinding:
For i = 0 to r:
ss(i) = H(e(i) * N(i)) = H(k(i) * E(i)) // shared secret known only by N(r) and N(i)
B(i) = HMAC256("blinded_node_id", ss(i)) * N(i) // Blinded node_id for N(i), private key known only by N(i)
rho(i) = HMAC256("rho", ss(i)) // Key used to encrypt payload for N(i) by N(r)
e(i+1) = H(E(i) || ss(i)) * e(i) // Ephemeral private key, only known by N(r)
E(i+1) = H(E(i) || ss(i)) * E(i) // NB: N(i) must not learn e(i)
```
Note that this is exactly the same construction as Sphinx, but at each hop we use the shared secret
to derive a blinded `node_id` for `N(i)` for which the private key will only be known by `N(i)`.
The recipient then creates `encrypted_data(i)` by encrypting application-specific data with
ChaCha20-Poly1305 using the `rho(i)` key.
To use the blinded route, senders need the following data:
* The real `node_id` of the introduction point `N(0)` (to locate the beginning of the route)
* The list of blinded `node_id`s: `[B(1),...,B(r)]`
* The encrypted data for each node: `[encrypted_data(0),...,encrypted_data(r)]`
* The first blinding ephemeral key: `E(0)`
### Sending to a blinded route
The sender finds a route to the introduction point `N(0)`, and extends it with the blinded route.
It then creates an onion for that whole route, and includes `E(0)` and `encrypted_data(0)` in the
onion payload for `N(0)`. It includes `encrypted_data(i)` in the onion payload for `B(i)`.
When `N(0)` receives the onion and decrypts it, it finds `E(0)` in the payload and is able to
compute the following:
```text
ss(0) = H(k(0) * E(0))
rho(0) = HMAC256("rho", ss(0))
E(1) = H(E(0) || ss(0)) * E(0)
```
It uses `rho(0)` to decrypt the `encrypted_data(0)` and discovers that `B(1)` is actually `N(1)`.
It forwards the onion to `N(1)` and includes `E(1)` in a TLV field in the lightning message
(e.g. in the extension field of an `update_add_htlc` message).
All the following intermediate nodes `N(i)` do the following steps:
```text
E(i) <- extracted from the lightning message's fields
ss(i) = H(k(i) * E(i))
b(i) = HMAC256("blinded_node_id", ss(i)) * k(i)
Use b(i) instead of k(i) to decrypt the incoming onion using sphinx
rho(i) = HMAC256("rho", ss(i))
Use rho(i) to decrypt the `encrypted_data` inside the onion and discover the next node
E(i+1) = H(E(i) || ss(i)) * E(i)
Forward the onion to the next node and include E(i+1) in a TLV field in the message
```
### Receiving from a blinded route
When `N(r)` receives the onion message and `E(r)`, they do the same unwrapping as intermediate
nodes. The difference is that the onion will be a final onion.
`N(r)` must also validate that the blinded route was used in the context it was created for, and is
a route that they created. It's important to note than anyone can create valid blinded routes to
anyone else. Alice for example is able to create a blinded route `Bob -> Carol -> Dave`. In most
cases, Dave wants to ignore messages that come through routes that were created by someone else.
The details of this validation step depends on the actual application using route blinding. For
example, when using a blinded route for payments, the recipient must verify that the route was
used in conjunction with the right `payment_hash`. It can do so by storing the `payment_preimage`
in the `encrypted_data` payload to itself and verifying it when receiving the payment: malicious
senders don't know the preimage beforehand, so they won't be able to create a satisfying route.
Without this validation step, the recipient exposes itself to malicious probing, which could let
attackers deanonymize the route.
### Blinded payments
This section provides more details on how route blinding can be used for payments.
In order to protect against malicious probing (detailed in the [Attacks](#attacks) section), it is
the recipient who chooses what payment relay parameters will be used inside the route (e.g. fees)
and encodes them in the `encrypted_data` payload for each blinded node. The sender will not set the
`amt_to_forward` and `outgoing_cltv_value` fields in the onion payloads for blinded intermediate
nodes: these nodes will instead follow the instructions found in their `encrypted_data`.
The `encrypted_data` for each intermediate node will contain the following fields:
* `short_channel_id`: outgoing channel that should be used to route the payment
* `fee_base_msat`: base fee that must be applied before relaying the payment
* `fee_proportional_millionths`: proportional fee that must be applied before relaying the payment
* `cltv_expiry_delta`: cltv expiry delta that must be applied before relaying the payment
* `max_cltv_expiry`: maximum expiry allowed for this payment
* `htlc_minimum_msat`: minimum htlc amount that should be accepted
* `allowed_features`: features related to payment relay that the sender is allowed to use
The recipient must use values that provide a good enough anonymity set, by looking at nearby
channels and selecting values that would work for a large enough number of those channels.
Otherwise it could be easy for a malicious sender to figure out which channels are hidden inside
the blinded route if for example the selected fees are lower than most other candidates.
The recipient also includes the `payment_preimage` (or another private unique identifier for the
payment) in the `path_id` field of the `encrypted_data` payload for itself: this will let the
recipient verify that the route is only used for that specific payment and was generated by them.
If a node inside the blinded route receives a payment that doesn't use the parameters provided in
the `encrypted_data`, it must reject the payment and respond with an unparsable error onion. That
ensures the payer won't know which node failed and for what reason (otherwise that would provide
data that the payer could use to probe nodes inside the route).
Note that we are also providing a `max_cltv_expiry` field: this ensures that the blinded route
expires after some time, restricting future probing attempts.
If we assume that all nodes support `var_onion_option`, we don't need to include the
`allowed_features` field for now as there are no other features that affect payment relay and
could be used as a probing vector. However, future updates may add such features (e.g. PTLC
support), in which case the `allowed_features` field must not be empty.
Let's go through an example to clarify those requirements.
Alice creates an invoice with the following blinded route: `Carol -> Bob -> Alice`.
The channels along that route have the following settings:
* `Carol -> Bob`
* `fee_base_msat`: 10
* `fee_proportional_millionths`: 250
* `cltv_expiry_delta`: 144
* `htlc_minimum_msat`: 1
* `Bob -> Alice`
* `fee_base_msat`: 50
* `fee_proportional_millionths`: 100
* `cltv_expiry_delta`: 48
* `htlc_minimum_msat`: 1000
Alice chooses the following parameters for the blinded route, that satisfy the requirements of the
channels described above and adds a safety margin in case nodes update their relay parameters:
* `fee_base_msat`: 100
* `fee_proportional_millionths`: 500
* `htlc_minimum_msat`: 1000
* `cltv_expiry_delta`: 144
Alice uses the same values for both channels for simplicity's sake. Alice can now compute aggregate
values for the complete route (iteratively starting from the end of the route), using integer
arithmetic to compute `ceil(a/b)` as `(a+b-1)/b` (we round values up, otherwise the sender may
receive slightly less than intended):
* `route_fee_base_msat(n+1) = (fee_base_msat(n+1) * 1000000 + route_fee_base_msat(n) * (1000000 + fee_proportional_millionths(n+1)) + 1000000 - 1) / 1000000`
* `route_fee_proportional_millionths(n+1) = ((route_fee_proportional_millionths(n) + fee_proportional_millionths(n+1)) * 1000000 + route_fee_proportional_millionths(n) * fee_proportional_millionths(n+1) + 1000000 - 1) / 1000000`
Alice wants to use a `min_final_cltv_expiry_delta` of 12 blocks, which she adds to the route's
total `cltv_expiry_delta`. This yields the following values:
* `route_fee_base_msat`: 201
* `route_fee_proportional_millionths`: 1001
* `route_cltv_expiry_delta`: 300
Let's assume the current block height is 1000. Alice wants the route to be used in the next 200
blocks, so she sets `max_cltv_expiry = 1200` and adds `cltv_expiry_delta` for each hop. Alice then
transmits the following information to the sender (most likely via an invoice):
* Blinded route: `[N(carol), B(bob), B(alice)]`
* First blinding ephemeral key: `E(carol)`
* Aggregated route relay parameters and constraints:
* `fee_base_msat`: 201
* `fee_proportional_millionths`: 1001
* `htlc_minimum_msat`: 1000
* `cltv_expiry_delta`: 300
* `max_cltv_expiry`: 1200 (may be conveyed via invoice expiration, assuming 10 minute blocks)
* `allowed_features`: empty
* Encrypted data for blinded nodes:
* `encrypted_payload(alice)`:
* `path_id`: `payment_preimage`
* `max_cltv_expiry`: 1200
* `encrypted_payload(bob)`:
* `outgoing_channel_id`: `scid_bob_alice`
* `fee_base_msat`: 100
* `fee_proportional_millionths`: 500
* `htlc_minimum_msat`: 1000
* `max_cltv_expiry`: 1356
* `encrypted_payload(carol)`:
* `outgoing_channel_id`: `scid_carol_bob`
* `fee_base_msat`: 100
* `fee_proportional_millionths`: 500
* `htlc_minimum_msat`: 1000
* `max_cltv_expiry`: 1500
Note that the introduction point (Carol) uses the real `node_id`, not the blinded one, because the
sender needs to be able to locate this introduction point and find a route to it. The sender will
send the first blinding ephemeral key `E(carol)` in the onion `hop_payload` for Carol, which will
allow Carol to compute the blinding shared secret and correctly forward. We put this blinding
ephemeral key in the onion instead of using a tlv in `update_add_htlc` because intermediate nodes
added before the blinded route may not support route blinding and wouldn't know how to relay it.
Erin wants to send 100 000 msat to this blinded route.
She can reach Carol via Dave: `Erin -> Dave -> Carol`, where the channel between Dave and Carol uses
the following relay parameters:
* `fee_base_msat`: 10
* `fee_proportional_millionths`: 100
* `cltv_expiry_delta`: 24
Erin uses the aggregated route relay parameters to compute how much should be sent to Carol:
* `amount = 100000 + 201 + (1001 * 100000 + 1000000 - 1) / 1000000 = 100302 msat`
Erin chooses a final expiry of 1100, which is below Alice's `max_cltv_expiry`. This value may be
chosen by adding a random cltv offset to the current block height as described in
[Recommendations for Routing](../07-routing-gossip.md#recommendations-for-routing).
Erin computes the expiry that should be sent to Carol:
* `expiry = 1100 + 300 = 1400`
When a node in the blinded route receives an htlc, the onion will not contain the `amt_to_forward`
or `outgoing_cltv_value`. They will have to compute them based on the fields contained in their
`encrypted_data` (`fee_base_msat`, `fee_proportional_millionths` and `cltv_expiry_delta`).
For example, here is how Carol will compute the values for the htlc she relays to Bob:
* `amount = ((100302 - fee_base_msat) * 1000000 + 1000000 + fee_proportional_millionths - 1) / (1000000 + fee_proportional_millionths) = 100152 msat`
* `expiry = 1400 - cltv_expiry_delta = 1256`
And here is how Bob computes the values for the htlc he relays to Alice:
* `amount = ((100152 - fee_base_msat) * 1000000 + 1000000 + fee_proportional_millionths - 1) / (1000000 + fee_proportional_millionths) = 100002 msat`
* `expiry = 1256 - cltv_expiry_delta = 1112`
Note that as the rounding errors aggregate, the recipient will receive slightly more than what was
expected. The sender includes `amt_to_forward` in the onion payload for the recipient to let them
verify that the received amount is (slightly) greater than what the sender intended to send (which
protects against intermediate nodes that would try to relay a lower amount).
The messages exchanged will contain the following values:
```text
Erin Dave Carol Bob Alice
| update_add_htlc | update_add_htlc | update_add_htlc | update_add_htlc |
| +--------------------------------+ | +------------------------------------------+ | +------------------------------------------+ | +--------------------------------+ |
| | amount: 100322 msat | | | amount: 100302 msat | | | amount: 100152 msat | | | amount: 100002 msat | |
| | expiry: 1424 | | | expiry: 1400 | | | expiry: 1256 | | | expiry: 1112 | |
| | onion_routing_packet: | | | onion_routing_packet: | | | onion_routing_packet: | | | onion_routing_packet: | |
| | +----------------------------+ | | | +--------------------------------------+ | | | +--------------------------------------+ | | | +----------------------------+ | |
| --> | | amount_fwd: 100302 msat | | --> | --> | | blinding_eph_key: E(carol) | | --> | --> | | encrypted_data: | | --> | --> | | amount_fwd: 100000 msat | | --> |
| | | outgoing_expiry: 1400 | | | | | encrypted_data: | | | | | +----------------------------------+ | | | | | outgoing_expiry: 1112 | | |
| | | scid: scid_dave_to_carol | | | | | +----------------------------------+ | | | | | | scid: scid_bob_to_alice | | | | | | encrypted_data: | | |
| | +----------------------------+ | | | | | scid: scid_carol_to_bob | | | | | | | fee_base_msat: 100 | | | | | | +-----------------------+ | | |
| | | blinding_eph_key: E(carol) | | | | | | fee_base_msat: 100 | | | | | | | fee_proportional_millionths: 500 | | | | | | | path_id: preimage | | | |
| | | encrypted_data(carol) | | | | | | fee_proportional_millionths: 500 | | | | | | | htlc_minimum_msat: 1000 | | | | | | | max_cltv_expiry: 1200 | | | |
| | +----------------------------+ | | | | | htlc_minimum_msat: 1000 | | | | | | | cltv_expiry_delta: 144 | | | | | | +-----------------------+ | | |
| | | encrypted_data(bob) | | | | | | cltv_expiry_delta: 144 | | | | | | | max_cltv_expiry: 1356 | | | | | +----------------------------+ | |
| | +----------------------------+ | | | | | max_cltv_expiry: 1500 | | | | | | +----------------------------------+ | | | | tlv_extension | |
| | | amount_fwd: 100000 msat | | | | | +----------------------------------+ | | | | +--------------------------------------+ | | | +----------------------------+ | |
| | | outgoing_expiry: 1112 | | | | +--------------------------------------+ | | | | amount_fwd: 100000 msat | | | | | blinding_eph_key: E(alice) | | |
| | | encrypted_data(alice) | | | | | encrypted_data(bob) | | | | | outgoing_expiry: 1112 | | | | +----------------------------+ | |
| | +----------------------------+ | | | +--------------------------------------+ | | | | encrypted_data(alice) | | | +--------------------------------+ |
| +--------------------------------+ | | | amount_fwd: 100000 msat | | | | +--------------------------------------+ | | |
| | | | outgoing_expiry: 1112 | | | | tlv_extension | | |
| | | | encrypted_data(alice) | | | | +--------------------------------------+ | | |
| | | +--------------------------------------+ | | | | blinding_eph_key: E(bob) | | | |
| | +------------------------------------------+ | | +--------------------------------------+ | | |
| | | +------------------------------------------+ | |
| | | | |
```
Note that all onion payloads are described in each `update_add_htlc` for clarity, but only the
first one can be decrypted by the intermediate node that receives the message (standard Bolt 4
onion encryption).
## Attacks
### Unblinding channels with payment probing
Recipients must be careful when using route blinding for payments to avoid letting attackers
guess which nodes are hidden inside of the route. Let's walk through an attack to understand
why.
Let's assume that our routing graph looks like this:
```text
+-------+ +-------+
| X | | X |
+-------+ +-------+
| |
| |
+-------+ +-------+ +-------+ +-------+
| X |------| Carol |------| Bob |------| Alice |
+-------+ +-------+ +-------+ +-------+
| |
| |
+-------+ +-------+
| X | | X |
+-------+ +-------+
```
Alice creates a blinded route `Carol -> Bob -> Alice`.
Alice has chosen what fee settings will be used inside the blinded route.
Let's assume she has chosen `fee_base_msat = 10` and `fee_proportional_millionths = 100`.
The attacker knows that the recipient is at most two hops away from Carol. Instead of making the
payment, the attacker watches for new `channel_update`s for every channel in a two-hops radius
around Carol. At some point, the attacker sees a `channel_update` for the channel `Bob -> Alice`
that sets `fee_proportional_millionths = 150`, which exceeds what Alice has chosen for the blinded
route. The attacker then tries to make the payment.
When Bob receives the payment, the fees are below its current settings, so it should reject it.
The attacker would then receive a failure, and be able to infer that it's very likely that Alice
is the final recipient.
If the attackers are able to frequently request invoices from the recipient (e.g. from a Bolt 12
offer), they don't even have to attempt the payment to detect this. They can simply periodically
request invoices from the recipient and detect when the recipient raises the fees or cltv of the
blinded route, and match that with recent `channel_update`s that they received.
Similarly, feature bits that apply to payment relaying behavior can be used to fingerprint nodes
inside the blinded route: this is why `allowed_features` are committed inside the `encrypted_data`.
If nodes across the network use different values for `htlc_minimum_msat`, it can also be used to
fingerprint nodes: that's why it is also committed inside the `encrypted_data`.
This type of attack is the reason why all parameters that affect payment relaying behavior (fees,
cltv, features, etc) are chosen by the recipient. The recipient should add a large enough margin
to the current values actually used by nodes inside the route to protect against future raises.
This is also why blinded routes used for payments have a `max_cltv_expiry` set by the recipient,
even though that doesn't fully address the issue if the attackers are able to frequently request
new blinded routes.
Altruistic relaying nodes inside a blinded route could choose to relay payments with fees below
their current settings, which would break this heuristic: however their economic incentive is to
reject them, so we cannot rely on them to protect recipient privacy.
Similarly, we mandate relaying nodes to only accept payments using exactly the fees provided in
the `encrypted_data` payload. Otherwise, when observing a `channel_update` that raises a specific
channel's fees, the attackers could try to use these new fees in a payment attempt: if the payment
goes through, they would have even more confidence about the channel used in the blinded route.
The incentives for relaying nodes aren't great, because we're asking them to reject payments that
give them the right amount of fees to protect recipient privacy.
### Unblinding nodes after restart
The attacks described in the previous section only applied to scenarios that use route blinding
for payments. However, a variation of the same technique can be used for any scenario relying on
route blinding to relay messages.
If attackers suspect that a given node `N` may be part of a blinded route, they can wait for that
node to go offline, and try using the blinded route while the node is offline. If the blinded
route fails, it's likely that this node was indeed part of the blinded route. By repeating this
sampling regularly, attackers can increase the confidence in their unblinding.
To address this, recipients should choose nodes with high uptime for their blinded routes and
periodically refresh them.
## Tips and Tricks
### Recipient pays fees
It may be unfair to make payers pay more fees to accommodate the recipient's wish for anonymity.
It should instead be the recipient that pays the fees of the blinded hops (and the payer pays the
fees to reach the introduction point).
If a merchant is selling an item for `N` satoshis, it should create an invoice for `N-f` satoshis,
where `f` is the fee of the blinded part of the route.
### Dummy hops
The sender knows an upper bound on the distance between the recipient and `N(0)`. If the recipient
is close to `N(0)`, this might not be ideal. In such cases, the recipient may add any number of
dummy hops at the end of the blinded route by using `N(j) = N(r)`. The sender will not be able to
distinguish those from normal blinded hops.
NB:
* the recipient needs to fully validate each dummy hop's onion payload to detect tampering (and
must ensure that these hops have been used and not truncated)
* the recipient must use padding to ensure all `encrypted_data` payloads have the same length,
otherwise the payer will be able to guess which hop is actually the recipient
### Wallets and unannounced channels
Route blinding is particularly useful for wallets that are connected to nodes via unannounced
channels. Such wallets could use a single blinded hop, which effectively hides their `node_id`
and `scid` from the sender. It obviously reveals to the blinded node that the next node is the
final recipient, but a wallet that's not online all the time with a stable IP will never be able
to hide that information from the nodes it connects to anyway (even with rendezvous).
### Blinded route selection
There is a wide array of strategies that a recipient may use when creating a blinded route to
ensure good privacy while maintaining good payment reliability. We will walk through some of
these strategies below. Note that these are only examples, implementations should find strategies
that suit their users' needs.
If the recipient is not a public node and has a small number of peers, then it's very simple:
they can include one path per peer. A mobile wallet's topology for example will typically look
like this:
```text
+-------+ +-------+
+----------| Carol | | X |
| +-------+ +-------+
| | |
| | |
+-------+ +-------+ +-------+ +-------+
| Alice |------| Bob |------| X |------| X |
+-------+ +-------+ +-------+ +-------+
| |
| |
| +-------+
+-------------------------| Dave |
+-------+
```
Alice could provide a blinded route containing one blinded path per peer and dummy hops:
* Bob -> Blinded(Alice) -> Blinded(Alice) -> Blinded(Alice)
* Carol -> Blinded(Alice) -> Blinded(Alice) -> Blinded(Alice)
* Dave -> Blinded(Alice) -> Blinded(Alice) -> Blinded(Alice)
Alice is able to use all of her inbound liquidity while benefiting from a large anonymity set: she
could be any node at most three hops away from Bob, Carol and Dave.
If the recipient is a public node, its strategy will be different. It should use introduction nodes
that have many peers to obtain a good anonymity set. Let's assume that Alice's neighbourhood has
the following topology:
```text
+-------+ +-------+
| X | | X |
+-------+ +-------+
| |
| |
+-------+ +-------+ +-------+
| N1 |------| N2 |------| X |
+-------+ +-------+ +-------+
| | |
| | |
+-------+ +-------+ +-------+ +-------+
| Alice |------| N3 |------| N4 |------| X |
+-------+ +-------+ +-------+ +-------+
```
Alice can run a BFS of depth 2 to identify that N2 and N4 are good introduction nodes that provide
a large anonymity set. She can then provide the following blinded paths:
* N2 -> Blinded(N1) -> Blinded(Alice) -> Blinded(Alice)
* N4 -> Blinded(N3) -> Blinded(Alice) -> Blinded(Alice)
Alice should analyze the payment relay parameters of all channels in her anonymity set and choose
fees/cltv that would work for a large enough subset of them.
Note that Alice chose non-overlapping paths: otherwise these paths may not have enough liquidity
to relay the payment she expects to receive, unless the path capacity is much larger than the
expected payment.
When the receiver expects to receive large payments, liquidity may become an issue if it is
scattered among too many peers. The receiver may be forced to use introduction nodes that are
direct peers to ensure that enough liquidity is available (in which case it's particularly useful
to include dummy hops in the blinded paths).
### Blinded trampoline route
Route blinding can also be used with trampoline very easily. Instead of providing the
`outgoing_channel_id` in `encrypted_data`, we simply need to provide the `outgoing_node_id`.
Each trampoline node can then decrypt the `node_id` of the next node and compute `E(i)` for the
next trampoline node. That `E(i)` can then be sent in the outer onion payload instead of using the
lightning message's fields, which is even cleaner and doesn't require nodes between trampoline
nodes to understand route blinding.
Using a blinded trampoline route is a good solution for public nodes that have many peers and
run into liquidity issues affecting payment reliability. Such recipients can choose trampoline
nodes that will be able to find many paths towards them:
```text
+-------+ +-------+
+----------| X |--------+ +--------| X |----------+
| +-------+ | | +-------+ |
| | | |
| | | |
+-------+ +-------+ +-------+ +-------+ +-------+
| T1 |------| X |------| Alice |------| X |------| T2 |
+-------+ +-------+ +-------+ +-------+ +-------+
| | | |
| | | |
| +-------+ | | +-------+ |
+----------| X |--------+ +--------| X |----------+
+-------+ +-------+
```
Alice can provide the following blinded trampoline paths:
* T1 -> Blinded(Alice)
* T2 -> Blinded(Alice)
T1 and T2 will be able to find many paths towards Alice and retry whenever some paths fail,
working around the potential liquidity constraints.
## FAQ
### Why not use rendezvous
While rendezvous is more private, it's also less flexible: senders cannot add data to the partial
onion nor reuse it. When used for payments, the amount must be fixed ahead of time in the partial
onion, which doesn't combine well with multi-part payments or temporary liquidity issues.
Route blinding lets senders choose most of the data they put in the onion payloads, which makes
it much more flexible, at the expense of introducing more probing surface for attackers.
### Why not use HORNET
HORNET requires a slow session setup before it can provide useful speedups. In cases where you
expect to send a single message per session (which is the case for payments and onion messages),
HORNET actually performs worse than Sphinx in latency, bandwidth and privacy.