Skip to content

Commit

Permalink
Use ByteArray64 and 32 for secNonce and partialSig
Browse files Browse the repository at this point in the history
  • Loading branch information
ekrembal committed Sep 5, 2024
1 parent 1b76d8a commit 5803bd5
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 41 deletions.
6 changes: 3 additions & 3 deletions core/src/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Aggregator {
operator_xonly_pk: secp256k1::XOnlyPublicKey,
operator_idx: usize,
agg_nonce: &MuSigAggNonce,
partial_sigs: Vec<[u8; 32]>,
partial_sigs: Vec<MuSigPartialSignature>,
) -> Result<[u8; 64], BridgeError> {
let mut tx = TransactionBuilder::create_slash_or_take_tx(
deposit_outpoint,
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Aggregator {
operator_xonly_pk: &secp256k1::XOnlyPublicKey,
operator_idx: usize,
agg_nonce: &MuSigAggNonce,
partial_sigs: Vec<[u8; 32]>,
partial_sigs: Vec<MuSigPartialSignature>,
) -> Result<[u8; 64], BridgeError> {
let move_tx_handler = TransactionBuilder::create_move_tx(
deposit_outpoint,
Expand Down Expand Up @@ -179,7 +179,7 @@ impl Aggregator {
evm_address: &EVMAddress,
recovery_taproot_address: &Address<NetworkUnchecked>,
agg_nonce: &MuSigAggNonce,
partial_sigs: Vec<[u8; 32]>,
partial_sigs: Vec<MuSigPartialSignature>,
) -> Result<[u8; 64], BridgeError> {
let mut tx = TransactionBuilder::create_move_tx(
deposit_outpoint,
Expand Down
8 changes: 3 additions & 5 deletions core/src/database/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ impl Database {
.push_values(nonces, |mut builder, (sec, pub_nonce)| {
builder
.push_bind(OutPointDB(deposit_outpoint))
.push_bind(hex::encode(sec))
.push_bind(sec)
.push_bind(pub_nonce);
})
.build()
Expand Down Expand Up @@ -412,15 +412,13 @@ impl Database {
.bind(OutPointDB(deposit_outpoint))
.execute(&self.connection)
.await?;
let res: (String, MuSigAggNonce) = sqlx::query_as("SELECT sec_nonce, agg_nonce FROM nonces WHERE deposit_outpoint = $1 AND idx = $2 AND sighash = $3;")
let res: (MuSigSecNonce, MuSigAggNonce) = sqlx::query_as("SELECT sec_nonce, agg_nonce FROM nonces WHERE deposit_outpoint = $1 AND idx = $2 AND sighash = $3;")
.bind(OutPointDB(deposit_outpoint))
.bind(*idx)
.bind(hex::encode(sighash))
.fetch_one(&self.connection)
.await?;
// println!("res: {:?}", res);
let sec_nonce: MuSigSecNonce = hex::decode(res.0).unwrap().try_into()?;
nonces.push((sec_nonce, res.1));
nonces.push(res);
}

Ok(Some(nonces))
Expand Down
10 changes: 9 additions & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ pub struct UTXO {
pub txout: bitcoin::TxOut,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[derive(Clone, Debug, Copy, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "bytea")]
pub struct ByteArray66(#[serde(with = "hex::serde")] pub [u8; 66]);

#[derive(Clone, Debug, Copy, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "bytea")]
pub struct ByteArray32(#[serde(with = "hex::serde")] pub [u8; 32]);

#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "bytea")]
pub struct ByteArray64(#[serde(with = "hex::serde")] pub [u8; 64]);
27 changes: 14 additions & 13 deletions core/src/musig2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{errors::BridgeError, ByteArray66};
use crate::{errors::BridgeError, ByteArray32, ByteArray64, ByteArray66};
use bitcoin::hashes::Hash;
use bitcoin::TapNodeHash;
use musig2::{sign_partial, AggNonce, KeyAggContext, SecNonce, SecNonceSpices};
Expand All @@ -9,13 +9,13 @@ use secp256k1::{rand::Rng, PublicKey};
// MuSigPubNonce consists of two curve points, so it's 66 bytes (compressed).
pub type MuSigPubNonce = ByteArray66;
// MuSigSecNonce consists of two scalars, so it's 64 bytes.
pub type MuSigSecNonce = [u8; 64];
pub type MuSigSecNonce = ByteArray64;
// MuSigAggNonce is a scalar, so it's 32 bytes.
pub type MuSigAggNonce = ByteArray66;
// MuSigPartialSignature is a scalar, so it's 32 bytes.
pub type MuSigPartialSignature = [u8; 32];
pub type MuSigPartialSignature = ByteArray32;
// MuSigFinalSignature is a Schnorr signature, so it's 64 bytes.
pub type MuSigFinalSignature = [u8; 64];
pub type MuSigFinalSignature = ByteArray64;
pub type MuSigNoncePair = (MuSigSecNonce, MuSigPubNonce);

pub trait AggregateFromPublicKeys {
Expand Down Expand Up @@ -100,7 +100,7 @@ pub fn aggregate_partial_signatures(
let key_agg_ctx = create_key_agg_ctx(pks, tweak, tweak_flag).unwrap();
let musig_partial_sigs: Vec<musig2::PartialSignature> = partial_sigs
.iter()
.map(|x| musig2::PartialSignature::from_slice(x).unwrap())
.map(|x| musig2::PartialSignature::from_slice(&x.0).unwrap())
.collect::<Vec<musig2::PartialSignature>>();
Ok(musig2::aggregate_partial_signatures(
&key_agg_ctx,
Expand Down Expand Up @@ -128,7 +128,8 @@ pub fn nonce_pair(
.with_spices(spices)
.build();
let pub_nonce = ByteArray66(sec_nonce.public_nonce().into());
(sec_nonce.into(), pub_nonce)
let sec_nonce: [u8; 64] = sec_nonce.into();
(ByteArray64(sec_nonce), pub_nonce)
}

// We are creating the key aggregation context manually here, adding the tweaks by hand.
Expand All @@ -144,7 +145,7 @@ pub fn partial_sign(
sighash: [u8; 32],
) -> MuSigPartialSignature {
let key_agg_ctx = create_key_agg_ctx(pks, tweak, tweak_flag).unwrap();
let musig_sec_nonce = SecNonce::from_bytes(&sec_nonce).unwrap();
let musig_sec_nonce = SecNonce::from_bytes(&sec_nonce.0).unwrap();
let musig_agg_nonce = AggNonce::from_bytes(&agg_nonce.0).unwrap();
let partial_signature: [u8; 32] = sign_partial(
&key_agg_ctx,
Expand All @@ -154,7 +155,7 @@ pub fn partial_sign(
sighash,
)
.unwrap();
partial_signature
ByteArray32(partial_signature)
}

#[cfg(test)]
Expand All @@ -165,7 +166,7 @@ mod tests {
use crate::{
actor::Actor,
errors::BridgeError,
musig2::AggregateFromPublicKeys,
musig2::{AggregateFromPublicKeys, MuSigPartialSignature},
transaction_builder::{TransactionBuilder, TxHandler},
utils,
};
Expand Down Expand Up @@ -213,7 +214,7 @@ mod tests {
// Extract the aggregated public key
let musig_agg_pubkey: musig2::secp256k1::PublicKey = key_agg_ctx.aggregated_pubkey();
// Calculate the partial signatures
let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down Expand Up @@ -317,7 +318,7 @@ mod tests {
let agg_nonce =
super::aggregate_nonces(nonce_pair_vec.iter().map(|x| x.1.clone()).collect());
let musig_agg_pubkey: musig2::secp256k1::PublicKey = key_agg_ctx.aggregated_pubkey();
let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down Expand Up @@ -458,7 +459,7 @@ mod tests {
.unwrap()
.to_byte_array();
let merkle_root = sending_address_spend_info.merkle_root();
let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down Expand Up @@ -549,7 +550,7 @@ mod tests {
.unwrap()
.to_byte_array();

let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down
17 changes: 13 additions & 4 deletions core/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,12 @@ where
// and the last output is the anyonecanpay output for fee bumping.
let kickoff_tx_min_relay_fee = match self.config.operator_num_kickoff_utxos_per_tx {
0..=250 => 154 + 43 * self.config.operator_num_kickoff_utxos_per_tx, // Handles all values from 0 to 250
_ => 156 + 43 * self.config.operator_num_kickoff_utxos_per_tx, // Handles all other values
_ => 156 + 43 * self.config.operator_num_kickoff_utxos_per_tx, // Handles all other values
};
if funding_utxo.txout.value.to_sat()
< (KICKOFF_UTXO_AMOUNT_SATS * self.config.operator_num_kickoff_utxos_per_tx as u64
+ kickoff_tx_min_relay_fee as u64 + 330)
+ kickoff_tx_min_relay_fee as u64
+ 330)
{
return Err(BridgeError::OperatorFundingUtxoAmountNotEnough(
self.signer.address.clone(),
Expand Down Expand Up @@ -227,7 +228,11 @@ where
txout: kickoff_tx_handler.tx.output[self.config.operator_num_kickoff_utxos_per_tx]
.clone(),
};
tracing::debug!("Change UTXO: {:?} after new kickoff UTXOs are generated for deposit UTXO: {:?}", change_utxo, deposit_outpoint);
tracing::debug!(
"Change UTXO: {:?} after new kickoff UTXOs are generated for deposit UTXO: {:?}",
change_utxo,
deposit_outpoint
);

let kickoff_utxo = UTXO {
outpoint: OutPoint {
Expand All @@ -236,7 +241,11 @@ where
},
txout: kickoff_tx_handler.tx.output[0].clone(),
};
tracing::debug!("Kickoff UTXO: {:?} after new kickoff UTXOs are generated for deposit UTXO: {:?}", kickoff_utxo, deposit_outpoint);
tracing::debug!(
"Kickoff UTXO: {:?} after new kickoff UTXOs are generated for deposit UTXO: {:?}",
kickoff_utxo,
deposit_outpoint
);

let kickoff_sig_hash = crate::sha256_hash!(
deposit_outpoint.txid,
Expand Down
5 changes: 4 additions & 1 deletion core/src/transaction_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,10 @@ impl TransactionBuilder {
"kickoff_utxo_script_pubkey: {:?}",
kickoff_utxo_address.script_pubkey()
);
tracing::debug!("kickoff_utxo_script_pubkey: {:?}", kickoff_utxo.txout.script_pubkey);
tracing::debug!(
"kickoff_utxo_script_pubkey: {:?}",
kickoff_utxo.txout.script_pubkey
);
tracing::debug!("Operator index: {:?}", operator_idx);
tracing::debug!("Operator xonly pk: {:?}", operator_xonly_pk);
tracing::debug!("Deposit OutPoint: {:?}", deposit_outpoint);
Expand Down
11 changes: 4 additions & 7 deletions core/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,7 @@ where
self.db.save_nonces(deposit_outpoint, &nonces).await?;
transaction.commit().await?;

let pub_nonces = nonces
.iter()
.map(|(_, pub_nonce)| pub_nonce.clone())
.collect();
let pub_nonces = nonces.iter().map(|(_, pub_nonce)| *pub_nonce).collect();

Ok(pub_nonces)
}
Expand Down Expand Up @@ -234,7 +231,7 @@ where
None,
false,
*sec_nonce,
agg_nonce.clone(),
*agg_nonce,
&self.signer.keypair,
*sighash,
)
Expand Down Expand Up @@ -413,7 +410,7 @@ where
None,
true,
*sec_nonce,
agg_nonce.clone(),
*agg_nonce,
&self.signer.keypair,
*sighash,
)
Expand Down Expand Up @@ -516,7 +513,7 @@ where
None,
false,
nonces[0].0,
nonces[0].1.clone(),
nonces[0].1,
&self.signer.keypair,
move_tx_sighash.to_byte_array(),
);
Expand Down
6 changes: 4 additions & 2 deletions core/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use clementine_core::database::common::Database;
use clementine_core::errors::BridgeError;
use clementine_core::extended_rpc::ExtendedRpc;
use clementine_core::mock::common;
use clementine_core::musig2::MuSigPartialSignature;
use clementine_core::servers::*;
use clementine_core::traits::rpc::AggregatorClient;
use clementine_core::traits::rpc::OperatorRpcClient;
Expand Down Expand Up @@ -124,7 +125,7 @@ pub async fn run_single_deposit(

// tracing::debug!("Slash or take sigs: {:#?}", slash_or_take_sigs);
// call burn_txs_signed_rpc
let mut operator_take_partial_sigs: Vec<Vec<[u8; 32]>> = Vec::new();
let mut operator_take_partial_sigs: Vec<Vec<MuSigPartialSignature>> = Vec::new();
for (client, ..) in verifiers.iter() {
let partial_sigs = client
.burn_txs_signed_rpc(deposit_outpoint, vec![], slash_or_take_sigs.clone())
Expand Down Expand Up @@ -189,6 +190,7 @@ mod tests {
use clementine_core::database::common::Database;
use clementine_core::extended_rpc::ExtendedRpc;
use clementine_core::mock::common;
use clementine_core::musig2::MuSigPartialSignature;
use clementine_core::servers::*;
use clementine_core::traits::rpc::AggregatorClient;
use clementine_core::traits::rpc::OperatorRpcClient;
Expand Down Expand Up @@ -364,7 +366,7 @@ mod tests {
.unwrap();

// call burn_txs_signed_rpc
let mut operator_take_partial_sigs: Vec<Vec<[u8; 32]>> = Vec::new();
let mut operator_take_partial_sigs: Vec<Vec<MuSigPartialSignature>> = Vec::new();
for (client, ..) in verifiers.iter() {
let partial_sigs = client
.burn_txs_signed_rpc(deposit_outpoint, vec![], slash_or_take_sigs.clone())
Expand Down
10 changes: 6 additions & 4 deletions core/tests/musig2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use bitcoin::{hashes::Hash, script, Amount, ScriptBuf};
use bitcoincore_rpc::RawTx;
use clementine_core::database::common::Database;
use clementine_core::mock::common;
use clementine_core::musig2::{aggregate_nonces, aggregate_partial_signatures, MuSigPubNonce};
use clementine_core::musig2::{
aggregate_nonces, aggregate_partial_signatures, MuSigPartialSignature, MuSigPubNonce,
};
use clementine_core::utils::handle_taproot_witness_new;
use clementine_core::{
actor::Actor,
Expand Down Expand Up @@ -77,7 +79,7 @@ async fn test_musig2_key_spend() {
tracing::debug!("Merkle Root: {:?}", merkle_root);
let key_agg_ctx = create_key_agg_ctx(pks.clone(), merkle_root, true).unwrap();

let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down Expand Up @@ -181,7 +183,7 @@ async fn test_musig2_key_spend_with_script() {
let merkle_root = from_address_spend_info.merkle_root();
let key_agg_ctx = create_key_agg_ctx(pks.clone(), merkle_root, true).unwrap();

let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down Expand Up @@ -289,7 +291,7 @@ async fn test_musig2_script_spend() {
.unwrap()
.to_byte_array();

let partial_sigs: Vec<[u8; 32]> = kp_vec
let partial_sigs: Vec<MuSigPartialSignature> = kp_vec
.iter()
.zip(nonce_pair_vec.iter())
.map(|(kp, nonce_pair)| {
Expand Down
2 changes: 1 addition & 1 deletion scripts/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ create table if not exists nonces (
idx serial primary key,
deposit_outpoint text not null check (deposit_outpoint ~ '^[a-fA-F0-9]{64}:(0|[1-9][0-9]{0,9})$'),
pub_nonce bytea not null check (length(pub_nonce) = 66),
sec_nonce text not null check (sec_nonce ~ '^[a-fA-F0-9]{128}$'),
sec_nonce bytea not null check (length(sec_nonce) = 64),
agg_nonce bytea check (length(agg_nonce) = 66),
sighash text check (sighash ~ '^[a-fA-F0-9]{64}'), /* 32 bytes */
created_at timestamp not null default now()
Expand Down

0 comments on commit 5803bd5

Please sign in to comment.