What is “Onion Routing” in the Lightning Network and how does it work?
How does Onion Routing work in the Lightning Network?Original author: LORENZO Translation: btcstudy
A computer in a network communicates with others based on protocols. Here, “protocol” refers to a set of rules that specify how messages should be transmitted and interpreted. The payment message transmission part of the Lightning Network protocol is described by BOLT#4, also called the “Onion Rounting Protocol”.
Onion routing is a technology that was invented 25 years before the Lightning Network. It is also used in Tor, and the name “Tor” comes from “The Onion Router”. Lightning Network uses a slightly modified version called “Source-routed Onion Routing”, abbreviated as “SPHINX”. In this article, we will discuss how onion routing works.
Why use onion routing?
There are many different communication protocols in the world, but because the Lightning Network is a payment network, it is reasonable to choose a protocol that reveals as little information about the payment being forwarded as possible.
- Can the fluctuating Worldcoin and the UBI economics of the AI era come true?
- “Tactical” dissolution, division of national treasury assets, new profit model for DAO?
- MakerDAO Core Development Team proposed to increase the DAI savings rate from 1% to 3.33%
If the Lightning Network used the same protocol as the Internet, every intermediary would know who the payment sender and receiver are, and who the other intermediaries on the entire path are. Onion routing is a good choice because its characteristics ensure that intermediate nodes:
Only know their previous node (who sent them the message) and their next node (where the message should be forwarded).
Do not know the length of the entire path;
Do not know their position in the path.
Overview of onion routing
Let’s use a package as an analogy to explain how onion routing works.
Suppose Alice wants to pay Dina. First, Alice needs to find a feasible path for her payment:
Alice → Bob → Chan → DinaThen, she constructs an “onion”. She starts from Dina (starting from the end of the path). She puts a secret message (payment content) in a package sent to Dina, and locks it with a key that only she and Dina know. Now, she puts this package into another package that is ready to be sent to Chan, and locks the package sent to Chan with a key that only she and Chan know. And so on.
Alice sends the final onion (package) to the first intermediate person on the path, Bob. Bob uses their own key to unlock their package and sees that the next package is meant for Chan. They then forward the package to Chan. Chan does the same, unlocks the package, and forwards the inner package to Dina. Finally, Dina opens their own package and finds the payment message inside.
In onion routing, intermediate nodes like Bob and Chan do not know the contents of the message intended for Dina, nor do they know the length of the payment path. The only thing they know is who sent them the package and who the next recipient is. This ensures message privacy and path confidentiality. Each intermediate node can only access the layer of the message specifically created for them.
In the source-based onion routing used by the Lightning Network, the sender chooses the payment path and constructs the complete onion for that path, which can be seen as a privacy vulnerability (the receiver’s network location must be exposed to the sender). Other routing schemes such as “blinded routing” address this issue by obscuring parts of the payment path from the sender. However, in this article, we focus on Sphinx.
Assembling the Onion
Now let’s look at the specifications for onion routing. To begin, we need to define the following:
-
The sender is the “origin node” (Alice);
-
The receiver is the “destination node” (Dina);
-
Each intermediate node on the payment path is a “hop” (Bob and Chan);
-
The communication information between each hop is called the “hop payload.”
Constructing the Hop Payload
Once Alice chooses a payment path, they obtain information about each payment channel from the gossip protocol in order to create the payload for each hop, essentially telling each hop how to create an HTLC (Hash Time Locked Contract) for the payment being forwarded.
To build a suitable HTLC, each hop needs:
-
The amount to forward;
-
The payment secret value;
-
The ID of the payment channel to continue forwarding the onion;
-
The length of the time lock.
Most of this data comes from “channel updates” messages, which include information about routing fees, required events, and payment channel IDs. The total amount that needs to be forwarded is the payment amount plus the total amount of fees charged for each subsequent hop; and the payment secret is calculated by Dina and embedded in the payment invoice (informed by the onion message at each hop along the path).
Alice starts from the final node Dina. She includes the forwarding amount, time lock duration value, payment secret value, and payment amount in the package. Note that she does not need to include the channel ID because Dina is the final node and does not need to forward the payment to anyone else.
At first glance, providing the forwarding amount is redundant because this amount is the same as the payment amount, but multi-path (multiBlockingth) payments will deliver the total payment amount through multiple paths, at which point the two values will be inconsistent.
In the Chan payload, Alice adds the channel ID between Chan and Dina. She also added the forwarding amount and time lock value. Finally, Alice creates a payload for Bob. Chan charges 100 satoshis for its payment through its channel with Dina, so Alice needs to tell Bob that the forwarding amount is the payment amount plus the fee. According to Chan’s channel update message, the time lock value has also increased by 20 (in blocks). Finally, Alice must also consider Bob’s fees and time lock requirements, giving him an HTLC with a time lock length of 700040 and a value of 100200 satoshis.
Shared Secret Value and Key Generation
Next, Alice generates a shared secret value for each hop (including the final node) to prepare the onion. This shared secret value can be generated by Alice and the target hop separately, by multiplying their private keys with each other’s public keys.
The shared secret value is necessary for onion routing, which allows Alice and each hop to derive the same key. Alice then uses these keys to obfuscate each layer of the onion, while the hop uses the key to unscramble the obfuscation.
To protect Alice’s privacy, she creates a one-time session key for an onion instead of using her node’s public key to derive the shared secret value. She uses this session key for the first hop, and for each subsequent hop, Alice deterministically randomizes the key by multiplying the latest key by a blinding factor. These keys used to create shared secret value are called “temporary keys”.
Bob, Chan, and Dina all need to get the same secret value from Alice, so they need to know the temporary key used in their session. Alice only puts the first key in the onion to save message size. Each hop calculates the next temporary key and embeds it in the onion given to the next node. Each hop can calculate the blinding factor used by Alice using their own public key and the shared secret value to determine the next temporary key.
As mentioned earlier, the shared secret value is used to generate some keys that Alice and the corresponding hop can use to perform some operations on the onion. Let’s see the purpose of each key.
Rho key
Alice uses the rho key to encrypt a layer of the onion, which confuses the content of the payload and makes it unreadable to outsiders. Only the owner of the rho key can decrypt the payload. That’s what the node receiving the onion does: use the shared secret value to derive the rho key and then decrypt the onion to read the content.
Mu key
Alice uses the mu key to create a checksum for each payload. She also hands the checksum to the hop receiving the onion. In turn, this hop uses the mu key to generate the checksum of the received payload and checks whether it matches the one given by Alice. This is to check the integrity of the payload and confirm that it has not been tampered with.
Blockingd key
This key is only used by Alice to generate random “garbage” data. This data is also part of the onion and is unrelated to the length of the payment path or how many hops the onion has passed through. It allows the onion to always have the same size, even if some of its content is irrelevant. This is how onion routing hides the length of the path, which actually protects the privacy of the sender and receiver.
Um key
This key is also used to check the integrity of the data contained in the onion, but only when an error is returned. Yes, it’s called “um” because it’s the reverse of “mu.” In the event of a payment error, the hop that found the error will use the um key to create a checksum, and the previous node that received the error will also use the um key to verify the integrity of the message.
Encapsulating the Onion Layer
The final onion packet looks like this:
Now, Alice has the payload for each hop and the shared secret value for each hop. Let’s see how Alice converts this information into the final onion. She starts from the final node and works her way back.
She first creates an empty 1300-byte field, which is the total length of all onion payloads. Then, she uses a Blockingd key to create a random string of 1300 bytes, which is useless for any hop. Doing this ensures that each layer of the onion looks the same, so neither the total length of the path (how many hops there are) nor who the sender and receiver are can be seen.
She then creates a checksum for the payload that needs to be used and places it at the end of the payload. In the message to the final node, all checksums are 0 to let Dina know that she is the final recipient of this onion. After adding the checksum to the end of the payload, Alice places the payload (and checksum) at the beginning of the garbage and removes any part of the message that is longer than 1300 bytes to ensure that the length of the entire message is exactly 1300 bytes.
Next, Alice creates a random byte string using the rho key and XORs the onion payload obtained in the previous step to get the obfuscated payload. The original text of the payload can be obtained by XORing the obfuscated text with the random byte string that was used (translator’s note: in other words, XOR here is a symmetric encryption algorithm, and the random byte string is the key). The XOR operation compares each bit of the onion payload and the (rho key-generated) random byte string one by one, and only outputs 1 when the bit of one of the data is 1; this produces an obfuscated payload. The clever part of the XOR operation is that once you have the correct random byte string and the obfuscated payload, you can use them to perform the XOR operation again to obtain the unobfuscated payload.
Because the node receiving the onion can deduce the same rho key, they can generate the same random byte string as Alice. This is how each node along the way can unobfuscate and read the content.
After preparing the next hop’s onion, Alice repeats the same steps. The key difference is that after completing Dina’s onion, she no longer needs to generate garbage. She only needs to attach the previously generated scrambled onion to the useful payload and checksum, and then cut off any excess beyond 1300 bytes. The following GIF demonstrates the entire process: https://youtu.be/FzedRXqZDyY
Finally, Alice obtains the final scrambled onion and adds a checksum so that Bob can verify the integrity of the onion. Then she adds the session public key so that Bob can use it to calculate the shared secret value. Finally, she adds a byte indicating the version to inform other nodes how to interpret the data. For the version described in BOLT#4, the version byte should be 0.
Forwarding the Onion
To send this onion packet, the sender creates an update_add_htlc
message that includes the following fields:
-
Channel ID: the specific channel that this message is related to.
-
ID: the identifier of this HTLC.
-
Amount: the value of this HTLC.
-
Payment hash: created by the payee.
-
Expiry: the HTLC will expire after a certain number of blocks.
-
Onion packet: the onion created for this payment, i.e. the thing mentioned above.
-
Extra data: used to specify additional data.
After preparing the message, Alice sends it to Bob. Upon receiving the message, Bob can start decoding his own onion. He first obtains the session key from the onion packet, and then uses it to derive the shared secret value with Alice.
With the shared secret value, Bob generates a mu key to verify the checksum embedded in the onion packet’s payload. If the payload has not been tampered with, the checksum should match.
To prevent other nodes on the path from knowing how long the path is, Bob adds a 1300-byte field filled with zeros inside the onion packet. Then, Bob generates a 2600-byte random byte string from the rho key. Bob uses this random byte string to perform an “XOR” operation on the onion payload filled with 0s.
Do you remember how I told you about the onion routing scheme? By using an obfuscated onion payload as input and XORing it with the same byte string, you can obtain the unobfuscated onion payload. Since Alice and Bob use the same shared secret value to generate the same rho key, Bob can unobfuscate it. An additional benefit of doing this is that it turns the 1300-byte padding characters into random bytes.
Bob’s unobfuscated payload includes his own hop’s payload data and a fingerprint. Bob saves this fingerprint to add to the onion packet sent to Chan. After Bob separates his own payload from the onion message, he converts the onion packet back to its original 1300-byte size and randomizes his session key just like Alice did. Finally, Bob adds the version byte, session key, and fingerprint he prepared for the onion payload and forwards the onion packet to Chan via the update_add_htlc message.
This process continues until the message reaches the final node, Dina. When Dina receives the update_add_htlc message, she can stuff the hash of the secret value she generated into it, which indicates that this HTLC is intended for her. Therefore, Dina only needs to check the fingerprint, unobfuscate the onion message, and reveal her own payload. This animated GIF shows the entire process: https://youtu.be/NhHAE6m9L6A
Failure handling
We have described a success case, where everything proceeds as planned, but if something goes wrong during this process, a message must be sent back along the path to notify all nodes that something is wrong. This process is similar to regular onion routing. A node that discovers an error needs to derive the um key from the shared secret value, generate a random byte string using it, and then obfuscate the returned onion packet using XOR.
The node that discovers the error sends a message back to the previous node on the payment path. Each hop performs the same operations with the um key and ammag key until the sender receives the packet. Finally, the sender unobfuscates and verifies the package with the ammag key and um key, respectively.
Errors can be caused by onion packets, nodes, or channels. If you use the Lightning Network frequently, you may encounter errors such as “channel unavailable” or “insufficient fee”.
References
Mastering the Lightning Network
BOLT #4: Onion Routing Protocol
We will continue to update Blocking; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- Comprehensive overview of the gaming industry: Pie in the sky or an oasis in the desert
- Mint Ventures Talks with Pendle CEO: Seizing Hotspots to Build Breakthrough Products
- Web3 Social: DID First, DAPP Second
- Understanding Rare Con is just one article: what other expandable gameplay is there?
- Understanding Consensus Mechanism and 11 Popular Consensus Algorithms in One Article
- Summary of the 162nd Ethereum Execution Layer core developer meeting: The reasonable target time for the Cancun upgrade is October.
- Explaining Futures Contracts in Contango: Low and Predictable Costs