Files
bitcoin/doc/musig.md
Ava Chow 2d46a89386 Squashed 'src/secp256k1/' changes from 2f2ccc46954..0cdc758a563
0cdc758a563 Merge bitcoin-core/secp256k1#1631: release: prepare for 0.6.0
39d5dfd542a release: prepare for 0.6.0
df2eceb2790 build: add ellswift.md and musig.md to release tarball
a306bb7e903 tools: fix check-abi.sh after cmake out locations were changed
145868a84d2 Do not export `secp256k1_musig_nonce_gen_internal`
b161bffb8bf Merge bitcoin-core/secp256k1#1579: Clear sensitive memory without getting optimized out (revival of #636)
a38d879a1a6 Merge bitcoin-core/secp256k1#1628: Name public API structs
7d48f5ed02e Merge bitcoin-core/secp256k1#1581: test, ci: Lower default iteration count to 16
694342fdb71 Name public API structs
0f73caf7c62 test, ci: Lower default iteration count to 16
9a8db52f4e9 Merge bitcoin-core/secp256k1#1582: cmake, test: Add `secp256k1_` prefix to test names
765ef53335a Clear _gej instances after point multiplication to avoid potential leaks
349e6ab916b Introduce separate _clear functions for hash module
99cc9fd6d01 Don't rely on memset to set signed integers to 0
97c57f42ba8 Implement various _clear() functions with secp256k1_memclear()
9bb368d1466 Use secp256k1_memclear() to clear stack memory instead of memset()
e3497bbf001 Separate between clearing memory and setting to zero in tests
d79a6ccd43a Separate secp256k1_fe_set_int( . , 0 ) from secp256k1_fe_clear()
1c081262227 Add secp256k1_memclear() for clearing secret data
1464f15c812 Merge bitcoin-core/secp256k1#1625: util: Remove unused (u)int64_t formatting macros
980c08df80a util: Remove unused (u)int64_t formatting macros
9b7c59cbb90 Merge bitcoin-core/secp256k1#1624: ci: Update macOS image
096e3e23f63 ci: Update macOS image
e7d384488e8 Don't clear secrets in pippenger implementation
68b55209f1b Merge bitcoin-core/secp256k1#1619: musig: ctimetests: fix _declassify range for generated nonce points
f0868a9b3d8 Merge bitcoin-core/secp256k1#1595: build: 45839th attempt to fix symbol visibility on Windows
1fae76f50c0 Merge bitcoin-core/secp256k1#1620: Remove unused scratch space from API
8be3839fb2e Remove unused scratch space from API
57eda3ba300 musig: ctimetests: fix _declassify range for generated nonce points
87384f5c0f2 cmake, test: Add `secp256k1_` prefix to test names
e59158b6eb7 Merge bitcoin-core/secp256k1#1553: cmake: Set top-level target output locations
18f9b967c25 Merge bitcoin-core/secp256k1#1616: examples: do not retry generating seckey randomness in musig
5bab8f6d3c4 examples: make key generation doc consistent
e8908221a45 examples: do not retry generating seckey randomness in musig
70b6be1834e extrakeys: improve doc of keypair_create (don't suggest retry)
01b5893389e Merge bitcoin-core/secp256k1#1599: #1570 improve examples: remove key generation loop
cd4f84f3ba8 Improve examples/documentation: remove key generation loops
a88aa935063 Merge bitcoin-core/secp256k1#1603: f can never equal -m
3660fe5e2a9 Merge bitcoin-core/secp256k1#1479: Add module "musig" that implements MuSig2 multi-signatures (BIP 327)
168c92011f5 build: allow enabling the musig module in cmake
f411841a46b Add module "musig" that implements MuSig2 multi-signatures (BIP 327)
0be79660f38 util: add constant-time is_zero_array function
c8fbdb1b972 group: add ge_to_bytes_ext and ge_from_bytes_ext
ef7ff03407f f can never equal -m
c232486d84e Revert "cmake: Set `ENVIRONMENT` property for examples on Windows"
26e4a7c2146 cmake: Set top-level target output locations
4c57c7a5a95 Merge bitcoin-core/secp256k1#1554: cmake: Clean up testing code
447334cb06d include: Avoid visibility("default") on Windows
472faaa8ee6 Merge bitcoin-core/secp256k1#1604: doc: fix typos in `secp256k1_ecdsa_{recoverable_,}signature` API description
292310fbb24 doc: fix typos in `secp256k1_ecdsa_{recoverable_,}signature` API description
85e224dd97f group: add ge_to_bytes and ge_from_bytes
7c987ec89e6 cmake: Call `enable_testing()` unconditionally
6aa576515ef cmake: Delete `CTest` module

git-subtree-dir: src/secp256k1
git-subtree-split: 0cdc758a56360bf58a851fe91085a327ec97685a
2024-11-04 14:59:46 -05:00

3.8 KiB

Notes on the musig module API

The following sections contain additional notes on the API of the musig module (include/secp256k1_musig.h). A usage example can be found in examples/musig.c.

API misuse

The musig API is designed with a focus on misuse resistance. However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation. While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes.

Therefore, users of the musig module must take great care to make sure of the following:

  1. A unique nonce per signing session is generated in secp256k1_musig_nonce_gen. See the corresponding comment in include/secp256k1_musig.h for how to ensure that.
  2. The secp256k1_musig_secnonce structure is never copied or serialized. See also the comment on secp256k1_musig_secnonce in include/secp256k1_musig.h.
  3. Opaque data structures are never written to or read from directly. Instead, only the provided accessor functions are used.

Key Aggregation and (Taproot) Tweaking

Given a set of public keys, the aggregate public key is computed with secp256k1_musig_pubkey_agg. A plain tweak can be added to the resulting public key with secp256k1_ec_pubkey_tweak_add by setting the tweak32 argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with secp256k1_xonly_pubkey_tweak_add by setting the tweak32 argument to the TapTweak hash defined in BIP 341. Both types of tweaking can be combined and invoked multiple times if the specific application requires it.

Signing

This is covered by examples/musig.c. Essentially, the protocol proceeds in the following steps:

  1. Generate a keypair with secp256k1_keypair_create and obtain the public key with secp256k1_keypair_pub.
  2. Call secp256k1_musig_pubkey_agg with the pubkeys of all participants.
  3. Optionally add a (Taproot) tweak with secp256k1_musig_pubkey_xonly_tweak_add and a plain tweak with secp256k1_musig_pubkey_ec_tweak_add.
  4. Generate a pair of secret and public nonce with secp256k1_musig_nonce_gen and send the public nonce to the other signers.
  5. Someone (not necessarily the signer) aggregates the public nonces with secp256k1_musig_nonce_agg and sends it to the signers.
  6. Process the aggregate nonce with secp256k1_musig_nonce_process.
  7. Create a partial signature with secp256k1_musig_partial_sign.
  8. Verify the partial signatures (optional in some scenarios) with secp256k1_musig_partial_sig_verify.
  9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using secp256k1_musig_partial_sig_agg.

The aggregate signature can be verified with secp256k1_schnorrsig_verify.

Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed. Whenever possible, it is recommended to generate the nonces only after the message is known. This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios. However, it does require two rounds of communication during the signing process. The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing. Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5).

Verification

A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7.