Skip to content

Commit

Permalink
Use secp256k1 musig2 (#405)
Browse files Browse the repository at this point in the history
* cargo: Add secp256k1 patch for musig.

* cargo: Revert secp to 0.29 and apply chainway patch.

* cargo: Remove musig2.

* musig2: Update functions with new secp types.

* errors: Remove old musig errors and add new ones.

* secp_musig: Switch to the new types wherever possible.

* database: Add MusigPubNonceDB type.

* database: Add new wrapper for MusigAggNonceDB and fix rest.

* verifier-musig2: Fix copying error for nonces in deposit_sign.

Co-authored-by: Ekrem BAL <[email protected]>

* musig2: Fix compilation errors caused by the switch.

* database: Add Message wrapper.

* core: Fix rest of the compilation errors caused by the switch.

* tests-musig: Fix compilation errors.

* clippy: Apply suggestions.

* musig: Convert from_digest_slices to from_digest.

* secp: Convert secp types into bitcoin::secp.

* musig2: Convert secp types into bitcoin::secp types.

* musig2: Remove tweak_flag from from_musig2_pks.

* cargo: Delete config generator.

* Revert "musig2: Remove tweak_flag from from_musig2_pks."

This reverts commit d0ccc06.

* musig2: Add initial tweak support.

* musig: Add create_key_agg_cache and MusigTweak.

* musig: Fix wrong params for MusigTweak and add KeyAndScriptSpend.

* Add signature verification to aggregate_partial_signatures (#417)

* database: Fix wrong encoding for pub and agg nonces.

* musig: Remove none from Musig2Mode and make them optional.

* feat(musig2): add musig2 tweaking

* musig2: add musig2 tweaking test and update README

* errors: Add Secp256k1ScalarOutOfRange and return BridgeError in musog2.

* musig2: Fix merge conflicts for key_agg_cache_tweak_checks test.

* tests: Fix musig2 test by changing musig2 tweak modes.

* musig2: Remove xonly field from Musig2Mode.

* watchtower pk's for watchtower challenge page tx (#404)

* Add watchtower xonly_pk to get_params and save to db

* fix clippy error

* add db helper to get single xonly_pk, remove unwrap

* Adjust sighash.rs and transaction.rs to remove nofn sigs from challenge page tx

* Incorporate Ceyhun's feedback

* Ozan/change anchor (#407)

* Update risc0-to-bitvm2, change anchor output

* Renaming fix from circuits to header-chain

* Use global context for secp256k1 (#408)

* Use global context for secp256k1

* Lint

* Delete comment

* Implement kickoff timeout tx (#413)

* Implement kickoff_timeoout_tx

* Clippy

* Add kickoff_timeout_tx to sighash_stream

* Change num_required_sigs

* Remove time_tx from the inputs of operator_challenge_nack_tx (#414)

* merge: Fix compilation errors caused by the merge.

* database: Remove redundant borsch usage for MessageDB.

* musig2: Add comments for Musig2Mode and update key_agg_cache tests.

---------

Co-authored-by: Ekrem BAL <[email protected]>
Co-authored-by: Ozan Kaymak <[email protected]>
Co-authored-by: Mehmet Efe Akça <[email protected]>
Co-authored-by: atacann <[email protected]>
  • Loading branch information
5 people authored Jan 17, 2025
1 parent c8d321f commit a562f4d
Show file tree
Hide file tree
Showing 24 changed files with 1,809 additions and 1,572 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ serial_test = "3.2.0"
# bitcoin
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", "global-context"] }
secp256k1 = { version = "0.30.0", features = ["serde", "rand", "std", "global-context"] }
bitcoin-script = { git = "https://github.com/BitVM/rust-bitcoin-script", branch= "StructuredScript" }

# async + gRPC
Expand Down Expand Up @@ -59,6 +58,8 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark/" }
ark-snark = { git = "https://github.com/arkworks-rs/snark/" }
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16" }

secp256k1 = { git = "https://github.com/jlest01/rust-secp256k1", branch = "musig2-module" }

[profile.release]
lto = true
strip = true
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ and configure Bitcoin Core if you haven't already.

### Preparing a Configuration File

Running a binary as a verifier, aggregator or operator requires a configuration
file. Example configuration file is located at
Running the binary as a verifier, aggregator or operator requires a configuration
file. An example configuration file is located at
[`core/tests/data/test_config.toml`](core/tests/data/test_config.toml) and can
be taken as reference. Please copy that configuration file to another location
and modify fields to your local configuration.
Expand Down Expand Up @@ -54,6 +54,30 @@ More information, use `--help` flag:

### Testing

#### Prerequisites

1. **PostgreSQL Database**

Tests require a PostgreSQL database. You can quickly set one up using Docker:

```bash
docker run --name clementine-test-db \
-e POSTGRES_USER=clementine \
-e POSTGRES_PASSWORD=clementine \
-e POSTGRES_DB=clementine \
-p 5432:5432 \
--restart always \
-d postgres:15
```

2. **RISC Zero Toolchain**

For prover tests, you'll need to install the RISC Zero toolchain:

```bash
cargo install cargo-risczero
```

#### Bitcoin Regtest Setup

To simulate deposits, withdrawals, proof generation on the Bitcoin Regtest
Expand Down
8 changes: 1 addition & 7 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sha2 = { workspace = true }
risc0-zkvm = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
secp256k1 = { workspace = true, features = ["serde"] }
secp256k1 = { workspace = true, features = ["serde", "rand", "std"] }
crypto-bigint = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
Expand All @@ -27,7 +27,6 @@ futures = { workspace = true }
clap = { workspace = true, features = ["derive"] }
toml = { workspace = true }
sqlx = { workspace = true, features = ["runtime-tokio", "postgres", "macros"] }
musig2 = { workspace = true }
header-chain = { workspace = true }
borsh = { workspace = true}
tonic = { workspace = true}
Expand All @@ -49,8 +48,3 @@ testing = []
[[bin]]
name = "server"
path = "src/bin/server.rs"

[[bin]]
name = "config_generator"
path = "src/bin/config_generator.rs"
required-features = ["testing"]
37 changes: 19 additions & 18 deletions core/src/actor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::builder::transaction::TxHandler;
use crate::errors::BridgeError;
use crate::utils::{self, SECP};
use bitcoin::secp256k1::PublicKey;
use bitcoin::sighash::SighashCache;
use bitcoin::taproot::LeafVersion;
use bitcoin::{
Expand All @@ -11,7 +13,6 @@ 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 @@ -91,22 +92,22 @@ impl Default for WinternitzDerivationPath {
pub struct Actor {
pub keypair: Keypair,
_secret_key: SecretKey,
winternitz_secret_key: Option<secp256k1::SecretKey>,
winternitz_secret_key: Option<SecretKey>,
pub xonly_public_key: XOnlyPublicKey,
pub public_key: secp256k1::PublicKey,
pub public_key: PublicKey,
pub address: Address,
}

impl Actor {
#[tracing::instrument(ret(level = tracing::Level::TRACE))]
pub fn new(
sk: SecretKey,
winternitz_secret_key: Option<secp256k1::SecretKey>,
winternitz_secret_key: Option<SecretKey>,
network: bitcoin::Network,
) -> Self {
let keypair = Keypair::from_secret_key(SECP256K1, &sk);
let keypair = Keypair::from_secret_key(&SECP, &sk);
let (xonly, _parity) = XOnlyPublicKey::from_keypair(&keypair);
let address = Address::p2tr(SECP256K1, xonly, None, network);
let address = Address::p2tr(&SECP, xonly, None, network);

Actor {
keypair,
Expand All @@ -124,19 +125,19 @@ impl Actor {
sighash: TapSighash,
merkle_root: Option<TapNodeHash>,
) -> Result<schnorr::Signature, BridgeError> {
Ok(SECP256K1.sign_schnorr(
&Message::from_digest_slice(sighash.as_byte_array()).expect("should be hash"),
Ok(utils::SECP.sign_schnorr(
&Message::from_digest(*sighash.as_byte_array()),
&self.keypair.add_xonly_tweak(
SECP256K1,
&SECP,
&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 {
SECP256K1.sign_schnorr(
&Message::from_digest_slice(sighash.as_byte_array()).expect("should be hash"),
utils::SECP.sign_schnorr(
&Message::from_digest(*sighash.as_byte_array()),
&self.keypair,
)
}
Expand Down Expand Up @@ -348,11 +349,12 @@ impl Actor {
mod tests {
use super::Actor;
use crate::config::BridgeConfig;
use crate::utils::initialize_logger;
use crate::utils::{initialize_logger, SECP};
use crate::{
actor::WinternitzDerivationPath, builder::transaction::TxHandler,
create_test_config_with_thread_name, database::Database, initialize_database,
};
use bitcoin::secp256k1::SecretKey;
use bitcoin::{
absolute::Height, transaction::Version, Amount, Network, OutPoint, Transaction, TxIn, TxOut,
};
Expand All @@ -363,8 +365,7 @@ mod tests {
},
treepp::script,
};
use secp256k1::SECP256K1;
use secp256k1::{rand, SecretKey};
use secp256k1::rand;
use std::env;
use std::str::FromStr;
use std::thread;
Expand Down Expand Up @@ -435,8 +436,8 @@ mod tests {
let actor = Actor::new(sk, None, network);

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

#[test]
Expand Down Expand Up @@ -555,7 +556,7 @@ mod tests {
let actor = Actor::new(
config.secret_key,
Some(
secp256k1::SecretKey::from_str(
SecretKey::from_str(
"451F451F451F451F451F451F451F451F451F451F451F451F451F451F451F451F",
)
.unwrap(),
Expand All @@ -577,7 +578,7 @@ mod tests {
let actor = Actor::new(
config.secret_key,
Some(
secp256k1::SecretKey::from_str(
SecretKey::from_str(
"451F451F451F451F451F451F451F451F451F451F451F451F451F451F451F451F",
)
.unwrap(),
Expand Down
Loading

0 comments on commit a562f4d

Please sign in to comment.