A Treasure Hunt Inside Every Lightning Payment

C

Camillarhi

Guest
Alice has spent weeks hunting for a solid wood bookshelf. She finally finds the one, made by Zoe, a carpenter who sells her work online and takes payment over Lightning. Alice scans the invoice, her wallet thinks about it for a second, and the payment goes through. Alice goes back to measuring her living room wall. Nobody thinks about the route.

There was a route, though. Lightning payments can only travel along payment channels. A channel is a shared pot of bitcoin that two nodes lock up together on the Bitcoin blockchain, so they can pass money back and forth between them instantly, without touching the blockchain each time. Alice has a channel with one node, that node has a channel with another, and so on across the network. What Alice doesn't have is a channel with Zoe. She could open one, but that means an on-chain transaction, a fee, and a wait, all to buy one bookshelf.

So her wallet did the sensible thing. It looked at the public map of channels and found a chain of them linking her to Zoe, through four nodes run by people neither of them has ever met. Each of those strangers had a job to do: take the payment in over one channel, pass it out over the next, and keep a small fee for the trouble. To do that job, each one needed a few instructions. And here is the interesting part. None of them should learn anything more than their own instructions. Not who Alice is, not that the money is for Zoe, not even how many people came before or after them.

Two things make this work. The first keeps the money safe while strangers carry it. At every step, the payment is locked behind a secret that only Zoe knows, with a deadline attached. A stranger can only collect what they're owed by passing the payment on, and if it never arrives, the money goes back where it came from. That arrangement is called an HTLC (Hashed Time-Locked Contract), and it's a story for another day. The second is the little packet of instructions that travels alongside the money, telling each stranger where to send it next while keeping everything else hidden. That packet is called an onion, and this article is about what's actually inside it.

A treasure hunt, run through the post​


A treasure hunt is a game where someone hides a prize and leaves a trail of clues. Each clue tells you where to find the next one, and the last clue leads to the treasure. If you've ever set one up, you know the trick: you hide the treasure first and write the clues backward. The last clue has to point at the treasure, so it gets written first, and every earlier clue has to point at a clue that already exists.

A Lightning onion works like a treasure hunt run through the post. Alice is the organizer, Zoe is the treasure, and the four strangers are station keepers. Instead of hiding clues around a park, Alice sends a stack of sealed envelopes to the first station. The keeper there can open only the top envelope. Inside is a card with their instructions: where to send the stack next, and how much to pass along. The keeper takes that envelope off and sends the rest of the stack on. The next keeper opens the new top envelope, and so on down the line until the stack reaches Zoe.

Every envelope is written in a private cipher that only one keeper can read. On top of that, picture everything under the top envelope as shrink-wrapped into one solid block. A keeper can open the top envelope, but the rest is a single wrapped lump with no visible edges, so they can't tell where one envelope ends and the next begins, let alone read any of them. And just like a real hunt, Alice has to build the stack backward. She prepares Zoe's envelope first, lays the fourth keeper's envelope on top of it, then the third's, and finishes with the first keeper's envelope on top of the whole stack. We'll see later that Lightning has an even stronger reason for this order than the rules of a good treasure hunt.

What's written on each card​


The cards are short and boring, which is exactly the point. We don't have to imagine them, either. The specification that defines Lightning onions, BOLT 4, comes with a test vector: a published example onion, along with everything that went into making it, which developers use to check that their code gets exactly the right answer. Its route has the same shape as Alice's, four keepers and a final stop, so from here on, every number in this article comes straight from it.

The first keeper's card is 19 bytes long. Decoded, it says three things: send 15,000 millisatoshis onward, set the payment's timelock to block 1500, and use channel number 1. That's all. The card doesn't say who Alice is, doesn't mention Zoe, and doesn't say how many stations are left. As far as the first keeper can tell, the next station might be the treasure or just one of many more stops.

Follow the amounts down the route, and you can watch the fees come off. The first keeper is told to forward 15,000 millisatoshis, the second 14,000, the third 12,500, and the fourth 10,000. Zoe's card says she should receive 10,000 millisatoshis, which is 10 sats. In the test vector, at least, Zoe badly needs to raise her prices.

Zoe's card is the biggest by far, at 275 bytes. Besides the amount and timelock, it carries a payment secret that proves the payment really belongs to her invoice, plus a large block of extra data. The test vector stuffs that extra data in on purpose, to check that implementations can handle a big card.

Where an ordinary treasure hunt leaks​


