Skip to content
buybitcoinsmart

Glossary / Lightning & layer 2

Onion routing

Also known as sphinx.

What is Onion routing?
Onion routing is the layered encryption Lightning uses to send a payment across several hops, giving each node only the instructions for its own forward and nothing else.

Every Lightning payment rides inside a fixed 1,366 byte packet whose layers are peeled one at a time, so a forwarding node learns its predecessor and successor, nothing more. The packet stays the same size at every hop, hiding the route length and your position in it. Your privacy from strangers in the middle is strong; from the wallet or exchange at each end it is not.

How it works

Onion routing encrypts the route in layers, one per hop, wrapped in reverse order so peeling the outermost layer is the only operation any node can perform.

BOLT 4 calls the construction Sphinx, extended with a per-hop payload. Before the payment moves, your wallet knows the public key of every node on the route and uses ECDH against each one to derive a shared secret. Four keys come out of every shared secret: rho generates the byte stream that obfuscates the packet, mu computes the integrity HMAC, um authenticates errors on the way back, and pad seeds the filler. That stream is ChaCha20 run over zeros with a 96-bit zero nonce, safe here only because no key is ever reused.

The packet has four fields and one fixed size: a version byte, currently 0x00, a 33-byte compressed secp256k1 point acting as the ephemeral key, 1,300 bytes of hop payloads, and a 32-byte HMAC. That is 1,366 bytes on the wire, needing no length prefix.

Assembly runs backwards. The 1,300 byte region starts as random bytes from a ChaCha20 stream, and for each hop from the last to the first it is right-shifted to make room, pushing the far end off the edge and throwing it away. For a payload under 253 bytes the shift is that payload's length plus 33: one length byte and 32 bytes of HMAC. Each shift is followed by an XOR against the hop's rho stream, which scrambles the earlier layers again.

What a hop reads is a short list of typed fields: type 2 is amt_to_forward in millisatoshis, type 4 is outgoing_cltv_value, the timelock it must put on the HTLC it offers next, and type 6 is short_channel_id, naming the channel to use, although a node may substitute another channel to the same peer. In place of that short channel id the final node gets type 8, carrying a 32 byte payment secret and the total amount.

One more step keeps consecutive packets unlinkable. Each hop tweaks the ephemeral key by a blinding factor before passing it on, so the same onion looks like unrelated bytes on every link it crosses. BOLT 4 is honest about the limit: the obfuscation "does not preclude the possibility of packet association by an attacker via traffic analysis."

Why this matters when you buy bitcoin

Onion routing protects you from the strangers in the middle of a route and from nobody at either end of it, which is the most misread thing about Lightning privacy.

The first hop is usually a service you already have a relationship with, and it sees far more than a random forwarder does. Our Phoenix review quotes ACINQ's own FAQ without softening it: "The current version of Phoenix offers no advantage regarding privacy over existing, hosted, custodial wallets. We (ACINQ) know the final destination and amount of payments." Phoenix rates 4.0 here and is genuinely self-custodial, a real node on the handset behind a 12 word seed. Custody and privacy are separate questions, and it answers only one of them well.

The receiving end is no better. Strike is custodial while funds sit in the app and requires identity verification, so a Lightning withdrawal to your own wallet tells Strike the amount, the moment and the invoice it paid, however many hops the onion crossed. Wallet of Satoshi carries a caution status and a 2.7 rating here partly because the company holds the keys, and it has already withdrawn its custodial Lightning service from the European Union.

So do not read onion routing as a compliance workaround. It does not change which legality section of a country guide applies to you, it does not hide a purchase from the exchange that sold it, and it gives you nothing when your wallet's operator is one of the endpoints. What it buys is still worth having: a routing node you have never heard of cannot build a graph of who pays whom, cannot tell whether you are the sender or another hop, and cannot tell a short route from a long one.

Paying a Strike invoice through two nodes you have never heard of

Paying a Strike invoice over Lightning shows what each node in a route does and does not learn.

Say your wallet picks a four node path: your own peer, two public routing nodes, then Strike. The packet is built from Strike backwards. Strike's payload gets the final amount and the payment secret. Each middle payload gets an amt_to_forward that still contains the fees of everyone downstream, an outgoing_cltv_value stepped down by that node's advertised delta, and the short_channel_id of the link to use.

The second routing node reads exactly one payload. It learns that the node before it handed over an HTLC and that it must offer a slightly smaller one onward. It does not learn that Strike is at the end, does not learn that you are at the start, and cannot tell whether the path is four hops or eight, because the region it passes on is the same 1,300 bytes it received.

If that node has no liquidity for the forward, it builds a return packet: an HMAC under its um key, a failure code, padding chosen so the failure message plus padding runs to at least 256 bytes, and the result XORed with a stream from an ammag key. Every hop on the way back obfuscates it again. Your wallet unwraps the layers and then keeps decrypting until the loop has run 27 times, the longest route the TLV payload format allows, so the failing node cannot work out its position by timing a repeated attempt. Newer nodes attach attribution data too: HMACs truncated to 4 bytes, 210 of them for a route sized at the maximum of 20 hops, and hold times in units of 100 milliseconds.

Onion routing vs blinded path

Onion routing hides the route from the nodes carrying a payment, while a blinded path hides the tail of the route from the person paying.

Plain onion routing needs the sender to know every node's real public key, because the shared secrets come from ECDH against those keys. Route blinding inverts that for the last leg: the recipient builds a chain of tweaked node ids, turning Bob into Bob prime and Carol into Carol prime in BOLT 4's own example, then hands the sender an introduction point plus one encrypted blob per hop. The sender wraps an onion around blobs it cannot read. The two compose rather than compete: BOLT 4 requires every onion message to use route blinding, and an onion message uses the same packet form as a payment onion.

Onion routing vs HTLC

Onion routing carries the instructions and an HTLC carries the money, and a Lightning payment needs both because each one checks the other.

The onion tells a hop where to forward and how much. The HTLC is the conditional payment actually offered on the channel. Because the payload region is covered by a packet-wide HMAC only the sender and that hop can produce, a node compares the HTLC it was offered against the amt_to_forward and outgoing_cltv_value written for it and fails when they disagree, which catches an upstream node quietly shaving the amount. They also come apart: an onion message, type 513, is the same construction carrying no money, and no error ever returns from a middle hop for one.

Not to be confused with

Frequently asked questions

Is Lightning onion routing the same thing as Tor?

No, although both borrow the same layered encryption idea. Lightning wraps a single payment in a fixed 1,366 byte packet routed over its own channel graph, where the specification's maximum supported route is 20 hops, while Tor carries general internet traffic over a separate volunteer network. Running your Lightning node over Tor is an extra and independent privacy step.

Does onion routing hide my purchase from the exchange I bought it from?

No. An exchange or wallet provider is an endpoint rather than a middle hop, so it sees the amount, the timing and the invoice regardless of how many nodes the onion crossed. Onion routing only blinds the nodes between the two ends of a route.

Why does my wallet know which hop failed if nodes cannot see the route?

Because failures are meant to be attributable to the sender and to nobody else. The failing node encrypts an error under a key only it and your wallet share, every hop obfuscates it again on the way back, and your wallet keeps decrypting until the loop has run 27 times, the longest route the payload format allows, so the failing node cannot work out its own position.

Read next

Sources

Last reviewed 2026-09-06.

Related terms

More in Lightning & layer 2