[Lightning-dev] Outsourcing route computation with trampoline payments

ZmnSCPxj ZmnSCPxj at protonmail.com
Mon Apr 1 04:04:44 UTC 2019


Good morning Rene and Pierre,

An issue here (which I think also affects Rendezvous Routing) is with compatibility of the HMAC.

HMAC covers the entire 1300-byte `hops_data` field.

If, in order to reach the next trampoline, more than one intermediate node is inserted, would the packet that reaches the next trampoline have a valid HMAC still?
Consider that the filler data generated by the current trampoline to communicate with intermediate nodes may cause different filler data to be XORed with the 0x00 data added to left-shift the data at each intermediate node.
(I am unsure if I express myself coherently here)

So for example, suppose I am the source and I trampoline to nodes B and C, and pay to destination D.
Suppose B is a direct neighbor of mine, but I have no idea where C and D are.

Suppose for simplicity that the onion packet is just 6 hops long.
So I initialize as:

[ 00000 ] [ 00000 ] [ 00000 ] [ 00000 ] [ 00000 ] [ 00000 ]

I right shift and insert destination D:

[ D, here's my payment ] [ 00000 ] [ 00000 ] [ 00000 ] [ 00000 ] [ 00000 ]

Then I encrypt with some shared secret known by me A and D:

[ encrypt(A * D, "D, here's my payment") ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ]

Then I right shift and insert trampoline C:

[ C, send this to D ] [ encrypt(A * D, "D, here's my payment") ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ] [ encrypt(A * D, 0) ]

Then I encrypt with some shared secret known by me A and C:

[ encrypt(A * C, "C, send this to D") ] [ encrypt(A * C, encrypt(A * D, "D, here's my payment")) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ]

Then I right shift and insert trampoline B:

[ B, send this to C ] [ encrypt(A * C, "C, send this to D") ] [ encrypt(A * C, encrypt(A * D, "D, here's my payment")) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ]

And encrypt with A * B:

[ encrypt(A * B, "B, send this to C") ] [ encrypt(A * B, encrypt(A * C, "C, send this to D")) ] [ encrypt(A * B, encrypt(A * C, encrypt(A * D, "D, here's my payment"))) ] [ encrypt(A * B, encrypt(A * C, encrypt(A * D, 0))) ] [ encrypt(A * B, encrypt(A * C, encrypt(A * D, 0))) ] [ encrypt(A * B, encrypt(A * C, encrypt(A * D, 0))) ]

I send this to B, who removes one layer of encryption:

[ B, send this to C ] [ encrypt(A * C, "C, send this to D") ] [ encrypt(A * C, encrypt(A * D, "D, here's my payment")) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ] [ encrypt(A * C, encrypt(A * D, 0)) ]

Now B finds the shortest route involves nodes N and O before reaching C.
So B has to insert N and O, pushing out one packet from the end.
But the pushed-out packet will no longer be recoverable and it cannot be re-encrypted except by A.

(Unless I misunderstand the onion construction)


Unless we propose to massively change the onion packet construction...?


> 1.) A different fee mechanism. Let us (only as a radical thought experiment) assume we drop the privacy of the final amount in routing.

Please no.

> A sending node could offer a fee for successful routing. Every routing node could decide how much fee it would collect for forwarding. Nodes could try to collect larger fees than the min they announce but that lowers the probably for the payment to be successful. Even more radical: Nodes would not even have to announce min fees anymore. Turning routing and fees to a real interactive market

Would this not also require that intermediate nodes know the ultimate destination of the payment?
How would intermediate nodes find out which next hop would be reasonable?

Regards,
ZmnSCPxj


More information about the Lightning-dev mailing list