Ordinary treasure hunts give away progress. Some clues literally say "clue 4 of 5". Even when they don't, a stack of envelopes gets shorter every time a keeper takes one off. A keeper who receives a stack of two knows the treasure is one stop away. On Lightning, that would be a real leak. A keeper who knew they were next to last would know they were probably one hop from the person being paid.

So Alice's stack never gets shorter. Before sending it, she fills the bottom of the stack with duds, envelopes that look exactly like the real ones but hold nothing useful. A stack for a two-hop route looks just like a stack for a twenty-hop route. Then, every time a keeper takes the top envelope off, they tuck a fresh dud into the bottom before sending the stack on. Every keeper receives a stack of exactly the same height as every other keeper.

And because everything under the top envelope is wrapped into one block, a keeper can't get around this by counting. From the outside, real envelopes and duds look identical, and you can't count what you can't see. Only the top envelope can ever be opened, and only by the keeper holding the stack.

In bytes, the whole thing is always 1366 bytes. The first byte is a version number, currently always 0. The next 33 bytes are a code written on the outside of the stack, which we'll come back to shortly. Then come 1300 bytes of routing information, which is the stack of envelopes itself. The last 32 bytes are a seal that lets a keeper check that nobody has tampered with the stack on the way.

The onion is the same size at every station. Each keeper can read only the highlighted window at the top of the stack, and everything below it stays unreadable.



The highlighted windows are drawn to scale using the real card sizes from the test vector. Notice how small each one is. Even Zoe's big card uses less than a quarter of the space. For the other keepers, the rest is envelopes they can't read and duds. For Zoe, it's all duds.

A private cipher for every keeper​


Each keeper needs their own cipher, which raises an obvious question. Alice has never met any of these keepers, so how do she and each of them end up agreeing on one?

The answer is a clever bit of cryptography called ECDH (Elliptic Curve Diffie-Hellman). Every Lightning node publishes a public key, a bit like a name on a door. Alice combines the first keeper's public key with a secret of her own and gets 32 bytes. The first keeper combines their own private key with the code written on the outside of the stack and gets the very same 32 bytes. Nobody ever said those bytes out loud, yet both sides now share them, and that shared secret becomes the keeper's cipher. In the test vector, the first keeper's shared secret starts with 53eb63ea, and that exact value appears in the BOLT 4 specification.

Then comes the sneaky part. If the code on the outside stayed the same all the way along the route, two keepers comparing notes over coffee could say "hey, I saw that stack too" and start piecing the route together. So the code changes at every station. Each keeper rewrites it before sending the stack on, in a way only the next keeper can use. Alice worked out every one of these rewrites in advance, so she knew each keeper's cipher before the stack ever left her hands.

Each shared secret then gets stretched into a few separate keys, each with one job. One key scrambles and unscrambles the envelopes. Another makes the seal. Keeping those jobs apart is part of what makes the whole thing safe. The spec gives them rather charming names, rho and mu, which is about as close to poetry as a payment protocol gets.

How a cipher scrambles without losing anything​


So what does a keeper's cipher actually do? There's no ink or paper in a stream of bytes. Instead, the envelopes are scrambled.

Each keeper's shared secret gives a rho key, and the rho key produces a long stream of random-looking bytes. The same key always produces the same stream, and without the key the stream is impossible to predict. That stream gets mixed into the stack with an operation called XOR (exclusive or).

XOR compares two bits and gives 1 when they differ and 0 when they match. It sounds dull, but it has a lovely property: it undoes itself. Here's one byte of a card, the letter A, mixed with one byte of stream:



Bits

Hex

Card byte

0100 0001

41

Stream byte

1001 1100

9c

XOR result, what travels

1101 1101

dd

XOR with the stream again

0100 0001

41

Mix once, and the card turns into noise. Mix again with the same stream and the card comes back, exactly as it was. So the same operation locks an envelope for Alice and unlocks it for the keeper, and nobody without the key can tell dd from any other random byte.

There's a bonus, too. When a keeper runs their stream across the stack, it doesn't just open the top envelope. It changes the look of every envelope underneath as well. So the stack leaving a station looks completely different from the stack that arrived, which makes it even harder for two keepers to recognise the same stack.

Why Alice really starts with Zoe​


Earlier we said Alice prepares Zoe's envelope first because that's how you set up a treasure hunt. The real reason is the seal.

Every envelope carries a seal for the stack underneath it. When a keeper receives the stack, the first thing they do is check the seal before reading a single card. If even one byte was changed along the way, the seal won't match, and the keeper rejects the whole stack. It's like a tamper-evident sticker on a medicine bottle, except it covers every byte.

