Replacing Payment Hashes with Payment Points
Speakers: Nadav Kohen
Date: October 20, 2019
Transcript By: Michael Folkson
Tags: Ptlc
Media: https://www.youtube.com/watch?v=TE65I9E8Q5k
Slides: https://docs.google.com/presentation/d/15l4h2_zEY4zXC6n1NqsImcjgA0fovl_lkgkKu1O3QT0/
https://twitter.com/kanzure/status/1220453531683115020
Intro
My name is Nadav Kohen. I’m a software engineer at Suredbits. I’m going to talk about payment points which have been alluded to throughout the conference by various talks.
Hash Timelocked Contract (HTLC) Routing
First of all, some preliminaries, HTLCs. I don’t think I’m going to spend much time on this slide. We all know what they are. For every hop forward you add a hash timelocked contract. Then on every hop backward you complete it. The hash preimage is often referred to as the proof of payment. It is this important thing that is used by applications. In Trey’s talk about atomic swaps with things that aren’t just other currencies he discussed use cases in which you use this preimage. That’s going to be a theme in this talk that this preimage is important.
Problems with HTLC Routing
Some problems with HTLC routing and why I want to get rid of it. Every hop uses the same hash. This has some major problems. Essentially any time you are using a payment preimage in an application you have to expect that the payment preimage will be on the Bitcoin blockchain for everyone to see. These proofs of payment aren’t actually real proofs of payment because everyone sees them. You have to in practice mix in the user’s pub key or some additional information which in a perfect world we wouldn’t actually want to have. Additionally since every hop uses the same hash there is a huge privacy leak. If two nodes find out… say we have a payer paying the payee over all of these hops. You have two malicious nodes, Mallory and Mike. They realize that they have the same hash on this payment. They know they are on the same route and they are communicating with each other. What they can do is something called a wormhole attack. During set up they are cooperative but during settlement the payee reveals the preimage, it goes all the way back. Mike gets it, rather than Mike revealing it to the hop in front of him, Mike reveals this preimage directly to Mallory. Then it keeps going all the way back to the payer. What happens here is that it doesn’t impact the payee or the payer but Mallory and Mike were able to steal the fees from every hop in between while holding their funds hostage. The reason you put up your funds is because you are getting a fee in return. This is not great. Aside from privacy concerns we also have these fee stealing concerns. We have no proof of payment that is really a proof of payment that is useful. Also importantly hashes are boring. They destroy too much information, you can’t do any fun magic. You can’t use fun payment point things that I am going to be talking about in a second. The best examples of this are that AMPs and stuckless payments as mentioned do not have proof of payment. Anytime you have a spontaneous payment where the user needs to know the preimage when you set up, you cannot have proof of payment. As mentioned you can have multihash lock stuff but I think that that is actually a bigger change than this which will be definitely be happening anyway to prevent wormhole attacks and for various other reasons. Just because it is the nice way to go, more on that later. Let’s start talking about elliptic curve points.
Elliptic Curve Points
Real quick, some review, Bitcoin uses secp256k1 which is this curve y^2 = x^3 + 7. It is a little white lie, you take the finite version of this but whatever. It kind of looks like that. It is important to note that adding points together is fast and scalar multiplication is fast. When I say scalar multiplication I mean if I have some number, just a normal number x. We have all agreed on this point G on this curve. Then taking xG which is just G+G+G+G… is really fast. But undoing scalar multiplication is really hard. This x is a private key, xG is a public key. This is exactly what private and public keys are in Bitcoin. We’re going to be reusing all of that fun public key cryptography math and we have this super nice property that has been mentioned earlier when we’re talking about Schnorr and various other things that you can do key aggregation. If I have xG and yG and I add these points together it is actually the same thing as if I have this number x+y and I multiply it by G. That is because if I have G+G+G+G, (x+y)G which is the same as xG + y*G. This is a nice addition preserving property which is what we’ll be using pretty heavily in doing things like replacing any solution that would require multiple hashes to lock as well as other cool things we can do with this.
Payment Points to the Rescue!
As I mentioned payment points to the rescue. We are going to replace HTLCs with PTLCs. Essentially rather than saying “Give me the preimage to this hash and you can have this money” you say “Give me the scalar to this point and you can have this money.” We are already assuming that the discrete log problem is hard in Bitcoin and in general. This is not adding to our cryptographic assumptions or anything like this. Essentially we use points for hiding rather than hashes because we don’t need to hide as much as hashes do. Hashes destroy all the information of which some we could still use while hiding the preimage which is really all you need in order to make payments atomic and things like this. As I’ll discuss in the next slide, now that we have these nice additive properties we can have every hop along a route use a different payment point. There’s no payment correlation problem, we get rid of wormhole attacks, better privacy, AMPs can be decorrelated between their partial payments, things like this. We can recover proof of payment and basically any scheme that is missing it. Payment points destroy just enough information so that they can be usable for the purposes that we use hashes over the Lightning Network whilst still letting us do lots of other cool things that I will discuss some of here. The first thing I want to talk about is the motivation for why payment points came around and that is wormhole attack mitigation and payment decorrelation.
Wormhole Attack Mitigation (Payment Decorrelation)
Essentially like I mentioned every hop is going to have a different point. How this is achieved? Alice is the person setting up this payment. She is paying Carol through Bob. For every single hop Alice will add a nonce. The point that we are using is z*G. The preimage is z here. Alice is going to come up with two nonces for her two hops. Alice is going to add nonce x to her hop with Bob and then inform Bob here is y. Bob is going to add y to his hop with Carol. You can imagine that if there were more hops here Alice would generate x_1, x_2, x_3 and give in the onion each person their nonce that they’re supposed to add on the way forward and subtract on the way back. What she gives Carol at the very end is the sum of all the nonces. This is the sum of all the things Carol doesn’t know. It is just a number. All of these are random so they all look entirely different. Carol who knows the preimage can now add the preimage to the sum of the nonces and reveal that. As we see down here during the reveal phase Carol knows x+y because it was told to her by Alice in the onion. She knows z, she can reveal x+y+z. Bob who knows y because he added it forward, can subtract it on the way back which gives Alice x+z. Alice who knows x and added it on the hop forward, subtracts it and learns z the payment preimage or the scalar or whatever you want to call it. This is an actual proof of payment because it will never end up on the chain even if every single hop along the route ends up onchain. No one but Alice learns what z is. Carol didn’t have to know anything about Alice in order to achieve this. That’s what payments are going to look like once we have payment points. How this is going to be achieved is not directly by having a script contract that says that if you reveal the preimage to this point then you get the money. It is going to be using adaptor signatures. Abstractly we can think about things in essentially terms of replacing hashes with points. I’ll discuss implementation in a second.
“Stuckless” Payments
To touch on stuckless payments briefly. I know that two talks ago we went over this in quite a bit of detail so I won’t spend too much time here. Essentially the idea is that we don’t want payments to get stuck on set up, terrible UX when a payment stalls and you have to wait a bunch of time. What is being proposed is that we add this update phase between set up and settlement in which through some means Carol responds with an ACK once a payment is successfully set up. Alice then reveals the sum of the nonce because until Carol knows the sum of the nonce, which is itself just a random number, Carol cannot complete the payment. Carol can then respond with the payment preimage at this point, it is safe to do so. Even if she doesn’t though eventually Alice will get that preimage just over the Lightning Network through completed PTLCs. The nice thing with this is that we have this proof of payment. If you wanted to implement this with hashes, as was mentioned earlier, you would need something like a multihash lock or something quite complicated. Here everything is completely indistinguishable from a normal payment. You still get this proof of payment property from stuckless payments as a proposal.
High AMPs
Another fun thing is what’s usually called High AMP. I’m trying to remember what Conner called it in his talk. DAMP I think. DAMP or High AMP is essentially OG AMP which was just called AMP in Conner’s talk, where you recover proof of payment. OG AMP is the AMP proposal in which you have nice mathematical assumptions rather than economic assumptions for what makes things atomic. If you want n different partial payments you create n secrets, s_1 through s_n. You XOR them together to get this base secret. Then you HMAC those for each index to get your preimage. Then you hash those to get your payment hash for each thing. Then on each payment you send with this hash one of the s_i’s. Only once they recover all of those s_i’s can they recreate the base secret and then HMAC and deterministically recreate all of the preimages. The drawback to this is there is no proof of payment because the person who is setting it up has to know all of the preimages in advance. You can’t do fancy math on hash preimages given input from someone else that would be hashes. You would need to use multihash locks. As I mentioned we don’t want those because we want these anyway so let’s do it this way. High AMP is essentially this exact same procedure except for rather than having a hash between r_1 and H_1 you have r_1 turning from a scalar into a point and adding some other point that the payee knows. So essentially you invoice as always, you give a point instead of a hash that the person getting paid knows the preimage to and then you can simply add that point to all of these P_1, P_2 through P_n rather than H. Then only once you receive everything can you reconstruct the r’s which are necessary in order to claim each of these payments. Then the first payment that reaches back to the payer, they will be able to subtract that r_i and learn the preimage to this point that they didn’t know earlier. In a somewhat similar way to how we recover proof of payment with stuckless we also recover proof of payment here. Essentially with any spontaneous payment set up you can always just add a point where you don’t know the preimage to it. If you know the preimage to the rest of it as is for usual spontaneous payments in hash-land then you can just subtract the stuff you know off and get something new that you don’t know which you can treat as proof of payment. That is all High AMP is. Essentially it is just OG AMP which in my opinion is the nicer of the AMPs because it doesn’t require the assumption that the proof of payment is valuable which Base AMP does. Essentially we have this nice atomic structure that also has a proof of payment.
Escrow over Lightning
This next scheme proposed by Z-man is called escrow over Lightning. Essentially you have some contract that a buyer and a seller agree to ahead of time in some language that the escrow understands be that English or C++. Then the buyer and the seller each have these points and the escrow also has a point. You tweak this point. I’m not going to get into the details here, go read the mailing list if you’re interested. Essentially you use as a payment point the Diffie Hellman secret exchange between the buyer and the escrow which is tweaked by the contract so that it is committed to, plus the seller. To break this down, to make it much easier to look at, essentially what this is saying is that this preimage can become known if the seller knows their preimage which they should, and either the buyer reveals their preimage or the escrow reveals their preimage. In the cooperative case what happens here is that the buyer had their service from the seller. After this payment has been set up, they agree that the seller say mowed their lawn, did a good job, great, here’s the preimage to B. From that you can compute the Diffie Hellman secret, add it to the S you already know and there you go, you’re done. s acts as a proof of payment because the buyer knows b. In the case of a dispute the seller can go to the escrow with this tweak essentially telling them what the contract is. Then the escrow runs the contract or reads the contract depending on whether it is C++ or English or whatever else language. If they agree with the seller that indeed this has been done and they deserve to be paid, the escrow can reveal their preimage tweaked and that is all you need to compute the ECDH secret between the buyer and the escrow. That also allows the seller to reveal the preimage and claim their payment. The buyer still gets s as proof of payment because they also know the ECDH preimage. What this does is you have this AND and OR structure where it is the buyer or the escrow and the seller. You can actually do this in a much more general way, I’m not going to talk about it too much now because I had this idea more generally after I made these slides and turned them in. But you can add as many points together as you want to have this AND structure. In certain circumstances you can have a bunch of ORs. So you can have these more general access data structures in which for example if you want to have a weird multisig condition payment where you have a bunch of parties who are actively involved. If m-of-n of them agree that this payment should go through they can compute the preimage to this point and let it go through. You can do much more general things. This is the nice, relatively easy to understand case that showcases both the AND and the OR. Once again we have proof of payment here so this is quite cool. You can do really cool, much more general stuff than just this, escrow.
Selling (Schnorr) Signatures
Another thing we can do with points is you can sell Schnorr signatures trustlessly. You can sell Schnorr signatures over Lightning today with HTLCs but it is not trustless and also the signature will get revealed to everyone if any of the hops go onchain. Essentially what I mean by selling Schnorr signatures over the Lightning Network is you use your Schnorr signature, the last 32 bytes of it, as the payment preimage. If you wanted to do that today, the person who sets up the payment has no way of knowing that the hash that they’re using is actually the hash of the signature that they want. Here’s the math. Basically the thing that you need to know is that you can compute s*G where s is the signature of some message just from public information. R which is a public key, X which is a public key and the message. From public information and the message that you want a signature on with these specific public keys you can compute the public point, set up a payment using that point as the payment point. Then you know that you will get a valid signature to a specific message with specific keys if and only if your money gets claimed. In order to claim your money they must reveal the signature to you. Essentially we can trustlessly sell Schnorr signatures over the Lightning Network in nice, private ways. This can be used with blind Schnorr signatures as well. That is a link to a Jonas Nick talk from a while ago about how you can use blind servers to implement e-cash systems and various things like this. Here’s the great way you can sell signatures in a trustless fashion. Another thing that you can do selling signatures is you can have discreet log contract like options contracts. Essentially rather than having both parties have the ability to execute some contract, one party sells its signatures to some contract, to the other party in return for a premium. You essentially then have an option on some future event. That is on the mailing list if you’re interested in hearing more. Just in general, selling Schnorr signatures is a new, nice atomic thing that you can use in various schemes.
Pay for Decommitment (Pay for Nonce)
Very close to this is paying for decommitment or pay for nonce. Essentially if someone has a Pedersen commitment for some number x, this means they’ve hidden this thing by adding some point to it. You use this point as your payment point and in return you get this nonce. Essentially what that is is it is a decommitment to some Pedersen commitment. When you see someone decommit, that means you can decommit as well. So you can also think of this as paying for a commitment. For example, if someone wanted to sell timestamps they are putting a bunch of Pedersen commitments as people ask them to for specific messages onchain. Then they’re selling the decommitment to those things. If you put things in Merkle trees it is basically no cost to just aggregate all of these things up. More on that on the mailing list as well.
Implementation
So a quick note on why don’t we have these already? These are great, hashes suck. Why are we doing HTLCs, everything is terrible? Option 1 is we could introduce OP_COMPUTEPUBKEY. I think actually this has been proposed not by this name, I forget exactly what this name was. Essentially the idea is replace OP_HASH160 in all of your HTLCs with this OP_COMPUTEPUBKEY. This isn’t going to happen. We have better things to do than add a bunch of OP codes that aren’t known to have a bunch of use cases. Another thing we can do is we can use 2p-ECDSA adaptor signatures. This is really complicated, it has fewer bits of security than what I’m going to discuss next. It requires another crypto system be implemented in an efficient way on top of libsecp256k1. In theory it could work today if we did this. I do know a couple of people who are interested in working on this. Option 3 is once we have bip-schnorr it is relatively simple once we have bip-schnorr. It only requires libsecp256k1. Sadly it is a couple of years away but once we have bip-schnorr we can do all of this pretty easily.
Recap - Payment Point Give Us
To recap, we get payment decorrelation, stuckless payments with proof of payment, AMP with proof of payment, Lightning escrow contracts, trustlessly selling signatures, trustlessly selling decommitment and a bunch more things that I just came up with in the past couple of days along with other people that’s up on the mailing list that didn’t make it onto these slides. That’s my talk.