Skip to content

Commit

Permalink
Add Musig2 module
Browse files Browse the repository at this point in the history
  • Loading branch information
jlest01 committed Jul 30, 2024
1 parent 46d5ef8 commit ee040cf
Show file tree
Hide file tree
Showing 87 changed files with 11,859 additions and 10,732 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ required-features = ["hashes", "std"]
name = "generate_keys"
required-features = ["rand", "std"]

[[example]]
name = "musig"
required-features = ["rand", "std"]

[workspace]
members = ["secp256k1-sys"]
exclude = ["no_std_test"]
79 changes: 79 additions & 0 deletions examples/musig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
extern crate secp256k1;

use secp256k1::{Keypair, Message, PublicKey, Scalar, Secp256k1, SecretKey };
use secp256k1::musig::{MusigKeyAggCache, MusigSessionId, new_musig_nonce_pair, MusigAggNonce, MusigSession};

fn main() {

let secp = Secp256k1::new();
let mut rng = rand::thread_rng();

let (seckey1, pubkey1) = secp.generate_keypair(&mut rng);

assert_eq!(pubkey1, PublicKey::from_secret_key(&secp, &seckey1));

let seckey2 = SecretKey::new(&mut rng);
let pubkey2 = PublicKey::from_secret_key(&secp, &seckey2);

assert_eq!(pubkey2, PublicKey::from_secret_key(&secp, &seckey2));

let pubkeys = [pubkey1, pubkey2];

let mut musig_key_agg_cache = MusigKeyAggCache::new(&secp, &pubkeys);

let plain_tweak: [u8; 32] = *b"this could be a BIP32 tweak....\0";
let xonly_tweak: [u8; 32] = *b"this could be a Taproot tweak..\0";

let plain_tweak = Scalar::from_be_bytes(plain_tweak).unwrap();
musig_key_agg_cache.pubkey_ec_tweak_add(&secp, &plain_tweak).unwrap();

let xonly_tweak = Scalar::from_be_bytes(xonly_tweak).unwrap();
let tweaked_agg_pk = musig_key_agg_cache.pubkey_xonly_tweak_add(&secp, &xonly_tweak).unwrap();

let agg_pk = musig_key_agg_cache.agg_pk();

assert_eq!(agg_pk, tweaked_agg_pk.x_only_public_key().0);

let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
let msg = Message::from_digest_slice(&msg_bytes).unwrap();

let musig_session_id1 = MusigSessionId::random();

let nonce_pair1 =
new_musig_nonce_pair(&secp, musig_session_id1, Some(&musig_key_agg_cache), Some(seckey1), pubkey1, Some(msg), None).unwrap();

let musig_session_id2 = MusigSessionId::random();

let nonce_pair2 =
new_musig_nonce_pair(&secp, musig_session_id2, Some(&musig_key_agg_cache), Some(seckey2), pubkey2, Some(msg), None).unwrap();

let sec_nonce1 = nonce_pair1.0;
let pub_nonce1 = nonce_pair1.1;

let sec_nonce2 = nonce_pair2.0;
let pub_nonce2 = nonce_pair2.1;

let nonces = [pub_nonce1, pub_nonce2];

let agg_nonce = MusigAggNonce::new(&secp, &nonces);

let session = MusigSession::new(&secp, &musig_key_agg_cache, agg_nonce, msg);

let keypair1 = Keypair::from_secret_key(&secp, &seckey1);
let partial_sign1 = session.partial_sign(&secp, sec_nonce1, &keypair1, &musig_key_agg_cache).unwrap();

let keypair2 = Keypair::from_secret_key(&secp, &seckey2);
let partial_sign2 = session.partial_sign(&secp, sec_nonce2, &keypair2, &musig_key_agg_cache).unwrap();

let is_partial_signature_valid = session.partial_verify(&secp, &musig_key_agg_cache, partial_sign1, pub_nonce1, pubkey1);
assert!(is_partial_signature_valid);

let is_partial_signature_valid = session.partial_verify(&secp, &musig_key_agg_cache, partial_sign2, pub_nonce2, pubkey2);
assert!(is_partial_signature_valid);

let partial_sigs = [partial_sign1, partial_sign2];

let sig64 = session.partial_sig_agg(&partial_sigs);

assert!(secp.verify_schnorr(&sig64, &msg_bytes, &agg_pk).is_ok());
}
2 changes: 1 addition & 1 deletion secp256k1-sys/depend/secp256k1-HEAD-revision.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# This file was automatically created by vendor-libsecp.sh
1ad5185cd42c0636104129fcc9f6a4bf9c67cc40
cf20ad88cd15bd21fcae9e3e7080d310434a21ce
7 changes: 5 additions & 2 deletions secp256k1-sys/depend/secp256k1/.cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ env:
MAKEFLAGS: -j4
BUILD: check
### secp256k1 config
ECMULTWINDOW: auto
ECMULTGENPRECISION: auto
ECMULTWINDOW: 15
ECMULTGENKB: 22
ASM: no
WIDEMUL: auto
WITH_VALGRIND: yes
Expand All @@ -21,6 +21,7 @@ env:
ECDH: no
RECOVERY: no
SCHNORRSIG: no
MUSIG: no
ELLSWIFT: no
### test options
SECP256K1_TEST_ITERS:
Expand Down Expand Up @@ -67,6 +68,7 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
MUSIG: yes
ELLSWIFT: yes
matrix:
# Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU
Expand All @@ -83,6 +85,7 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
MUSIG: yes
ELLSWIFT: yes
WRAPPER_CMD: 'valgrind --error-exitcode=42'
SECP256K1_TEST_ITERS: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ runs:
cat valgrind_fingerprint
shell: bash
- uses: actions/cache@v3
- uses: actions/cache@v4
id: cache
with:
path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ runs:
load: true
cache-from: type=gha

- # Workaround for https://github.com/google/sanitizers/issues/1614 .
# The underlying issue has been fixed in clang 18.1.3.
run: sudo sysctl -w vm.mmap_rnd_bits=28
shell: bash

- # Tell Docker to pass environment variables in `env` into the container.
run: >
docker run \
Expand Down
Loading

0 comments on commit ee040cf

Please sign in to comment.