Skip to content

fix(keymap): use correct derivation_path for keys with origin - #863

Merged
apoelstra merged 1 commit into
rust-bitcoin:masterfrom
oleonardolima:fix/getkey-bip32-key-origin-deriv
Oct 10, 2025
Merged

fix(keymap): use correct derivation_path for keys with origin#863
apoelstra merged 1 commit into
rust-bitcoin:masterfrom
oleonardolima:fix/getkey-bip32-key-origin-deriv

Conversation

@oleonardolima

Copy link
Copy Markdown
Contributor
  • Fixes the implementation of GetKey for KeyRequest::Bip32 when there's Xpriv has an origin, and it matches with the given KeyRequest::Bip32 derivation_path. It should strip the matching part, to correctly derive the key at the correct child number.
  • Updates the existing test to the correct and expected behavior.

- Fixes the implementation of `GetKey` for `KeyRequest::Bip32` when
  there's `Xpriv` has an origin, and it matches with the given
`KeyRequest::Bip32` derivation_path. It should strip the matching part,
to correctly derive the key at the correct child number.
- Updates the existing test to the correct and expected behavior.
@oleonardolima
oleonardolima force-pushed the fix/getkey-bip32-key-origin-deriv branch from b8f4d24 to 2f72b27 Compare October 10, 2025 01:23
Comment thread src/descriptor/key_map.rs
if let Some(matched_path) = descriptor_xkey.matches(key_source, secp) {
let (_, full_path) = key_source;

let derivation_path = &full_path[matched_path.len()..];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The matched path includes the xkey.derivation_path, therefore we need to derive the xkey.derivation_path together with the remaining un-matched path. That's my hunch.

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.

This was never resolved, did you investigate this @oleonardolima?

Is this what you were talking about at the Summit @ValuedMammal or was that a different bug you think you found?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, VM explained this issue to me at the summit.

I'm planning on working on this issue and adding more integration tests for different signing scenarios this week.

@ValuedMammal let me know if you found any other issues with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this will work, following the same implementation in bdk.

if let Some(..) = descriptor_xkey.matches(key_source, secp) {
    let (_, full_path) = key_source;

    let derived = match &descriptor_xkey.origin {
        Some((_, origin_path)) => {
            let derivation_path = &full_path[origin_path.len()..];
            descriptor_xkey.xkey.derive_priv(secp, &derivation_path)?
        }
        None => descriptor_xkey.xkey.derive_priv(secp, &full_path)?,
    };

    return Ok(Some(derived.to_priv()));
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've opened a new PR with the fix: #872 and I'll work on adding some more testing for different scenarios, specifically the multipath one.

@apoelstra

Copy link
Copy Markdown
Member

Yep, I think this is correct.

@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 2f72b27; successfully ran local tests

@apoelstra
apoelstra merged commit 1179ea2 into rust-bitcoin:master Oct 10, 2025
31 checks passed
@oleonardolima
oleonardolima deleted the fix/getkey-bip32-key-origin-deriv branch October 13, 2025 13:32
apoelstra added a commit that referenced this pull request Jun 27, 2026
…info

a2f4497 test(key_map): improve `Xprv` key origin tests (Leonardo Lima)
20ae466 fix(key_map): derivation_path for `Xprv` with key origin info (Leonardo Lima)

Pull request description:

  ### Description
  
  The `GetKey` for `DescriptorSecretKey` (and thus `KeyMap`) returned the wrong key when an extended private key with key origin info was queried via `KeyRequest::Bip32`.
  
  The key request path is master-relative, but the `xkey` is anchored at its origin (e.g. `[d34db33f/84h/1h/0h]`). The old code stripped the path returned by `matches()`; the fix strips the origin prefix instead (and uses the full path when there is no origin) before deriving from the `xkey`.
  
  --
  
  Also, this PR introduces the test `get_key_xpriv_with_key_origin` covering the scenarios: bare wildcard; single fixed step; fixed step then wildcard, and the matching/non-matching cases build requests from explicit `(fingerprint, path)` key sources.
  
  ### Notes
  
  If you'd like an overview on the issue, see: #863 (comment)
  
  ### Changelog notice
  
  ```​
  ### Fixed
  - keymap: fix `GetKey` derivation path for `Xprv` with key origin info [#872](#872)
  ```
  
  ### Checklists
  
  #### Bugfixes:
  
  * [ ] This pull request breaks the existing API
  * [x] I've added tests to reproduce the issue which are now passing
  * [ ] I'm linking the issue being fixed by this PR


ACKs for top commit:
  notmandatory:
    ACK a2f4497
  noahjoeris:
    tACK a2f4497
  apoelstra:
    ACK a2f4497; successfully ran local tests


Tree-SHA512: 7980e4cfccc8b0b53a054350dd7870122192407c4e17c36f75350093d7be63d4a5e75be40f4e4583c1a1cf0641a469d55842b7108e8bce6e8aa44f519e51b963
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.

4 participants