From f53a7ced5d9d661df9e6a5c72bebfcd03721a232 Mon Sep 17 00:00:00 2001 From: t-bast Date: Fri, 13 Sep 2019 19:53:37 +0200 Subject: [PATCH 1/2] Bolt 11: add a payment secret to invoice 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). --- 04-onion-routing.md | 22 ++++++++++++++++------ 11-payment-encoding.md | 27 +++++++++++++++++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/04-onion-routing.md b/04-onion-routing.md index 17851c7a8..d3ac0a75c 100644 --- a/04-onion-routing.md +++ b/04-onion-routing.md @@ -235,10 +235,13 @@ parameters may lead to extraneous routing failure. ### `tlv_payload` payload format -This is a more flexible format, which avoids the redundant `short_channel_id` field for the final node. +This is a more flexible format, which avoids the redundant `short_channel_id` field for the final node. 1. tlvs: `tlv_payload` 2. types: + 1. type: 1 (`payment_secret`) + 2. data: + * [`u16`:`payment_secret`] 1. type: 2 (`amt_to_forward`) 2. data: * [`tu64`:`amt_to_forward`] @@ -253,6 +256,8 @@ This is a more flexible format, which avoids the redundant `short_channel_id` fi The writer: - MUST include `amt_to_forward` and `outgoing_cltv_value` for every node. + - MUST include `payment_secret` for the final node if provided by the recipient. + - MUST NOT include `payment_secret` for non-final nodes. - MUST include `short_channel_id` for every non-final node. - MUST NOT include `short_channel_id` for the final node. @@ -282,7 +287,7 @@ sent across. Nodes implementing non-strict forwarding are able to make real-time assessments of channel bandwidths with a particular peer, and use the channel that is -locally-optimal. +locally-optimal. For example, if the channel specified by `short_channel_id` connecting A and B does not have enough bandwidth at forwarding time, then A is able use a @@ -313,6 +318,8 @@ using an alternate channel. When building the route, the origin node MUST use a payload for the final node with the following values: +* `payment_secret`: set to the payment secret specified by the recipient (e.g. + `payment_secret` from a [BOLT #11](11-payment-encoding.md) payment invoice) * `outgoing_cltv_value`: set to the final expiry specified by the recipient (e.g. `min_final_cltv_expiry` from a [BOLT #11](11-payment-encoding.md) payment invoice) * `amt_to_forward`: set to the final amount specified by the recipient (e.g. `amount` @@ -577,7 +584,6 @@ The processing node: - MUST drop the packet. - MUST signal a route failure. - # Filler Generation Upon receiving a packet, the processing node extracts the information destined @@ -827,9 +833,10 @@ handling by the processing node. * [`u64`:`htlc_msat`] * [`u32`:`height`] -The `payment_hash` is unknown to the final node, the amount for that -`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 +the CLTV expiry of the htlc is too close to the current block height for safe +handling. The `htlc_msat` parameter is superfluous, but left in for backwards compatibility. The value of `htlc_msat` always matches the amount specified in @@ -952,6 +959,9 @@ An _intermediate hop_ MUST NOT, but the _final node_: - if the payment hash has already been paid: - MAY treat the payment hash as unknown. - MAY succeed in accepting the HTLC. + - if the `payment_secret` doesn't match the expected value for that `payment_hash`: + - MUST fail the HTLC. + - MUST return an `incorrect_or_unknown_payment_details` error. - if the amount paid is less than the amount expected: - MUST fail the HTLC. - MUST return an `incorrect_or_unknown_payment_details` error. diff --git a/11-payment-encoding.md b/11-payment-encoding.md index d22d4de8a..dc2da3096 100644 --- a/11-payment-encoding.md +++ b/11-payment-encoding.md @@ -128,9 +128,10 @@ Each Tagged Field is of the form: Currently defined tagged fields are: -* `p` (1): `data_length` 52. 256-bit SHA256 payment_hash. Preimage of this provides proof of payment. -* `d` (13): `data_length` variable. Short description of purpose of payment (UTF-8), e.g. '1 cup of coffee' or 'ナンセンス 1杯' -* `n` (19): `data_length` 53. 33-byte public key of the payee node +* `p` (1): `data_length` 52. 256-bit SHA256 payment_hash. Preimage of the payment_hash provides proof of payment. +* `s` (16): `data_length` 26. 128-bit payment_secret. This secret prevents forwarding nodes from probing the payment recipient. +* `d` (13): `data_length` variable. Short description of purpose of payment (UTF-8), e.g. '1 cup of coffee' or 'ナンセンス 1杯'. +* `n` (19): `data_length` 53. 33-byte public key of the payee node. * `h` (23): `data_length` 52. 256-bit description of purpose of payment (SHA256). This is used to commit to an associated description that is over 639 bytes, but the transport mechanism for the description in that case is transport specific and not defined here. * `x` (6): `data_length` variable. `expiry` time in seconds (big-endian). Default is 3600 (1 hour) if not specified. * `c` (24): `data_length` variable. `min_final_cltv_expiry` to use for the last HTLC in the route. Default is 9 if not specified. @@ -148,7 +149,7 @@ Currently defined tagged fields are: ### Requirements A writer: - - MUST include exactly one `p` field. + - MUST include exactly one `p` and `s` fields. - MUST set `payment_hash` to the SHA2 256-bit hash of the `payment_preimage` that will be given in return for payment. - MUST include either exactly one `d` or exactly one `h` field. @@ -191,8 +192,8 @@ A writer: - MUST specify the most-preferred field first, followed by less-preferred fields, in order. A reader: - - MUST skip over unknown fields, OR an `f` field with unknown `version`, OR `p`, `h`, or - `n` fields that do NOT have `data_length`s of 52, 52, or 53, respectively. + - MUST skip over unknown fields, OR an `f` field with unknown `version`, OR `p`, `s`, `h`, or + `n` fields that do NOT have `data_length`s of 52, 26, 52, or 53, respectively. - if the `9` field contains unknown _odd_ bits that are non-zero: - MUST ignore the bit. - if the `9` field contains unknown _even_ bits that are non-zero: @@ -215,6 +216,10 @@ specs could add a new variant of different length: in which case, writers could support both old and new variants, and old readers would ignore the variant not the correct length. +The `s` field prevents forwarding nodes from probing to test if a node is the +recipient of the payment. The length of the `s` field could change in the +future so readers ignore it if it's not 128 bits. + The `d` field allows inline descriptions, but may be insufficient for complex orders. Thus, the `h` field allows a summary: though the method by which the description is served is as-yet unspecified and will @@ -278,6 +283,16 @@ The field is big-endian. The least-significant bit is numbered 0, which is _even_, and the next most significant bit is numbered 1, which is _odd_. +The following feature bits are currently assigned by this specification: + +| Bits | Name | Description | +|------|-------------------------|-------------------------------------------------------| +| 0/1 | `option_payment_secret` | Requires or supports the `payment_secret` field (`s`) | + +The payee should set the _even_ `payment_secret` bit to prevent probing attacks +by the next-to-last node. If the payee wants to allow legacy payers, he may set +the _odd_ `payment_secret` bit instead. In that case probing attacks are possible. + # Payer / Payee Interactions These are generally defined by the rest of the Lightning BOLT series, From b9d677011d2990ce609ec68d8d96f4e57d202e29 Mon Sep 17 00:00:00 2001 From: Bastien Teinturier Date: Mon, 16 Sep 2019 09:31:42 +0200 Subject: [PATCH 2/2] fixup! Bolt 11: add a payment secret to invoice --- 04-onion-routing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04-onion-routing.md b/04-onion-routing.md index d3ac0a75c..12e49eb12 100644 --- a/04-onion-routing.md +++ b/04-onion-routing.md @@ -241,7 +241,7 @@ This is a more flexible format, which avoids the redundant `short_channel_id` fi 2. types: 1. type: 1 (`payment_secret`) 2. data: - * [`u16`:`payment_secret`] + * [`16*byte`:`payment_secret`] 1. type: 2 (`amt_to_forward`) 2. data: * [`tu64`:`amt_to_forward`]