diff --git a/src/protocols/thresholdsig/bitcoin_schnorr.rs b/src/protocols/thresholdsig/bitcoin_schnorr.rs index 7c2dca8..f45fce9 100644 --- a/src/protocols/thresholdsig/bitcoin_schnorr.rs +++ b/src/protocols/thresholdsig/bitcoin_schnorr.rs @@ -182,18 +182,7 @@ impl LocalSig { let beta_i = local_ephemeral_key.x_i.clone(); let alpha_i = local_private_key.x_i.clone(); - let message_len_bits = message.len() * 8; - let R = local_ephemeral_key.y.bytes_compressed_to_big_int(); - let X = local_private_key.y.bytes_compressed_to_big_int(); - let X_vec = BigInt::to_vec(&X); - let X_vec_len_bits = X_vec.len() * 8; - let e_bn = HSha256::create_hash_from_slice( - &BigInt::to_vec( - &((((R << X_vec_len_bits) + X) << message_len_bits) + BigInt::from(message)), - )[..], - ); - - let e: FE = ECScalar::from(&e_bn); + let e = compute_e(&local_ephemeral_key.y, &local_private_key.y, message); let gamma_i = beta_i + e.clone() * alpha_i; LocalSig { gamma_i, e } @@ -278,12 +267,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; @@ -297,3 +281,65 @@ impl Signature { } } } + +/// Compute e = h(V || Y || message) +pub fn compute_e(v: &GE, y: &GE, message: &[u8]) -> FE { + let v = v.get_element().serialize(); + let y = y.get_element().serialize(); + + let mut vec: Vec = Vec::with_capacity(v.len() + y.len() + message.len()); + vec.extend(&v[..]); + vec.extend(&y[..]); + vec.extend(message); + + let e_bn = HSha256::create_hash_from_slice(&vec[..]); + ECScalar::from(&e_bn) +} + +#[cfg(test)] +mod tests { + use super::compute_e; + use curv::elliptic::curves::traits::{ECPoint, ECScalar}; + use curv::{BigInt, FE, GE}; + + #[test] + fn test_compute_e() { + let v_x_bn = BigInt::from_str_radix( + "06705d6b7fd5a7a34ea47b6a8d0ce8372a83d2129a65458e2bef6f45892e7d5d", + 16, + ) + .unwrap(); + let v_y_bn = BigInt::from_str_radix( + "c6441397d43ff1e0bd9d7da39caf55dffbaa246fb70b1d08d2aa85903e7ec3e0", + 16, + ) + .unwrap(); + let v: GE = ECPoint::from_coor(&v_x_bn, &v_y_bn); + + let y_x_bn = BigInt::from_str_radix( + "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 16, + ) + .unwrap(); + let y_y_bn = BigInt::from_str_radix( + "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 16, + ) + .unwrap(); + let y: GE = ECPoint::from_coor(&y_x_bn, &y_y_bn); + + // It should be equal to expected when the message started with "00" byte. + let message = + hex::decode("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap(); + + let expected_bn = BigInt::from_str_radix( + "85e8da2401b58b960965aab0df09554fde8d1e41b67b9cebac8d8421d6919c2a", + 16, + ) + .unwrap(); + let expected: FE = ECScalar::from(&expected_bn); + + assert_eq!(expected, compute_e(&v, &y, &message[..])); + } +} diff --git a/src/protocols/thresholdsig/zilliqa_schnorr.rs b/src/protocols/thresholdsig/zilliqa_schnorr.rs index 9cb8d9a..c601f11 100644 --- a/src/protocols/thresholdsig/zilliqa_schnorr.rs +++ b/src/protocols/thresholdsig/zilliqa_schnorr.rs @@ -221,13 +221,8 @@ impl LocalSig { + (BigInt::from(message) << 528); let e_bn = HSha256::create_hash(&[&hash_in_concat]); */ - 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.sub(&(e.clone() * alpha_i).get_element()); // let gamma_i = e.clone() * alpha_i ; @@ -346,12 +341,7 @@ impl Signature { let r = HSha256::create_hash(&[&hash_in_concat]); */ - let r = HSha256::create_hash(&[ - &sg_plus_ey.bytes_compressed_to_big_int(), - &pubkey_y.bytes_compressed_to_big_int(), - &BigInt::from(message), - ]); - let r: FE = ECScalar::from(&r); + let r = compute_e(&sg_plus_ey, &pubkey_y, message); if r == self.e { Ok(()) @@ -360,3 +350,65 @@ impl Signature { } } } + +/// Compute e = h(V || Y || message) +pub fn compute_e(v: &GE, y: &GE, message: &[u8]) -> FE { + let v = v.get_element().serialize(); + let y = y.get_element().serialize(); + + let mut vec: Vec = Vec::with_capacity(v.len() + y.len() + message.len()); + vec.extend(&v[..]); + vec.extend(&y[..]); + vec.extend(message); + + let e_bn = HSha256::create_hash_from_slice(&vec[..]); + ECScalar::from(&e_bn) +} + +#[cfg(test)] +mod tests { + use super::compute_e; + use curv::elliptic::curves::traits::{ECPoint, ECScalar}; + use curv::{BigInt, FE, GE}; + + #[test] + fn test_compute_e() { + let v_x_bn = BigInt::from_str_radix( + "06705d6b7fd5a7a34ea47b6a8d0ce8372a83d2129a65458e2bef6f45892e7d5d", + 16, + ) + .unwrap(); + let v_y_bn = BigInt::from_str_radix( + "c6441397d43ff1e0bd9d7da39caf55dffbaa246fb70b1d08d2aa85903e7ec3e0", + 16, + ) + .unwrap(); + let v: GE = ECPoint::from_coor(&v_x_bn, &v_y_bn); + + let y_x_bn = BigInt::from_str_radix( + "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 16, + ) + .unwrap(); + let y_y_bn = BigInt::from_str_radix( + "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 16, + ) + .unwrap(); + let y: GE = ECPoint::from_coor(&y_x_bn, &y_y_bn); + + // It should be equal to expected when the message started with "00" byte. + let message = + hex::decode("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap(); + + let expected_bn = BigInt::from_str_radix( + "85e8da2401b58b960965aab0df09554fde8d1e41b67b9cebac8d8421d6919c2a", + 16, + ) + .unwrap(); + let expected: FE = ECScalar::from(&expected_bn); + + assert_eq!(expected, compute_e(&v, &y, &message[..])); + } +}