[Lightning-dev] Extending Associated Data in the Sphinx Packet to Cover All Payment Details

Christian Decker decker.christian at gmail.com
Fri Feb 8 11:13:05 UTC 2019

Hi Laolu,

thanks for bringing this up. I think committing to more data might be
nice, but I have some reservations re signaling in the onion packet
version. But let's start at the top:

> However, since the CLTV isn't also authenticated, then it's possible
> to attempt to inject a new HTLC with a fresher CLTV. If the node isn't
> keeping around all pre-images, then they might forward this since it
> passes the regular expiry tests. If we instead extend the associated
> data payload to cover the CLTV as well, then this binds the adversary
> to using the same CLTV details.

The CLTV is actually committed to indirectly through the outgoing CLTV
value in the onion payload itself (both for intermediate hops and final
hops). For intermediate hops we will refuse any forward that has a CLTV
value for the next leg that is not far enough in the future based on the
incoming CLTV value. Notice that the values we commit to are not deltas,
but absolute values. This means that a node needs to keep a cache of
shared secrets used until the `outgoing_cltv_value` from the onion dips
below `incoming_cltv_value - cltv_expiry_delta`). Any replay attempt
after that will result in the first hop (adjacent to the attacker) to
reject the HTLC with an `incorrect_cltv_expiry` error.

That being said I'm happy to add more information to the AD, but it may
need to be rolled out differently from what you describe.

> If this were to be deployed, then we can do it by using a new packet version
> in the Sphinx packet. Nodes that come across this new version (signalled by
> a global feature bit) would then know to include the extra information in
> the AD for their MAC check.

This will not really work if the route contains any node that does not
understand the new version of the packet. The node prior to the
non-upgraded node would have to downgrade the packet version from v1 to
v0 understood by the non-upgraded node, which could be done via an
instruction in the per-hop payload itself, but the non-upgraded node
would not have any way of learning that it needs to upgrade the packet
version to v1 again. This means we can use v1 up to the first node that
doesn't understand v1 and have a permanent downgrade for the rest of the

We might get away with signalling this in the payload itself, but that
inverts the processing of the onion into parse and interpret the payload
before checking the HMAC, which I can already hear cryptographers groan
about :-)

> While we're at it, we should also actually *commit* to the packet
> version. Right now nodes can swap out the version to anything they
> want, potentially causing another node to reject the packet.  This
> should also be added to the AD to ensure the packet can't be modified
> without another node detecting it.

I don't think this is really useful. If a node wants to cause us to
reject a packet it can just tamper with anything in the payload and
we'll fail with an HMAC failure. The version really is just a hint as to
how we should process the packet, and if tampered with it'll just cause
us to reject, similarly to when the attacker modifies the ephemeral key.

> Longer term, we may end up with _all_ payment details in the Sphinx packet.

Agreed, we can also just use the serialized HTLC output, since that is
the on-chain representation of the payment, and therefore has to include
all relevant details :-)


More information about the Lightning-dev mailing list