diff --git a/Cargo.toml b/Cargo.toml index 7d6c866..7c9125e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ crate-type = ["lib"] serde = "1.0" serde_derive = "1.0" curv = { git = "https://github.com/KZen-networks/curv" , tag = "v0.2.3", features = ["ec_secp256k1","merkle"]} +sha2 = "0.8.1" [dependencies.centipede] git = "https://github.com/KZen-networks/centipede" diff --git a/src/lib.rs b/src/lib.rs index bfbd076..60fb46e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,9 @@ extern crate serde_derive; extern crate serde; +#[cfg(test)] +extern crate sha2; + extern crate centipede; extern crate curv; pub mod protocols; diff --git a/src/protocols/thresholdsig/bitcoin_schnorr.rs b/src/protocols/thresholdsig/bitcoin_schnorr.rs index 9b0babb..84a0331 100644 --- a/src/protocols/thresholdsig/bitcoin_schnorr.rs +++ b/src/protocols/thresholdsig/bitcoin_schnorr.rs @@ -182,12 +182,7 @@ impl LocalSig { let beta_i = local_ephemaral_key.x_i.clone(); let alpha_i = local_private_key.x_i.clone(); - let e_bn = HSha256::create_hash(&[ - &local_ephemaral_key.y.bytes_compressed_to_big_int(), - &local_private_key.y.bytes_compressed_to_big_int(), - &BigInt::from(message), - ]); - let e: FE = ECScalar::from(&e_bn); + let e = compute_e(&local_ephemaral_key.y, &local_private_key.y, message); let gamma_i = beta_i + e.clone() * alpha_i; // let gamma_i = e.clone() * alpha_i ; @@ -273,12 +268,7 @@ impl Signature { } pub fn verify(&self, message: &[u8], pubkey_y: &GE) -> Result<(), Error> { - let e_bn = HSha256::create_hash(&[ - &self.v.bytes_compressed_to_big_int(), - &pubkey_y.bytes_compressed_to_big_int(), - &BigInt::from(message), - ]); - let e: FE = ECScalar::from(&e_bn); + let e = compute_e(&self.v, pubkey_y, message); let g: GE = GE::generator(); let sigma_g = g * &self.sigma; @@ -292,3 +282,54 @@ impl Signature { } } } + +/// Compute e = h(V || Y || message) +fn compute_e(v: &GE, y: &GE, message: &[u8]) -> FE { + let v_bn = v.bytes_compressed_to_big_int(); + let y_bn = y.bytes_compressed_to_big_int(); + + let mut big_ints = vec![&v_bn, &y_bn]; + + let m: Vec = Vec::from(message) + .into_iter() + .map(|i| BigInt::from(i as i32)) + .collect(); + for i in &m { + big_ints.push(i); + } + + let e_bn = HSha256::create_hash(&big_ints); + ECScalar::from(&e_bn) +} + +#[cfg(test)] +mod tests { + use super::compute_e; + use curv::elliptic::curves::secp256_k1::Secp256k1Scalar; + use curv::elliptic::curves::traits::{ECPoint, ECScalar}; + use curv::{BigInt, FE, GE}; + use sha2::Digest; + + #[test] + fn test_compute_e() { + let g: GE = ECPoint::generator(); + let v: GE = g * Secp256k1Scalar::new_random(); + let y: GE = g * Secp256k1Scalar::new_random(); + + // It should be equal to expected when the message started with "00" byte. + let message = + hex::decode("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") + .unwrap(); + + let expected: FE = { + let mut hasher = sha2::Sha256::new(); + hasher.input(&v.get_element().serialize()[..]); + hasher.input(&y.get_element().serialize()[..]); + hasher.input(&message[..]); + let bn = BigInt::from(&hasher.result()[..]); + ECScalar::from(&bn) + }; + + assert_eq!(expected, compute_e(&v, &y, &message[..])); + } +}