Skip to content

Require minimally-encoded features in BOLT 11 invoices #1245

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

Merged

Conversation

TheBlueMatt
Copy link
Collaborator

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.

Copy link
Contributor

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just playing with this yesterday lightningdevkit/rust-lightning#3703

I agree that making the invoice valid required a bunch of tricky code that does not make sense to have.

ACK e2e81aa

Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, I just need to add the test vector to eclair and will properly ACK.

@rustyrussell
Copy link
Collaborator

Ack.

Shall we similarly make the other "SHOULD use minimal encoding" into MUST?

@TheBlueMatt TheBlueMatt force-pushed the 2025-04-require-minimal-11-features branch from 7b9451c to 8c712d6 Compare April 7, 2025 23:34
When decoding BOLT 11 invoices, LDK has always read them into
fields, parsing what it can. When parsing features, CLTV deltas,
and expiry times, 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 fields 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.
@t-bast mentioned on the call that they've run into non-largest
multipliers in BOLT 11 invoices in the wild and as such we can't
reject them.
@TheBlueMatt TheBlueMatt force-pushed the 2025-04-require-minimal-11-features branch from 8c712d6 to 4042520 Compare April 7, 2025 23:46
@TheBlueMatt
Copy link
Collaborator Author

Clarified what the minimal length thing means as requested at the meeting.

Shall we similarly make the other "SHOULD use minimal encoding" into MUST?

Oops, indeed, done. Note that for any of the three LDK would have failed to pay the invoice (invalid signature or wrong pubkey from recovery) and we haven't received any reports of it.

Sadly, I did not apply this to the amount because @t-bast indicated at the meeting that they've seen non-minimal ones.

t-bast added a commit to ACINQ/eclair that referenced this pull request Apr 8, 2025
lightning/bolts#1245 highlights that invoice
writers must minimally encode Bolt11 features (and other fields).
We were already correctly doing that, but tests were lacking.

lightning/bolts#1242 added a test vector for
invoices without payment secrets, which we're now verifying.
t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Apr 8, 2025
lightning/bolts#1245 highlights that invoice
writers must minimally encode Bolt11 features (and other fields).
We were already correctly doing that, but tests were lacking.

lightning/bolts#1242 added a test vector for
invoices without payment secrets, which we're now verifying.
Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK, verified that eclair and lightning-kmp minimally-encode all of these.

t-bast added a commit to ACINQ/eclair that referenced this pull request Apr 8, 2025
lightning/bolts#1245 highlights that invoice
writers must minimally encode Bolt11 features (and other fields).
We were already correctly doing that, but tests were lacking.

lightning/bolts#1242 added a test vector for
invoices without payment secrets, which we're now verifying.
t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Apr 8, 2025
lightning/bolts#1245 highlights that invoice
writers must minimally encode Bolt11 features (and other fields).
We were already correctly doing that, but tests were lacking.

lightning/bolts#1242 added a test vector for
invoices without payment secrets, which we're now verifying.
Copy link
Collaborator

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🦧

@t-bast
Copy link
Collaborator

t-bast commented Apr 28, 2025

@TheBlueMatt I think we can merge that PR now, can't we?

@TheBlueMatt TheBlueMatt merged commit 011bf84 into lightning:master May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants