[Lightning-dev] [Proposal][Payment Route Reservation] PTLC/HTLC with Reusable Static Invoices
Proposal Summary The following proposal is intended to adapt the existing PTLC protocol into Payment Route Reservation[1] flow. Modifying the original PTLC protocol slightly, we get support for reusable static invoices with atomic proof of payment and payer proofs, that don't require previous communications between sender and receiver. By doing so, we will also reduce the number of cryptographic calculations the sender needs to perform for each PTCL payment. Then a similar approach is also applied to HTLC, with the same benefits. To best understand the proposal, let's first start by presenting the original PTLC protocol and then proceed to describe the iterative changes made to it. PTLC protocol = Let's use Alice, Bob, Carol, and Dave example from this page: https://github.com/BlockstreamResearch/scriptless-scripts/blob/master/md/multi-hop-locks.md Z <- Z = z*G Alice ---> Bob ---> Carol --> Dave || | | y0 y1 y2 z tab=z+y0tbc=z+y0+y1tcd=z+y0+y1+y2 Tab=Z+y0*G Tbc=Z+y0*G+y1*G Tcd=Z+y0*G+y1*G+y2*G * y0, y1, y2 - decorrelation secrets * z - proof of payment * tij - adaptor secret for the adaptor point between nodes i and j * Tij = tij*G adaptor lock point between nodes i and j * sig(m,Tij) := psig(i,m,Tij) + psig(j,m,Tij) + tij - is the complete Schnorr signature for the transaction between i and j. A brief summary of the PTLC protocol: 1. The receiver, Dave, shares proof of payment point Z(=z*G) with the sender, Alice. This is typically done by publishing a QR code. 2. Alice generates random decorrelation secrets (y0, y1, y2). 3. For each hop in the route, Alice calculates a tuple (Li,yi,Ri) using the formula: Ri <- Li + yi*G and Lj <- Ri. * Li - left adaptor point * Ri - right adaptor point * yi - decorrelation secret 4. Alice generates a payment onion that includes the previously calculated lock information for each hop on the route. For Dave, Alice includes (y0+y1+y2) decorrelation secret sum(we ignore stuckless payment for now). 5. Forwarding nodes use the lock information to construct a partial 2-of-2 MuSig2 signature. 6. When Dave signs the transaction with Carol, he reveals the adaptor secret `tcd` to Carol. 7. Carol then calculates adaptor `tbc` secret using the formula `tbc = tcd - y2`, which allows her to sign the transaction with Bob. 8. Bob calculates the adaptor secret `tab` using the similar formula `tab = tbc - y1`. 9. Eventually, when Bob signs his transactions with Alice, Alice can calculate the proof of payment `z = tab - y0`. Note that Alice does a lot of work here, especially in step 3, which requires a lot of elliptic curve additions and multiplications. This workload increases with the length of the route, resulting in more work for the sender. While this is not typically problematic, it can become an issue if the sender is a mobile wallet with limited computational resources. PTLC with reusable static invoices == We gonna make two modifications to the vanilla PTLC flow: 1) To alleviate Alice of heavy elliptic curve calculations, we will let routing nodes calculate their decorations secrets and adaptor points independently. But in such a way that the sender (Alice) and routing nodes get to the same shared decorrelation secret. This can be easily done because sphinx onion routing already establishes one shared secret with each hop, from which we can calculate as much as new shared secrets as we want. For instance, we can use this formula: yi = hmac("decorrelation secret", sharedSecret(i)) 2) The second change we gonna make is how the tuple (Li,yi,Ri) is calculated for each hop. Currently is made using this formula: Ri <- Li + yi*G, Lj <- Ri. and we gonna change it into: Ri + yi*G <- Li and Lj <- Ri. After applying this formula to the previous example, we get the following: Alice ---> Bob ---> Carol > Dave || | | y1 y2 y3, z tab=(z+y1+y2+y3)tbc=(z+y2+y3) tcd=(z+y3) During the PTLC resolve phase, everything remains the same, with the exception that intermediate hops will now add their decorrelation secrets instead of subtracting them: tbc = tcd + y2 tab = tbc + y1. In addition, Alice calculates the proof of payment (z) slightly differently: z = tab - (y1 + y2 + y3) // tab will get when bob signs the transactionAB, (y1, y2
[Lightning-dev] Payment correlation attacks
Using payment correlation attacks adversary can try to link the sender and receiver of payment by observing traffic from the potential sender to the potential receiver. Such observations can be made by the adversary nodes if they are present on the payment path or if the adversary is able to monitor the network traffic of the potential sender and receiver. In some circumstances, the adversary can detect not only his presence on the payment path, but also if the monitored nodes are the sender and receiver. ___ ___ | | | | | | | | --| S |->| A1 |--> . -->| A2 |->| R |-- |___| || || |___| S - potential sender R - potential receiver A1, A2 - adversary surveillance node For big well-distributed networks, these forms of attacks are very costly and can be economically applied only on a small set of nodes. However, if a network is centralized, with the majority of traffic passing through a small number of big nodes, an adversary's job is much easier. An adversary can monitor traffic on those nodes, or in the case of a state-funded surveillance adversary, an adversary can acquire a court order to get complete access to big nodes routing information. The adversary job can be simplified if: - A1 and A2 are the same nodes. The sender and receiver are connected through a single node, the adversary node. - A2 and R are the same nodes. The receiver is some form of custodial wallet, directly controlled or in collusion with the adversary. The adversary is going to be aware of all income transactions. The only thing left is to find out who the sender is. - S and A1 are the same nodes. If the sender is some form of custodial wallet, directly controlled or in collusion with the adversary, the sender has no privacy, so correlation attacks are unnecessary. - S->A1 is an unpublished channel. An adversary can identify S as the sender for all payments originating from S and passing through A1. - A2->R is an unpublished channel. An adversary can identify R as the receiver for all payments destined for R and passing through A2. The most notable LN payment correlations in order of severity are: * Hash correlation * Amount correlation * CLTV correlation * Timing correlation Hash correlation Hash correlation is the most straightforward to detect for surveillance nodes. If adversary nodes A1 and A2 observe a payment with the same hash, they can confidently conclude that they are on the payment path. However, the adversary cannot yet determine with enough certainty whether S is the sender and R the receiver. Yet, when combined with other correlation attacks or network topology examination, the adversary can establish such a conclusion with enough probability. Fortunately, payment hash correlation is soon expected to be fixed with point time lock contracts (PTLCs)[1]. Each payment hop will use a unique lock contract point, so there will be no information that can correlate different payments. Amount correlation == Payment amount correlation is only slightly better than hash correlation in terms of privacy because the receiver amount on each hop is mixed with the fees of all the downstream nodes. Fees on LN are just a tiny fraction of the amount, so for the attacker fees are not an issue, especially in combination with timing correlation attacks. Single-path payments are the most vulnerable to amount correlation attacks. Besides the fact that nodes A1 and A2 will see a payment with roughly the same amount, node A2 depending on the payment amount, can conclude that R is a receiver. For instance, if the receiver is a shop that sells some product for X satoshis, and if the attacker sees a payment of around X satoshis, he can be sure that this payment goes to that shop node. Multi-path payments have better privacy because the amount is now split into multiple parts. The attacker can not easily find out what product the sender is buying. But there is still a potential correlation factor, depending on how we split the payment amount. If we split the payment into equal parts, the attacker still can find out if a partial payment is multiple of the price of some of the shop products. Also, those sub-payment paths will be easily distinguishable by the amount, just like in the case of single-path payment. So, what can be done to de-correlate sub-path payment amounts? Rather than splitting the payment amount into equal parts, we split it into predefined values. For instance: 10k, 20k, 50k, 100k, 200k, 500k, 1000k, ... satoshis. Just like physical cash. By doing so, every individual payment is part of a much larger anonymity set consisting of all the payments at that moment. Using this approach, we can split a payment into as many paths as needed until we get to the exact number of satoshis. Splitting the payment amount into enough sub-paths to get
Re: [Lightning-dev] [Proposal] Payment Route Reservation
There are two more improvements I missed in my first mail. The first one is that all the nodes on the route get the same amount to reserve. So there is no need to put the amount inside the onion. This way node can fail reservation faster if there is no reservation balance left without opening the onion. Also, the onion gets smaller, and now it holds just the next hop information. This might simplify rendezvous routing(needs to explore this further). And the second improvement is that we don't need HTLC onion in the second step. Route hops already contain all the information to create HTLC. So all that's left to do is for the sender to sign the commitment and to revoke the state with a first node in the route. Thus increase in payment latency would be just one more call between the route nodes. Best Regards, g0b1el > If ASCII graphics are not rendering correctly, you can read the proposal on > the mailing list archive, where for some reason are rendered correctly - > https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-February/003867.html ___ Lightning-dev mailing list Lightning-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
Re: [Lightning-dev] [Proposal] Payment Route Reservation
If ASCII graphics are not rendering correctly, you can read the proposal on the mailing list archive, where for some reason are rendered correctly - https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-February/003867.html Cheers, g0b1el ___ Lightning-dev mailing list Lightning-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
[Lightning-dev] [Proposal] Payment Route Reservation
Hi, lightning devs It's my first mail, so first, I'd like to say a big thanks to everyone involved in the development of the lightning network. I've just finished going through this mailing list, so I'm not sure if Payment Route Reservation is already proposed in some other place. If there is a similar proposal, please point me to the right place. I'll first list some potential improvements with this proposal: 1) Higher reliability of payments 2) Lower payment latency (on average) 3) Lower fees 4) Increase in privacy 5) Trampoline payment improvements 6) Significant reduction of gossip messages 7) Healthier, more decentralized network 8) Simplified routing algorithm 9) LN Wallet UX improvements 10) Fast spam prevention 11) Channel liquidity probing prevention 12) Eliminates the need for splice-in (and partially splice-out) 13) Eliminates the need for rebalancing and fee update scripts 14) Eliminates the need for global nodes' reputation So what is a payment route reservation? Payment Route Reservation = The idea behind Payment Route Reservation is to split the payment into two steps. In the first step, we reserve the route, and in the second, we send a payment. In the reservation step, routing nodes will not sign a new commitment state. Instead, they will just reserve a specified amount of satoshis. Those satoshis might be used with the next payment step or not if the reservation is canceled. Each reservation has a timeout (let's say 1 min). After a timeout, the reservation is removed from the channel reservation set and considered canceled. Reservation can be canceled manually by any upstream node. For example: add_reservation(payment_hash, amount) --> ┌───┐ ┌───┐ ┌───┐ ───►│ ├►│ ├►│ ├► S │ A │ │ B │ │ C │ R ◄───┤ │◄┤ │◄┤ │◄ └───┘ └───┘ └───┘ <- reservation_success(fees_sum, cltv_delta_sum) S is a sender, R is a receiver, and A, B, and C are routing nodes. S wants to send `amount` satoshis with `payment hash`[1] to R. S first creates a reservation onion for A->B->C->R route and then sends the onion to the first node in the route, using `add_reservation` call. A unwraps the onion, and if he has enough unreserved balance in A->B channel, he will add a new reservation for the `amount` request to the channel reservation set and then forward the onion to B. Reservation in reservation set can be addressed by `payment hash`. If A has an insufficient channel reservation balance, A will return 'reservation_failed' to the upstream node(sender S). B and C will do the same. Assuming there is enough reservation balance in all channels to reserve a payment, reservation flow eventually reaches R. R unwraps the onion and checks if he knows the preimage. If he knows, R returns `reservation_success` to upstream node C. At this point, we have successfully reserved the payment route for `amount` satoshis from S to R. But, our route nodes haven't included the fees(or cltv_delta) of downstream nodes. `reservation_success` returns to upstream route node tuple (fees_sum, cltv_delta_sum). In this case, R will return (0, 0) to C because he is the last node in the route[2]. C will try to extend his reservation by fees from the R. If reservation extension is successful, C sends `reservation_success` to B, with a tuple increased by his fees[3] and his cltv delta. If C can't extend the reservation, he will send to B `reservation_failure` and to R `cancel_reservation`[4]. A will do the same. Eventually, if everything is ok with nodes A and B, S will receive a tuple (fees_sum, cltv_delta_sum). Now S knows precisely how much fees and cltv_delta route expects, and he can now send the payment onion. If S doesn't like the fees or cltv_delta, he can try some other route. Let's compare current payment forwarding to payment with reservation forwarding: +---+ +---+ +---+ +---+ | |--(1) update_add_htlc >| | | |--(1) add_reservation >| | | | | | | |<-(2) reservation_success--| | reservation onion | | | | ──|─ | |--(2)--- commitment_signed --->| | | |--(3)--- commitment_signed --->| | | A |<-(3) revoke_and_ack --| B | | A |<-(4) revoke_and_ack --| B | | | | | | | | | HTLC onion | |<-(4)--- commitment_signed | | | |<-(5)---