算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
bitcoin-musig2【设计与创意】MuSig2 (BIP327): two-round Schnorr key aggregation for n-of-n multisig. Aggregates n public keys into a single 32-byte x-only pubkey indistinguishable from a single-sig. Used in Taproot cooperative spends. Quick refs: protocol round-trip, key aggregation math, common attacks. USE WHEN: implementing n-of-n cooperative Taproot signing, designing Lightn…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Quick refs: protocol.md, key-agg.md, attacks.md
MuSig2 is the standard Schnorr key-aggregation protocol for Bitcoin.
n parties hold separate private keys, jointly produce a single public
key Q and a single signature (R, s) indistinguishable from a
single-key Schnorr signature.
Replaces MuSig1 (3-round) and MuSig-DN with simpler 2-round + better security proofs.
BIP327 is Status: Deployed, spec version 1.0.4 (as of September 2026).
Q was aggregated.Each signer i:
(k_{i,1}, k_{i,2}).(R_{i,1}, R_{i,2}) = (k_{i,1}*G, k_{i,2}*G).R_{i,1}, R_{i,2} to all other signers (66 bytes total).Aggregator computes:
R_1 = sum(R_{i,1}), R_2 = sum(R_{i,2}).b = TaggedHash("MuSig/noncecoef", R_1 || R_2 || agg_pubkey || msg).R = R_1 + b*R_2.Each signer i:
s_i using R, message, key-agg
coefficient a_i, etc.s_i.Aggregator: s = sum(s_i) mod n.
Final sig: (R.x, s) — 64 bytes, valid BIP340 sig under Q.
Inputs: pubkeys P_1, ..., P_n (in agreed-upon order)
1. L = sorted(P_i) (canonical order, byte-lex)
2. a_i = TaggedHash("KeyAgg coefficient", L || P_i.x)
3. Q = sum(a_i * P_i)
If Q.y is odd, parity bit g_q = -1, otherwise g_q = +1. This
parity is tracked through signing.
The coefficients a_i defeat the rogue-key attack that MuSig1
patched but earlier schemes had: an attacker who could pick their
public key after seeing others' would otherwise control the sum.
After key aggregation, Taproot tweak applies:
Q_tweaked = Q + t*G where t = TaggedHash("TapTweak", Q.x || merkle_root)
Signing for Q_tweaked requires an extra adjustment in the partial
sig phase. BIP327 specifies "tweak context" maintaining the
accumulated tweak.
NonceGen deterministic from secret + msg + extra_in.BIP327 covers only the signing math. Three companion BIPs (all by Ava Chow) carry MuSig2 into wallet software — statuses as of September 2026:
868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965
(SHA256 of the text MuSig2MuSig2MuSig2). Only unhardened
derivation is possible — there is no aggregate private key. Each
CKDpub step's I_L enters the session context as a plain
tweak (is_xonly_t = false), so every signer must recompute the
derivation tweaks for the child key being signed for.musig(KEY,KEY,...,KEY) descriptor
key expression. Allowed only inside tr(), rawtr() or sp(),
never nested in another musig(). Keys are sorted with KeySort
after all derivation and before aggregation, so the order written
in the descriptor does not matter. musig(...)/NUM/.../* derives
from the aggregate key per BIP328, and is legal only when every
participant is an xpub (or derived from one) and no participant
itself uses /* or /<NUM;NUM;...>. No hardened steps after
musig().PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS (0x1a),
PSBT_IN_MUSIG2_PUB_NONCE (0x1b),
PSBT_IN_MUSIG2_PARTIAL_SIG (0x1c) and
PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS (0x08).Bitcoin Core parses musig() descriptors and reads/writes the BIP373
PSBT fields from v30.0 (October 2025); descriptor support merged
in PR #31244 (2025-07-31). Core accepts musig() only inside tr()
— not rawtr() or sp() — per doc/descriptors.md (v31.1, July
2026).
b coefficient).musig() key expressions since
v2.4.0 (CHANGELOG 2025-03-07; GitHub release 2025-03-17): at most
5 keys per musig(), at most 8 parallel signing sessions
(persistent state is scarce), musig() allowed in multi_a but
not sortedmulti_a, and only musig(...)/** or
musig(...)/<M;N>/* — participants must be aggregated without
further per-key derivation. v2.5.1 (CHANGELOG 2026-09-09) fixed
musig() inside multi_a fragments. Coldcard is the opposite
case: the Mk4 and Q1 board configs both set NGU_INCL_MUSIG = 0
("Exclude unused optional libngu secp256k1 features to save
firmware space"), so MuSig is compiled out of the firmware
entirely (as of September 2026). Either way a coordinator that
speaks BIP373 PSBTs is required.libsecp256k1 (secp256k1_musig_* — no 2 in the prefix).
Mainline since v0.6.0 (2024-11-04) and built by default
(--enable-module-musig is [default=yes]); not experimental.
secp256k1_musig_keyagg_cache and secp256k1_musig_session still
have no serialization/parsing functions as of v0.8.0 (2026-08-03),
so signing state cannot be persisted across a process restart
between round 1 and round 2.rust-secp256k1 — the module is musig, not musig2
(secp256k1::musig: KeyAggCache, SecretNonce/PublicNonce,
AggregatedNonce, Session, PartialSignature,
AggregatedSignature). Support was added in the 0.32 development
series (CHANGELOG entry "0.32.0 - 2025-10-02", which also removed
the Secp256k1 context from the public API), but no stable
0.32.0 was ever published — the three 0.32.0-beta.* crates are
yanked. The first stable release carrying MuSig2 is 0.33.0
(2026-08-28); current stable is 0.33.1 (2026-08-29).rust-miniscript: PR #954 (Add BIP390 musig() descriptor key
expressions) is still open, so bdk_wallet 3.1.0 (2026-06-14)
cannot even parse tr(musig(...)) — bdk-ffi pins that behaviour in
a test literally named cannotCreateMusigDescriptor.g_q and g_b must propagate).a_i → produces a sig under a
different aggregated pubkey.