MuSig2 - #794
Conversation
|
Cherry-picked the latest version of all the independent PRs. Other than displaying an address this should be all you need to use MuSig2. |
5dd2951 to
ec2a844
Compare
|
Somehow I thought I already implemented sending, but it seems I didn't. Done now. Tested with key path as well as script path. |
|
Did a complete overhaul to match Sjors/async-hwi#2 (though just Ledger, we'll leave ColdCard for a followup). Much vibed, but manually tested. I'll extract smaller patches as separate PR's later. This PR is orthogonal to #819, however I would prefer to use the newer Ledger app version from it, since it contains various MuSig2 related fixes. |
|
Testing this out, I noticed that it seems like if the ledger is the last signer to add a pubnonce, and I pass that PSBT right back to |
|
Rebased and probably fixed the ledger is the last signer issue. I can't test this myself at the moment. |
The sort in sortedmulti occurs only during script expansion. Keep the pubkeys in the order that they were provided to the parser.
For BIP388 policies, we will need to know wht index of each key expression, so keep track of them explicitly with a key expression index stored in each PubkeyProvider. This also mirrors what Bitcoin Core does for descriptors.
The derivation path should be parsed and validated for correctness, not just copied directly into a pubkey provider.
get_bip388_template returns the descriptor as a BIP 388 Wallet Descriptor Template string. get_pubkey_providers returns all of the pubkey providers from the descriptor, in the same order as the placeholders in the bip388 template. Callers can get the strings for the key information vector by calling PubkeyProvider.to_string_no_deriv()
After a descriptor is registered, we want to return to the caller some information about the registration. RegisteredDescriptor is a class that contains the name, the descriptor, the device type, and any data that the device returned in response to the registration. This class can be de/serialized from/to a string.
Adds registerdescriptor CLI command and its handlers. Adds register_descriptor to HardwareWalletClient with boilerplate implementation.
Translate the registered policy into a BitBox02 script configuration and display the selected receive or change address.
Co-authored-by: Codex (GPT-5.6 Sol) <noreply@openai.com>
Accept a serialized registered descriptor with signtx and dispatch policy signing through a dedicated device method.
Extend the generic descriptor registration test to fund, sign, and finalize a transaction spending from the registered policy.
Reconstruct the registered wallet policy and pass its registration HMAC when signing the PSBT.
HWI's Coldcard simulator patch stores multiple derivation paths per fingerprint so one seed can represent several multisig cosigners. get_xfp_paths() iterates fingerprint keys instead of path lists. This breaks descriptor enrollment and later signing fails with "Unknown multisig wallet". Iterate over the mapping values instead.
Sign with the existing PSBT flow after registerdescriptor has stored the policy on the device.
Sign with the existing PSBT flow after registerdescriptor has stored the policy on the device.
Move descriptor-to-policy translation into a reusable helper without changing registration behavior.
Translate the registered descriptor into the policy script configuration and use it for transaction inputs and change outputs.
dec7507 to
d1c3f0a
Compare
|
Rebased for the new approach. Github is currently broken, so I can't update the PR description. I'm not sure what the best way to handle miniscript fragments is. For now I added |
|
I dropped the temporary commit 1b4cd98 that used |
d509360 to
037ee58
Compare
Registered descriptor policies may contain Miniscript expressions in Taproot script leaves. Preserve these expressions as text while parsing their extended keys into the BIP388 key information vector. Restrict this fallback to tr() descriptors and known Miniscript fragment and wrapper names.
This adds support handling public nonces and partial signatures.
Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
Exercise descriptor registration and address display with a Miniscript recovery leaf in addition to the MuSig2 key path. Relax the Nano X automation match for its truncated primary-path label.
Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
This branch starts with these two merges, in order:
Both branches include the descriptor-registration work from #842.
It is developed and tested together with:
Bitcoin Core passes HWI the ordinary multipath descriptor. HWI translates it
to the representation expected by the device and returns an opaque serialized
registration.
For Ledger, HWI constructs the BIP388 descriptor template and key information
vector internally. Registered descriptors are subsequently supplied through
--registrationwhen displaying an address or signing a PSBT.The general workflow is:
tr(musig(...)/<0;1>/*)descriptor;registerdescriptorRPC, which invokes HWI'sregisterdescriptorcommand;walletdisplayaddress;sendcall.Bitcoin Core drives both MuSig2 signing rounds. HWI first returns the Ledger's
public nonce and later its partial signature. HWI preserves the other
participants' MuSig2 fields while communicating with Ledger.
Registered Taproot policies may contain Miniscript expressions in tapscript
leaves. HWI recognizes known Miniscript fragment and wrapper names there and
preserves the policy text while extracting the extended keys for BIP388. It
does not implement or compile Miniscript itself. This fallback is restricted
to
tr()descriptors with tapscript leaves.CI runs an end-to-end scenario against Bitcoin Core PR 91 and the Ledger
Bitcoin app 2.5.0 under Speculos. It covers:
and_v(v:pk(...),older(1));Rebuild instructions:
git fetch origin git fetch sjors git switch -c musig2 origin/master git merge --no-ff sjors/2026/08/display-address-bip388 git merge --no-ff sjors/2025/07/policy-sign git cherry-pick # the restMuSig2 support in this branch currently targets Ledger. Support for additional
hardware-wallet implementations can be added separately.