TSP-0011 โ€” Native MuSig2

Proposal Number: TSP-0011

Proposal Number: TSP-0011
Proposal Name: Native MuSig2 Multi-Signatures
Category: Consensus (C) โ€” pre-Oct 2025 numbering retained as 000x
Status: Draft
Author: Tondi Foundation Development Team & Avato Labs
Created: 2025-09-05
Target: Tondi Frontier (v2026a)
Scope: Tapscript opcodes for MuSig2 key and nonce aggregation, partial signature operations, on-chain validation semantics, interoperability with TSP-0008 (CISA) and TSP-0007 (ANYPREVOUT), governance & activation

This document uses RFC 2119 keywords (MUST/SHOULD/MAYโ€ฆ).
This proposal introduces native support for the MuSig2 multi-signature scheme, building on BIP-340 Schnorr signatures. It complements TSP-0008 by enabling MuSig2 for general multi-party scripts without cross-input restrictions, and TSP-0010 (PTLC) for adaptor-compatible multi-sigs. v1 focuses on n-of-n schemes, with future extensions for thresholds.

1. Abstract

Native MuSig2 integrates the MuSig2 protocol directly into Tondi tapscript, allowing multi-party key aggregation, nonce handling, and signature verification via new opcodes. This enables compact, private multi-signatures for Taproot outputs, where aggregated keys appear as single keys on-chain. MuSig2 supports two-round interactive signing, rogue-key resistance, and tweaking for BIP-32 derivations or Taproot scripts. The proposal ensures soft-fork compatibility, with on-chain verification matching BIP-340.

2. Background and Motivation

  • Efficiency and Privacy: MuSig2 aggregates multiple keys into one BIP-340 public key, producing a single 64B signature. This reduces on-chain size (e.g., 30-50% fee savings vs. OP_CHECKSIGADD) and hides multi-party nature, enhancing privacy over explicit multi-sig scripts.

  • Interactivity Reduction: Two-round protocol (nonce exchange + partial signs) is faster than three-round schemes, suitable for Tondi's DAG high-TPS environment.

  • Security: Proven under AOMDL assumption, resistant to rogue-key attacks via coefficients.

  • Composability: Integrates with PTLC adaptors (TSP-0010) for multi-party conditionals and CISA (TSP-0008) for aggregated settlements.

Design Goals:

  • Soft fork (tapscript-only + OP_SUCCESSx tightening);
  • BIP-340 compatible;
  • Non-interactive aggregation where possible;
  • v1: n-of-n only, no thresholds.

3. Terminology and Overall Design

  • MuSig2: Two-round Schnorr multi-signature scheme for n signers, producing a single signature under an aggregated key.

  • Key Aggregation: Computes aggregated public key X from individual X_i using coefficients a_i to prevent rogue-key attacks.

  • Nonce Aggregation: Each signer contributes two nonces; aggregated with a binding factor b.

  • Partial Signature: Each signer's contribution s_i, summed to final s.

  • Tweaking: Plain (BIP-32) or x-only (Taproot) adjustments to aggregated keys.

v1 Scope:

  • Tapscript script-path only;
  • SIGHASH_ALL default;
  • Interoperable with APO/CISA but no mixing in v1 cohorts;
  • On-chain ops for aggregation/verification.

4. Specification

4.1 New Opcodes

  • Via OP_SUCCESSx for soft fork:

    • OP_MUSIGKEYAGG (0xBA): Aggregates public keys with coefficients.
    • OP_MUSIGNONCEAGG (0xBB): Aggregates nonces with binding.
    • OP_MUSIGPARTIALSIG (0xBC): Computes partial signature (off-chain hint, on-chain verify).
    • OP_MUSIGVERIFY (0xBD): Verifies aggregated signature.
      Specific values allocated from TSP-0001 reserved range 0xB2-0xBF.
  • Non-upgraded nodes: Unconditional success; upgraded: Tighten to MuSig2 logic.

4.2 Key Aggregation
Stack: <pubkey_n> ... <pubkey_1> n OP_MUSIGKEYAGG

  • Sort pubkeys X_1..X_n (x-only, ascending).
  • L = TaggedHash("KeyAgg list", X_1 || ... || X_n)
  • For each X_i: a_i = TaggedHash("KeyAgg coeff", L || X_i) (a_i=1 if n=1 or X_i is second in sorted unique list).
  • Agg key X = sum (a_i * X_i)
  • Push X (x-only 32B) to stack.
  • Fail if any X_i invalid or n>1024 (configurable).

