Skip to content

Commit

Permalink
secp256k1-zkp-sys: Add Rust FFI for Musig2 module
Browse files Browse the repository at this point in the history
  • Loading branch information
GeneFerneau committed Aug 22, 2021
1 parent 7becbb1 commit f735f14
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 1 deletion.
3 changes: 3 additions & 0 deletions secp256k1-zkp-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ fn main() {
.define("ENABLE_MODULE_GENERATOR", Some("1"))
.define("ENABLE_MODULE_RANGEPROOF", Some("1"))
.define("ENABLE_MODULE_ECDSA_ADAPTOR", Some("1"))
.define("ENABLE_MODULE_EXTRAKEYS", Some("1"))
.define("ENABLE_MODULE_MUSIG", Some("1"))
.define("ENABLE_MODULE_SCHNORRSIG", Some("1"))
.define("ECMULT_GEN_PREC_BITS", Some("4"))
// TODO these three should be changed to use libgmp, at least until secp PR 290 is merged
.define("USE_NUM_NONE", Some("1"))
Expand Down
252 changes: 251 additions & 1 deletion secp256k1-zkp-sys/src/zkp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::{fmt, hash};
use {types::*, Context, PublicKey, Signature};
use {types::*, Context, KeyPair, PublicKey, Signature, XOnlyPublicKey};
use {secp256k1_xonly_pubkey_from_pubkey};

/// Rangeproof maximum length
pub const RANGEPROOF_MAX_LENGTH: size_t = 5134;
Expand Down Expand Up @@ -334,6 +335,157 @@ extern "C" {
adaptor_sig162: *const EcdsaAdaptorSignature,
enckey: *const PublicKey,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_pubkey_combine"
)]
pub fn secp256k1_musig_pubkey_combine(
cx: *const Context,
scratch: *mut ScratchSpace,
combined_pk: *mut XOnlyPublicKey,
pre_session: *mut MusigPreSession,
pubkeys: *const *const XOnlyPublicKey,
n_pubkeys: size_t,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_pubkey_tweak_add"
)]
pub fn secp256k1_musig_pubkey_tweak_add(
cx: *const Context,
pre_session: *mut MusigPreSession,
output_pubkey: *mut PublicKey,
internal_pubkey: *const XOnlyPublicKey,
tweak32: *const c_uchar,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_session_init"
)]
pub fn secp256k1_musig_session_init(
cx: *const Context,
secnonce: *mut MusigSecNonce,
pubnonce: *mut c_uchar,
session_id32: *const c_uchar,
seckey: *const c_uchar,
msg32: *const c_uchar,
combined_pk: *const XOnlyPublicKey,
extra_intput32: *const c_uchar,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_nonces_combine"
)]
pub fn secp256k1_musig_nonces_combine(
cx: *const Context,
combined_pubnonce: *const c_uchar,
pubnonces: *const *const c_uchar,
n_pubnonces: size_t,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_process_nonces"
)]
pub fn secp256k1_musig_process_nonces(
cx: *const Context,
session_cache: *mut MusigSessionCache,
sig_template: *mut MusigTemplate,
nonce_parity: *mut c_int,
pubnonces: *const *const c_uchar,
n_pubnonces: size_t,
msg32: *const c_uchar,
combined_pk: *const XOnlyPublicKey,
pre_session: *const MusigPreSession,
adaptor: *const PublicKey,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_signature_serialize"
)]
pub fn secp256k1_musig_partial_signature_serialize(
cx: *const Context,
out32: *mut c_uchar,
sig: *const MusigPartialSignature,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_signature_parse"
)]
pub fn secp256k1_musig_partial_signature_parse(
cx: *const Context,
sig: *mut MusigPartialSignature,
in32: *const c_uchar,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_sign"
)]
pub fn secp256k1_musig_partial_sign(
cx: *const Context,
partial_sig: *mut MusigPartialSignature,
secnonce: *mut MusigSecNonce,
keypair: *const KeyPair,
pre_session: *const MusigPreSession,
session_cache: *const MusigSessionCache,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_sig_verify"
)]
pub fn secp256k1_musig_partial_sig_verify(
cx: *const Context,
partial_sig: *const MusigPartialSignature,
pubnonce: *const c_uchar,
pubkey: *const XOnlyPublicKey,
pre_session: *const MusigPreSession,
session_cache: *const MusigSessionCache,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_sig_combine"
)]
pub fn secp256k1_musig_partial_sig_combine(
cx: *const Context,
sig64: *mut c_uchar,
sig_template: *const MusigTemplate,
partial_sigs: *const *const MusigPartialSignature,
n_sigs: size_t,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_partial_sig_adapt"
)]
pub fn secp256k1_musig_partial_sig_adapt(
cx: *const Context,
adaptor_sig: *mut MusigPartialSignature,
partial_sig: *const MusigPartialSignature,
sec_adaptor32: *const c_uchar,
nonce_parity: c_int,
) -> c_int;

#[cfg_attr(
not(feature = "external-symbols"),
link_name = "rustsecp256k1zkp_v0_4_0_musig_extract_secret_adaptor"
)]
pub fn secp256k1_musig_extract_secret_adaptor(
cx: *const Context,
sec_adaptor32: *mut c_uchar,
sig64: *const c_uchar,
partial_sigs: *const MusigPartialSignature,
n_partial_sigs: size_t,
nonce_parity: c_int,
) -> c_int;
}

#[repr(C)]
Expand Down Expand Up @@ -510,3 +662,101 @@ impl EcdsaAdaptorSignature {
&self.0
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigPreSession {
pub magic: u64,
pub pk_hash: [c_uchar; 32],
pub second_pk: [c_uchar; 32],
pub pk_parity: c_int,
pub is_tweaked: c_int,
pub tweak: [c_uchar; 32],
pub internal_key_parity: c_int,
}

impl MusigPreSession {
pub fn new() -> Self {
Self {
magic: 0xf4ad_bbdf_7c7d_d304,
pk_hash: [0; 32],
second_pk: [0; 32],
pk_parity: 0,
is_tweaked: 0,
tweak: [0; 32],
internal_key_parity: 0,
}
}
}

#[repr(C)]
pub struct ScratchSpace(c_int);

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigPartialSignature {
pub data: [c_uchar; 32],
}

impl MusigPartialSignature {
pub fn new() -> Self {
Self { data: [0; 32] }
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigTemplate {
pub data: [c_uchar; 64],
}

impl MusigTemplate {
pub fn new() -> Self {
Self { data: [0; 64] }
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigSessionCache {
pub data: [c_uchar; 65],
}

impl MusigSessionCache {
pub fn new() -> Self {
Self { data: [0; 65] }
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigSecNonce {
pub data: [c_uchar; 64],
}

impl MusigSecNonce {
pub fn new() -> Self {
Self { data: [0; 64] }
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct MusigPubNonce {
pub data: [c_uchar; 66],
}

impl MusigPubNonce {
pub fn new() -> Self {
Self { data: [0; 66] }
}
}

pub fn xonly_from_pubkey(cx: *const Context, pubkey: *const PublicKey) -> (XOnlyPublicKey, c_int) {
unsafe {
let mut xonly = XOnlyPublicKey::new();
let mut parity = 0;
secp256k1_xonly_pubkey_from_pubkey(cx, &mut xonly, &mut parity, pubkey);
(xonly, parity)
}
}

0 comments on commit f735f14

Please sign in to comment.