Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/conduition/musig2

Flexible Rust implementation of the MuSig2 multisignature protocol, compatible with Bitcoin.
https://github.com/conduition/musig2

bip340 bitcoin blockchain multisig multisignature musig musig2 schnorr-signatures

Last synced: 6 days ago
JSON representation

Flexible Rust implementation of the MuSig2 multisignature protocol, compatible with Bitcoin.

Awesome Lists containing this project

README

        

# MuSig2

This crate provides a flexible rust implementation of [MuSig2](https://eprint.iacr.org/2020/1261), 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](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki), 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.

## ⚠️ Beta Status ⚠️

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`.

## Overview

If you're not already familiar with MuSig2, the process of cooperative signing runs like so:

1. All signers share their public keys with one-another. The group computes an _aggregated public key_ which they collectively control.
2. 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.
3. 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.
4. In the **second signing round,** signers share their partial signatures with one-another. Partial signatures can be verified to place blame on misbehaving signers.
5. A valid set of partial signatures can be aggregated into a final signature, which is just a normal [Schnorr signature](https://en.wikipedia.org/wiki/Schnorr_signature), valid under the aggregated public key.

## Choice of Backbone

This crate does not implement elliptic curve point math directly. Instead we depend on one of two reputable libraries:

- C bindings to [`libsecp256k1`](https://github.com/bitcoin-core/secp256k1), via [the `secp256k1` crate](https://crates.io/crates/secp256k1), maintained by the Bitcoin Core team.
- A pure-rust implementation via [the `k256` crate](https://crates.io/crates/k256), maintained by the [RustCrypto](https://github.com/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.

```notrust
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](https://crates.io/crates/secp) and its types:

- [`secp::Scalar`](https://docs.rs/secp/struct.Scalar.html) for non-zero scalar values.
- [`secp::Point`](https://docs.rs/secp/struct.Point.html) for non-infinity curve points
- [`secp::MaybeScalar`](https://docs.rs/secp/enum.Point.html) for possibly-zero scalars.
- [`secp::MaybePoint`](https://docs.rs/secp/enum.Point.html) 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`](https://docs.rs/secp256k1/struct.PublicKey.html) or [`k256::SecretKey`](https://docs.rs/k256/type.SecretKey.html). 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.

## Documentation

[Head on over to docs.rs to see the full API documentation and usage examples.](https://docs.rs/musig2)