Rusty Russell [ARCHIVE] on Nostr: 📅 Original date posted:2018-11-04 📝 Original message: Anthony Towns <aj at ...
📅 Original date posted:2018-11-04
📝 Original message:
Anthony Towns <aj at erisian.com.au> writes:
>> 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.
>
> I don't object to that, but I think it's unnecessary; as long as there
> was a payment for delivery of the widget to "aj" in "Australia" does it
> matter if the payment was technically made by "aj" by "Visa on behalf
> of aj" or by "Bank of America on behalf of Mastercard on behalf of aj's
> friend who owed him some money" ?
You often don't want the vendor to know anything about you, and there's
often no reason why they should.
And it just doesn't work unless you give over uniquely identifying
information. AJ posts to r/bitcoin demonstrating payment, demanding his
goods. Sock puppet says "No, I'm the AJ in Australia" and cut & pastes
the same proof.
Even if you did, that's exactly the problem we have now. *In theory*
the invoice should be specific enough that it identifies where they
shipped the item, in practice it never is (even the Blockstream store
gets this wrong!).
Sure, in case of digital delivery there's no proof that delivery
(didn't) happen, but you can at least show you paid.
>> How does this interact with AMP, however?
>
> The way I see it is they're separate: you have a way of getting the
> preimage back over lightning (which is affected by AMP), and you have a
> way of turning a preimage into a third-party-verifiable PoP (with
> Schnorr or whatever).
>
> (That might not be true if there's a clever way of safely feeding the
> nonce R back, so that you can go straight from a generic offer to an
> accepted payment with proof of payment)
>
>> > 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.
>
> Crap, do I need to give you proof of payment for it now? :)
Please :)
>> > - 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.
>
> Or you could just see a $5 bill, send $0.50 through, and wait to see
> if the take the partial payment immediately before even trying the
> remaining $4.50.
Sure, that's true today, too?
>> > - 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...
>
> Vendor -> *: "I sell widgets for 0.01 BTC, my pubkey is P"
> Customer -> Vendor: "I want to buy a widget"
> Vendor -> Customer: "Here's an R value"
> Customer: calculates S = R + H(P,R,"send $me a widget at $address")*P
> Customer -> Vendor: "here's 0.01 BTC for s corresponding to S, my
> details are R, $me, $address"
> Vendor: looks up r for R=r*G, calculates s = r + H(P,R,"send $me a
> widget at $address")*p, checks S=s*G
> Vendor -> Customer: <accepts payment, revealing s>
>
> Customer -> Court: reveals the invoice ("send $me a widget...") and the
> signature by Vendor's pubkey P, (s,R)
>
> I think the way to do secp256k1 AMP with that is that when sending
> through the payment is for the customer to send three payments to the
> Vendor conditional on preimages for A,B,C calculated as:
>
> A = S + H(1,secret)*G
> B = S + H(2,secret)*G
> C = S + H(3,secret)*G
Note: I prefer the construction H(<secret>,<part-of-secret-in-that-payment>)
which doesn't require an explicit order.
> where "secret" is your xor of info from each of the three message hashes.
Note that this only works if the message "send $me a widget at $address"
includes a nonce, since it may be easily grindable otherwise.
Since I'm suggesting it include a signature in msg, we're covered here.
We could chacha20 the msg in A, and just xor the key between other
payments for a bit of space saving.
>> > 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?
>
> Sorry, I mean "source-directed splits and joins", so rather than
> your source routing being a linear "me -> A -> B -> C -> D -> you",
> you specify a graph: "me -> A -> B,E ; B -> C ; E -> F -> G ; C,G ->
> D -> you" so you tell "A" how to split the payment into two new routes,
> and tell "D" to join two payments and continue it on. The ECC part works
> fine for that, but the onion routed messages seem difficult and probably
> not worth considering for spec v1.1.
I'm not sure I see the benefit over just treating them independently,
so I also think we should defer.
>> [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...
>
> Could leave the interactivity to the "web store" layer, eg have a BOLT
> 11 v1.1 "offer" include a url for the website where you go an enter your
> name and address and whatever other info they need, and get a personalised
> BOLT 11 v1.1 "invoice" back with payment-hash/nonce/signature/whatever?
I think that's out-of-scope, and I generally dislike including a URL
since it's an unsigned externality and in practice has horrible privacy
properties.
Cheers,
Rusty.
📝 Original message:
Anthony Towns <aj at erisian.com.au> writes:
>> 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.
>
> I don't object to that, but I think it's unnecessary; as long as there
> was a payment for delivery of the widget to "aj" in "Australia" does it
> matter if the payment was technically made by "aj" by "Visa on behalf
> of aj" or by "Bank of America on behalf of Mastercard on behalf of aj's
> friend who owed him some money" ?
You often don't want the vendor to know anything about you, and there's
often no reason why they should.
And it just doesn't work unless you give over uniquely identifying
information. AJ posts to r/bitcoin demonstrating payment, demanding his
goods. Sock puppet says "No, I'm the AJ in Australia" and cut & pastes
the same proof.
Even if you did, that's exactly the problem we have now. *In theory*
the invoice should be specific enough that it identifies where they
shipped the item, in practice it never is (even the Blockstream store
gets this wrong!).
Sure, in case of digital delivery there's no proof that delivery
(didn't) happen, but you can at least show you paid.
>> How does this interact with AMP, however?
>
> The way I see it is they're separate: you have a way of getting the
> preimage back over lightning (which is affected by AMP), and you have a
> way of turning a preimage into a third-party-verifiable PoP (with
> Schnorr or whatever).
>
> (That might not be true if there's a clever way of safely feeding the
> nonce R back, so that you can go straight from a generic offer to an
> accepted payment with proof of payment)
>
>> > 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.
>
> Crap, do I need to give you proof of payment for it now? :)
Please :)
>> > - 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.
>
> Or you could just see a $5 bill, send $0.50 through, and wait to see
> if the take the partial payment immediately before even trying the
> remaining $4.50.
Sure, that's true today, too?
>> > - 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...
>
> Vendor -> *: "I sell widgets for 0.01 BTC, my pubkey is P"
> Customer -> Vendor: "I want to buy a widget"
> Vendor -> Customer: "Here's an R value"
> Customer: calculates S = R + H(P,R,"send $me a widget at $address")*P
> Customer -> Vendor: "here's 0.01 BTC for s corresponding to S, my
> details are R, $me, $address"
> Vendor: looks up r for R=r*G, calculates s = r + H(P,R,"send $me a
> widget at $address")*p, checks S=s*G
> Vendor -> Customer: <accepts payment, revealing s>
>
> Customer -> Court: reveals the invoice ("send $me a widget...") and the
> signature by Vendor's pubkey P, (s,R)
>
> I think the way to do secp256k1 AMP with that is that when sending
> through the payment is for the customer to send three payments to the
> Vendor conditional on preimages for A,B,C calculated as:
>
> A = S + H(1,secret)*G
> B = S + H(2,secret)*G
> C = S + H(3,secret)*G
Note: I prefer the construction H(<secret>,<part-of-secret-in-that-payment>)
which doesn't require an explicit order.
> where "secret" is your xor of info from each of the three message hashes.
Note that this only works if the message "send $me a widget at $address"
includes a nonce, since it may be easily grindable otherwise.
Since I'm suggesting it include a signature in msg, we're covered here.
We could chacha20 the msg in A, and just xor the key between other
payments for a bit of space saving.
>> > 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?
>
> Sorry, I mean "source-directed splits and joins", so rather than
> your source routing being a linear "me -> A -> B -> C -> D -> you",
> you specify a graph: "me -> A -> B,E ; B -> C ; E -> F -> G ; C,G ->
> D -> you" so you tell "A" how to split the payment into two new routes,
> and tell "D" to join two payments and continue it on. The ECC part works
> fine for that, but the onion routed messages seem difficult and probably
> not worth considering for spec v1.1.
I'm not sure I see the benefit over just treating them independently,
so I also think we should defer.
>> [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...
>
> Could leave the interactivity to the "web store" layer, eg have a BOLT
> 11 v1.1 "offer" include a url for the website where you go an enter your
> name and address and whatever other info they need, and get a personalised
> BOLT 11 v1.1 "invoice" back with payment-hash/nonce/signature/whatever?
I think that's out-of-scope, and I generally dislike including a URL
since it's an unsigned externality and in practice has horrible privacy
properties.
Cheers,
Rusty.