Skip to content

Commit 9428b6c

Browse files
committed
Add musig combine
1 parent 11e2eb5 commit 9428b6c

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ fn main() {
5555
.define("USE_ENDOMORPHISM", Some("1"))
5656
.define("ENABLE_MODULE_ECDH", Some("1"))
5757
.define("ENABLE_MODULE_RECOVERY", Some("1"))
58-
.define("ENABLE_MODULE_SCHNORRSIG", Some("1"));
58+
.define("ENABLE_MODULE_SCHNORRSIG", Some("1"))
59+
.define("ENABLE_MODULE_MUSIG", Some("1"));
5960

6061
if let Ok(target_endian) = env::var("CARGO_CFG_TARGET_ENDIAN") {
6162
if target_endian == "big" {

src/ffi.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,13 @@ extern "C" {
8282
pk: *const *const PublicKey,
8383
n_sigs: usize,
8484
) -> c_int;
85+
86+
pub fn secp256k1_musig_pubkey_combine(
87+
cx: *const Context,
88+
scratch: *mut ScratchSpace,
89+
combined_pk: *mut PublicKey,
90+
pk_hash32: *mut c_uchar,
91+
pubkeys: *const PublicKey,
92+
n_pubkeys: usize,
93+
) -> c_int;
8594
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub extern crate secp256k1;
3939
mod macros;
4040
pub mod ffi;
4141
pub mod schnorrsig;
42+
pub mod musig;
4243
mod test_utils;
4344

4445
/// TODO: Scratch space doc

src/musig.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// secp256k1-zkp bindings
2+
// Written in 2019 by
3+
// Jonas Nick
4+
//
5+
// To the extent possible under law, the author(s) have dedicated all
6+
// copyright and related and neighboring rights to this software to
7+
// the public domain worldwide. This software is distributed without
8+
// any warranty.
9+
//
10+
// You should have received a copy of the CC0 Public Domain Dedication
11+
// along with this software.
12+
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13+
//
14+
15+
//! # MuSig
16+
//! Support for bip-schnorr compliant multisignatures in the plain-pubkey model
17+
//!
18+
19+
use std::{ptr, mem};
20+
21+
use secp256k1::{self, Secp256k1, Verification};
22+
use secp256k1::key::PublicKey;
23+
24+
use ffi;
25+
26+
pub trait Verify {
27+
fn combine(&self, pks: &[PublicKey]) -> PublicKey;
28+
}
29+
30+
impl<C: Verification> Verify for Secp256k1<C> {
31+
// TODO: doc want to combine a collection of keys
32+
fn combine(&self, pks: &[PublicKey]) -> PublicKey {
33+
let mut pkptrs = Vec::with_capacity(pks.len());
34+
for pk in pks {
35+
pkptrs.push(pk.as_ptr());
36+
}
37+
unsafe {
38+
let mut pk: PublicKey = mem::uninitialized();
39+
// TODO
40+
// scratch space is NULL so only error can be
41+
// due to keys adding up to infinity
42+
assert_eq!(ffi::secp256k1_musig_pubkey_combine(*self.ctx(),
43+
ptr::null_mut(),
44+
pk.as_mut_ptr(),
45+
ptr::null_mut(),
46+
pks[0].as_ptr(),
47+
pks.len()), 1);
48+
pk
49+
}
50+
}
51+
}
52+
#[cfg(test)]
53+
mod tests {
54+
use rand::thread_rng;
55+
use secp256k1::{Secp256k1};
56+
use super::Verify;
57+
use test_utils::GenerateKeypair;
58+
59+
#[test]
60+
fn combine() {
61+
let s = Secp256k1::new();
62+
let mut pks = vec![];
63+
for _ in 0..10 {
64+
let (_, pk) = s.generate_keypair(&mut thread_rng());
65+
pks.push(pk);
66+
}
67+
let combined = s.combine(&pks);
68+
println!("{}", combined);
69+
}
70+
}
71+

0 commit comments

Comments
 (0)