Tapscript & MuSig2 support, with a miniscript decoder and satisfier#535
Open
odudex wants to merge 9 commits into
Open
Tapscript & MuSig2 support, with a miniscript decoder and satisfier#535odudex wants to merge 9 commits into
odudex wants to merge 9 commits into
Conversation
Adds tr() descriptors with script paths: the WALLY_LEAF_VERSION_TAPSCRIPT constant, multi_a/sortedmulti_a tapscript fragments, taptree parsing with BIP-341 merkle-root/leaf hashing, tr() address derivation including the key-path tweak, and the taproot tree/leaf/control-block/key-enumeration accessor APIs. Includes the C and Python descriptor test suites. Co-authored-by: odudex <odudex@proton.me>
Adds a standalone miniscript decoder (miniscript_decode.{c,h}): a Script
tokenizer and recursive-descent decoder for all miniscript fragments
(pk_k/pk_h, hashes, timelocks, multi/multi_a, and_v/and_b, or_b/c/d/i,
andor, thresh, and the wrapper fragments), with stack-overflow and
non-minimal-push hardening. Relocates ms_node and the shared KIND_*
constants into descriptor_int.h so the new translation unit can share
them. Includes the C decoder tests and the BIP-379 differential vectors.
Co-authored-by: odudex <odudex@proton.me>
Adds the witness satisfier (miniscript_satisfy.c): per-fragment satisfaction/dissatisfaction with non-malleable minimum-weight selection (satisfaction_best, or_b/c/d/i, andor, thresh with a DP sort) and a satisfy_node dispatch over the decoded tree, plus the ms_witness / ms_satisfaction structures and lifecycle helpers. Includes witness_weight overflow saturation, iterative tree traversal to bound stack usage, and the geometric-growth / move-not-copy / precomputed-weight optimizations. Exercised directly by the C satisfy tests. Co-authored-by: odudex <odudex@proton.me>
Adds the MuSig2 implementation (musig.c) over the secp256k1-zkp musig module: key aggregation, nonce generation and aggregation, the signing pipeline (nonce_process, partial_sign, verify, aggregate), and lifecycle helpers for the opaque keyagg-cache / nonce / session / partial-sig types, plus BIP-328 synthetic-xpub helpers and the language bindings. Enables the secp256k1 musig module in the build and routes a malformed parsed keyagg-cache/session through a non-aborting illegal-argument callback. Includes the BIP-327/328 vector and protocol test suites. Co-authored-by: odudex <odudex@proton.me>
Adds the musig() key expression to the descriptor parser (valid only as a taproot internal key or tapscript leaf key), a format_key_node helper for serializing key nodes, and the musig() introspection API (participant count and per-participant keys). This enables parsing and address derivation for tr(musig(...)) descriptors. Includes the musig() descriptor parsing / address-generation tests and the BIP-390 vectors.
Adds PSBT support for the new descriptor types. BIP-371 taproot: internal key, leaf scripts, merkle root and tap bip32 derivation fields; script-path sighash, signing and descriptor-based taproot population; and the finalizers (p2wsh, p2tr key/script path, multisig). BIP-373 MuSig2: participant pubkey, public-nonce and partial-sig fields with nonce generation, partial signing, aggregation and finalization, plus wally_psbt_populate_musig2_from_descriptor. Includes the PSBT, MuSig2-PSBT, BIP-373 interop and satisfier differential test suites. Co-authored-by: odudex <odudex@proton.me>
Adds a PSBT MuSig2 field fuzzer and musig() cases to the descriptor fuzzer, with seed corpus for the musig() descriptor parser.
Adds the MuSig2 API reference, wires it into the docs index, notes the changes in CHANGES.md, and adds a runnable 2-of-2 MuSig2 PSBT signing example using real randomness and a compressed aggregate key.
Includes musig.c and the miniscript decoder/satisfier in the single-file amalgamation build, gated on BUILD_STANDARD_SECP for the MuSig2 module.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds tapscript (taproot script-path) descriptors, a Script→miniscript decoder
and a witness satisfier, MuSig2 (BIP-327) signing, and the descriptor / PSBT plumbing to
use them end-to-end.
The bulk of this work was authored by @pythcoiner. My own contributions are some bug fixes,
hardening, the amalgamation build integration folded into the relevant commits and a rebase proposed in #533 .
Goals
tr()script-path spending: taptree parsing,multi_a/sortedmulti_afragments, BIP-341 merkle-root/leaf hashing, and thetree/leaf/control-block accessor APIs.
witness satisfier (covering tapscript).
and BIP-328 synthetic-xpub helpers over the secp256k1-zkp musig module.
musig()descriptors (BIP-390) —tr(musig(...))parsing, address derivation,and participant introspection.
finalization, wired up from descriptors.
consumers building with
-DBUILD_STANDARD_SECP(MuSig2 compiled out) still build clean.Review structure
The original development history (100+ commits) has been reorganized into 9
self-contained commits, each a coherent milestone with its own tests. The intent is
to make this reviewable and mergeable gradually. Each commit builds, passes its
tests, and can be assessed (or landed) on its own rather than as one monolithic diff.
descriptor: add taproot (tapscript) descriptor supporttr()script paths:multi_a/sortedmulti_a, taptree parsing & BIP-341 leaf/merkle hashing, script-path address derivation, tree/leaf/control-block accessorsminiscript: add Script-to-miniscript decoderminiscript: add miniscript satisfiermusig2: add MuSig2 (BIP-327) core APIdescriptor: add musig() key expressions (BIP-390)musig()as a taproot internal/leaf key,tr(musig(...))derivation, participant introspection API; BIP-390 vectorspsbt: add taproot (BIP-371) and MuSig2 (BIP-373) supportfuzz: add fuzzers for musig() descriptor and PSBT MuSig2 fieldsmusig()descriptor fuzz cases + seed corpusdocs: document the MuSig2 API and add a 2-of-2 PSBT examplebuild: add musig and miniscript sources to the amalgamationBUILD_STANDARD_SECPBIPs implemented
BIP-327 (MuSig2), BIP-328 (xpub for aggregate keys), BIP-341 (Taproot), BIP-371
(PSBT Taproot fields), BIP-373 (PSBT MuSig2 fields), BIP-379 (Miniscript),
BIP-390 (
musig()descriptors).Tests
This branch was integrated in Kern project, where tapscript is under tests.
Musig2 support is not currently being tested in a consumer project. I believe @pythcoiner is baking some ideas and can share a north for practical tests.