Skip to content

Commit 16b1339

Browse files
committed
Require minimally-encoded features in BOLT 11 invoices
When decoding BOLT 11 invoices, LDK has always read them into fields, parsing what it can. When parsing features, this loses the information on the number of field elements which were used to encode the features in the invoice itself. When we then go to calculate a hash of the invoice for signature validation/key recovery, we go re-serialize the invoice. At this point, any excess field elements used to encode features will be lost and the invoice's hash will be different from what the original encoder intended. Luckily, this doesn't appear to have ever happened in practice. This was, in fact, only found by @erickcestari, @brunoerg, and @morehouse when doing differential fuzzing. Because this hasn't happened and it breaks a straightforward way to handle BOLT 11 parsing, there's no reason to retain it, so instead here we simply forbid non-minimally-encoded features in BOLT 11 invoices. See lightningdevkit/rust-lightning#3693 for the specific example generated by fuzzing.
1 parent ccfa38e commit 16b1339

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

11-payment-encoding.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ A writer:
197197
specified in [BOLT #7](07-routing-gossip.md#the-channel_update-message).
198198
- MAY include more than one `r` field to provide multiple routing options.
199199
- if `9` contains non-zero bits:
200-
- SHOULD use the minimum `data_length` possible.
200+
- MUST use the minimum `data_length` possible.
201201
- otherwise:
202202
- MUST omit the `9` field altogether.
203203
- MUST pad field data to a multiple of 5 bits, using 0s.
@@ -222,6 +222,10 @@ A reader:
222222
- MUST use an expiry delta of at least 18 when making the payment
223223
- if an `m` field is provided:
224224
- MUST use that as [`payment_metadata`](04-onion-routing.md#tlv_payload-payload-format)
225+
- if a `9` field is provided which has a non-minimal `data_length` for the set bits
226+
- SHOULD treat the invoice as invalid.
227+
228+
225229
### Rationale
226230

227231
The type-and-length format allows future extensions to be backward

0 commit comments

Comments
 (0)