Lightning Watching for Cheaters

The Lightning protocol works by peers constantly exchanging updated transaction pairs as payments move between them. Say the first one pays $1 to me and $1 to you. you want to pay me 5c, the next one pays $1.05 to me and $0.95 to you, etc.

This raises the obvious question: what if one side tries to publish an old transaction? The answer is one of the key insights in the original Lightning paper: to update to a new transaction, we send a revocation secret which allows the other side to spend the old transaction if we were to ever try to spend it. And all of the transactions incorporate a delay (say, 1 day), to allow the other side to take the funds if they have that revocation secret.

Lightning channels require attention: you need to check for on-chain cheating every so often.

But what if you know your counterparty is going to be offline for a day? Here’s your chance to publish an old transaction and profit! It’s risky, but certainly not inconceivable.

Thus the original paper suggested you could outsource the vigilance to a third party, who would broadcast your presigned “take all the funds” tx for you if it ever saw the cheating attempt. You might pay them some monthly fee. Think of it as a form of insurance: it’s not 100% reliable (third party watchers could be bribed), but on the other hand, your counterparty can never know for certain that you didn’t ask some other watcher, too.

Tadge recently started implementing it, but he also set a very ambitious bar: the watcher should learn nothing about your lightning transactions, not even the transaction which opened the channel, unless a cheating attempt was made. Then the watcher only learns about the transaction which was actually used to cheat and the funding transaction. His solution required significant changes to the form of commitment transactions to avoid information leakage.

I’d toyed with the idea before (as I’m sure others have); my solution was to give the watcher an encrypted signature and metadata for the “take all the funds” transaction, where the cheating transaction itself can be used to decrypt it (say, the SHA256(txid) as the key, which thanks to Segregated Witness, is immalleable).

But I assumed we’d tell the watcher the channel funding tx, for it to trivially determine what txs were potential cheaters (rather than examine every transaction against everything it was told to watch for). And I hadn’t worried about information leakage in the case where a cheating attempt was found.

Tadge fixed the first problem by providing a truncated (8 or 16 byte) txid with each watch notification, indicating the first bytes of the cheating txid. As long as you can’t guess what’s in that transaction, you can’t get any information from that txid prefix.

The problem is, that once a watcher has one commitment transaction (eg, cheat attempt or unilateral close), it becomes much easier to guess what the previous transactions looked like. Assume the previous transaction had one fewer HTLCs, or add another known HTLC, etc. We need an unpredictable large field in the commitment transaction to prevent this; the 160-bit revocation hash is sufficient, for example.

But there’s a final wrinkle: the revocation preimages are generated using a tree (eg. shachain, or elkrem), to save storage costs. This means if you have one, you can generate some or all previous ones; and the watcher is given a preimage as part of the “take all the funds” transaction which it can access once it sees a cheating attempt. So a minor tweak to the protocol: we SHA256 the leaves of the tree again before using them as preimages, thus revealing the preimage doesn’t allow you to know previous ones.

There are many more asides, and more details to be worked out; Tadge’s thread has many more fascinating details. But it shows the subtlety of lightning protocol design: if he hadn’t tried to implement this, we might have settled on a protocol where outsourcing vigilance meant unnecessarily compromising privacy…