diff --git a/src/arithmetic/big_gmp.rs b/src/arithmetic/big_gmp.rs index 9026f1a2..7aa0ee56 100644 --- a/src/arithmetic/big_gmp.rs +++ b/src/arithmetic/big_gmp.rs @@ -45,7 +45,7 @@ impl Converter for Mpz { self.to_str_radix(super::HEX_RADIX) } - fn from_hex(value: &str) -> Mpz { + fn from_hex(value: &str) -> Self { BigInt::from_str_radix(value, super::HEX_RADIX).expect("Error in serialization") } } @@ -110,7 +110,7 @@ impl Samplable for Mpz { let bytes = (bit_size - 1) / 8 + 1; let mut buf: Vec = vec![0; bytes]; rng.fill_bytes(&mut buf); - Self::from(&*buf) >> (bytes * 8 - bit_size) + Self::from(buf.as_slice()) >> (bytes * 8 - bit_size) } fn strict_sample(bit_size: usize) -> Self { diff --git a/src/cryptographic_primitives/commitments/hash_commitment.rs b/src/cryptographic_primitives/commitments/hash_commitment.rs index c70f2ab5..22456453 100644 --- a/src/cryptographic_primitives/commitments/hash_commitment.rs +++ b/src/cryptographic_primitives/commitments/hash_commitment.rs @@ -16,22 +16,25 @@ use super::traits::Commitment; use super::SECURITY_BITS; use crate::arithmetic::traits::Samplable; use sha3::{Digest, Sha3_256}; -//TODO: using the function with BigInt's as input instead of string's makes it impossible to commit to empty message or use empty randomness + impl Commitment for HashCommitment { fn create_commitment_with_user_defined_randomness( message: &BigInt, blinding_factor: &BigInt, ) -> BigInt { let mut digest = Sha3_256::new(); + let bytes_message: Vec = message.into(); - digest.input(&bytes_message); - let bytes_blinding_factor: Vec = blinding_factor.into(); - digest.input(&bytes_blinding_factor); + digest.input(bytes_message.as_slice()); + + let salt: Vec = blinding_factor.into(); + digest.input(salt.as_slice()); + BigInt::from(digest.result().as_ref()) } fn create_commitment(message: &BigInt) -> (BigInt, BigInt) { - let blinding_factor = BigInt::sample(SECURITY_BITS); + let blinding_factor = BigInt::strict_sample(SECURITY_BITS); let com = HashCommitment::create_commitment_with_user_defined_randomness( message, &blinding_factor, @@ -59,10 +62,10 @@ mod tests { let message = BigInt::sample(SECURITY_BITS); let (commitment, blind_factor) = HashCommitment::create_commitment(&message); if commitment.to_str_radix(2).len() == hex_len { - ctr_commit_len = ctr_commit_len + 1; + ctr_commit_len += 1; } if blind_factor.to_str_radix(2).len() == hex_len { - ctr_blind_len = ctr_blind_len + 1; + ctr_blind_len += 1; } } //test commitment length - works because SHA256 output length the same as sec_bits @@ -74,18 +77,9 @@ mod tests { assert!(ctr_blind_len / sample_size > 0.3); } - #[test] - fn test_bit_length_create_commitment_with_user_defined_randomness() { - let message = BigInt::sample(SECURITY_BITS); - let (_commitment, blind_factor) = HashCommitment::create_commitment(&message); - let commitment2 = - HashCommitment::create_commitment_with_user_defined_randomness(&message, &blind_factor); - assert_eq!(commitment2.to_str_radix(16).len(), SECURITY_BITS / 4); - } - #[test] fn test_random_num_generation_create_commitment_with_user_defined_randomness() { - let message = BigInt::sample(SECURITY_BITS); + let message = BigInt::strict_sample(SECURITY_BITS); let (commitment, blind_factor) = HashCommitment::create_commitment(&message); let commitment2 = HashCommitment::create_commitment_with_user_defined_randomness(&message, &blind_factor); @@ -96,14 +90,18 @@ mod tests { fn test_hashing_create_commitment_with_user_defined_randomness() { let mut digest = Sha3_256::new(); let message = BigInt::one(); + let commitment = HashCommitment::create_commitment_with_user_defined_randomness( &message, &BigInt::zero(), ); + let message2: Vec = (&message).into(); - digest.input(&message2); + digest.input(message2.as_slice()); + let bytes_blinding_factor: Vec = (&BigInt::zero()).into(); - digest.input(&bytes_blinding_factor); + digest.input(bytes_blinding_factor.as_slice()); + let hash_result = BigInt::from(digest.result().as_ref()); assert_eq!(&commitment, &hash_result); } diff --git a/src/elliptic/curves/secp256_k1.rs b/src/elliptic/curves/secp256_k1.rs index 8be6f46a..1a54d379 100644 --- a/src/elliptic/curves/secp256_k1.rs +++ b/src/elliptic/curves/secp256_k1.rs @@ -25,7 +25,7 @@ use crate::ErrorKey; use crypto::digest::Digest; use crypto::sha3::Sha3; use merkle::Hashable; -use rand::{thread_rng, Rng}; +use rand::thread_rng; use secp256k1::constants::{ CURVE_ORDER, GENERATOR_X, GENERATOR_Y, SECRET_KEY_SIZE, UNCOMPRESSED_PUBLIC_KEY_SIZE, }; @@ -101,11 +101,9 @@ impl Zeroize for Secp256k1Scalar { impl ECScalar for Secp256k1Scalar { fn new_random() -> Self { - let mut arr = [0u8; 32]; - thread_rng().fill(&mut arr[..]); Self { purpose: "random", - fe: SK::from_slice(&arr[0..arr.len()]).unwrap(), + fe: SK::new(&mut thread_rng()), } } @@ -222,7 +220,7 @@ impl Add for Secp256k1Scalar { impl<'o> Add<&'o Secp256k1Scalar> for Secp256k1Scalar { type Output = Self; - fn add(self, other: &'o Secp256k1Scalar) -> Self { + fn add(self, other: &'o Self) -> Self { (&self).add(&other.get_element()) } } @@ -282,7 +280,7 @@ impl Zeroize for Secp256k1Point { impl ECPoint for Secp256k1Point { fn generator() -> Self { - let mut v = vec![4 as u8]; + let mut v = vec![4u8]; v.extend(GENERATOR_X.as_ref()); v.extend(GENERATOR_Y.as_ref()); Self { @@ -305,82 +303,49 @@ impl ECPoint for Secp256k1Point { } fn x_coor(&self) -> Option { - let serialized_pk = PK::serialize_uncompressed(&self.ge); - let x = &serialized_pk[1..serialized_pk.len() / 2 + 1]; - let x_vec = x.to_vec(); - Some(BigInt::from(&x_vec[..])) + let serialized_pk = self.ge.serialize_uncompressed(); + let x = &serialized_pk[1..=serialized_pk.len() / 2]; + Some(BigInt::from(x)) } fn y_coor(&self) -> Option { - let serialized_pk = PK::serialize_uncompressed(&self.ge); - let y = &serialized_pk[(serialized_pk.len() - 1) / 2 + 1..serialized_pk.len()]; - let y_vec = y.to_vec(); - Some(BigInt::from(&y_vec[..])) + let serialized_pk = self.ge.serialize_uncompressed(); + let y = &serialized_pk[(serialized_pk.len() - 1) / 2 + 1..]; + Some(BigInt::from(y)) } fn from_bytes(bytes: &[u8]) -> Result { - let bytes_vec = bytes.to_vec(); - let mut bytes_array_65 = [0u8; 65]; - let mut bytes_array_33 = [0u8; 33]; - - let byte_len = bytes_vec.len(); - match byte_len { - 33..=63 => { - let mut template = vec![0; 64 - bytes_vec.len()]; - template.extend_from_slice(&bytes); - let bytes_vec = template; - let mut template: Vec = vec![4]; - template.append(&mut bytes_vec.clone()); - let bytes_slice = &template[..]; - - bytes_array_65.copy_from_slice(&bytes_slice[0..65]); - let result = PK::from_slice(&bytes_array_65); - let test = result.map(|pk| Self { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) - } - - 0..=32 => { - let mut template = vec![0; 32 - bytes_vec.len()]; - template.extend_from_slice(&bytes); - let bytes_vec = template; - let mut template: Vec = vec![2]; - template.append(&mut bytes_vec.clone()); - let bytes_slice = &template[..]; - - bytes_array_33.copy_from_slice(&bytes_slice[0..33]); - let result = PK::from_slice(&bytes_array_33); - let test = result.map(|pk| Self { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) + let len = bytes.len(); + + let formalized: Vec = match len { + 65 | 33 => bytes.to_vec(), + 64 => { + // x, y without prefix + let mut v = Vec::new(); + v.push(0x04); + v.extend(bytes.iter()); + v } - _ => { - let bytes_slice = &bytes_vec[0..64]; - let bytes_vec = bytes_slice.to_vec(); - let mut template: Vec = vec![4]; - template.append(&mut bytes_vec.clone()); - let bytes_slice = &template[..]; - - bytes_array_65.copy_from_slice(&bytes_slice[0..65]); - let result = PK::from_slice(&bytes_array_65); - let test = result.map(|pk| Self { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) + 32 => { + // x without prefix + let mut v = Vec::new(); + v.push(0x02); // according to standard, 02/03 when y is even/odd, but we just set 02 here + v.extend(bytes.iter()); + v } - } + _ => bytes.to_vec(), + }; + + PK::from_slice(formalized.as_slice()) + .map(|pk| Self { + purpose: "random", + ge: pk, + }) + .map_err(|_| ErrorKey::InvalidPublicKey) } - fn pk_to_key_slice(&self) -> Vec { - let mut v = vec![4 as u8]; - v.extend(BigInt::to_vec(&self.x_coor().unwrap())); - v.extend(BigInt::to_vec(&self.y_coor().unwrap())); - v + fn pk_to_key_slice(&self) -> Vec { + self.ge.serialize_uncompressed().to_vec() } fn scalar_mul(&self, fe: &SK) -> Self { @@ -456,7 +421,6 @@ impl ECPoint for Secp256k1Point { let mut v = vec![4 as u8]; v.extend(vec_x); v.extend(vec_y); - Secp256k1Point { purpose: "base_fe", ge: PK::from_slice(&v).unwrap(), @@ -481,7 +445,7 @@ impl Hashable for Secp256k1Point { } impl Mul for Secp256k1Point { - type Output = Secp256k1Point; + type Output = Self; fn mul(self, other: Secp256k1Scalar) -> Self::Output { self.scalar_mul(&other.get_element()) } @@ -502,8 +466,8 @@ impl<'o> Mul<&'o Secp256k1Scalar> for &'o Secp256k1Point { } impl Add for Secp256k1Point { - type Output = Secp256k1Point; - fn add(self, other: Secp256k1Point) -> Self::Output { + type Output = Self; + fn add(self, other: Self) -> Self::Output { self.add_point(&other.get_element()) } } @@ -528,8 +492,8 @@ impl Serialize for Secp256k1Point { S: Serializer, { let mut state = serializer.serialize_struct("Secp256k1Point", 2)?; - state.serialize_field("x", &self.x_coor().unwrap().to_hex())?; - state.serialize_field("y", &self.y_coor().unwrap().to_hex())?; + state.serialize_field("x", &self.x_coor().unwrap())?; + state.serialize_field("y", &self.y_coor().unwrap())?; state.end() } } @@ -550,7 +514,7 @@ impl<'de> Visitor<'de> for Secp256k1PointVisitor { type Value = Secp256k1Point; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Secp256k1Point") + formatter.write_str("struct Secp256k1Point") } fn visit_map>(self, mut map: E) -> Result { @@ -570,7 +534,6 @@ impl<'de> Visitor<'de> for Secp256k1PointVisitor { let bx = BigInt::from_hex(&x); let by = BigInt::from_hex(&y); - Ok(Secp256k1Point::from_coor(&bx, &by)) } } @@ -582,17 +545,32 @@ mod tests { use super::Secp256k1Scalar; use crate::arithmetic::traits::Converter; use crate::arithmetic::traits::Modulo; - use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; - use crate::cryptographic_primitives::hashing::traits::Hash; use crate::elliptic::curves::traits::ECPoint; use crate::elliptic::curves::traits::ECScalar; use serde_json; #[test] - fn serialize_sk() { - let scalar: Secp256k1Scalar = ECScalar::from(&BigInt::from(123456)); - let s = serde_json::to_string(&scalar).expect("Failed in serialization"); - assert_eq!(s, "\"1e240\""); + fn serialize_deserialize_sk() { + let sk: Secp256k1Scalar = ECScalar::from(&BigInt::from(1234)); + let encoded = serde_json::to_string(&sk).unwrap(); + assert_eq!(encoded, "\"4d2\""); + + let decoded: Secp256k1Scalar = serde_json::from_str(&encoded).unwrap(); + assert_eq!(decoded, sk); + } + + #[test] + fn serialize_deserialize_pk() { + let pk = Secp256k1Point::generator(); + let x = pk.x_coor().unwrap(); + let y = pk.y_coor().unwrap(); + let encoded = serde_json::to_string(&pk).unwrap(); + + let expected = format!("{{\"x\":\"{}\",\"y\":\"{}\"}}", x.to_hex(), y.to_hex()); + assert_eq!(encoded, expected); + + let decoded: Secp256k1Point = serde_json::from_str(&encoded).unwrap(); + assert_eq!(decoded, pk); } #[test] @@ -624,30 +602,6 @@ mod tests { assert_eq!(r.y_coor().unwrap(), r_expected.y_coor().unwrap()); } - #[test] - fn deserialize_sk() { - let s = "\"1e240\""; - let dummy: Secp256k1Scalar = serde_json::from_str(s).expect("Failed in serialization"); - - let sk: Secp256k1Scalar = ECScalar::from(&BigInt::from(123456)); - - assert_eq!(dummy, sk); - } - - #[test] - fn serialize_pk() { - let pk = Secp256k1Point::generator(); - let x = pk.x_coor().unwrap(); - let y = pk.y_coor().unwrap(); - let s = serde_json::to_string(&pk).expect("Failed in serialization"); - - let expected = format!("{{\"x\":\"{}\",\"y\":\"{}\"}}", x.to_hex(), y.to_hex()); - assert_eq!(s, expected); - - let des_pk: Secp256k1Point = serde_json::from_str(&s).expect("Failed in serialization"); - assert_eq!(des_pk.ge, pk.ge); - } - use crate::elliptic::curves::secp256_k1::{FE, GE}; use crate::ErrorKey; @@ -677,11 +631,26 @@ mod tests { #[test] fn test_from_bytes() { - let g = Secp256k1Point::generator(); - let hash = HSha256::create_hash(&vec![&g.bytes_compressed_to_big_int()]); - let hash_vec = BigInt::to_vec(&hash); - let result = Secp256k1Point::from_bytes(&hash_vec); - assert_eq!(result.unwrap_err(), ErrorKey::InvalidPublicKey) + let base_point = Secp256k1Point::generator(); + let y = BigInt::to_vec(&base_point.y_coor().unwrap()); + let result = Secp256k1Point::from_bytes(y.as_slice()); + assert_eq!(result.unwrap_err(), ErrorKey::InvalidPublicKey); + + let g = Secp256k1Point::random_point(); + + let mut b = [0u8; 64]; + b[63] = 1; + assert!(Secp256k1Point::from_bytes(&b).is_err()); + + let x = BigInt::to_vec(&g.x_coor().unwrap()); + let y = BigInt::to_vec(&g.y_coor().unwrap()); + + let mut x_and_y = Vec::new(); + x_and_y.extend(x.iter()); + x_and_y.extend(y.iter()); + + assert!(Secp256k1Point::from_bytes(x.as_slice()).is_ok()); + assert!(Secp256k1Point::from_bytes(x_and_y.as_slice()).is_ok()) } #[test] @@ -725,10 +694,10 @@ mod tests { let a_minus_b = BigInt::mod_add(&a.to_big_int(), &minus_b, &order); let a_minus_b_fe: FE = ECScalar::from(&a_minus_b); let base: GE = ECPoint::generator(); - let point_ab1 = base.clone() * a_minus_b_fe; + let point_ab1 = base * a_minus_b_fe; - let point_a = base.clone() * a; - let point_b = base.clone() * b; + let point_a = base * a; + let point_b = base * b; let point_ab2 = point_a.sub_point(&point_b.get_element()); assert_eq!(point_ab1.get_element(), point_ab2.get_element()); }