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.x.y
version number. Expect breaking changes and security fixes. Once this crate is stabilized, we will tag and release v1.0.0
.
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 (AKASecNonce
) 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 thesecp256k1
crate, maintained by the Bitcoin Core team. - A pure-rust implementation via the
k256
crate, 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
If both k256
and 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 k256
.
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::Scalar
for non-zero scalar values.secp::Point
for non-infinity curve pointssecp::MaybeScalar
for possibly-zero scalars.secp::MaybePoint
for 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 secp256k1::PublicKey
or 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.
Head on over to docs.rs to see the full API documentation and usage examples.