This crate provides a flexible rust implementation of MuSig2, an optimized digital signature aggregation protocol, on the
secp256k1 elliptic curve.
MuSig2 allows groups of mutually distrusting parties to cooperatively sign data and aggregate their signatures into a single aggregated signature which is indistinguishable from a signature made by a single private key. The group collectively controls an aggregated public key which can only create signatures if everyone in the group cooperates (AKA an N-of-N multisignature scheme). MuSig2 is optimized to support secure signature aggregation with only two round-trips of network communication.
Specifically, this crate implements BIP-0327, for creating and verifying signatures which validate under Bitcoin consensus rules, but the protocol is flexible and can be applied to any N-of-N multisignature use-case.
This crate is in beta status. The latest release is a
v0.0.x version number. Expect breaking changes and security fixes. Once this crate is stabilized, we will tag and release
If you're not already familiar with MuSig2, the process of cooperative signing runs like so:
- All signers share their public keys with one-another. The group computes an aggregated public key which they collectively control.
- In the first signing round, signers generate and share nonces (random numbers) with one-another. These nonces have both secret and public versions. Only the public nonce (AKA
PubNonce) should be shared, while the corresponding secret nonce (AKA
SecNonce) must be kept secret.
- Once every signer has received the public nonces of every other signer, each signer makes a partial signature for a message using their secret key and secret nonce.
- In the second signing round, signers share their partial signatures with one-another. Partial signatures can be verified to place blame on misbehaving signers.
- A valid set of partial signatures can be aggregated into a final signature, which is just a normal Schnorr signature, valid under the aggregated public key.
This crate does not implement elliptic curve point math directly. Instead we depend on one of two reputable libraries:
- C bindings to
libsecp256k1, via the
secp256k1crate, maintained by the Bitcoin Core team.
- A pure-rust implementation via the
k256crate, maintained by the RustCrypto team.
One or the other can be used. By default, this crate prefers to rely on
libsecp256k1, as this is the most vetted and publicly trusted implementation of secp256k1 curve math available anywhere. However, if you need a pure-rust implementation, you can install this crate without it, and use the pure-rust
k256 crate instead.
cargo add musig2 --no-default-features --features k256
secp256k1 features are enabled, then we default to using
libsecp256k1 bindings for the actual math, but still provide trait implementations to make this crate interoperable with
This crate internally represents elliptic curve points (e.g. public keys) and scalars (e.g. private keys) using the
secp crate and its types:
secp::Scalarfor non-zero scalar values.
secp::Pointfor non-infinity curve points
secp::MaybeScalarfor possibly-zero scalars.
secp::MaybePointfor possibly-infinity curve points.
Depending on which features of this crate are enabled, conversion traits are implemented between these types and higher-level types such as
k256::SecretKey. Generally, our API can accept or return any type that converts to/from the equivalent
secp representations, although callers are also welcome to use
secp directly too.