Skip to content
This repository was archived by the owner on Oct 22, 2026. It is now read-only.

descriptor: correct master_fingerprint docs for keys without origin - #1063

Merged
apoelstra merged 1 commit into
rust-bitcoin:masterfrom
milah-247:fix-998-master-fingerprint
Oct 13, 2026
Merged

apoelstra merged 1 commit into
rust-bitcoin:masterfrom
milah-247:fix-998-master-fingerprint

Conversation

@milah-247

@milah-247 milah-247 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Related to #998.

The docs for DescriptorPublicKey::master_fingerprint and DefiniteDescriptorKey::master_fingerprint said the result is 0x00000000 when the key has no origin. The code has never done that. A key without origin is treated as its own master key:

  • an xpub returns its own fingerprint (Xpub::fingerprint)
  • a single key returns the first four bytes of HASH160 of its serialization (33 bytes for a full key, 32 bytes for an x-only key)

That is the same key origin Bitcoin Core's descriptor code reports for constant pubkeys (ConstPubkeyProvider returns the key ID's fingerprint with an empty path). It is also consistent with BIP-174, where an empty path means the key is its own master.

This PR fixes the docs instead of the behavior. Returning 0x00000000 would make every origin-less key look the same as (0x00000000, []), which would break key matching in plan::Assets (has_ecdsa_key, has_taproot_*_key). Leaving these keys out of the PSBT origin maps would lose the Taproot leaf-hash information carried in tap_key_origins.

Changes:

  • Rewrite the master_fingerprint docs on both wrappers to describe the real behavior.
  • Document in PsbtInputExt / PsbtOutputExt::update_with_descriptor_unchecked that origin-less keys are recorded with their own fingerprint and an empty derivation path.
  • Extend test_master_fingerprint to cover x-only keys and DefiniteDescriptorKey.
  • Add test_update_item_no_origin_single_key, which checks the bip32_derivation (wpkh) and tap_key_origins (tr) entries from the issue's reproductions.

The docs for `DescriptorPublicKey::master_fingerprint` and
`DefiniteDescriptorKey::master_fingerprint` claimed the result is
`0x00000000` when the key has no origin. That has never been the
behavior: a key without origin is treated as its own master key, so
xpubs return their own fingerprint and single keys return the first
four bytes of HASH160 of their serialization. This is the same key
origin Bitcoin Core reports for constant pubkeys, and code such as
`Assets` in `plan.rs` relies on it to tell origin-less keys apart.

Fix the docs to describe the actual behavior, document what the PSBT
`update_with_descriptor_unchecked` helpers write into
`bip32_derivation` / `tap_key_origins` for such keys, and add tests
pinning down the fingerprint for full and x-only keys and the PSBT
entries for both segwit v0 and Taproot descriptors.

Fixes rust-bitcoin#998

@apoelstra apoelstra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK 68a2681; successfully ran local tests

@apoelstra
apoelstra merged commit 6adab21 into rust-bitcoin:master Oct 13, 2026
13 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants