diff --git a/Cargo.toml b/Cargo.toml index 9f17ce12..fcc74740 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["lib"] [features] default = ["rust-gmp"] -ec_secp256k1 = ["rust-gmp" ,"ecc", "secp256k1"] +ec_secp256k1 = ["rust-gmp" ,"ecc", "secp256k1", "merkle"] ec_ristretto = ["rust-gmp", "ecc" , "curve25519-dalek"] ec_ed25519 = ["rust-gmp", "ecc" , "cryptoxide"] ec_jubjub = ["rust-gmp", "ecc" , "pairing", "sapling-crypto"] @@ -17,15 +17,15 @@ merkle = ["rust-crypto", "merkle-sha3"] [dependencies] rand = "0.6" -serde = "1.0" -serde_derive = "1.0" +serde = { version = "1.0", features = ["derive"] } zeroize = "0.10" sha3 = "0.8.2" sha2 = "0.8.0" hmac = "0.7.1" digest = "0.8.1" hex = "^0.3" -blake2b_simd = "0.5.7" +blake2b_simd = "0.5.8" +lazy_static = "1.4" [dependencies.rust-crypto] version = "^0.2" @@ -65,5 +65,5 @@ version = "0.1.2" optional = true [dev-dependencies] -bincode = "1.1" +bincode = "1.2.0" serde_json = "1.0" diff --git a/examples/pedersen_commitment.rs b/examples/pedersen_commitment.rs index 6432c7da..1157b45a 100644 --- a/examples/pedersen_commitment.rs +++ b/examples/pedersen_commitment.rs @@ -19,11 +19,10 @@ pub fn ped_com(message: &BigInt) { let security_bits = 256; let blinding_factor = BigInt::sample(security_bits); - let com = PedersenCommitment::create_commitment_with_user_defined_randomness( + let _com = PedersenCommitment::create_commitment_with_user_defined_randomness( message, &blinding_factor, ); - (com, blinding_factor); } fn main() { diff --git a/examples/proof_of_knowledge_of_dlog.rs b/examples/proof_of_knowledge_of_dlog.rs index 6c0fad74..6fd41a98 100644 --- a/examples/proof_of_knowledge_of_dlog.rs +++ b/examples/proof_of_knowledge_of_dlog.rs @@ -16,10 +16,8 @@ pub fn dlog_proof() { let witness: FE = ECScalar::new_random(); let dlog_proof = DLogProof::prove(&witness); let verified = DLogProof::verify(&dlog_proof); - match verified { - Ok(_t) => assert!(true), - Err(_e) => assert!(false), - } + + assert!(verified.is_ok()); } fn main() { diff --git a/examples/verifiable_secret_sharing.rs b/examples/verifiable_secret_sharing.rs index 2da91442..88adaaee 100644 --- a/examples/verifiable_secret_sharing.rs +++ b/examples/verifiable_secret_sharing.rs @@ -26,7 +26,7 @@ pub fn secret_sharing_3_out_of_5() { shares_vec.push(secret_shares[4].clone()); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 1, 2, 4], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 1, 2, 4], &shares_vec); assert_eq!(secret, secret_reconstructed); // test secret shares are verifiable @@ -36,7 +36,7 @@ pub fn secret_sharing_3_out_of_5() { assert!(valid1.is_ok()); let g: GE = GE::generator(); - let share1_public = g * &secret_shares[0]; + let share1_public = g * secret_shares[0]; let valid1_public = vss_scheme.validate_share_public(&share1_public, 1); assert!(valid1_public.is_ok()); @@ -47,11 +47,11 @@ pub fn secret_sharing_3_out_of_5() { let l2 = vss_scheme.map_share_to_new_params(2, &s); let l3 = vss_scheme.map_share_to_new_params(3, &s); let l4 = vss_scheme.map_share_to_new_params(4, &s); - let w = l0 * secret_shares[0].clone() - + l1 * secret_shares[1].clone() - + l2 * secret_shares[2].clone() - + l3 * secret_shares[3].clone() - + l4 * secret_shares[4].clone(); + let w = l0 * secret_shares[0] + + l1 * secret_shares[1] + + l2 * secret_shares[2] + + l3 * secret_shares[3] + + l4 * secret_shares[4]; assert_eq!(w, secret_reconstructed); } 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/cryptographic_primitives/hashing/blake2b512.rs b/src/cryptographic_primitives/hashing/blake2b512.rs index d3e10427..485954f1 100644 --- a/src/cryptographic_primitives/hashing/blake2b512.rs +++ b/src/cryptographic_primitives/hashing/blake2b512.rs @@ -46,22 +46,18 @@ mod tests { #[test] // Very basic test here, TODO: suggest better testing fn create_hash_test() { - let result = - Blake::create_hash(&vec![&BigInt::one(), &BigInt::zero()], b"Zcash_RedJubjubH"); + let result = Blake::create_hash(&[&BigInt::one(), &BigInt::zero()], b"Zcash_RedJubjubH"); assert!(result > BigInt::zero()); } #[test] fn create_hash_from_ge_test() { let point = GE::base_point2(); - let result1 = - Blake::create_hash_from_ge(&vec![&point, &GE::generator()], b"Zcash_RedJubjubH"); + let result1 = Blake::create_hash_from_ge(&[&point, &GE::generator()], b"Zcash_RedJubjubH"); assert!(result1.to_big_int().to_str_radix(2).len() > 240); - let result2 = - Blake::create_hash_from_ge(&vec![&GE::generator(), &point], b"Zcash_RedJubjubH"); + let result2 = Blake::create_hash_from_ge(&[&GE::generator(), &point], b"Zcash_RedJubjubH"); assert_ne!(result1, result2); - let result3 = - Blake::create_hash_from_ge(&vec![&GE::generator(), &point], b"Zcash_RedJubjubH"); + let result3 = Blake::create_hash_from_ge(&[&GE::generator(), &point], b"Zcash_RedJubjubH"); assert_eq!(result2, result3); } } diff --git a/src/cryptographic_primitives/hashing/hash_sha256.rs b/src/cryptographic_primitives/hashing/hash_sha256.rs index 0095fc6b..28176575 100644 --- a/src/cryptographic_primitives/hashing/hash_sha256.rs +++ b/src/cryptographic_primitives/hashing/hash_sha256.rs @@ -55,14 +55,14 @@ mod tests { // https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/secure-hashing#shavs fn vector_sha256_test() { // Empty Message - let result: BigInt = HSha256::create_hash(&vec![]); + let result: BigInt = HSha256::create_hash(&[]); assert_eq!( result.to_str_radix(16), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ); // 256 bit message - let result: BigInt = HSha256::create_hash(&vec![&BigInt::from_str_radix( + let result: BigInt = HSha256::create_hash(&[&BigInt::from_str_radix( "09fc1accc230a205e4a208e64a8f204291f581a12756392da4b8c0cf5ef02b95", 16, ) @@ -73,7 +73,7 @@ mod tests { ); // 2x128 bit messages - let result: BigInt = HSha256::create_hash(&vec![ + let result: BigInt = HSha256::create_hash(&[ &BigInt::from_str_radix("09fc1accc230a205e4a208e64a8f2042", 16).unwrap(), &BigInt::from_str_radix("91f581a12756392da4b8c0cf5ef02b95", 16).unwrap(), ]); @@ -83,7 +83,7 @@ mod tests { ); // 512 bit message - let result: BigInt = HSha256::create_hash(&vec![&BigInt::from_str_radix("5a86b737eaea8ee976a0a24da63e7ed7eefad18a101c1211e2b3650c5187c2a8a650547208251f6d4237e661c7bf4c77f335390394c37fa1a9f9be836ac28509", 16).unwrap()]); + let result: BigInt = HSha256::create_hash(&[&BigInt::from_str_radix("5a86b737eaea8ee976a0a24da63e7ed7eefad18a101c1211e2b3650c5187c2a8a650547208251f6d4237e661c7bf4c77f335390394c37fa1a9f9be836ac28509", 16).unwrap()]); assert_eq!( result.to_str_radix(16), "42e61e174fbb3897d6dd6cef3dd2802fe67b331953b06114a65c772859dfc1aa" @@ -93,11 +93,11 @@ mod tests { #[test] fn create_sha256_from_ge_test() { let point = GE::base_point2(); - let result1 = HSha256::create_hash_from_ge(&vec![&point, &GE::generator()]); + let result1 = HSha256::create_hash_from_ge(&[&point, &GE::generator()]); assert!(result1.to_big_int().to_str_radix(2).len() > 240); - let result2 = HSha256::create_hash_from_ge(&vec![&GE::generator(), &point]); + let result2 = HSha256::create_hash_from_ge(&[&GE::generator(), &point]); assert_ne!(result1, result2); - let result3 = HSha256::create_hash_from_ge(&vec![&GE::generator(), &point]); + let result3 = HSha256::create_hash_from_ge(&[&GE::generator(), &point]); assert_eq!(result2, result3); } } diff --git a/src/cryptographic_primitives/hashing/hash_sha512.rs b/src/cryptographic_primitives/hashing/hash_sha512.rs index 3e2522b7..f19be2cd 100644 --- a/src/cryptographic_primitives/hashing/hash_sha512.rs +++ b/src/cryptographic_primitives/hashing/hash_sha512.rs @@ -55,14 +55,14 @@ mod tests { // https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/secure-hashing#shavs fn vector_sha512_test() { // Empty message - let result: BigInt = HSha512::create_hash(&vec![]); + let result: BigInt = HSha512::create_hash(&[]); assert_eq!( result.to_str_radix(16), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ); // 2x256 bit message - let result: BigInt = HSha512::create_hash(&vec![ + let result: BigInt = HSha512::create_hash(&[ &BigInt::from_str_radix( "c1ca70ae1279ba0b918157558b4920d6b7fba8a06be515170f202fafd36fb7f7", 16, @@ -80,7 +80,7 @@ mod tests { ); // 512 bit message - let result: BigInt = HSha512::create_hash(&vec![&BigInt::from_str_radix( + let result: BigInt = HSha512::create_hash(&[&BigInt::from_str_radix( "c1ca70ae1279ba0b918157558b4920d6b7fba8a06be515170f202fafd36fb7f79d69fad745dba6150568db1e2b728504113eeac34f527fc82f2200b462ecbf5d", 16, ) @@ -91,7 +91,7 @@ mod tests { ); // 1024 bit message - let result: BigInt = HSha512::create_hash(&vec![&BigInt::from_str_radix("fd2203e467574e834ab07c9097ae164532f24be1eb5d88f1af7748ceff0d2c67a21f4e4097f9d3bb4e9fbf97186e0db6db0100230a52b453d421f8ab9c9a6043aa3295ea20d2f06a2f37470d8a99075f1b8a8336f6228cf08b5942fc1fb4299c7d2480e8e82bce175540bdfad7752bc95b577f229515394f3ae5cec870a4b2f8", 16).unwrap()]); + let result: BigInt = HSha512::create_hash(&[&BigInt::from_str_radix("fd2203e467574e834ab07c9097ae164532f24be1eb5d88f1af7748ceff0d2c67a21f4e4097f9d3bb4e9fbf97186e0db6db0100230a52b453d421f8ab9c9a6043aa3295ea20d2f06a2f37470d8a99075f1b8a8336f6228cf08b5942fc1fb4299c7d2480e8e82bce175540bdfad7752bc95b577f229515394f3ae5cec870a4b2f8", 16).unwrap()]); assert_eq!( result.to_str_radix(16), "a21b1077d52b27ac545af63b32746c6e3c51cb0cb9f281eb9f3580a6d4996d5c9917d2a6e484627a9d5a06fa1b25327a9d710e027387fc3e07d7c4d14c6086cc" @@ -101,11 +101,11 @@ mod tests { #[test] fn create_sha512_from_ge_test() { let point = GE::base_point2(); - let result1 = HSha512::create_hash_from_ge(&vec![&point, &GE::generator()]); + let result1 = HSha512::create_hash_from_ge(&[&point, &GE::generator()]); assert!(result1.to_big_int().to_str_radix(2).len() > 240); - let result2 = HSha512::create_hash_from_ge(&vec![&GE::generator(), &point]); + let result2 = HSha512::create_hash_from_ge(&[&GE::generator(), &point]); assert_ne!(result1, result2); - let result3 = HSha512::create_hash_from_ge(&vec![&GE::generator(), &point]); + let result3 = HSha512::create_hash_from_ge(&[&GE::generator(), &point]); assert_eq!(result2, result3); } } diff --git a/src/cryptographic_primitives/hashing/hmac_sha512.rs b/src/cryptographic_primitives/hashing/hmac_sha512.rs index e090ba94..39345aa5 100644 --- a/src/cryptographic_primitives/hashing/hmac_sha512.rs +++ b/src/cryptographic_primitives/hashing/hmac_sha512.rs @@ -51,7 +51,6 @@ impl KeyedHash for HMacSha512 { mod tests { use super::HMacSha512; - use crate::arithmetic::traits::Converter; use crate::arithmetic::traits::Samplable; use crate::cryptographic_primitives::hashing::traits::KeyedHash; use crate::BigInt; @@ -59,20 +58,16 @@ mod tests { #[test] fn create_hmac_test() { let key = BigInt::sample(512); - let result1 = HMacSha512::create_hmac(&key, &vec![&BigInt::from(10)]); - let result1_bytes = &BigInt::to_vec(&result1)[..]; - let mut array_result: [u8; 64] = [0u8; 64]; - array_result.copy_from_slice(result1_bytes); - assert!(HMacSha512::verify(&key, &vec![&BigInt::from(10)], array_result).is_ok()); + let result1 = HMacSha512::create_hmac(&key, &[&BigInt::from(10)]); let key2 = BigInt::sample(512); // same data , different key - let result2 = HMacSha512::create_hmac(&key2, &vec![&BigInt::from(10)]); + let result2 = HMacSha512::create_hmac(&key2, &[&BigInt::from(10)]); assert_ne!(result1, result2); // same key , different data - let result3 = HMacSha512::create_hmac(&key, &vec![&BigInt::from(10), &BigInt::from(11)]); + let result3 = HMacSha512::create_hmac(&key, &[&BigInt::from(10), &BigInt::from(11)]); assert_ne!(result1, result3); // same key, same data - let result4 = HMacSha512::create_hmac(&key, &vec![&BigInt::from(10)]); + let result4 = HMacSha512::create_hmac(&key, &[&BigInt::from(10)]); assert_eq!(result1, result4) } } diff --git a/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_enc.rs b/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_enc.rs index 0cb076a2..75f2fc5c 100644 --- a/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_enc.rs +++ b/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_enc.rs @@ -5,6 +5,7 @@ (https://github.com/KZen-networks/curv) License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; use super::ProofError; use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; @@ -92,11 +93,11 @@ mod tests { }; let G: GE = ECPoint::generator(); let h: FE = ECScalar::new_random(); - let H = &G * &h; + let H = G * h; let y: FE = ECScalar::new_random(); - let Y = &G * &y; - let D = &H * &witness.x + Y.clone() * &witness.r; - let E = G.clone() * &witness.r; + let Y = G * y; + let D = H * witness.x + Y * witness.r; + let E = G * witness.r; let delta = HomoElGamalStatement { G, H, Y, D, E }; let proof = HomoELGamalProof::prove(&witness, &delta); assert!(proof.verify(&delta).is_ok()); @@ -110,16 +111,10 @@ mod tests { }; let G: GE = GE::generator(); let y: FE = FE::new_random(); - let Y = &G * &y; - let D = &G * &witness.x + Y.clone() * &witness.r; - let E = G.clone() * &witness.r; - let delta = HomoElGamalStatement { - G: G.clone(), - H: G, - Y, - D, - E, - }; + let Y = G * y; + let D = G * witness.x + Y * witness.r; + let E = G * witness.r; + let delta = HomoElGamalStatement { G, H: G, Y, D, E }; let proof = HomoELGamalProof::prove(&witness, &delta); assert!(proof.verify(&delta).is_ok()); } @@ -134,11 +129,11 @@ mod tests { }; let G: GE = ECPoint::generator(); let h: FE = ECScalar::new_random(); - let H = &G * &h; + let H = G * h; let y: FE = ECScalar::new_random(); - let Y = &G * &y; - let D = &H * &witness.x + Y.clone() * &witness.r; - let E = &G * &witness.r + G.clone(); + let Y = G * y; + let D = H * witness.x + Y * witness.r; + let E = G * witness.r + G; let delta = HomoElGamalStatement { G, H, Y, D, E }; let proof = HomoELGamalProof::prove(&witness, &delta); assert!(proof.verify(&delta).is_ok()); diff --git a/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_encryption_of_dlog.rs b/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_encryption_of_dlog.rs index dcafd213..fb65fb22 100644 --- a/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_encryption_of_dlog.rs +++ b/src/cryptographic_primitives/proofs/sigma_correct_homomorphic_elgamal_encryption_of_dlog.rs @@ -5,6 +5,7 @@ (https://github.com/KZen-networks/curv) License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; use super::ProofError; use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; @@ -95,10 +96,10 @@ mod tests { }; let G: GE = ECPoint::generator(); let y: FE = ECScalar::new_random(); - let Y = G.clone() * &y; - let D = G.clone() * &witness.x + Y.clone() * &witness.r; - let E = G.clone() * &witness.r; - let Q = G.clone() * &witness.x; + let Y = G * y; + let D = G * witness.x + Y * witness.r; + let E = G * witness.r; + let Q = G * witness.x; let delta = HomoElGamalDlogStatement { G, Y, Q, D, E }; let proof = HomoELGamalDlogProof::prove(&witness, &delta); assert!(proof.verify(&delta).is_ok()); @@ -115,10 +116,10 @@ mod tests { }; let G: GE = ECPoint::generator(); let y: FE = ECScalar::new_random(); - let Y = G.clone() * &y; - let D = G.clone() * &witness.x + Y.clone() * &witness.r; - let E = G.clone() * &witness.r + G.clone(); - let Q = G.clone() * &witness.x + G.clone(); + let Y = G * y; + let D = G * witness.x + Y * witness.r; + let E = G * witness.r + G; + let Q = G * witness.x + G; let delta = HomoElGamalDlogStatement { G, Y, Q, D, E }; let proof = HomoELGamalDlogProof::prove(&witness, &delta); assert!(proof.verify(&delta).is_ok()); diff --git a/src/cryptographic_primitives/proofs/sigma_dlog.rs b/src/cryptographic_primitives/proofs/sigma_dlog.rs index 42e9bc17..dce9fb69 100644 --- a/src/cryptographic_primitives/proofs/sigma_dlog.rs +++ b/src/cryptographic_primitives/proofs/sigma_dlog.rs @@ -4,6 +4,7 @@ (https://github.com/KZen-networks/curv) License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; use super::ProofError; use crate::FE; @@ -98,9 +99,7 @@ mod tests { let witness: FE = ECScalar::new_random(); let dlog_proof = DLogProof::prove(&witness); let verified = DLogProof::verify(&dlog_proof); - match verified { - Ok(_t) => assert!(true), - Err(_e) => assert!(false), - } + + assert!(verified.is_ok()) } } diff --git a/src/cryptographic_primitives/proofs/sigma_ec_ddh.rs b/src/cryptographic_primitives/proofs/sigma_ec_ddh.rs index 4d3a91a4..5a59b969 100644 --- a/src/cryptographic_primitives/proofs/sigma_ec_ddh.rs +++ b/src/cryptographic_primitives/proofs/sigma_ec_ddh.rs @@ -4,6 +4,7 @@ (https://github.com/KZen-networks/curv) License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; use super::ProofError; use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; @@ -90,8 +91,8 @@ mod tests { let x: FE = ECScalar::new_random(); let g1: GE = ECPoint::generator(); let g2: GE = GE::base_point2(); - let h1 = &g1 * &x; - let h2 = &g2 * &x; + let h1 = g1 * x; + let h2 = g2 * x; let delta = ECDDHStatement { g1, g2, h1, h2 }; let w = ECDDHWitness { x }; let proof = ECDDHProof::prove(&w, &delta); @@ -105,8 +106,8 @@ mod tests { let g1: GE = ECPoint::generator(); let g2: GE = GE::base_point2(); let x2: FE = ECScalar::new_random(); - let h1 = &g1 * &x; - let h2 = &g2 * &x2; + let h1 = g1 * x; + let h2 = g2 * x2; let delta = ECDDHStatement { g1, g2, h1, h2 }; let w = ECDDHWitness { x }; let proof = ECDDHProof::prove(&w, &delta); diff --git a/src/cryptographic_primitives/proofs/sigma_valid_pedersen.rs b/src/cryptographic_primitives/proofs/sigma_valid_pedersen.rs index bd031b25..e26a4407 100644 --- a/src/cryptographic_primitives/proofs/sigma_valid_pedersen.rs +++ b/src/cryptographic_primitives/proofs/sigma_valid_pedersen.rs @@ -4,6 +4,7 @@ (https://github.com/KZen-networks/curv) License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; use super::ProofError; use crate::cryptographic_primitives::commitments::pedersen_commitment::PedersenCommitment; @@ -40,7 +41,7 @@ pub trait ProvePederesen { } impl ProvePederesen for PedersenProof { - fn prove(m: &FE, r: &FE) -> PedersenProof { + fn prove(msg: &FE, blind_factor: &FE) -> PedersenProof { let g: GE = ECPoint::generator(); let h = GE::base_point2(); let mut s1: FE = ECScalar::new_random(); @@ -48,8 +49,8 @@ impl ProvePederesen for PedersenProof { let a1 = g.scalar_mul(&s1.get_element()); let a2 = h.scalar_mul(&s2.get_element()); let com = PedersenCommitment::create_commitment_with_user_defined_randomness( - &m.to_big_int(), - &r.to_big_int(), + &msg.to_big_int(), + &blind_factor.to_big_int(), ); let g: GE = ECPoint::generator(); let challenge = HSha256::create_hash(&[ @@ -62,9 +63,9 @@ impl ProvePederesen for PedersenProof { let e: FE = ECScalar::from(&challenge); - let em = e.mul(&m.get_element()); + let em = e.mul(&msg.get_element()); let z1 = s1.add(&em.get_element()); - let er = e.mul(&r.get_element()); + let er = e.mul(&blind_factor.get_element()); let z2 = s2.add(&er.get_element()); s1.zeroize(); s2.zeroize(); diff --git a/src/cryptographic_primitives/proofs/sigma_valid_pedersen_blind.rs b/src/cryptographic_primitives/proofs/sigma_valid_pedersen_blind.rs index ff40c080..89c1934f 100644 --- a/src/cryptographic_primitives/proofs/sigma_valid_pedersen_blind.rs +++ b/src/cryptographic_primitives/proofs/sigma_valid_pedersen_blind.rs @@ -5,6 +5,8 @@ License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE */ +use serde::{Deserialize, Serialize}; + use super::ProofError; use crate::cryptographic_primitives::commitments::pedersen_commitment::PedersenCommitment; use crate::cryptographic_primitives::commitments::traits::Commitment; @@ -38,30 +40,31 @@ pub trait ProvePederesenBlind { } impl ProvePederesenBlind for PedersenBlindingProof { //TODO: add self verification to prover proof - fn prove(m: &FE, r: &FE) -> PedersenBlindingProof { - let h = GE::base_point2(); + fn prove(msg: &FE, blind_factor: &FE) -> PedersenBlindingProof { + let base_point = GE::base_point2(); let mut s: FE = ECScalar::new_random(); - let a = h.scalar_mul(&s.get_element()); + let a = base_point.scalar_mul(&s.get_element()); let com = PedersenCommitment::create_commitment_with_user_defined_randomness( - &m.to_big_int(), - &r.to_big_int(), + &msg.to_big_int(), + &blind_factor.to_big_int(), ); let g: GE = ECPoint::generator(); let challenge = HSha256::create_hash(&[ &g.bytes_compressed_to_big_int(), - &h.bytes_compressed_to_big_int(), + &base_point.bytes_compressed_to_big_int(), &com.bytes_compressed_to_big_int(), &a.bytes_compressed_to_big_int(), - &m.to_big_int(), + &msg.to_big_int(), ]); - let e: FE = ECScalar::from(&challenge); - let er = e.mul(&r.get_element()); + let e: FE = ECScalar::from(&challenge); + let er = e.mul(&blind_factor.get_element()); let z = s.add(&er.get_element()); s.zeroize(); + PedersenBlindingProof { e, - m: *m, + m: *msg, a, com, z, @@ -107,7 +110,6 @@ mod tests { let m: FE = ECScalar::new_random(); let r: FE = ECScalar::new_random(); let pedersen_proof = PedersenBlindingProof::prove(&m, &r); - let _verified = - PedersenBlindingProof::verify(&pedersen_proof).expect("error pedersen blind"); + PedersenBlindingProof::verify(&pedersen_proof).expect("error pedersen blind"); } } diff --git a/src/cryptographic_primitives/secret_sharing/feldman_vss.rs b/src/cryptographic_primitives/secret_sharing/feldman_vss.rs index a029f340..3ad33bf0 100644 --- a/src/cryptographic_primitives/secret_sharing/feldman_vss.rs +++ b/src/cryptographic_primitives/secret_sharing/feldman_vss.rs @@ -5,6 +5,7 @@ (https://github.com/KZen-networks/curv) License MIT: */ +use serde::{Deserialize, Serialize}; use crate::elliptic::curves::traits::*; use crate::BigInt; @@ -66,9 +67,7 @@ impl VerifiableSS { let secret_shares = VerifiableSS::evaluate_polynomial(&poly, index_vec); let G: GE = ECPoint::generator(); - let commitments = (0..poly.len()) - .map(|i| G.clone() * &poly[i]) - .collect::>(); + let commitments = (0..poly.len()).map(|i| G * poly[i]).collect::>(); ( VerifiableSS { parameters: ShamirSecretSharing { @@ -196,8 +195,7 @@ impl VerifiableSS { let mut comm_iterator = self.commitments.iter().rev(); let head = comm_iterator.next().unwrap(); let tail = comm_iterator; - let comm_to_point = tail.fold(head.clone(), |acc, x: &GE| *x + acc * index_fe); - comm_to_point + tail.fold(head.clone(), |acc, x: &GE| *x + acc * index_fe) } //compute \lambda_{index,S}, a lagrangian coefficient that change the (t,n) scheme to (|S|,|S|) @@ -254,7 +252,7 @@ mod tests { shares_vec.push(secret_shares[4].clone()); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 1, 4, 5], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 1, 4, 5], &shares_vec); assert_eq!(secret, secret_reconstructed); } @@ -271,7 +269,7 @@ mod tests { shares_vec.push(secret_shares[4].clone()); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 1, 2, 4], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 1, 2, 4], &shares_vec); assert_eq!(secret, secret_reconstructed); // test secret shares are verifiable @@ -281,7 +279,7 @@ mod tests { assert!(valid1.is_ok()); let g: GE = GE::generator(); - let share1_public = g * &secret_shares[0]; + let share1_public = g * secret_shares[0]; let valid1_public = vss_scheme.validate_share_public(&share1_public, 1); assert!(valid1_public.is_ok()); @@ -292,11 +290,11 @@ mod tests { let l2 = vss_scheme.map_share_to_new_params(2, &s); let l3 = vss_scheme.map_share_to_new_params(3, &s); let l4 = vss_scheme.map_share_to_new_params(4, &s); - let w = l0 * secret_shares[0].clone() - + l1 * secret_shares[1].clone() - + l2 * secret_shares[2].clone() - + l3 * secret_shares[3].clone() - + l4 * secret_shares[4].clone(); + let w = l0 * secret_shares[0] + + l1 * secret_shares[1] + + l2 * secret_shares[2] + + l3 * secret_shares[3] + + l4 * secret_shares[4]; assert_eq!(w, secret_reconstructed); } @@ -313,7 +311,7 @@ mod tests { shares_vec.push(secret_shares[4].clone()); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 6, 2, 4], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 6, 2, 4], &shares_vec); assert_eq!(secret, secret_reconstructed); // test secret shares are verifiable @@ -329,11 +327,11 @@ mod tests { let l3 = vss_scheme.map_share_to_new_params(3, &s); let l4 = vss_scheme.map_share_to_new_params(4, &s); let l6 = vss_scheme.map_share_to_new_params(6, &s); - let w = l0 * secret_shares[0].clone() - + l1 * secret_shares[1].clone() - + l3 * secret_shares[3].clone() - + l4 * secret_shares[4].clone() - + l6 * secret_shares[6].clone(); + let w = l0 * secret_shares[0] + + l1 * secret_shares[1] + + l3 * secret_shares[3] + + l4 * secret_shares[4] + + l6 * secret_shares[6]; assert_eq!(w, secret_reconstructed); } @@ -348,7 +346,7 @@ mod tests { shares_vec.push(secret_shares[1].clone()); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 1], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 1], &shares_vec); assert_eq!(secret, secret_reconstructed); // test secret shares are verifiable @@ -362,7 +360,7 @@ mod tests { let l0 = vss_scheme.map_share_to_new_params(0, &s); let l1 = vss_scheme.map_share_to_new_params(1, &s); - let w = l0 * secret_shares[0].clone() + l1 * secret_shares[1].clone(); + let w = l0 * secret_shares[0] + l1 * secret_shares[1]; assert_eq!(w, secret_reconstructed); } @@ -378,19 +376,19 @@ mod tests { // test commitment to point and sum of commitments let (vss_scheme2, secret_shares2) = VerifiableSS::share(1, 3, &secret); - let sum = secret_shares[0].clone() + secret_shares2[0].clone(); + let sum = secret_shares[0] + secret_shares2[0]; let point_comm1 = vss_scheme.get_point_commitment(1); let point_comm2 = vss_scheme.get_point_commitment(2); let g: GE = GE::generator(); - let g_sum = g.clone() * ∑ - assert_eq!(g.clone() * secret_shares[0].clone(), point_comm1.clone()); - assert_eq!(g.clone() * secret_shares[1].clone(), point_comm2.clone()); + let g_sum = g * sum; + assert_eq!(g * secret_shares[0], point_comm1.clone()); + assert_eq!(g * secret_shares[1], point_comm2.clone()); let point1_sum_com = vss_scheme.get_point_commitment(1) + vss_scheme2.get_point_commitment(1); assert_eq!(point1_sum_com, g_sum); //test reconstruction - let secret_reconstructed = vss_scheme.reconstruct(&vec![0, 1], &shares_vec); + let secret_reconstructed = vss_scheme.reconstruct(&[0, 1], &shares_vec); assert_eq!(secret, secret_reconstructed); // test secret shares are verifiable @@ -404,7 +402,7 @@ mod tests { let l0 = vss_scheme.map_share_to_new_params(0, &s); let l2 = vss_scheme.map_share_to_new_params(2, &s); - let w = l0 * secret_shares[0].clone() + l2 * secret_shares[2].clone(); + let w = l0 * secret_shares[0] + l2 * secret_shares[2]; assert_eq!(w, secret_reconstructed); } } diff --git a/src/cryptographic_primitives/twoparty/coin_flip_optimal_rounds.rs b/src/cryptographic_primitives/twoparty/coin_flip_optimal_rounds.rs index 8e70f3e5..363d715c 100644 --- a/src/cryptographic_primitives/twoparty/coin_flip_optimal_rounds.rs +++ b/src/cryptographic_primitives/twoparty/coin_flip_optimal_rounds.rs @@ -5,6 +5,8 @@ License MIT: */ +use serde::{Deserialize, Serialize}; + use crate::cryptographic_primitives::proofs::sigma_valid_pedersen::PedersenProof; use crate::cryptographic_primitives::proofs::sigma_valid_pedersen::ProvePederesen; use crate::cryptographic_primitives::proofs::sigma_valid_pedersen_blind::PedersenBlindingProof; @@ -55,7 +57,7 @@ impl Party1SecondMessage { ( Party1SecondMessage { proof, - seed: party1seed.clone(), + seed: *party1seed, }, ECScalar::from(&coin_flip_result), ) diff --git a/src/cryptographic_primitives/twoparty/dh_key_exchange.rs b/src/cryptographic_primitives/twoparty/dh_key_exchange.rs index 3155c29d..95193e71 100644 --- a/src/cryptographic_primitives/twoparty/dh_key_exchange.rs +++ b/src/cryptographic_primitives/twoparty/dh_key_exchange.rs @@ -9,6 +9,8 @@ /// Bob chooses at random a secret "b" and sends to Alice B = bG. /// Both parties can compute a joint secret: C =aB = bA = abG which cannot be computed by /// a man in the middle attacker. +use serde::{Deserialize, Serialize}; + use crate::elliptic::curves::traits::*; use crate::FE; use crate::GE; diff --git a/src/cryptographic_primitives/twoparty/dh_key_exchange_variant_with_pok_comm.rs b/src/cryptographic_primitives/twoparty/dh_key_exchange_variant_with_pok_comm.rs index d6cc1ba9..76e8cb05 100644 --- a/src/cryptographic_primitives/twoparty/dh_key_exchange_variant_with_pok_comm.rs +++ b/src/cryptographic_primitives/twoparty/dh_key_exchange_variant_with_pok_comm.rs @@ -13,6 +13,8 @@ /// The variant below is to protect not only from man in the middle but also from malicious /// Alice or Bob that can bias the result. The details of the protocol can be found in /// https://eprint.iacr.org/2017/552.pdf protocol 3.1 first 3 steps. +use serde::{Deserialize, Serialize}; + use crate::arithmetic::traits::Samplable; use crate::cryptographic_primitives::commitments::hash_commitment::HashCommitment; use crate::cryptographic_primitives::commitments::traits::Commitment; diff --git a/src/elliptic/curves/secp256_k1.rs b/src/elliptic/curves/secp256_k1.rs index 9408c0e4..a0b11760 100644 --- a/src/elliptic/curves/secp256_k1.rs +++ b/src/elliptic/curves/secp256_k1.rs @@ -16,14 +16,17 @@ // The Public Key codec: Point <> SecretKey // -use super::traits::{ECPoint, ECScalar}; -use crate::arithmetic::traits::{Converter, Modulo}; -use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; -use crate::cryptographic_primitives::hashing::traits::Hash; -use crate::BigInt; -use crate::ErrorKey; +use std::fmt; +use std::ops::{Add, Mul}; +use std::ptr; +use std::sync::atomic; -use rand::{thread_rng, Rng}; +use crypto::digest::Digest; +use crypto::sha3::Sha3; +use gmp::mpz::ParseMpzError; +use lazy_static::lazy_static; +use merkle::Hashable; +use rand::thread_rng; use secp256k1::constants::{ CURVE_ORDER, GENERATOR_X, GENERATOR_Y, SECRET_KEY_SIZE, UNCOMPRESSED_PUBLIC_KEY_SIZE, }; @@ -33,62 +36,66 @@ use serde::de::{MapAccess, SeqAccess, Visitor}; use serde::ser::SerializeStruct; use serde::ser::{Serialize, Serializer}; use serde::{Deserialize, Deserializer}; -use std::fmt; -use std::ops::{Add, Mul}; -use std::ptr; -use std::sync::{atomic, Once}; use zeroize::Zeroize; -#[cfg(feature = "merkle")] -use crypto::digest::Digest; -#[cfg(feature = "merkle")] -use crypto::sha3::Sha3; -#[cfg(feature = "merkle")] -use merkle::Hashable; +use super::traits::{ECPoint, ECScalar}; +use crate::arithmetic::traits::{Converter, Modulo}; +use crate::cryptographic_primitives::hashing::hash_sha256::HSha256; +use crate::cryptographic_primitives::hashing::traits::Hash; +use crate::BigInt; +use crate::ErrorKey; pub type SK = SecretKey; pub type PK = PublicKey; +lazy_static! { + static ref CONTEXT: Secp256k1 = Secp256k1::verification_only(); +} + #[derive(Clone, Debug, Copy)] pub struct Secp256k1Scalar { purpose: &'static str, fe: SK, } + #[derive(Clone, Debug, Copy)] pub struct Secp256k1Point { purpose: &'static str, ge: PK, } + pub type GE = Secp256k1Point; pub type FE = Secp256k1Scalar; impl Secp256k1Point { - pub fn random_point() -> Secp256k1Point { + pub fn random_point() -> Self { let random_scalar: Secp256k1Scalar = Secp256k1Scalar::new_random(); - let base_point = Secp256k1Point::generator(); + let base_point = Self::generator(); let pk = base_point.scalar_mul(&random_scalar.get_element()); - Secp256k1Point { + Self { purpose: "random_point", ge: pk.get_element(), } } - // To generate a random base point we take the hash of the curve generator. - // This hash creates a random string which do not encode a valid (x,y) curve point. + // To generate another base point we take the hash of the curve generator (base point). + // This hash creates a number which do not encode a valid (x,y) curve point. // Therefore we continue to hash the result until the first valid point comes out. // This function is a result of a manual testing to find // this minimal number of hashes and therefore it is written like this. // the prefix "2" is to complete for the right parity of the point - pub fn base_point2() -> Secp256k1Point { - let g: Secp256k1Point = ECPoint::generator(); + pub fn base_point2() -> Self { + let g = Self::generator(); + let hash = HSha256::create_hash(&[&g.bytes_compressed_to_big_int()]); let hash = HSha256::create_hash(&[&hash]); let hash = HSha256::create_hash(&[&hash]); - let mut hash_vec = BigInt::to_vec(&hash); - let mut template: Vec = vec![2]; - template.append(&mut hash_vec); - Secp256k1Point { + + let mut possible_pk = vec![2u8]; + possible_pk.append(&mut BigInt::to_vec(&hash)); + + Self { purpose: "random", - ge: PK::from_slice(&template).unwrap(), + ge: PK::from_slice(possible_pk.as_slice()).unwrap(), } } } @@ -102,19 +109,16 @@ impl Zeroize for Secp256k1Scalar { } impl ECScalar for Secp256k1Scalar { - fn new_random() -> Secp256k1Scalar { - let mut arr = [0u8; 32]; - thread_rng().fill(&mut arr[..]); - Secp256k1Scalar { + fn new_random() -> Self { + Self { purpose: "random", - fe: SK::from_slice(&arr[0..arr.len()]).unwrap(), + fe: SK::new(&mut thread_rng()), } } - fn zero() -> Secp256k1Scalar { - let zero_arr = [0u8; 32]; - let zero = unsafe { std::mem::transmute::<[u8; 32], SecretKey>(zero_arr) }; - Secp256k1Scalar { + fn zero() -> Self { + let zero = unsafe { std::mem::transmute::<[u8; 32], SecretKey>([0u8; 32]) }; + Self { purpose: "zero", fe: zero, } @@ -128,7 +132,7 @@ impl ECScalar for Secp256k1Scalar { self.fe = element } - fn from(n: &BigInt) -> Secp256k1Scalar { + fn from(n: &BigInt) -> Self { let curve_order = FE::q(); let n_reduced = BigInt::mod_add(n, &BigInt::from(0), &curve_order); let mut v = BigInt::to_vec(&n_reduced); @@ -139,7 +143,7 @@ impl ECScalar for Secp256k1Scalar { v = template; } - Secp256k1Scalar { + Self { purpose: "from_big_int", fe: SK::from_slice(&v).unwrap(), } @@ -153,7 +157,7 @@ impl ECScalar for Secp256k1Scalar { BigInt::from(CURVE_ORDER.as_ref()) } - fn add(&self, other: &SK) -> Secp256k1Scalar { + fn add(&self, other: &SK) -> Self { let mut other_scalar: FE = ECScalar::new_random(); other_scalar.set_element(other.clone()); let res: FE = ECScalar::from(&BigInt::mod_add( @@ -161,13 +165,13 @@ impl ECScalar for Secp256k1Scalar { &other_scalar.to_big_int(), &FE::q(), )); - Secp256k1Scalar { + Self { purpose: "add", fe: res.get_element(), } } - fn mul(&self, other: &SK) -> Secp256k1Scalar { + fn mul(&self, other: &SK) -> Self { let mut other_scalar: FE = ECScalar::new_random(); other_scalar.set_element(other.clone()); let res: FE = ECScalar::from(&BigInt::mod_mul( @@ -175,13 +179,13 @@ impl ECScalar for Secp256k1Scalar { &other_scalar.to_big_int(), &FE::q(), )); - Secp256k1Scalar { + Self { purpose: "mul", fe: res.get_element(), } } - fn sub(&self, other: &SK) -> Secp256k1Scalar { + fn sub(&self, other: &SK) -> Self { let mut other_scalar: FE = ECScalar::new_random(); other_scalar.set_element(other.clone()); let res: FE = ECScalar::from(&BigInt::mod_sub( @@ -189,42 +193,42 @@ impl ECScalar for Secp256k1Scalar { &other_scalar.to_big_int(), &FE::q(), )); - Secp256k1Scalar { + Self { purpose: "sub", fe: res.get_element(), } } - fn invert(&self) -> Secp256k1Scalar { + fn invert(&self) -> Self { let bignum = self.to_big_int(); let bn_inv = bignum.invert(&FE::q()).unwrap(); ECScalar::from(&bn_inv) } } impl Mul for Secp256k1Scalar { - type Output = Secp256k1Scalar; - fn mul(self, other: Secp256k1Scalar) -> Secp256k1Scalar { + type Output = Self; + fn mul(self, other: Self) -> Self { (&self).mul(&other.get_element()) } } impl<'o> Mul<&'o Secp256k1Scalar> for Secp256k1Scalar { - type Output = Secp256k1Scalar; - fn mul(self, other: &'o Secp256k1Scalar) -> Secp256k1Scalar { + type Output = Self; + fn mul(self, other: &'o Self) -> Self { (&self).mul(&other.get_element()) } } impl Add for Secp256k1Scalar { - type Output = Secp256k1Scalar; - fn add(self, other: Secp256k1Scalar) -> Secp256k1Scalar { + type Output = Self; + fn add(self, other: Self) -> Self { (&self).add(&other.get_element()) } } impl<'o> Add<&'o Secp256k1Scalar> for Secp256k1Scalar { - type Output = Secp256k1Scalar; - fn add(self, other: &'o Secp256k1Scalar) -> Secp256k1Scalar { + type Output = Self; + fn add(self, other: &'o Self) -> Self { (&self).add(&other.get_element()) } } @@ -239,7 +243,7 @@ impl Serialize for Secp256k1Scalar { } impl<'de> Deserialize<'de> for Secp256k1Scalar { - fn deserialize(deserializer: D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -253,23 +257,25 @@ impl<'de> Visitor<'de> for Secp256k1ScalarVisitor { type Value = Secp256k1Scalar; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Secp256k1Scalar") + formatter.write_str("struct Secp256k1Scalar") } - fn visit_str(self, s: &str) -> Result { - let v = BigInt::from_str_radix(s, 16).expect("Failed in serde"); + fn visit_str(self, s: &str) -> Result { + let v = BigInt::from_str_radix(s, 16).map_err(|e| match e { + ParseMpzError { .. } => de::Error::invalid_value(de::Unexpected::Str(s), &self), + })?; Ok(ECScalar::from(&v)) } } impl PartialEq for Secp256k1Scalar { - fn eq(&self, other: &Secp256k1Scalar) -> bool { + fn eq(&self, other: &Self) -> bool { self.get_element() == other.get_element() } } impl PartialEq for Secp256k1Point { - fn eq(&self, other: &Secp256k1Point) -> bool { + fn eq(&self, other: &Self) -> bool { self.get_element() == other.get_element() } } @@ -283,11 +289,11 @@ impl Zeroize for Secp256k1Point { } impl ECPoint for Secp256k1Point { - fn generator() -> Secp256k1Point { - let mut v = vec![4 as u8]; + fn generator() -> Self { + let mut v = vec![4u8]; v.extend(GENERATOR_X.as_ref()); v.extend(GENERATOR_Y.as_ref()); - Secp256k1Point { + Self { purpose: "base_fe", ge: PK::from_slice(&v).unwrap(), } @@ -307,112 +313,74 @@ 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[..])) - } - - 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| Secp256k1Point { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) + 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 len = bytes.len(); + + let formalized: Vec = match len { + 65 | 33 => bytes.to_vec(), // uncompressed/compressed public key + 34..=64 => { + // try to convert to uncompressed format + let mut v = vec![4u8]; + v.extend(vec![0; 64 - len]); + v.extend(bytes.iter()); + v } - 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| Secp256k1Point { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) + // try to convert to compressed format + let mut v = vec![2u8]; + v.extend(vec![0; 32 - len]); + 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| Secp256k1Point { - purpose: "random", - ge: pk, - }); - test.map_err(|_err| ErrorKey::InvalidPublicKey) + // > 65, we take the first 64 bytes anyway + let mut v = vec![4u8]; + v.extend(bytes[..64].iter()); + v } - } - } - fn pk_to_key_slice(&self) -> Vec { - let mut v = vec![4 as u8]; - let x_vec = BigInt::to_vec(&self.x_coor().unwrap()); - let y_vec = BigInt::to_vec(&self.y_coor().unwrap()); - - let mut raw_x: Vec = Vec::new(); - let mut raw_y: Vec = Vec::new(); - raw_x.extend(vec![0u8; 32 - x_vec.len()]); - raw_x.extend(x_vec); + }; - raw_y.extend(vec![0u8; 32 - y_vec.len()]); - raw_y.extend(y_vec); + PK::from_slice(formalized.as_slice()) + .map(|pk| Self { + purpose: "random", + ge: pk, + }) + .map_err(|_| ErrorKey::InvalidPublicKey) + } - v.extend(raw_x); - v.extend(raw_y); - v + fn pk_to_key_slice(&self) -> Vec { + self.ge.serialize_uncompressed().to_vec() } - fn scalar_mul(&self, fe: &SK) -> Secp256k1Point { + fn scalar_mul(&self, fe: &SK) -> Self { let mut new_point = *self; new_point .ge - .mul_assign(get_context(), &fe[..]) + .mul_assign(&CONTEXT, &fe[..]) .expect("Assignment expected"); new_point } - fn add_point(&self, other: &PK) -> Secp256k1Point { - Secp256k1Point { + fn add_point(&self, other: &PK) -> Self { + Self { purpose: "combine", ge: self.ge.combine(other).unwrap(), } } - fn sub_point(&self, other: &PK) -> Secp256k1Point { - let point = Secp256k1Point { + fn sub_point(&self, other: &PK) -> Self { + let point = Self { purpose: "sub_point", ge: *other, }; @@ -439,53 +407,27 @@ impl ECPoint for Secp256k1Point { x_vec.extend_from_slice(&y_vec); let minus_point: GE = ECPoint::from_bytes(&x_vec).unwrap(); - //let minus_point: GE = ECPoint::from_coor(&x, &y_inv); ECPoint::add_point(self, &minus_point.get_element()) } - fn from_coor(x: &BigInt, y: &BigInt) -> Secp256k1Point { - let mut vec_x = BigInt::to_vec(x); - let mut vec_y = BigInt::to_vec(y); - let coor_size = (UNCOMPRESSED_PUBLIC_KEY_SIZE - 1) / 2; - - if vec_x.len() < coor_size { - // pad - let mut x_buffer = vec![0; coor_size - vec_x.len()]; - x_buffer.extend_from_slice(&vec_x); - vec_x = x_buffer - } - - if vec_y.len() < coor_size { - // pad - let mut y_buffer = vec![0; coor_size - vec_y.len()]; - y_buffer.extend_from_slice(&vec_y); - vec_y = y_buffer - } - - assert_eq!(x, &BigInt::from(vec_x.as_ref())); - assert_eq!(y, &BigInt::from(vec_y.as_ref())); + fn from_coor(x: &BigInt, y: &BigInt) -> Self { + let x = BigInt::to_vec(x); + let y = BigInt::to_vec(y); + let coor_size = (UNCOMPRESSED_PUBLIC_KEY_SIZE - 1) / 2; // 32 - let mut v = vec![4 as u8]; - v.extend(vec_x); - v.extend(vec_y); + let mut v = vec![4u8]; + v.extend(vec![0; coor_size - x.len()]); + v.extend(x); + v.extend(vec![0; coor_size - y.len()]); + v.extend(y); - Secp256k1Point { + Self { purpose: "base_fe", - ge: PK::from_slice(&v).unwrap(), + ge: PK::from_slice(v.as_slice()).unwrap(), } } } -static mut CONTEXT: Option> = None; -pub fn get_context() -> &'static Secp256k1 { - static INIT_CONTEXT: Once = Once::new(); - INIT_CONTEXT.call_once(|| unsafe { - CONTEXT = Some(Secp256k1::verification_only()); - }); - unsafe { CONTEXT.as_ref().unwrap() } -} - -#[cfg(feature = "merkle")] impl Hashable for Secp256k1Point { fn update_context(&self, context: &mut Sha3) { let bytes: Vec = self.pk_to_key_slice(); @@ -494,7 +436,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()) } @@ -515,8 +457,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()) } } @@ -541,8 +483,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() } } @@ -563,10 +505,10 @@ 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_seq(self, mut seq: V) -> Result + fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de>, { @@ -600,7 +542,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)) } } @@ -620,10 +561,43 @@ mod tests { 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); + + let mut encoded = bincode::serialize(&sk).unwrap(); + let decoded: Secp256k1Scalar = bincode::deserialize(encoded.as_slice()).unwrap(); + assert_eq!(decoded, sk); + + encoded[0] = 0u8; + let decoded: Result = bincode::deserialize(encoded.as_slice()); + assert!(decoded.is_err()); + } + + #[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!(r#"{{"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); + + let mut encoded = bincode::serialize(&pk).unwrap(); + let decoded: Secp256k1Point = bincode::deserialize(encoded.as_slice()).unwrap(); + assert_eq!(decoded, pk); + + encoded[0] = 0u8; + let decoded: Result = bincode::deserialize(encoded.as_slice()); + assert!(decoded.is_err()); } #[test] @@ -655,38 +629,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); - } - - #[test] - fn bincode_pk() { - let pk = Secp256k1Point::generator(); - let bin = bincode::serialize(&pk).unwrap(); - let decoded: Secp256k1Point = bincode::deserialize(bin.as_slice()).unwrap(); - assert_eq!(decoded, pk); - } - use crate::elliptic::curves::secp256_k1::{FE, GE}; use crate::ErrorKey; @@ -717,10 +659,43 @@ 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 hash = HSha256::create_hash(&[&g.bytes_compressed_to_big_int()]); + let result = Secp256k1Point::from_bytes(BigInt::to_vec(&hash).as_slice()); + assert_eq!(result.unwrap_err(), ErrorKey::InvalidPublicKey); + + let mut b = [0u8; 64]; + b[63] = 1; + assert!(Secp256k1Point::from_bytes(&b).is_err()); + + let mut b = [0u8; 65]; + b[64] = 1; + assert!(Secp256k1Point::from_bytes(&b).is_err()); + + let mut b = [0u8; 66]; + b[65] = 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_eq!( + Secp256k1Point::from_bytes(y.as_slice()).unwrap_err(), + ErrorKey::InvalidPublicKey + ); + assert!(Secp256k1Point::from_bytes(x_and_y.as_slice()).is_ok()); + + let mut xy_push_1 = x_and_y.clone(); + xy_push_1.push(1); + xy_push_1.push(1); + assert_eq!(xy_push_1.len(), 66); + assert!(Secp256k1Point::from_bytes(xy_push_1.as_slice()).is_ok()); } #[test] @@ -764,10 +739,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()); } diff --git a/src/lib.rs b/src/lib.rs index 4b64e185..15710c2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,6 @@ License MIT: */ -#[macro_use] -extern crate serde_derive; - #[cfg(feature = "ecc")] pub mod elliptic;