AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 35 Bitcoin

rust client: build PSBTv2 maps from all pairs, not an enumerated list

Public commit record

What the developer wrote

Authored by Salvatore Ingala

73/100 · Adequate
rust client: build PSBTv2 maps from all pairs, not an enumerated list

`get_v2_{global,input,output}_pairs` were a hand-maintained copy of
rust-bitcoin's `Map::get_pairs`.

This is error-prone, and forced us to reimplement a lot of the
(de)serialization logic.

Instead, we let rust-bitcoin serialization the psbt as v0, instead, and
only touch the keys where v0 and v2 actually differ: drop
PSBT_GLOBAL_UNSIGNED_TX, add the global v2 fields and each input's and
output's v2 fields.

This also simplifies the code, as more is delegated to rust-bitcoin.

`get_v2_global_pairs`, `get_v2_input_pairs` and `get_v2_output_pairs`
are replaced with a single `get_v2_maps` function, so the whole PSBT
is serialized once rather than once per input and output.

Key order is irrelevant -- `add_known_mapping` and
`get_merkleized_map_commitment` both sort -- so the commitments
remain valid as per the app's expectations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
The short version

What changed, and why it matters

This commit refactors how the Ledger Bitcoin app's Rust client converts a PSBT (Partially Signed Bitcoin Transaction) from version 0 to version 2. Previously, the code manually listed every PSBT field it knew how to serialize, which risked silently dropping newer or unknown fields. The new code lets the rust-bitcoin library do most of the serialization, then only adds, removes, or changes the specific fields that differ between v0 and v2. It also adds checks that reject malformed PSBTs where v2 fields already exist and conflict with the v0 transaction data. The change is a defensive cleanup that reduces the chance of an incomplete or inconsistent PSBT being sent to the hardware wallet.

Recommended action

Review the new `split_maps` and `read_prefixed` parsing logic for off-by-one or length-prefix edge cases, and ensure the test suite exercises PSBTs with proprietary, unknown, and all standard input/output fields. Consider fuzzing `get_v2_maps` against arbitrary PSBT byte streams. No immediate incident response is indicated by the diff alone.

Security signals we found

01

Refactor of PSBT serialization path used before signing on hardware wallet

02

Removal of hand-maintained field enumeration that could omit or mis-serialize PSBT fields

03

Addition of explicit error handling for PSBTs containing pre-existing v2 keys that conflict with v0 transaction data

04

Delegation of known-field serialization to upstream rust-bitcoin library

05

Addition of unit tests covering malformed/truncated serialization and conflicting v2 fields

Risk score

Why this scored 35/100

Our methodology →
Potential impact 8/30
Exploitability 6/25
Stealth signal 5/15
Affected reach 7/15
Confidence 6/10
Evidence quality 3/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.