The seal is also what stops a keeper from shuffling the envelopes. They can't see the edges between envelopes to begin with, and the seal covers the whole block, every byte in its exact order. Cut the wrap open and swap two envelopes around, and the next keeper's seal check fails straight away. The stack is rejected, the payment fails, and the keeper who meddled gains nothing for their trouble.

Now think about what that means for Alice. To make the first keeper's seal, she needs the exact stack the first keeper will hand to the second. That stack includes the second keeper's envelope and seal, which in turn need the third keeper's envelope and seal, and so on down to Zoe. The first seal can't exist until everything under it exists. So Alice has no choice. She starts with Zoe and works up, and the stack travels the other way.

Zoe's envelope gets something special. Every other envelope carries a real seal for the next keeper, but Zoe's has a seal made entirely of zeros. There's no next station, so there's nothing to seal. When Zoe opens her envelope and finds all zeros, she knows the hunt ends with her, and everything still underneath is duds she can ignore. She's the treasure.

Alice builds the onion starting from Zoe's envelope, while the stack itself travels from the first keeper toward Zoe.



In the figure, the left end of each bar is the top of the stack. Each step places one keeper's card and the seal for the next station at the top, then scrambles all 1300 bytes with that keeper's stream. Anything pushed off the other end is simply dropped, because the stack never grows either.

The duds Alice predicts in advance​


Back to those duds. When a keeper takes the top envelope off, the stack loses that keeper's card and seal, so the keeper adds a dud at the bottom to keep the height the same. In bytes, they tack 1300 zeros onto the end of the stack, run their stream across all 2600 bytes, and keep exactly 1300 bytes, starting just after their own card and the next keeper's seal. The front reveals their card and the seal for the next keeper. The zeros at the back turn into a fresh, random-looking dud. The stack leaves at exactly the size it arrived.

One keeper's turn. Check the seal first, then unscramble, then keep exactly 1300 bytes for the next station.



There's a catch, and it's the cleverest part of the whole design. Those fresh duds become part of the stack the next keeper receives, and the next keeper's seal covers them too. So Alice had to know, before the stack ever left her hands, exactly what every dud would look like. And she did. Each dud comes out of a keeper's own stream, and Alice knows every keeper's cipher, so she can predict every dud byte for byte. The spec calls this precomputed padding the filler. Alice slots it into the stack while preparing Zoe's envelope, and from then on it rides along looking like every other scrambled byte.

When Zoe finally opens her envelope, she finds her card, then that all-zero seal. No next station, nothing to forward. The bookshelf is paid for.

One stack, one payment​


One more detail keeps the hunt honest. Each seal covers more than the 1300 bytes of the stack. It also covers the payment hash, the fingerprint that identifies Alice's payment and the HTLC carrying it. So a keeper can't lift the stack off Alice's payment and attach it to a different one. The next keeper's seal check would fail, and the stack would go nowhere.

A keeper also can't simply send the same stack through twice. The spec tells every node to remember the seals it has already seen and reject a repeat.

Put it all together and you get a stack that is the same height at every station, opens for exactly one keeper at a time, tells each of them only their own instructions, and falls apart the moment anyone meddles with it. All of that for a 10 sat bookshelf.

What the keepers can still see​


No disguise is perfect, so it's worth being honest about the gaps. Every keeper knows who handed them the stack and who they're passing it to. There's no hiding that, since they're moving money between those two neighbours. Their card also shows an amount and a timelock, and those can give rough hints about how close the end might be. These side clues are a known limitation of Lightning privacy, and they sit outside what the onion itself can hide. What the onion does guarantee is that nothing inside the stack gives the rest of the route away.

Going further​


Everything in this article can be checked against the real thing. The card sizes, the amounts, the shared secret, and the all-zero seal all come from the BOLT 4 test vector, which contains the full onion, every keeper's card, and each keeper's private key. The rules themselves are in the BOLT 4 specification. If you want to see how a production Lightning node builds and peels onions, rust-lightning's onion code is open source and well commented.

The same machinery shows up elsewhere in Lightning too. When a payment fails partway along a route, the failing node uses its shared secret to send a scrambled error back to Alice. Blinded paths let Zoe hide the last stretch of the route from Alice herself. Both are described in BOLT 4, and once you understand the stack, they are much easier to follow.
 

Thread statistics

Created
Camillarhi,
Replies
0
Views
12
Back
Top