Skip to content

common/bolt11: Fix BOLT11 hash calculation for unknown fallback address versions #8302

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

erickcestari
Copy link
Contributor

When processing BOLT11 invoices containing unknown fallback address versions (discovered using bitcoinfuzz differential fuzzing), the hash calculation produces different results across Lightning implementations (Lnd vs CLightning):

The example invoice is decoded differently by Lnd and CLightning.

lnbc1qqqqqqg9qqsqqsqqsqqdqqpp5s7zxqqqqqqqqqqqqqqqdqqqqqqqqqqqqqqqqqqqqq8qqq9qqqqqqfq95xw7tfpp35qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcqpjqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqyqyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq5s846z

This results in different recipient pubkeys:

LND: 03027be81b41bdfda1ded1f4e0dd5a997635ad325a6e119f414a92fe78c86a45cf
CLightning: 03e6b1f437d1984a58e4192289e8e0f21e2bbcd863dc43374037e61621abb8d1de

The difference occurs in the hash calculation which affects signature verification.

Root Cause

The issue occurs in the fallback address processing (decode_f function). When an unknown version is encountered in the fallback address field, the current implementation incorrectly includes the version bytes in the hash calculation before determining whether it's a known or unknown version. Then, when delegating to the unknown_field handler, the version bytes get included in the hash calculation a second time, resulting in inconsistent hash values across implementations.

Solution

The fix separates the version reading from the hash commitment:

  • First reads the version without committing it to the hash
  • For unknown versions, properly delegates to the unknown_field handler
  • For known versions (17, 18, or < 17), processes them normally with proper hash calculation

CI Failure Details

The issue was caught by bitcoinfuzz in CI with the following error:

Invoice deserialization failed for lnbc1qqqqqqg9qqsqqsqqsqqdqqpp5s7zxqqqqqqqqqqqqqqqdqqqqqqqqqqqqqqqqqqqqq8qqq9qqqqqqfq95xw7tfpp35qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcqpjqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqyqyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq5s846z
bitcoinfuzz: driver.cpp:125: void bitcoinfuzz::Driver::InvoiceDeserializationTarget(std::span<const uint8_t>) const: Assertion `*res == *last_response' failed.
==38107== ERROR: libFuzzer: deadly signal
Module: Lnd
Result: HASH=878460000000000000000000d000000000000000000000000001c00014000000;AMOUNT=0;DESCRIPTION=;RECIPIENT=03027be81b41bdfda1ded1f4e0dd5a997635ad325a6e119f414a92fe78c86a45cf;EXPIRY=3600;TIMESTAMP=8;ROUTING_HINTS=0;MIN_CLTV=18
Module: CLightning
Result: HASH=878460000000000000000000d000000000000000000000000001c00014000000;AMOUNT=0;DESCRIPTION=;RECIPIENT=03e6b1f437d1984a58e4192289e8e0f21e2bbcd863dc43374037e61621abb8d1de;EXPIRY=3600;TIMESTAMP=8;ROUTING_HINTS=0;MIN_CLTV=18

See full details at: https://github.com/bitcoinfuzz/bitcoinfuzz/actions/runs/15113684421/job/42478878043#step:33:58

@erickcestari erickcestari force-pushed the fix-unknow-fallback-field-hash-calculation branch 3 times, most recently from 08a8c96 to be3f15d Compare May 21, 2025 20:09
…ss versions

Changelog-Fixed: Fixed hash calculation inconsistency when processing
invoices with unknown fallback address versions.
@erickcestari erickcestari force-pushed the fix-unknow-fallback-field-hash-calculation branch from be3f15d to 8848b69 Compare May 21, 2025 22:34
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.

1 participant