Route Blinding Explained: A step to understanding the proposal.
The goal of this article.
The point of this article is to explain the bolt pull request 24/25. This pull request introduces the concept of route blinding to the lightning protocol. I like to think of this article as explaining route blinding to someone who has read and understood the routing procedure as explained in Mastering The Lightning Network. I aim to help explain the basic concepts of route blinding and how it differs from the normal routing procedure the reader might be familiar with from that book. I would have achieved my goal if I had gotten the readers well set up to read the proposal by themselves and understand more about it.
Prerequisites and Suggested Reading.
As stated in the introduction, this article builds on the groundwork already laid out by Mastering The Lightning Network. I expect that the reader has at least read and understood chapters 8 and 10 of that book before reading this article. If that is not the case for you, I recommend you do that. You can also check out these blogs: Lightning Network Onion Routing: Preliminaries and Lightning Network Onion Routing: Sphinx Packet Construction by Elle Mouton, one of the engineers at LND, for the required preliminaries. She really did a great job at explaining these concepts as well.
Introduction.
I will explain this using the scenario from the book Mastering the Lightning Network.
Source: https://github.com/lnbook/lnbook/blob/develop/10_onion_routing.asciidoc#alice_dina_htlc_path
Brief background of what is going on in the picture.
What is important to understand in that diagram is that Alice is sending payment to Diana. Alice sends the payment through Bob, who sends it to Chan, and Chan eventually sends it to Dina.
The more detailed explanation of what is happening in the diagram is that Alice is sending 10,000 sat to Dina. Dina would send back, H
which is shown on top of the arrow that connects Dina to Alice, as proof that she has received the payment. Alice will make this payment through Bob and Chan. She would have to incentivize them to help her, so she adds an extra 200 sat to the money that she would send for the payment to do this. Bob receives the 10,200 sat, collects his fee of 100 sat, and forwards the rest to Chan. Chan receives the 10,100 sat, collects his fee of 100 sat, and forwards the rest (10,000 sat) to Diana, the final receiver. The in-depth explanation about fees and how they are routed is well explained in the prerequisites I mentioned.
Recapping unblinded routing briefly to understand the why of route blinding.
In this section, I will be recapping the routing that was explained in Mastering the Lightning Network, which I will refer to as unblinded routing. The aim of this section is to understand the why behind the concept of route blinding.
While sending the payment through an unblinded route, the sender, in this case, Alice, decides what nodes are included in the route that sends payment to Diana, the final receiver. Lightning invoices (a request for payment in the lightning network) have what is known as hop hints
. By including hop hints
in the invoice, Diana can communicate to Alice what nodes should be part of the route that Alice would create for the payment. hop hints
are most especially useful for unannounced/private channels known to Diana and not Alice. Note that Diana would need to reveal the details of these private channels through the lightning invoice to inform senders to include them in the payment route.
Senders know the identity of all nodes, including the final receiver, in an unblinded route. This means that they know the relay parameters of the nodes in the route, such as fees, cltv_expiry, minimum htlc, etc. Knowing this would help the sender know how best to craft the payload of each node so that it does not get rejected by the node. For example, in our illustration above, Alice wants to pay Diana 10,000 sats, but she does not just forward 10,000 sats. She adds an extra 200 sats to account for the fees requested by Bob and Chan on the route. She knows to add this 200 sats because of her knowledge of the relay parameters of Bob and Chan.
On the other hand, receivers do not know all the nodes in the unblinded payment route. Most importantly, they do not know the node that initiated the payment. A receiver would only know the node from which it receives its HTLC for payment but cannot determine who actually initiated the payment. To further explain, using the illustration above, Diana does not know nodes Alice and Bob; all she knows is Chan, and there is no way she can be certain if Chan is the one who actually sent her money or if Chan is just relaying payments.
In this way, unblinded routes offer sender anonymity but do not offer receiver anonymity.
I would summarise the major points to be taken away using bullet points below:
Unblinded payment routes do not offer receiver anonymity.
If receivers want certain private channels to be part of the payment route, they must expose the details of these channels to the senders.
The above points summarise the shortcomings of unblinded routes, which route blinding aims to solve (there are other techniques that solve this as well, such as rendezvous, hornet, etc. The proposal dedicated a section to explain how route blinding compares to these two). This leads us to our next section, which is: what is route blinding?
Defining route blinding.
Route blinding is a lightweight technique to provide recipient anonymity by blinding an arbitrary amount of hops from a node known as the introduction point (first node in the route) to the final receiver. Blinding here means replacing each node’s public keys in the route with random public keys. The keys produced due to this process are known as blinded node IDs. This blinding is done by the receiver and communicated to the sender as the sender still creates the onion routing packet, which includes the payload for each node in the packet (more in-depth explanation on how this works later).
The below summarises how blinded routes operate as written in the spec:
Intermediate nodes in the blinded route MUST NOT learn the
node_id
orscid
of other intermediate nodes except for their immediate predecessor or successor.Intermediate nodes in the blinded route MUST NOT learn their distance to the final recipient
N(r)
.Senders MUST NOT learn the real
node_id
andscid
of the blinded intermediate hops after the introduction pointN(0)
.
Up next, I will delve deeper into how route blinding actually works. But before that, it would be helpful to have a broad overview of its operation, which is what the next section is about.
Overview of route blinding
I defined route blinding in the previous section. Let us now take a look at how it works here. I would add extra nodes between Chan and Diana in our previous reference diagram to do this. These nodes are Elma, Han, and Ella.
So let me restate what is going on in that diagram. Diana wants to receive payment. However, she hopes to achieve these requirements while receiving this payment:
She does not want to reveal her identity to whoever sends her this payment.
She has a certain route through which she wants the payment to come through. Diana wants to ensure that her payment goes through Elma, Han, and Ella before it gets to her.
Some or all of these channels are private; she does not want to reveal their details to the sender. If she uses
hop hints
, she would have to reveal the identity of these channels for sure.
As a result of all these, she opts to employ route-blinding as it helps her to fulfill all the requirements mentioned above.
A rough overview of how she does this is to create a blinded route and communicate its details in a request for payment (lightning invoice). The sender can decide to fulfill this payment by creating an unblinded route that links to the blinded route (concatenating an unblinded and blinded route) or using another blinded route to link to the blinded route (concatenating two blinded routes).
The diagram above depicts the route of payment chosen for the scenario. The boxes marked pink represent the nodes in the blinded route, while the boxes marked blue represent the nodes in the unblinded route. The illustration depicts Diana receiving the payment from Alice by concatenating an unblinded and blinded route. We will be going into more detail on how this is done in the following section.
How a receiver creates a blinded route.
To achieve her goal, Diana would create a blinded route. This blinded route would consist of the following nodes, Elma, Han, and Ella. The route would start with Elma and terminate with Diana. The first node in any blinded route is known as the introduction point/node. In this case, Elma is the introduction point of the route. This is the only node in the blinded route whose true identity the sender would know.
Next, for each node, i
she creates a blinding point, E(i)
in the blinded route. This blinding point is used to create the blinded node ID and the encryption key (rho(i)
) for each node.
The blinded node ID is the randomized public key of a node in the blinded route. This represents the node to nodes outside the blinded route while still hiding its true identity.
The encryption key (
rho(i)
) is used to encryptencrypted_data
for node,i
.The
encrypted_data
for intermediate nodes (in this case, Elma, Ella, and Han) contain enough data to help a node identify the next node in the blinded route. It would contain the following fields as stated in the spec:
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 (I recommend reading the spec to understand what this is, it would not be covered in this article).The
encrypted data
for the final receiver (Diana) is a bit different as it only contains these fields:
payment_preimage
(or another private unique identifier for the payment) in thepath_id
field of theencrypted_data
.
max_cltv_expiry
(explained above)There is also another field known as the
next_blinding_override
field. This is useful when concatenating two blinded routes for payment. In that case Diana would not be the final receiver for this payment just the last node in this blinded route. Theencrypted_data
for the first node in the next blinded route would have its first ephemeral blinding point present in this field. Read more about this here.The proposal also states that the
encrypted_data
fields may be extended to include other data in the future.
The blinding point (E(i))
)is a sphinx ephemeral public key, and it is defined as:
E(i) = G * e(i)
where, e(i)
is its ephemeral private key, and G
is a constant point called the generator point.
The blinding point that she creates for the introduction node is known as the first ephemeral blinding point, E(0)
. In this case, the first ephemeral blinding point is, E(Elma)
.
The first ephemeral blinding point and its private key serve as the initial basis for creating the blinding node IDs and the subsequent blinding points for other nodes in the blinded route.
This means that Diana generates an ephemeral blinding point and private key for Elma (note that there would be no need to generate a blinding node ID for Elma). This is then used as a starting point to generate the blinding node ID of all the other nodes in the blinded route, i.e., Han, Ella, and Elma. The algorithm below, which loops through each node (i
) from the introduction node (0
) to the final receiver (r
) shows how the shared secret (ss(i)
) is computed and how it is used to generate the blinded node ID (B(i)
), encryption key(rho(i)
), ephemeral private key(e(i)
) and blinding point(E(i)
) for each node.
NB: N(i)
is the node’s public key, while k(i)
is its accompanying private key.
Blinding:
For i = 0 to r, where r is the final receiver and 0 is the introduction point:
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)
N.B: Copied from the spec proposal.
Diana’s task of creating a blinded route is now complete. The next thing she does is select a suitable route relay parameter that satisfies the requirements of the channels in the blinded route while adding some safety margin. For example, assuming the below are the relay parameters for the channel between Elma and Han and then Han and Ella (this example was lifted from the spec):
Elma -> Han
fee_base_msat
: 10fee_proportional_millionths
: 250cltv_expiry_delta
: 144htlc_minimum_msat
: 1
Han -> Ella
fee_base_msat
: 50fee_proportional_millionths
: 100cltv_expiry_delta
: 48htlc_minimum_msat
: 1000
Diana can choose the relay parameter -below, which satisfies the requirement above, along with some safety margin. I would call this the selected route relay parameter for the blinded route for easy reference:
fee_base_msat
: 100fee_proportional_millionths
: 500htlc_minimum_msat
: 1000cltv_expiry_delta
: 144
The selected route relay parameter for the blinded route is encrypted in each blinded node's encrypted_data
except from the encrypted_data
of the final receiver as it does not need to relay payments. The selected route relay parameter for the blinded route serves an important purpose that we will learn about later in this article.
Remember that we stated earlier that the sender of the payments knows nothing about the nodes in the blinded route. How, then, would the sender know the relay parameters required by each node, e.g., fees, cltv expiry delta, etc?
This is where the aggregated route relay parameters come in. It is roughly the total amount of fees, cltv_expiry delta required by each node in the blinded route. This is used to compute the required cltv_expiry and the total amount that should be forwarded to the introduction node.
These aggregated route relay parameters consist of the following:
route_fee_base_msat
route_fee_proportional_millionths
route_cltv_expiry_delta
Diana’s task of creating a blinded route is now complete. She now needs to communicate the following details to the sender in her request for payment (lightning invoice):
The node ID of the introduction node. In this case, Elma’s node ID (
N(Elma)
).Blinded node IDs of nodes after the blinded route. In this case, the blinded node ID of Han, Ella, and Diana [
B(Han)
,B(Ella)
,B(Diana)
].The encrypted data for each node in the blinded route. In this case,
encrypted_data
of Han, Ella, and Diana, [encrypted_data(Elma)
,encrypted_data(Han)
,encrypted_data(Ella)
,encrypted_data(Diana)
]The first ephemeral blinding key,
E(Elma)
.Aggregated route relay parameters.
Sending payment to the blinded route.
Alice buys coffee from Diana and wants to make a payment. On receiving Diana’s request for payment (lightning invoice), she noticed that it includes blinded node IDs, encrypted data, and all the other fields mentioned earlier. This means that she is to make her payment to a blinded route.
Alice still creates a route from the final receiver to herself, but this time, things would change slightly.
Note that two new fields were added to the onion routing packet
payload
as a result of this proposal:
encrypted_data
.
current_blinding_point
.
Everything we learned in creating an onion routing packet for payment still applies but with these modifications listed below:
The payload Alice creates for all nodes in the blinded route would contain the corresponding
encrypted_data
for that node which she received from Diana. This would be placed in theencrypted_data
field of the payload.For nodes in the blinded route with a blinded node ID (which should be all nodes apart from the introduction node), whatever functions the node’s public key served during payload creation, the blinded node ID of those nodes would serve.
In the case of the payload of the introduction node, Elma, her payload would contain not just her
encrypted_data
but also the first ephemeral blinding key. This key would be placed in thecurrent_blinding_point
payload field.The payloads in the blinded route do not have
amt_to_forward
oroutgoing_cltv_value
. The blinded node knows the amount and outgoing_cltv_value to forward by calculating this at each hop.The sender uses the aggregate route relay parameters to compute the amount and other relay parameters that should be sent to the introduction node.
Bob and Chan’s payload is still as we learned in mastering the lightning network book.
Receiving payment from the blinded route.
Everything we learned in the prerequisites about decrypting the onion routing packet, deobfuscating the payload, and checking for payload integrity using HMAC still applies when receiving payment through a blinded route. I would just be explaining what happens when the introduction node receives the packet, as that is where there is a slight modification:
When Elma (introduction node) receives the update_add_htlc
message which contains the onion_routing_packet
she deobfuscates her payload from the packet using her node’s private key, k(0)
.
Remember, while Alice created her payload
, she included the current_blinding_point
, which contains the first ephemeral blinding key (E(0)
) as well as encrypted_data
in the encrypted_data
field.
She uses the first ephemeral blinding key to compute the following:
ss(0) = H(k(0) * E(0)) // shared secret.
rho(0) = HMAC256("rho", ss(0)) //encryption key.
E(1) = H(E(0) || ss(0)) * E(0) //Next ephemeral blinding key.
Notice that the computation here is a bit weird as it seems that the introduction node is a creating a shared secret with itself. Well, don't ask me, ask the spec!
She uses rho(0)
to decrypt the encrypted_data
. This exposes the next node to which the payment should be routed, which is Han in this case. The encrypted_data
also contains fee_base_msat
, cltv_expiry_delta
and fee_proportional_millionths
which is used to compute the amount to forward and the cltv_expiry to forward to the next node.
The payload of nodes in the blinded route generally do not contain
amt_to_forward
andoutgoing_cltv_value
. To know the amount and expiry value to forward to the next node, they would need to compute it.Refer to the spec for the algorithm used to compute it.
The next ephemeral blinding point (E(1)
) is communicated to the next node in the blinded route via the update_add_htlc
as the blinding_point
field in the message.
A new field
blinding_point
was added to theupdate_add_htlc
message as a result of this proposal.
The process with intermediate nodes when they receive the update_add_htlc
message is similar. This means that Han and Ella would perform the following steps when they receive the update_add_htlc
:
Compute the next blinding ephemeral key (
E(i+1)
), the encryption key (rho(i)
) and blinding private key (b(i)
) using the blinding point that they received (E(i)
) as well as their node’s private key (k(i)
). The following algorithm is used:E(i) <- extracted from the lightning message's fields (`update_add_htlc`) 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 `update_add_htlc`.
Use the blinding private key (
b(i)
)to deobfuscate node(i)’s payload from the packet.Use
rho(i)
to decrypt theencrypted_data
found in the payload.Use
fee_base_msat
,cltv_expiry_delta
andfee_proportional_millionths
found in theencrypted_data
to compute the amount and cltv_expiry required to be forwarded to the next node.Communicate the next blinding ephemeral key (
E(i+1)
) via theupdate_add_htlc
'sblinding_point
field in the message.Use the information contained in the
encrypted_data
to determine the next node to forward payment to.
The final receiver, Diana, would perform the following steps but would not be computing the amount and expiry value to forward. She would not also be forwarding the next blinding point. In fact, as I explained earlier, her encrypted_data
would not contain details of any next node to forward to. Rather she verifies using the payment_preimage
that it was indeed the blinded route she created for this particular payment that was used to route payment to her.
Voila payment is complete!
Concatenating two blinded routes.
Earlier, I stated that Alice could send payment to the blinded route given to her by Diana through an unblinded route. That is what the diagram above depicts.
It is also possible for Alice to route payment to Diana’s blinded route through another blinded route. Although the spec does not state this, my thinking is that both blinded routes have to come from the same receiver, as that is the only way one can know for sure if one blinded route can pay to the other
There is another field in the encrypted_data that we have not talked about, the
next_blinding_overide
. We would see its use here.
In the picture above, we see that Alice is making the payment using two blinding routes, blinding route 1
and blinding route 2
For blinding route 2
, the introduction node is Bob, while for blinding route 2
, the introduction node is Elma.
Though Chan is the last node in blinded route 2
, in this scenario, her payload would possess details of the next node to which the HTLC should be routed, unlike what was explained earlier. Elma’s encrypted_data
would contain a field known as the next_blinding_override
; this field would contain the first ephemeral blinding point for blinded route 1
. Elma would use this blinding point instead of the one in the update_htlc
message.
Conclusion
As stated in my article, my aim is to create a soft landing to understand route blinding for anyone who has read and understood the onion routing explained in Mastering the Lightning Network book. Now, I would encourage you to read the spec for all the juicy details that I might not have covered here.