<oembed><type>rich</type><version>1.0</version><author_name>npub17rld56k4365lfphyd8u8kwuejey5xcazdxptserx03wc4jc9g24stx9l2h</author_name><author_url>https://nostr.ae/npub17rld56k4365lfphyd8u8kwuejey5xcazdxptserx03wc4jc9g24stx9l2h</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2018-11-04&#xA;📝 Original message:&#xA;On Sun, Nov 04, 2018 at 01:30:48PM +1030, Rusty Russell wrote:&#xA;&gt; I&#39;m not sure.  Jonas Nick proposed a scheme, which very much assumes&#xA;&gt; Schnorr AFAICT:&#xA;&gt; Jonas Nick wrote:&#xA;&gt; &gt; How I thought it would work is that the invoice would contain a&#xA;&gt; &gt; Schnorr nonce R.&#xA;&#xA;(Note this means the &#34;invoice&#34; must be unique for each payment)&#xA;&#xA;&gt; &gt; Then the payer would construct s*G = R +&#xA;&gt; &gt; H(payee_pubkey,R,&#34;I&#39;ve bought 5 shirts shipped to Germany&#34;)*G. Then&#xA;&gt; &gt; the payer builds the scriptless script payment path such that when the&#xA;&gt; &gt; payee claims, the payer learns s and thus has a complete&#xA;&gt; &gt; signature. However, that doesn’t work with recurrent payments because&#xA;&gt; &gt; the payee can use the nonce only once.&#xA;&#xA;So that&#39;s totally fine to do however you receive the &#34;s&#34; value -- the&#xA;message that&#39;s getting the Schnorr signature isn&#39;t a valid bitcoin&#xA;transaction, so it&#39;s something that only needs to be validated by&#xA;BOLT-aware courts.&#xA;&#xA;&#xA;I also think you can get recurrent payments easily by extending the&#xA;verification algorithm. Basically instead of Verify(m,P,sig) have&#xA;Verify(m,P,n,sig) to verify you&#39;ve made n payments of the invoice &#34;m&#34;.&#xA;&#xA;Construct &#34;m&#34; to include the postimage X = H(pre,1000) which indicates&#xA;&#34;pre&#34; has been hashed 1000 times, so X = H(H(pre,1000-n),n).&#xA;&#xA;Calculate the original signature as:&#xA;&#xA;   s = r + H(P,R,m+X)*p&#xA;&#xA;and verify that n payments have been made by checking:&#xA;&#xA;   Verify(m,P,n,(s,R,rcpt)) :: s*G = R + H(P,R,m+H(rcpt,n))*P&#xA;&#xA;You&#39;d provide s,R,X when setting up the subscription, then reveal the&#xA;preimage to X, the preimage to the preimage of X etc on each payment.&#xA;(Maybe shachain would work here?)&#xA;&#xA;I think that approach is independent of using sha256/secp256k1 for&#xA;preimages over lightning too.&#xA;&#xA;&gt; I would probably enhance this to include a nonce, which allows for AMP&#xA;&gt; (you have to xor the AMP payments to get the nonce):&#xA;&gt; R + H(payee_pubkey,R,&#34;I&#39;ve bought 5 shirts shipped to Germany&#34;,NONCE)*G&#xA;&#xA;R is already a unique nonce under the hash here, so I don&#39;t think a&#xA;second one adds any value fwiw.&#xA;&#xA;&gt; &gt; I think it makes sense to think of proof-of-payment in terms of a&#xA;&gt; &gt; verification algorithm (that a third party court could use), that takes:&#xA;&gt; &gt;&#xA;&gt; &gt;   m - the invoice details, eg&#xA;&gt; &gt;       &#34;aj paid $11 for stickers to be delivered to Australia&#34;&#xA;&gt; &gt;   P - the pubkey of the vendor&#xA;&gt; &gt;   sig - some signature&#xA;&gt; &gt;&#xA;&gt; &gt; With the current SHA256 preimages, you can make sig=(R,s,pre)&#xA;&gt; &gt; where the sig is valid if:&#xA;&gt; &gt;&#xA;&gt; &gt;   s*G = R + H(P,R,m+SHA256(pre))*P&#xA;&gt; &gt;&#xA;&gt; &gt; If you share R,s,SHA256(pre) beforehand, the payer can tell they&#39;ll have&#xA;&gt; &gt; a valid signature if they pay to SHA256(pre). That&#39;s a 96B signature,&#xA;&gt; &gt; and it requires &#34;pre&#34; be different for each sale, and needs pre-payment&#xA;&gt; &gt; interactivity to agree on m and communicate R,s back to the payer.&#xA;&gt; For current-style invoices (no payer-supplied data), the payee knows&#xA;&gt; &#39;m&#39;, so no interactivity needed, which is nice.&#xA;&#xA;I&#39;m looking at it as needing interactivity to determine m prior to&#xA;the payment going through -- the payer needs to send through &#34;aj&#34; and&#xA;&#34;Australia&#34; in the example above, before the payee can generate s,R to&#xA;send back, at which point the payer can make the payment knowing they&#39;ll&#xA;either get a cryptographic proof of payment or a refund.&#xA;&#xA;&gt; In the payer-supplied data case, I think &#39;m&#39; should include a signature&#xA;&gt; for a key only the payer knows: this lets them prove *they* made the&#xA;&gt; payment.&#xA;&#xA;I don&#39;t object to that, but I think it&#39;s unnecessary; as long as there&#xA;was a payment for delivery of the widget to &#34;aj&#34; in &#34;Australia&#34; does it&#xA;matter if the payment was technically made by &#34;aj&#34; by &#34;Visa on behalf&#xA;of aj&#34; or by &#34;Bank of America on behalf of Mastercard on behalf of aj&#39;s&#xA;friend who owed him some money&#34; ?&#xA;&#xA;&gt; How does this interact with AMP, however?&#xA;&#xA;The way I see it is they&#39;re separate: you have a way of getting the&#xA;preimage back over lightning (which is affected by AMP), and you have a&#xA;way of turning a preimage into a third-party-verifiable PoP (with&#xA;Schnorr or whatever).&#xA;&#xA;(That might not be true if there&#39;s a clever way of safely feeding the&#xA;nonce R back, so that you can go straight from a generic offer to an&#xA;accepted payment with proof of payment)&#xA;&#xA;&gt; &gt; With seckp256k1 preimages, it&#39;s easy to reduce that to sig=(R,s),&#xA;&gt; &gt; and needing to communicate an R to the payer initially, who can then&#xA;&gt; &gt; calculate S and send &#34;m&#34; along with the payment.&#xA;&gt; OK, I buy that.&#xA;&#xA;Crap, do I need to give you proof of payment for it now? :)&#xA;&#xA;&gt; &gt; Maybe it makes sense to disambiguate the term &#34;invoice&#34; -- when you don&#39;t&#xA;&gt; &gt; know who you might be giving the goods/service to, call it an &#34;offer&#34;,&#xA;&gt; &gt; which can be a write-once/accept-by-anyone deal that you just leave on&#xA;&gt; &gt; a webpage or your email signature; but an &#34;invoice&#34; should be specific&#xA;&gt; &gt; to each individual payment, with a &#34;receipt&#34; provided once an invoice&#xA;&gt; &gt; is paid.&#xA;&gt; &#34;offer&#34; is a good name, since I landed on the same one while thinking&#xA;&gt; about this too :)&#xA;&#xA;Yay!&#xA;&#xA;&gt; &gt; It seems to me like there are three levels that could be implemented:&#xA;&gt; &gt;&#xA;&gt; &gt;  - laolu/conner: (&#34;low AMP&#34; ?)&#xA;&gt; &gt;     works with sha256&#xA;&gt; &gt;     some privacy improvement&#xA;&gt; &gt;     loses proof-of-payment&#xA;&gt; &gt;     can&#39;t claim unless all payments arrive&#xA;&gt; &#xA;&gt; Yep.&#xA;&gt; &#xA;&gt; &gt;  - just send multiple payments with the same hash:&#xA;&gt; &gt;     works with sha256&#xA;&gt; &gt;     privacy not improved much (some intermediary nodes no longer know&#xA;&gt; &gt;       full invoice value)&#xA;&gt; &gt;     can claim partial payments as soon as they arrive&#xA;&gt; &gt;     accepting any partial payment provides proof-of-payment&#xA;&gt; &#xA;&gt; Interestingly, if vendor takes part payment, rest can be stolen by&#xA;&gt; intermediaries.&#xA;&#xA;Or you could just see a $5 bill, send $0.50 through, and wait to see&#xA;if the take the partial payment immediately before even trying the&#xA;remaining $4.50.&#xA;&#xA;&gt; &gt;  - secp256k1: (&#34;high AMP&#34; ?)&#xA;&gt; &gt;     needs secp256k1 preimages&#xA;&gt; &gt;     works fine with decorrelation improving privacy at every step&#xA;&gt; &gt;     can set it up so can only claim once all partial payments arrive&#xA;&gt; &gt;     accepting partial payment provides proof-of-payment&#xA;&gt; Yes.  Though I&#39;m not sure exactly how this works with your scheme&#xA;&gt; above...&#xA;&#xA; Vendor -&gt; *:        &#34;I sell widgets for 0.01 BTC, my pubkey is P&#34;&#xA; Customer -&gt; Vendor: &#34;I want to buy a widget&#34;&#xA; Vendor -&gt; Customer: &#34;Here&#39;s an R value&#34;&#xA; Customer: calculates S = R + H(P,R,&#34;send $me a widget at $address&#34;)*P&#xA; Customer -&gt; Vendor: &#34;here&#39;s 0.01 BTC for s corresponding to S, my&#xA;                      details are R, $me, $address&#34;&#xA; Vendor: looks up r for R=r*G, calculates s = r + H(P,R,&#34;send $me a&#xA;         widget at $address&#34;)*p, checks S=s*G&#xA; Vendor -&gt; Customer: &lt;accepts payment, revealing s&gt;&#xA;&#xA; Customer -&gt; Court: reveals the invoice (&#34;send $me a widget...&#34;) and the&#xA;                    signature by Vendor&#39;s pubkey P, (s,R)&#xA;&#xA;I think the way to do secp256k1 AMP with that is that when sending&#xA;through the payment is for the customer to send three payments to the&#xA;Vendor conditional on preimages for A,B,C calculated as:&#xA;&#xA;   A = S + H(1,secret)*G&#xA;   B = S + H(2,secret)*G&#xA;   C = S + H(3,secret)*G&#xA;&#xA;where &#34;secret&#34; is your xor of info from each of the three message hashes.&#xA;&#xA;&gt; &gt; In theory, both &#34;just send multiple payments&#34; and &#34;secp256k1&#34; could have&#xA;&gt; &gt; splitting and joining at any hop, if we could encode the instructions&#xA;&gt; &gt; on how to do that in the onion message; joining is probably easy, but&#xA;&gt; &gt; splitting seems like it might be hard?&#xA;&gt; I don&#39;t think so.  If you can join two payments, it wasn&#39;t private?&#xA;&#xA;Sorry, I mean &#34;source-directed splits and joins&#34;, so rather than&#xA;your source routing being a linear &#34;me -&gt; A -&gt; B -&gt; C -&gt; D -&gt; you&#34;,&#xA;you specify a graph: &#34;me -&gt; A -&gt; B,E ; B -&gt; C ; E -&gt; F -&gt; G ; C,G -&gt;&#xA;D -&gt; you&#34; so you tell &#34;A&#34; how to split the payment into two new routes,&#xA;and tell &#34;D&#34; to join two payments and continue it on. The ECC part works&#xA;fine for that, but the onion routed messages seem difficult and probably&#xA;not worth considering for spec v1.1.&#xA;&#xA;&gt; Note: if we need an interaction message for BOLT11 features we want in&#xA;&gt; future[1], then it has the advantage that it decouples the bolt11&#xA;&gt; features from changing preimages to secp256k1.  That makes this question&#xA;&gt; *critical* for the Summit next week.&#xA;&gt; &#xA;&gt; Thanks!&#xA;&gt; Rusty.&#xA;&gt; &#xA;&gt; [1] If we&#39;re not careful we&#39;re going to implement HORNET so we can pass&#xA;&gt; arbitrary messages around, which means we want to start charging for&#xA;&gt; them to prevent spam, which means we reopen the pre-payment debate, and&#xA;&gt; need reliable error messages...&#xA;&#xA;Could leave the interactivity to the &#34;web store&#34; layer, eg have a BOLT&#xA;11 v1.1 &#34;offer&#34; include a url for the website where you go an enter your&#xA;name and address and whatever other info they need, and get a personalised&#xA;BOLT 11 v1.1 &#34;invoice&#34; back with payment-hash/nonce/signature/whatever?&#xA;&#xA;Cheers,&#xA;aj</html></oembed>