Skip to content

Commit

Permalink
Use global context for secp256k1 (#408)
Browse files Browse the repository at this point in the history
* Use global context for secp256k1

* Lint

* Delete comment
  • Loading branch information
ozankaymak authored Jan 13, 2025
1 parent 6f10485 commit c3ed546
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 84 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ serial_test = "3.2.0"
bitcoin = "0.32.5"
bitcoincore-rpc = "0.18.0"
musig2 = { version = "0.0.11", features = ["serde"] }
secp256k1 = { version = "0.29.1", features = ["serde", "rand-std"] }
secp256k1 = { version = "0.29.1", features = ["serde", "rand-std", "global-context"] }
bitcoin-script = { git = "https://github.com/BitVM/rust-bitcoin-script", branch= "StructuredScript" }

# async + gRPC
Expand Down
20 changes: 10 additions & 10 deletions core/src/actor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::builder::transaction::TxHandler;
use crate::errors::BridgeError;
use crate::utils;
use bitcoin::sighash::SighashCache;
use bitcoin::taproot::LeafVersion;
use bitcoin::{
Expand All @@ -12,6 +11,7 @@ use bitcoin::{TapLeafHash, TapNodeHash, TapSighashType, TxOut, Witness};
use bitvm::signatures::winternitz::{
self, BinarysearchVerifier, StraightforwardConverter, Winternitz,
};
use secp256k1::SECP256K1;

/// Available transaction types for [`WinternitzDerivationPath`].
#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -104,9 +104,9 @@ impl Actor {
winternitz_secret_key: Option<secp256k1::SecretKey>,
network: bitcoin::Network,
) -> Self {
let keypair = Keypair::from_secret_key(&utils::SECP, &sk);
let keypair = Keypair::from_secret_key(SECP256K1, &sk);
let (xonly, _parity) = XOnlyPublicKey::from_keypair(&keypair);
let address = Address::p2tr(&utils::SECP, xonly, None, network);
let address = Address::p2tr(SECP256K1, xonly, None, network);

Actor {
keypair,
Expand All @@ -124,18 +124,18 @@ impl Actor {
sighash: TapSighash,
merkle_root: Option<TapNodeHash>,
) -> Result<schnorr::Signature, BridgeError> {
Ok(utils::SECP.sign_schnorr(
Ok(SECP256K1.sign_schnorr(
&Message::from_digest_slice(sighash.as_byte_array()).expect("should be hash"),
&self.keypair.add_xonly_tweak(
&utils::SECP,
SECP256K1,
&TapTweakHash::from_key_and_tweak(self.xonly_public_key, merkle_root).to_scalar(),
)?,
))
}

#[tracing::instrument(skip(self), ret(level = tracing::Level::TRACE))]
pub fn sign(&self, sighash: TapSighash) -> schnorr::Signature {
utils::SECP.sign_schnorr(
SECP256K1.sign_schnorr(
&Message::from_digest_slice(sighash.as_byte_array()).expect("should be hash"),
&self.keypair,
)
Expand Down Expand Up @@ -363,7 +363,8 @@ mod tests {
},
treepp::script,
};
use secp256k1::{rand, Secp256k1, SecretKey};
use secp256k1::SECP256K1;
use secp256k1::{rand, SecretKey};
use std::env;
use std::str::FromStr;
use std::thread;
Expand Down Expand Up @@ -428,15 +429,14 @@ mod tests {

#[test]
fn actor_new() {
let secp = Secp256k1::new();
let sk = SecretKey::new(&mut rand::thread_rng());
let network = Network::Regtest;

let actor = Actor::new(sk, None, network);

assert_eq!(sk, actor._secret_key);
assert_eq!(sk.public_key(&secp), actor.public_key);
assert_eq!(sk.x_only_public_key(&secp).0, actor.xonly_public_key);
assert_eq!(sk.public_key(SECP256K1), actor.public_key);
assert_eq!(sk.x_only_public_key(SECP256K1).0, actor.xonly_public_key);
}

#[test]
Expand Down
24 changes: 12 additions & 12 deletions core/src/builder/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use bitcoin::{
taproot::{TaprootBuilder, TaprootSpendInfo},
Address, ScriptBuf,
};
use secp256k1::XOnlyPublicKey;
use secp256k1::{XOnlyPublicKey, SECP256K1};

/// Creates a taproot address with either key path spend or script spend path
/// addresses. This depends on given arguments.
Expand Down Expand Up @@ -53,16 +53,16 @@ pub fn create_taproot_address(
};

let tree_info = match internal_key {
Some(xonly_pk) => taproot_builder.finalize(&utils::SECP, xonly_pk).unwrap(),
Some(xonly_pk) => taproot_builder.finalize(SECP256K1, xonly_pk).unwrap(),
None => taproot_builder
.finalize(&utils::SECP, *utils::UNSPENDABLE_XONLY_PUBKEY)
.finalize(SECP256K1, *utils::UNSPENDABLE_XONLY_PUBKEY)
.unwrap(),
};

let taproot_address = match internal_key {
Some(xonly_pk) => Address::p2tr(&utils::SECP, xonly_pk, tree_info.merkle_root(), network),
Some(xonly_pk) => Address::p2tr(SECP256K1, xonly_pk, tree_info.merkle_root(), network),
None => Address::p2tr(
&utils::SECP,
SECP256K1,
*utils::UNSPENDABLE_XONLY_PUBKEY,
tree_info.merkle_root(),
network,
Expand Down Expand Up @@ -162,25 +162,25 @@ mod tests {
use crate::{
builder,
musig2::AggregateFromPublicKeys,
utils::{self, SECP},
utils::{self},
};
use bitcoin::{key::TapTweak, Address, AddressType, Amount, ScriptBuf, XOnlyPublicKey};
use secp256k1::{rand, Keypair, PublicKey, SecretKey};
use secp256k1::{rand, Keypair, PublicKey, SecretKey, SECP256K1};
use std::str::FromStr;

#[test]
fn create_taproot_address() {
let secret_key = SecretKey::new(&mut rand::thread_rng());
let internal_key =
XOnlyPublicKey::from_keypair(&Keypair::from_secret_key(&SECP, &secret_key)).0;
XOnlyPublicKey::from_keypair(&Keypair::from_secret_key(SECP256K1, &secret_key)).0;

// No internal key or scripts (key path spend).
let (address, spend_info) =
builder::address::create_taproot_address(&[], None, bitcoin::Network::Regtest);
assert_eq!(address.address_type().unwrap(), AddressType::P2tr);
assert!(address.is_related_to_xonly_pubkey(
&utils::UNSPENDABLE_XONLY_PUBKEY
.tap_tweak(&SECP, spend_info.merkle_root())
.tap_tweak(SECP256K1, spend_info.merkle_root())
.0
.to_inner()
));
Expand All @@ -196,7 +196,7 @@ mod tests {
assert_eq!(address.address_type().unwrap(), AddressType::P2tr);
assert!(address.is_related_to_xonly_pubkey(
&internal_key
.tap_tweak(&SECP, spend_info.merkle_root())
.tap_tweak(SECP256K1, spend_info.merkle_root())
.0
.to_inner()
));
Expand All @@ -212,7 +212,7 @@ mod tests {
assert_eq!(address.address_type().unwrap(), AddressType::P2tr);
assert!(address.is_related_to_xonly_pubkey(
&internal_key
.tap_tweak(&SECP, spend_info.merkle_root())
.tap_tweak(SECP256K1, spend_info.merkle_root())
.0
.to_inner()
));
Expand All @@ -228,7 +228,7 @@ mod tests {
assert_eq!(address.address_type().unwrap(), AddressType::P2tr);
assert!(address.is_related_to_xonly_pubkey(
&internal_key
.tap_tweak(&SECP, spend_info.merkle_root())
.tap_tweak(SECP256K1, spend_info.merkle_root())
.0
.to_inner()
));
Expand Down
10 changes: 5 additions & 5 deletions core/src/builder/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use bitcoin::{
};
use bitcoin::{Network, Transaction, Txid};
use bitvm::signatures::winternitz;
use secp256k1::XOnlyPublicKey;
use secp256k1::{XOnlyPublicKey, SECP256K1};

/// Verbose information about a transaction.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -335,7 +335,7 @@ pub fn create_kickoff_utxo_txhandler(
);
let (musig2_and_operator_address, _) =
builder::address::create_taproot_address(&[musig2_and_operator_script], None, network);
let operator_address = Address::p2tr(&utils::SECP, operator_xonly_pk, None, network);
let operator_address = Address::p2tr(SECP256K1, operator_xonly_pk, None, network);
let change_amount = funding_utxo.txout.value
- Amount::from_sat(KICKOFF_UTXO_AMOUNT_SATS.to_sat() * num_kickoff_utxos_per_tx as u64)
// - builder::script::anyone_can_spend_txout().value
Expand Down Expand Up @@ -1123,9 +1123,9 @@ pub fn create_tx_outs(pairs: Vec<(Amount, ScriptBuf)>) -> Vec<TxOut> {

#[cfg(test)]
mod tests {
use crate::{builder, utils::SECP};
use crate::builder;
use bitcoin::{hashes::Hash, Amount, OutPoint, Txid, XOnlyPublicKey};
use secp256k1::{rand, Keypair, SecretKey};
use secp256k1::{rand, Keypair, SecretKey, SECP256K1};

#[test]
fn create_move_tx() {
Expand All @@ -1135,7 +1135,7 @@ mod tests {
};
let secret_key = SecretKey::new(&mut rand::thread_rng());
let nofn_xonly_pk =
XOnlyPublicKey::from_keypair(&Keypair::from_secret_key(&SECP, &secret_key)).0;
XOnlyPublicKey::from_keypair(&Keypair::from_secret_key(SECP256K1, &secret_key)).0;
let bridge_amount_sats = Amount::from_sat(0x1F45);
let network = bitcoin::Network::Regtest;

Expand Down
4 changes: 2 additions & 2 deletions core/src/database/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ mod tests {
hashes::Hash,
Amount, BlockHash, CompactTarget, OutPoint, ScriptBuf, TxMerkleNode, TxOut, Txid,
};
use secp256k1::schnorr::Signature;
use secp256k1::{schnorr::Signature, SECP256K1};
use sqlx::{encode::IsNull, postgres::PgArgumentBuffer, Encode, Type};

#[test]
Expand Down Expand Up @@ -344,7 +344,7 @@ mod tests {
);

let address = bitcoin::Address::p2tr(
&utils::SECP,
SECP256K1,
*utils::UNSPENDABLE_XONLY_PUBKEY,
None,
bitcoin::Network::Regtest,
Expand Down
27 changes: 12 additions & 15 deletions core/src/musig2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,14 @@ mod tests {
hashes::Hash, opcodes::all::OP_CHECKSIG, script, Amount, OutPoint, ScriptBuf, TapNodeHash,
TxOut, Txid,
};
use secp256k1::{rand::Rng, Keypair, Message, XOnlyPublicKey};
use secp256k1::{rand::Rng, Keypair, Message, XOnlyPublicKey, SECP256K1};
use std::vec;

// Generates a test setup with a given number of signers. Returns a vector of keypairs and a vector of nonce pairs.
fn generate_test_setup(num_signers: usize) -> (Vec<Keypair>, Vec<MuSigNoncePair>) {
let mut keypair_vec: Vec<Keypair> = Vec::new();
for _ in 0..num_signers {
keypair_vec.push(Keypair::new(
&crate::utils::SECP,
&mut secp256k1::rand::thread_rng(),
));
keypair_vec.push(Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng()));
}
let nonce_pair_vec: Vec<MuSigNoncePair> = keypair_vec
.iter()
Expand Down Expand Up @@ -245,9 +242,9 @@ mod tests {
// Test that the verification fails if one of the partial signatures is invalid.
#[test]
fn test_musig2_raw_fail() {
let kp_0 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_1 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_2 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_0 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let kp_1 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let kp_2 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let message: [u8; 32] = secp256k1::rand::thread_rng().gen();
let pks = vec![kp_0.public_key(), kp_1.public_key(), kp_2.public_key()];
let (sec_nonce_0, pub_nonce_0) =
Expand Down Expand Up @@ -346,9 +343,9 @@ mod tests {

#[test]
fn test_musig2_tweak_fail() {
let kp_0 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_1 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_2 = secp256k1::Keypair::new(&utils::SECP, &mut secp256k1::rand::thread_rng());
let kp_0 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let kp_1 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let kp_2 = secp256k1::Keypair::new(SECP256K1, &mut secp256k1::rand::thread_rng());
let message: [u8; 32] = secp256k1::rand::thread_rng().gen();
let tweak: [u8; 32] = secp256k1::rand::thread_rng().gen();
let pks = vec![kp_0.public_key(), kp_1.public_key(), kp_2.public_key()];
Expand Down Expand Up @@ -420,7 +417,7 @@ mod tests {
let dummy_script = script::Builder::new().push_int(1).into_script();
let scripts: Vec<ScriptBuf> = vec![dummy_script];
let receiving_address = bitcoin::Address::p2tr(
&utils::SECP,
SECP256K1,
*utils::UNSPENDABLE_XONLY_PUBKEY,
None,
bitcoin::Network::Regtest,
Expand Down Expand Up @@ -486,7 +483,7 @@ mod tests {
XOnlyPublicKey::from_musig2_pks(pks, merkle_root, true);
// musig2::verify_single(musig_agg_pubkey, &final_signature, message)
// .expect("Verification failed!");
utils::SECP
SECP256K1
.verify_schnorr(
&secp256k1::schnorr::Signature::from_slice(&final_signature).unwrap(),
&Message::from_digest(message),
Expand All @@ -513,7 +510,7 @@ mod tests {
.into_script();
let scripts: Vec<ScriptBuf> = vec![musig2_script];
let receiving_address = bitcoin::Address::p2tr(
&utils::SECP,
SECP256K1,
*utils::UNSPENDABLE_XONLY_PUBKEY,
None,
bitcoin::Network::Regtest,
Expand Down Expand Up @@ -577,7 +574,7 @@ mod tests {
.unwrap();
// musig2::verify_single(musig_agg_pubkey, &final_signature, message)
// .expect("Verification failed!");
utils::SECP
SECP256K1
.verify_schnorr(
&secp256k1::schnorr::Signature::from_slice(&final_signature).unwrap(),
&Message::from_digest(message),
Expand Down
4 changes: 2 additions & 2 deletions core/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use bitvm::signatures::winternitz;
use jsonrpsee::core::client::ClientT;
use jsonrpsee::http_client::HttpClientBuilder;
use jsonrpsee::rpc_params;
use secp256k1::{schnorr, Message};
use secp256k1::{schnorr, Message, SECP256K1};
use serde_json::json;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -442,7 +442,7 @@ impl Operator {
};
tx.input[0].witness.push(user_sig_wrapped.serialize());

utils::SECP.verify_schnorr(
SECP256K1.verify_schnorr(
&user_sig,
&Message::from_digest(*sighash.as_byte_array()),
&user_xonly_pk,
Expand Down
10 changes: 5 additions & 5 deletions core/src/rpc/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
},
errors::BridgeError,
musig2::{self, MuSigPubNonce, MuSigSecNonce},
sha256_hash, utils,
sha256_hash,
verifier::{NofN, NonceSession, Verifier},
ByteArray32, ByteArray66, EVMAddress,
};
Expand All @@ -19,7 +19,7 @@ use bitvm::{
bridge::transactions::signing_winternitz::WinternitzPublicKey, signatures::winternitz,
};
use futures::StreamExt;
use secp256k1::{schnorr, Message, XOnlyPublicKey};
use secp256k1::{schnorr, Message, XOnlyPublicKey, SECP256K1};
use std::{pin::pin, str::FromStr};
use tokio::sync::mpsc;
use tokio_stream::wrappers::ReceiverStream;
Expand Down Expand Up @@ -127,7 +127,7 @@ impl ClementineVerifier for Verifier {
timeout_tx_sighash_stream
.enumerate()
.map(|(i, sighash)| {
utils::SECP
SECP256K1
.verify_schnorr(
&timeout_tx_sigs[i],
&Message::from(sighash?),
Expand Down Expand Up @@ -253,7 +253,7 @@ impl ClementineVerifier for Verifier {
session_id
};

let public_key = secp256k1::PublicKey::from_secret_key(&utils::SECP, &private_key)
let public_key = secp256k1::PublicKey::from_secret_key(SECP256K1, &private_key)
.serialize()
.to_vec();
let public_key_hash = sha256_hash!(&public_key);
Expand Down Expand Up @@ -515,7 +515,7 @@ impl ClementineVerifier for Verifier {
};

tracing::debug!("Verifying Final Signature");
utils::SECP
SECP256K1
.verify_schnorr(
&final_sig,
&secp256k1::Message::from(sighash),
Expand Down
5 changes: 0 additions & 5 deletions core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ use tracing::level_filters::LevelFilter;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::{fmt, EnvFilter, Registry};

lazy_static::lazy_static! {
/// Global secp context.
pub static ref SECP: secp256k1::Secp256k1<secp256k1::All> = secp256k1::Secp256k1::new();
}

lazy_static::lazy_static! {
/// This is an unspendable pubkey.
///
Expand Down
Loading

0 comments on commit c3ed546

Please sign in to comment.