diff --git a/secp256k1-zkp-sys/build.rs b/secp256k1-zkp-sys/build.rs index 24049782..0d339e2f 100644 --- a/secp256k1-zkp-sys/build.rs +++ b/secp256k1-zkp-sys/build.rs @@ -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")) diff --git a/secp256k1-zkp-sys/src/zkp.rs b/secp256k1-zkp-sys/src/zkp.rs index 23db2a6b..78efc09c 100644 --- a/secp256k1-zkp-sys/src/zkp.rs +++ b/secp256k1-zkp-sys/src/zkp.rs @@ -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; @@ -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)] @@ -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) + } +}