Pseudocode:

fn musig_key_agg(pubkeys: Vec<XOnlyPubKey>) -> XOnlyPubKey {
    let sorted = sort(pubkeys);
    let L = tag_hash("KeyAgg list", concat(sorted));
    let mut X = Point::infinity();
    for (i, Xi) in sorted.iter().enumerate() {
        let ai = if sorted.len() == 1 || (i > 0 && Xi == sorted[1]) { 1 } else { tag_hash("KeyAgg coeff", L || Xi) };
        X += ai * Xi;
    }
    X.x_only()
}

4.3 Nonce Aggregation
Each signer generates two secret nonces k_{i,1}, k_{i,2}; computes R_{i,1} = k_{i,1}*G, R_{i,2} = k_{i,2}*G (off-chain).

Stack: <R_{n,2}> <R_{n,1}> ... <R_{1,2}> <R_{1,1}> n OP_MUSIGNONCEAGG

  • Compute R1_sum = sum R_{i,1}, R2_sum = sum R_{i,2}
  • b = TaggedHash("MuSig/noncecoeff", R1_sum.x || R2_sum.x || agg_X || m)
  • Agg nonce R = R1_sum + b * R2_sum
  • Push R (x-only 32B).
  • Fail if R even (adjust as per BIP-340) or invalid points.

4.4 Partial Signature and Aggregation
Off-chain: Each signer computes s_i = k_{i,1} + b * k_{i,2} + e * a_i * x_i, where e = TaggedHash("BIP0340/challenge", R.x || agg_X || m)

On-chain (for verify): Sum s = sum s_i

4.5 Verification
Stack: <sig_s> <agg_R> <agg_X> OP_MUSIGVERIFY

  • e = TaggedHash("BIP0340/challenge", agg_R.x || agg_X || m)
  • Verify: s * G == agg_R + e * agg_X
  • Fail tx if false (VERIFY variant pops and fails script).

4.6 Tweaking

  • Plain: agg_X' = agg_X + t * G, for BIP-32.
  • X-only: agg_X' = agg_X + TaggedHash("TapTweak", agg_X || merkle_root).
  • Use in scripts: <tweaked_X> OP_CHECKSIG (standard BIP-340).

4.7 Interoperability and Constraints

  • v1: No APO mixing in MuSig2 sessions (future extension).
  • With CISA (TSP-0008): Use MuSig2 coeffs in cohorts.
  • Failure: Invalid points, overflow, mismatched n.

5. DAG / Mempool Policy

  • Size/Fee: Aggregated sigs count as 64B; limit n=1024.
  • Validation: Batch verify; relay only standard templates.
  • RBF: Compatible.

6. Security Analysis

6.1 Rogue-Key Resistance: Coeffs a_i bind key set.
6.2 Nonce Security: Two nonces per signer; binding b prevents reuse.
6.3 Provable: EUF under AOMDL; no replay via tags.

7. Economic and Privacy Impacts

  • Savings: ~47 vBytes/input vs. SegWit.
  • Privacy: Indistinguishable from single-sig.

8. Compatibility and Deployment

8.1 Soft Fork: Tapscript-only.
8.2 Activation: Testnet 3 months; version bit.

9. Reference Implementation (Pseudocode)

fn musig_verify(s: Scalar, R: Point, X: Point, m: Bytes) -> bool {
    let e = tag_hash("BIP0340/challenge", R.x_only() || X || m);
    s * G == R + e * X
}

10. Test Vectors

  • 2-signer agg key, nonce, sig.
  • Negative: Rogue-key attempt, nonce reuse.

11. Interoperability and Evolution

  • Thresholds via future TSP.
  • Multi-session batching.

12. Deployment Checklist

  • Test vectors, audits.

13. Conclusion

TSP-0011 enables native MuSig2 for efficient, private multi-sigs in Tondi.

Appendix A: Size Example

  • n=3: Single 64B sig vs. 3x64B.

References

  • BIP-327: MuSig2
  • MuSig2 Paper (eprint.iacr.org/2020/1261)
  • BIP-340/341/342