Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bolt 11: add a payment secret to invoice #671

Closed
wants to merge 2 commits into from

Conversation

@t-bast
Copy link
Collaborator

t-bast commented Sep 13, 2019

It is currently very easy for a forwarding node to discover if the next node is the recipient.
Imagine for example that we use the following route:

Alice -> Bob -> Carol -> Dave

When Carol receives the HTLC from Bob, instead of normally forwarding the onion, she can instead
create a new one-hop payment to Dave with the payment hash, amount and cltv that she would have
forwarded.

If Dave fulfills the HTLC, then he was the recipient and Carol can forward the HTLC fulfill,
completing the payment normally.
If Dave returns an error, he isn't the recipient and Carol resumes the normal payment flow by
sending him the peeled onion received from Bob.

This is a very cheap de-anonymization attack. Fortunately, it is also quite easy to fix by adding
a payment secret in the invoice that the payer needs to include in the last hop payload.

For backwards-compatibility with legacy payers, we use feature bits in the invoice to allow payees
to generate both invoices that require this payment_secret and invoices that don't (but hopefully
in a few releases we can make all implementations set this bit to mandatory by default).

It is currently very easy for a forwarding node to discover if the next node is the recipient.
Imagine for example that we use the following route:

```
Alice -> Bob -> Carol -> Dave
```

When Carol receives the HTLC from Bob, instead of normally forwarding the onion, she can instead
create a new one-hop payment to Dave with the payment hash, amount and cltv that she would have
forwarded.

If Dave fulfills the HTLC, then he was the recipient and Carol can forward the HTLC fulfill,
completing the payment normally.
If Dave returns an error, he isn't the recipient and Carol resumes the normal payment flow by
sending him the peeled onion received from Bob.

This is a very cheap de-anonymization attack. Fortunately, it is also quite easy to fix by adding
a payment secret in the invoice that the payer needs to include in the last hop payload.

For backwards-compatibility with legacy payers, we use feature bits in the invoice to allow payees
to generate both invoices that require this payment_secret and invoices that don't (but hopefully
in a few releases we can make all implementations set this bit to mandatory by default).
@t-bast t-bast requested review from rustyrussell and cfromknecht Sep 13, 2019

1. tlvs: `tlv_payload`
2. types:
1. type: 1 (`payment_secret`)
2. data:
* [`u16`:`payment_secret`]

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Sep 16, 2019

Collaborator

This is a 16 bit field! You mean 16*bytes I think.

This comment has been minimized.

Copy link
@t-bast

t-bast Sep 16, 2019

Author Collaborator

Woops definitely, thanks for spotting this

@t-bast

This comment has been minimized.

Copy link
Collaborator Author

t-bast commented Sep 16, 2019

@cfromknecht this should also cover the attack on 0-amount invoices (for both normal invoices and AMP). Let me know what you think.

@t-bast t-bast added this to Scheduled in Specification Meeting Agenda Sep 16, 2019
@t-bast t-bast referenced this pull request Sep 17, 2019
`payment_hash` is incorrect or the CLTV expiry of the htlc is too close to the
current block height for safe handling.
The `payment_hash` is unknown to the final node, the `payment_secret` doesn't
match the `payment_hash`, the amount for that `payment_hash` is incorrect or

This comment has been minimized.

Copy link
@niftynei

niftynei Oct 28, 2019

Collaborator

this is kind of confusing: "the payment_secret doesn't match the payment_hash"

I think what you really mean to convey is that the payment_secret corresponds with the expected secret for that payment_hash.

'match' implies equivalence, which isn't the exact case here.

This comment has been minimized.

Copy link
@t-bast

t-bast Nov 8, 2019

Author Collaborator

True, the wording isn't great. This PR is now included in the MPP once so I'll be closing it anyway ;)

@t-bast

This comment has been minimized.

Copy link
Collaborator Author

t-bast commented Nov 8, 2019

This has been included in #643 and evolution is being done over there

@t-bast t-bast closed this Nov 8, 2019
@t-bast t-bast deleted the b11-payment-secret branch Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
3 participants
You can’t perform that action at this time.