From rusty at rustcorp.com.au Sun Nov 4 03:00:48 2018 From: rusty at rustcorp.com.au (Rusty Russell) Date: Sun, 04 Nov 2018 13:30:48 +1030 Subject: [Lightning-dev] BOLT11 In the World of Scriptless Scripts In-Reply-To: <20181103044332.el2ro3sso3rcmwpg@erisian.com.au> References: <87sh0ke4rt.fsf@rustcorp.com.au> <20181102031945.uyf74qr73wspsktb@erisian.com.au> <87d0rodppt.fsf@rustcorp.com.au> <20181103044332.el2ro3sso3rcmwpg@erisian.com.au> Message-ID: <875zxdczrz.fsf@rustcorp.com.au> Anthony Towns writes: >> > - channel announcements: do you support secp256k1 for hashes or just >> > sha256? >> Worse, it becomes "I support secp256k1 with ECDSA" then a new "I support >> secp256k1 with Schnorr". You need a continuous path of channels with >> the same feature. > > I don't think that's correct: whether it's 2p-ecdsa, Schnorr or script > magic only matters for the two nodes directly involved in the channel > (who need to be able to understand the commitment transactions they're > signing, and extract the private key from the on-chain tx if the channel > gets unilaterally closed). For everyone else, they just need to know that > they can put in a public key based HTLC, and get back the corresponding > private key when the HTLC goes through. I'm not sure. Jonas Nick proposed a scheme, which very much assumes Schnorr AFAICT: Jonas Nick wrote: > How I thought it would work is that the invoice would contain a > Schnorr nonce R. Then the payer would construct s*G = R + > H(payee_pubkey,R,"I've bought 5 shirts shipped to Germany")*G. Then > the payer builds the scriptless script payment path such that when the > payee claims, the payer learns s and thus has a complete > signature. However, that doesn?t work with recurrent payments because > the payee can use the nonce only once. I would probably enhance this to include a nonce, which allows for AMP (you have to xor the AMP payments to get the nonce): R + H(payee_pubkey,R,"I've bought 5 shirts shipped to Germany",NONCE)*G > I think it makes sense to think of proof-of-payment in terms of a > verification algorithm (that a third party court could use), that takes: > > m - the invoice details, eg > "aj paid $11 for stickers to be delivered to Australia" > P - the pubkey of the vendor > sig - some signature > > With the current SHA256 preimages, you can make sig=(R,s,pre) > where the sig is valid if: > > s*G = R + H(P,R,m+SHA256(pre))*P > > If you share R,s,SHA256(pre) beforehand, the payer can tell they'll have > a valid signature if they pay to SHA256(pre). That's a 96B signature, > and it requires "pre" be different for each sale, and needs pre-payment > interactivity to agree on m and communicate R,s back to the payer. For current-style invoices (no payer-supplied data), the payee knows 'm', so no interactivity needed, which is nice. In the payer-supplied data case, I think 'm' should include a signature for a key only the payer knows: this lets them prove *they* made the payment. How does this interact with AMP, however? > With seckp256k1 preimages, it's easy to reduce that to sig=(R,s), > and needing to communicate an R to the payer initially, who can then > calculate S and send "m" along with the payment. OK, I buy that. > Maybe it makes sense to disambiguate the term "invoice" -- when you don't > know who you might be giving the goods/service to, call it an "offer", > which can be a write-once/accept-by-anyone deal that you just leave on > a webpage or your email signature; but an "invoice" should be specific > to each individual payment, with a "receipt" provided once an invoice > is paid. "offer" is a good name, since I landed on the same one while thinking about this too :) For an "offer" you would need a (lightning-network-carried) req/resp to get the per-payment invoice. An offer could use a 128-bit 'p': smaller would do, but this is too large to brute-force iterate through (hey, I wonder if they sell other stuff?). > Rereading through the AMP threads, Christian's post makes a lot of sense > to me: > > https://lists.linuxfoundation.org/pipermail/lightning-dev/2018-February/001023.html > > I'm not really seeing the benefits in complicated AMP schemes without > decorrelation... In practice it should increase reliability of payments through capacity bottlenecks. But don't underestimate the benefits of PoP: we're so used to intermediates we take it for granted, but once the middleman is removed the ability to prove the invoice/payment cycles is vital for usability. > It seems to me like there are three levels that could be implemented: > > - laolu/conner: ("low AMP" ?) > works with sha256 > some privacy improvement > loses proof-of-payment > can't claim unless all payments arrive Yep. > - just send multiple payments with the same hash: > works with sha256 > privacy not improved much (some intermediary nodes no longer know > full invoice value) > can claim partial payments as soon as they arrive > accepting any partial payment provides proof-of-payment Interestingly, if vendor takes part payment, rest can be stolen by intermediaries. This puts pressure on vendor to treat them atomically. I haven't thought about this before, but it has desirable attributes. (If the contract is "you will only release preimage once you've got the payment", all this requires is a single bit to say "I know this is partial, more are coming, please wait"). > - secp256k1: ("high AMP" ?) > needs secp256k1 preimages > works fine with decorrelation improving privacy at every step > can set it up so can only claim once all partial payments arrive > accepting partial payment provides proof-of-payment Yes. Though I'm not sure exactly how this works with your scheme above... > In theory, both "just send multiple payments" and "secp256k1" could have > splitting and joining at any hop, if we could encode the instructions > on how to do that in the onion message; joining is probably easy, but > splitting seems like it might be hard? I don't think so. If you can join two payments, it wasn't private? For splitting, in the specific case of having two channels between the same nodes, you might be able to do something, but that's a pretty narrow case. And as TCP discovered, you're better off failing back to sender than trying to add fragmentation to the protocol. Note: if we need an interaction message for BOLT11 features we want in future[1], then it has the advantage that it decouples the bolt11 features from changing preimages to secp256k1. That makes this question *critical* for the Summit next week. Thanks! Rusty. [1] If we're not careful we're going to implement HORNET so we can pass arbitrary messages around, which means we want to start charging for them to prevent spam, which means we reopen the pre-payment debate, and need reliable error messages...