From 35cd278f24f70b498095190e360754b2c13cc4b8 Mon Sep 17 00:00:00 2001 From: DanieleDiBenedetto <50587279+DanieleDiBenedetto@users.noreply.github.com> Date: Tue, 24 Oct 2023 16:16:58 +0200 Subject: [PATCH] Release 0.6.1 (#215) * Replaced prints with logs, and added error logs where needed (#211) * Bump version to 0.6.1 --- algebra/Cargo.toml | 4 +- algebra/algebra-derive/Cargo.toml | 4 +- algebra/field-assembly/Cargo.toml | 3 +- algebra/src/fft/polynomial/mod.rs | 2 +- algebra/src/fields/arithmetic.rs | 2 +- algebra/src/fields/macros.rs | 44 +++--- algebra/src/fields/mod.rs | 2 - bench-utils/Cargo.toml | 2 +- primitives/Cargo.toml | 3 +- primitives/benches/crypto_primitives/comm.rs | 9 +- primitives/benches/crypto_primitives/ecvrf.rs | 5 +- primitives/src/commitment/pedersen/mod.rs | 2 - primitives/src/crh/bowe_hopwood/mod.rs | 59 ++++---- primitives/src/crh/pedersen/mod.rs | 12 +- .../field_based_mht/append_only/mod.rs | 65 +++++---- .../merkle_tree/field_based_mht/naive/mod.rs | 17 ++- .../src/merkle_tree/field_based_mht/path.rs | 47 +++---- .../smt/big_lazy_merkle_tree.rs | 81 ++++++----- primitives/src/merkle_tree/mod.rs | 23 ++-- .../signature/schnorr/field_based_schnorr.rs | 2 +- primitives/src/signature/schnorr/mod.rs | 2 +- primitives/src/vrf/ecvrf/mod.rs | 68 +++++----- primitives/src/vrf/ecvrf/nonce_generation.rs | 84 ++++++------ primitives/src/vrf/mod.rs | 5 +- proof-systems/Cargo.toml | 4 +- proof-systems/src/darlin/proof_aggregator.rs | 57 ++++++-- proof-systems/src/gm17/tests/mimc.rs | 23 ++-- proof-systems/src/groth16/r1cs_to_qap.rs | 6 +- proof-systems/src/groth16/tests/mimc.rs | 12 +- proof-systems/src/lib.rs | 1 - proof-systems/src/marlin/Cargo.toml | 3 +- proof-systems/src/marlin/src/ahp/indexer.rs | 8 +- proof-systems/src/marlin/src/lib.rs | 4 +- proof-systems/src/poly-commit/Cargo.toml | 3 +- .../poly-commit/src/ipa_pc/data_structures.rs | 4 +- .../src/poly-commit/src/ipa_pc/mod.rs | 24 ++-- proof-systems/src/poly-commit/src/lib.rs | 6 +- r1cs/core/Cargo.toml | 2 +- r1cs/gadgets/crypto/Cargo.toml | 3 +- .../src/commitment/injective_map/mod.rs | 3 +- .../crypto/src/commitment/pedersen/mod.rs | 26 ++-- .../crypto/src/crh/bowe_hopwood/mod.rs | 10 +- .../crypto/src/crh/injective_map/mod.rs | 3 +- r1cs/gadgets/crypto/src/crh/pedersen/mod.rs | 15 +-- r1cs/gadgets/crypto/src/merkle_tree/mod.rs | 17 ++- r1cs/gadgets/crypto/src/vrf/ecvrf/mod.rs | 70 +++++++--- r1cs/gadgets/std/Cargo.toml | 3 +- r1cs/gadgets/std/src/bits/boolean.rs | 98 ++++++++------ r1cs/gadgets/std/src/fields/fp.rs | 25 +--- .../nonnative/nonnative_field_gadget.rs | 102 ++++++-------- .../short_weierstrass_jacobian.rs | 127 +++++++++++++----- .../short_weierstrass_projective.rs | 127 +++++++++++++----- r1cs/gadgets/std/src/groups/mod.rs | 79 ++++++++--- .../short_weierstrass_jacobian.rs | 86 +++++++++--- 54 files changed, 892 insertions(+), 606 deletions(-) diff --git a/algebra/Cargo.toml b/algebra/Cargo.toml index e4072368a..7aa62434c 100644 --- a/algebra/Cargo.toml +++ b/algebra/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "algebra" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", @@ -42,10 +42,10 @@ colored = { version = "2.0.0", optional = true } rayon = { version = "1.5.1", optional = true } rayon-core = { version = "1.9.1", optional = true } - unroll = "0.1.5" serde = { version = "1.0.130", features = ["derive"] } +log = { version = "0.4.0", features = ["std"] } [dev-dependencies] blake2 = "0.8.1" diff --git a/algebra/algebra-derive/Cargo.toml b/algebra/algebra-derive/Cargo.toml index 9befdf57d..5d2691973 100644 --- a/algebra/algebra-derive/Cargo.toml +++ b/algebra/algebra-derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "algebra-derive" -version = "0.6.0" -authors = [ "arkworks Contributors" ] +version = "0.6.1" +authors = ["arkworks Contributors"] description = "A library for deriving serialization traits" include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] license = "MIT/Apache-2.0" diff --git a/algebra/field-assembly/Cargo.toml b/algebra/field-assembly/Cargo.toml index 8a7b0b4ae..5992e0c76 100644 --- a/algebra/field-assembly/Cargo.toml +++ b/algebra/field-assembly/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "field-assembly" -version = "0.6.0" +version = "0.6.1" authors = [ "jon-chuang <9093549+jon-chuang@users.noreply.github.com>", "Michele d'Amico ", @@ -11,6 +11,7 @@ rust-version = "1.60" [dependencies] quote = "1.0.0" syn = { version = "1.0.0", features = ["full", "parsing", "extra-traits"] } +log = { version = "0.4.0", features = ["std"] } [lib] proc-macro = true diff --git a/algebra/src/fft/polynomial/mod.rs b/algebra/src/fft/polynomial/mod.rs index 1959cc708..cd7e751ad 100644 --- a/algebra/src/fft/polynomial/mod.rs +++ b/algebra/src/fft/polynomial/mod.rs @@ -106,7 +106,7 @@ impl DenseOrSparsePolynomial<'_, F> { if self.is_zero() { Some((DensePolynomial::zero(), DensePolynomial::zero())) } else if divisor.is_zero() { - eprintln!("Dividing by zero polynomial"); + log::error!("Dividing by zero polynomial"); None } else if self.degree() < divisor.degree() { Some((DensePolynomial::zero(), self.clone().into())) diff --git a/algebra/src/fields/arithmetic.rs b/algebra/src/fields/arithmetic.rs index 8055d27d0..d993b386a 100644 --- a/algebra/src/fields/arithmetic.rs +++ b/algebra/src/fields/arithmetic.rs @@ -325,7 +325,7 @@ macro_rules! sqrt_impl { check.square_in_place(); } if !check.is_one() { - eprintln!("Input is not a square root, but it passed the QR test"); + log::error!("Input is not a square root, but it passed the QR test"); return None; } } diff --git a/algebra/src/fields/macros.rs b/algebra/src/fields/macros.rs index 5a92770fb..0575a862c 100644 --- a/algebra/src/fields/macros.rs +++ b/algebra/src/fields/macros.rs @@ -214,13 +214,13 @@ macro_rules! impl_Fp { let mut s = $BigInteger::from(1); let mut k: u16 = 0; // TODO: Make it independent from the limb size - let two_n : u16 = 2 * 64 * $limbs; // R2 = 2^two_n mod MODULUS - // At each step we want to have the following equalities: - // something * p + r*A = - u, something * p + s*A = v - // The inverse at the end will be -r mod p. The sign is due to the fact - // that our big integers are unsigned so we can work with positive numbers. - // The arithmetic can be improved drastically since, at the beginning, - // r and s are very small. + let two_n: u16 = 2 * 64 * $limbs; // R2 = 2^two_n mod MODULUS + // At each step we want to have the following equalities: + // something * p + r*A = - u, something * p + s*A = v + // The inverse at the end will be -r mod p. The sign is due to the fact + // that our big integers are unsigned so we can work with positive numbers. + // The arithmetic can be improved drastically since, at the beginning, + // r and s are very small. while v != zero { while u.is_even() { u.div2(); @@ -280,20 +280,22 @@ macro_rules! impl_Fp { // byte_size + 1 > output_byte_size fn from_random_bytes_with_flags(bytes: &[u8]) -> Option<(Self, F)> { if F::BIT_SIZE > 8 { - return None + return None; } else { let mut result_bytes = [0u8; $limbs * 8 + 1]; // Copy the input into a temporary buffer. - result_bytes.iter_mut().zip(bytes).for_each(|(result, input)| { - *result = *input; - }); + result_bytes + .iter_mut() + .zip(bytes) + .for_each(|(result, input)| { + *result = *input; + }); // This mask retains everything in the last limb // that is below `P::MODULUS_BITS`. let last_limb_mask = (u64::MAX >> P::REPR_SHAVE_BITS).to_le_bytes(); let mut last_bytes_mask = [0u8; 9]; last_bytes_mask[..8].copy_from_slice(&last_limb_mask); - // Length of the buffer containing the field element and the flag. let output_byte_size = buffer_byte_size(P::MODULUS_BITS as usize + F::BIT_SIZE); // Location of the flag is the last byte of the serialized @@ -377,7 +379,7 @@ macro_rules! impl_Fp { fn full_root_of_unity() -> Option { match P::FULL_ROOT_OF_UNITY { Some(v) => Some($Fp::

(v, PhantomData)), - None => None + None => None, } } } @@ -447,7 +449,7 @@ macro_rules! impl_Fp { impl FromBytes for $Fp

{ #[inline] fn read(reader: R) -> IoResult { - $BigInteger::read(reader).and_then( |b| + $BigInteger::read(reader).and_then(|b| { if b.is_zero() { Ok($Fp::zero()) } else { @@ -455,13 +457,13 @@ macro_rules! impl_Fp { if f == $Fp::zero() { Err(IoError::new( ErrorKind::InvalidData, - "Attempt to deserialize a field element over the modulus") - ) + "Attempt to deserialize a field element over the modulus", + )) } else { Ok(f) } } - ) + }) } } @@ -507,10 +509,10 @@ macro_rules! impl_Fp { res.add_assign(&Self::from_repr(::BigInt::from( u64::from(c), ))); - }, + } None => { return Err(()); - }, + } } } if !res.is_valid() { @@ -524,7 +526,7 @@ macro_rules! impl_Fp { impl Display for $Fp

{ #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, stringify!($Fp"({})"), self.into_repr()) + write!(f, stringify!("({})"$Fp), self.into_repr()) } } @@ -651,5 +653,5 @@ macro_rules! impl_Fp { other.into_repr().into() } } - } + }; } diff --git a/algebra/src/fields/mod.rs b/algebra/src/fields/mod.rs index ca9ab951b..a48bfbfa8 100644 --- a/algebra/src/fields/mod.rs +++ b/algebra/src/fields/mod.rs @@ -408,7 +408,6 @@ pub trait PrimeField: } impl ToBits for F { - /// Serializes `self` into a vector of bits, in big-endian bit order. #[inline] fn write_bits(&self) -> Vec { @@ -433,7 +432,6 @@ impl ToBits for F { } } - impl FromBits for F { // Defines a prime field element from a big endian bit-ordered vector of // bits, which must not exceed the field modulus. diff --git a/bench-utils/Cargo.toml b/bench-utils/Cargo.toml index 853f26a09..7aa188425 100644 --- a/bench-utils/Cargo.toml +++ b/bench-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bench-utils" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 59a762395..a1d5e35b9 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "primitives" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", @@ -43,6 +43,7 @@ sha2 = { version = "0.8.2", optional = true } hmac = { version = "0.7.1", optional = true } serde = { version = "1.0.130", features = ["derive"] } +log = { version = "0.4.0", features = ["std"] } [features] asm = ["algebra/asm"] diff --git a/primitives/benches/crypto_primitives/comm.rs b/primitives/benches/crypto_primitives/comm.rs index 128a6dd2d..205c393fc 100644 --- a/primitives/benches/crypto_primitives/comm.rs +++ b/primitives/benches/crypto_primitives/comm.rs @@ -14,7 +14,7 @@ impl PedersenWindow for CommWindow { } const BENCH_INPUT_SIZE: usize = 128; -type C = PedersenCommitment::; +type C = PedersenCommitment; fn pedersen_comm_setup(c: &mut Criterion) { c.bench_function("Pedersen Commitment Setup", move |b| { @@ -33,12 +33,7 @@ fn pedersen_comm_eval(c: &mut Criterion) { b.iter(|| { let rng = &mut rand::thread_rng(); let commitment_randomness = PedersenRandomness::rand(rng); - C::commit( - ¶meters, - &input, - &commitment_randomness, - ) - .unwrap(); + C::commit(¶meters, &input, &commitment_randomness).unwrap(); }) }); } diff --git a/primitives/benches/crypto_primitives/ecvrf.rs b/primitives/benches/crypto_primitives/ecvrf.rs index 51be13e3f..0cd4062fd 100644 --- a/primitives/benches/crypto_primitives/ecvrf.rs +++ b/primitives/benches/crypto_primitives/ecvrf.rs @@ -1,6 +1,6 @@ use algebra::curves::mnt6753::G1Projective as MNT6G1Projective; use algebra::fields::mnt4753::fr::{Fr as MNT4Fr, FrParameters as MNT4FrParameters}; -use algebra::{UniformRand, FpParameters}; +use algebra::{FpParameters, UniformRand}; use criterion::Criterion; use primitives::{ crh::{bowe_hopwood::BoweHopwoodPedersenCRH, pedersen::PedersenWindow, MNT4PoseidonHash}, @@ -18,7 +18,8 @@ impl PedersenWindow for TestWindow { const NUM_WINDOWS: usize = 2; } -const BHMNT6_INPUT_SIZE: usize = ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS)/8) as usize; +const BHMNT6_INPUT_SIZE: usize = + ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS) / 8) as usize; type BHMNT6 = BoweHopwoodPedersenCRH; type EcVrfMNT4 = FieldBasedEcVrf; diff --git a/primitives/src/commitment/pedersen/mod.rs b/primitives/src/commitment/pedersen/mod.rs index df4e73359..ecaaf72c5 100644 --- a/primitives/src/commitment/pedersen/mod.rs +++ b/primitives/src/commitment/pedersen/mod.rs @@ -58,7 +58,6 @@ impl CommitmentScheme for PedersenC type Output = G; fn setup(rng: &mut R) -> Result { - let time = start_timer!(|| format!( "PedersenCOMM::Setup: {} {}-bit windows; {{0,1}}^{{{}}} -> G", W::NUM_WINDOWS, @@ -81,7 +80,6 @@ impl CommitmentScheme for PedersenC input: &[u8], randomness: &Self::Randomness, ) -> Result { - let commit_time = start_timer!(|| "PedersenCOMM::Commit"); // Invoke Pedersen CRH here, to prevent code duplication. diff --git a/primitives/src/crh/bowe_hopwood/mod.rs b/primitives/src/crh/bowe_hopwood/mod.rs index 6172461b6..12f66499b 100644 --- a/primitives/src/crh/bowe_hopwood/mod.rs +++ b/primitives/src/crh/bowe_hopwood/mod.rs @@ -49,7 +49,6 @@ impl BoweHopwoodPedersenParameters { } impl BoweHopwoodPedersenCRH { - pub fn check_setup_preconditions(maximum_num_chunks_in_segment: usize) -> Result<(), Error> { assert_eq!(CHUNK_SIZE, 3); @@ -70,7 +69,7 @@ impl BoweHopwoodPedersenCRH BoweHopwoodPedersenCRH) -> Result<(), Error> { - Self::check_setup_preconditions(params.maximum_num_chunks_in_segment)?; if params.generators.len() != W::NUM_WINDOWS { @@ -108,8 +106,11 @@ impl BoweHopwoodPedersenCRH>) -> Result<::Parameters, Error> { - let maximum_num_chunks_in_segment = BoweHopwoodPedersenParameters::::calculate_num_chunks_in_segment::(); + pub fn setup_from_generators( + generators: Vec>, + ) -> Result<::Parameters, Error> { + let maximum_num_chunks_in_segment = + BoweHopwoodPedersenParameters::::calculate_num_chunks_in_segment::(); let parameters = BoweHopwoodPedersenParameters { generators, maximum_num_chunks_in_segment, @@ -139,13 +140,16 @@ impl BoweHopwoodPedersenCRH FixedLengthCRH for BoweHopwoodPedersenCRH { +impl FixedLengthCRH + for BoweHopwoodPedersenCRH +{ const INPUT_SIZE_BITS: usize = N * 8; type Output = G; type Parameters = BoweHopwoodPedersenParameters; fn setup(rng: &mut R) -> Result { - let maximum_num_chunks_in_segment = Self::Parameters::calculate_num_chunks_in_segment::(); + let maximum_num_chunks_in_segment = + Self::Parameters::calculate_num_chunks_in_segment::(); Self::check_setup_preconditions(maximum_num_chunks_in_segment)?; let time = start_timer!(|| format!( @@ -156,12 +160,10 @@ impl FixedLengthCRH for BoweHopwood )); let generators = Self::create_generators(rng); end_timer!(time); - Ok( - Self::Parameters { - generators, - maximum_num_chunks_in_segment, - } - ) + Ok(Self::Parameters { + generators, + maximum_num_chunks_in_segment, + }) } fn evaluate(parameters: &Self::Parameters, input: &[u8]) -> Result { @@ -173,12 +175,7 @@ impl FixedLengthCRH for BoweHopwood // Check fixed size input if input.len() != N { return Err(Box::new(CryptoError::Other( - format!( - "incorrect input length {:?} expected {:?}", - input.len(), - N, - ) - .to_owned(), + format!("incorrect input length {:?} expected {:?}", input.len(), N,).to_owned(), ))); } @@ -266,7 +263,8 @@ mod test { const WINDOW_SIZE: usize = 63; const NUM_WINDOWS: usize = 2; } - const TEST_CORRECT_INPUT_LENGTH: usize = (TestWindow::WINDOW_SIZE * TestWindow::NUM_WINDOWS * CHUNK_SIZE)/8; + const TEST_CORRECT_INPUT_LENGTH: usize = + (TestWindow::WINDOW_SIZE * TestWindow::NUM_WINDOWS * CHUNK_SIZE) / 8; #[derive(Clone)] struct WrongTestWindow {} @@ -274,7 +272,8 @@ mod test { const WINDOW_SIZE: usize = 66; const NUM_WINDOWS: usize = 2; } - const TEST_WRONG_INPUT_LENGTH: usize = (WrongTestWindow::WINDOW_SIZE * WrongTestWindow::NUM_WINDOWS * CHUNK_SIZE)/8; + const TEST_WRONG_INPUT_LENGTH: usize = + (WrongTestWindow::WINDOW_SIZE * WrongTestWindow::NUM_WINDOWS * CHUNK_SIZE) / 8; #[test] fn regression() { @@ -287,8 +286,11 @@ mod test { as FixedLengthCRH>::setup(rng) .unwrap(); - assert_eq!(params.maximum_num_chunks_in_segment, EXPECTED_MAX_WINDOW_SIZE); - + assert_eq!( + params.maximum_num_chunks_in_segment, + EXPECTED_MAX_WINDOW_SIZE + ); + assert_eq!( hex::encode( to_bytes!( @@ -296,8 +298,10 @@ mod test { ¶ms, &[1, 2, 3], ).unwrap() - ).unwrap() - ).as_str(), + ) + .unwrap() + ) + .as_str(), EXPECTED_RESULT ); } @@ -326,7 +330,9 @@ mod test { #[test] fn test_wrong_params_in_evaluate() { let rng = &mut thread_rng(); - let params = as FixedLengthCRH>::setup(rng).unwrap(); + let params = + as FixedLengthCRH>::setup(rng) + .unwrap(); // Wrong window parameters for given input size assert!( @@ -386,6 +392,5 @@ mod test { .to_string() .contains("incorrect input length") ); - } } diff --git a/primitives/src/crh/pedersen/mod.rs b/primitives/src/crh/pedersen/mod.rs index 1eadc37cd..a0147c10f 100644 --- a/primitives/src/crh/pedersen/mod.rs +++ b/primitives/src/crh/pedersen/mod.rs @@ -46,7 +46,6 @@ impl PedersenCRH { } pub fn check_setup_preconditions() -> Result<(), Error> { - if Self::INPUT_SIZE_BITS > W::WINDOW_SIZE * W::NUM_WINDOWS { return Err(Box::new(CryptoError::Other( format!( @@ -58,12 +57,11 @@ impl PedersenCRH { .to_owned(), ))); } - + Ok(()) } pub fn check_preconditions(params: &PedersenParameters) -> Result<(), Error> { - Self::check_setup_preconditions()?; if params.generators.len() != W::NUM_WINDOWS { @@ -115,18 +113,12 @@ impl FixedLengthCRH for PedersenCRH } fn evaluate(parameters: &Self::Parameters, input: &[u8]) -> Result { - Self::check_preconditions(parameters)?; // Check fixed size input if input.len() != N { return Err(Box::new(CryptoError::Other( - format!( - "incorrect input length {:?} expected {:?}", - input.len(), - N, - ) - .to_owned(), + format!("incorrect input length {:?} expected {:?}", input.len(), N,).to_owned(), ))); } diff --git a/primitives/src/merkle_tree/field_based_mht/append_only/mod.rs b/primitives/src/merkle_tree/field_based_mht/append_only/mod.rs index 2ed19fab6..3b3a72b1c 100644 --- a/primitives/src/merkle_tree/field_based_mht/append_only/mod.rs +++ b/primitives/src/merkle_tree/field_based_mht/append_only/mod.rs @@ -1,3 +1,4 @@ +use crate::merkle_tree::NoPreComputedHashForFieldBasedMerkleTreeParameters; use crate::{ check_precomputed_parameters, BatchFieldBasedHash, BatchFieldBasedMerkleTreeParameters, Error, FieldBasedHash, FieldBasedHashParameters, FieldBasedMHTPath, FieldBasedMerkleTree, @@ -5,7 +6,6 @@ use crate::{ }; use algebra::{serialize::*, Field}; use std::marker::PhantomData; -use crate::merkle_tree::NoPreComputedHashForFieldBasedMerkleTreeParameters; /// An implementation of FieldBasedMerkleTree, optimized in time and memory, /// and able to support any BatchFieldBasedHash and Merkle arity. @@ -45,7 +45,6 @@ impl FieldBasedAppendOnlyMHT { /// `primitives/src/benches/poseidon_mht.rs` to properly tune the `processing_step` /// parameter according to your use case. pub fn init(height: usize, processing_step: usize) -> Result { - if !check_precomputed_parameters::(height) { Err(Box::new(MerkleTreeError::Other( format!( @@ -61,10 +60,13 @@ impl FieldBasedAppendOnlyMHT { // is reasonable and simplify the design. assert_eq!(rate, T::MERKLE_ARITY); - let last_level_size = T::MERKLE_ARITY.checked_pow(height as u32) - .ok_or(MerkleTreeError::Other( - "Integer overflow when building FieldBasedAppendOnlyMHT: height too big".to_string() - ))?; + let last_level_size = + T::MERKLE_ARITY + .checked_pow(height as u32) + .ok_or(MerkleTreeError::Other( + "Integer overflow when building FieldBasedAppendOnlyMHT: height too big" + .to_string(), + ))?; if processing_step == 0 || processing_step > last_level_size { Err(Box::new(MerkleTreeError::Other( format!( @@ -198,9 +200,11 @@ impl FieldBasedAppendOnlyMHT { parent_level: usize, ) -> Result<(), Error> { let mut i = 0; - let empty = T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[parent_level - 1]; + let empty = T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[parent_level - 1]; // Stores the chunk that must be hashed, i.e. the ones containing at least one non-empty node let mut to_hash = Vec::new(); @@ -213,15 +217,17 @@ impl FieldBasedAppendOnlyMHT { // therefore we already have the output, otherwise it must be computed. for input_chunk in input.chunks(T::MERKLE_ARITY) { if input_chunk.iter().all(|&item| item == empty) { - output[i] = T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[parent_level]; + output[i] = T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[parent_level]; } else { to_hash.extend_from_slice(input_chunk); output_pos.push(i); } i += 1; - }; + } // Compute the hash of the non-all-empty chunks if to_hash.len() != 0 { @@ -293,7 +299,10 @@ impl FieldBasedMerkleTree for FieldBased copy.new_elem_pos[0] = copy.final_pos[0]; copy.compute_subtree()?; copy.finalized = true; - copy.root = *copy.array_nodes.last().ok_or(MerkleTreeError::EmptyMerkleTree)?; + copy.root = *copy + .array_nodes + .last() + .ok_or(MerkleTreeError::EmptyMerkleTree)?; } Ok(copy) @@ -305,7 +314,10 @@ impl FieldBasedMerkleTree for FieldBased self.new_elem_pos[0] = self.final_pos[0]; self.compute_subtree()?; self.finalized = true; - self.root = *self.array_nodes.last().ok_or(MerkleTreeError::EmptyMerkleTree)?; + self.root = *self + .array_nodes + .last() + .ok_or(MerkleTreeError::EmptyMerkleTree)?; } Ok(self) } @@ -336,23 +348,28 @@ impl FieldBasedMerkleTree for FieldBased } fn get_merkle_path(&self, leaf_index: usize) -> Option { - let num_leaves = T::MERKLE_ARITY.checked_pow(self.height as u32) + let num_leaves = T::MERKLE_ARITY + .checked_pow(self.height as u32) .ok_or(MerkleTreeError::Other( - "Integer overflow in FieldBasedAppendOnlyMHT: height too big".to_string() - )).unwrap(); + "Integer overflow in FieldBasedAppendOnlyMHT: height too big".to_string(), + )) + .unwrap(); if leaf_index as usize >= num_leaves { - eprintln!( + log::error!( "Invalid leaf index {} for num leaves {}", - leaf_index, num_leaves + leaf_index, + num_leaves ); return None; } match self.finalized { true => { - let num_leaves = T::MERKLE_ARITY.checked_pow(self.height as u32) + let num_leaves = T::MERKLE_ARITY + .checked_pow(self.height as u32) .ok_or(MerkleTreeError::Other( - "Integer overflow in FieldBasedAppendOnlyMHT: height too big".to_string() - )).unwrap(); + "Integer overflow in FieldBasedAppendOnlyMHT: height too big".to_string(), + )) + .unwrap(); let mut merkle_path = Vec::with_capacity(self.height); let mut node_index = leaf_index; @@ -403,7 +420,7 @@ mod test { BatchFieldBasedMerkleTreeParameters, FieldBasedAppendOnlyMHT, FieldBasedMerkleTree, FieldBasedMerkleTreeParameters, FieldBasedMerkleTreePath, NaiveMerkleTree, }, - FieldBasedMHTPath, FieldBasedMerkleTreePrecomputedZeroConstants, + FieldBasedMHTPath, FieldBasedMerkleTreePrecomputedZeroConstants, }; fn merkle_tree_root_test( diff --git a/primitives/src/merkle_tree/field_based_mht/naive/mod.rs b/primitives/src/merkle_tree/field_based_mht/naive/mod.rs index 1e7f03f42..514b20408 100644 --- a/primitives/src/merkle_tree/field_based_mht/naive/mod.rs +++ b/primitives/src/merkle_tree/field_based_mht/naive/mod.rs @@ -27,8 +27,11 @@ pub struct NaiveMerkleTree { impl NaiveMerkleTree

{ pub fn new(height: usize) -> Self { - assert!(check_precomputed_parameters::

(height), "Unsupported height. Max supported height is: {}", - P::ZERO_NODE_CST.unwrap().nodes.len()); + assert!( + check_precomputed_parameters::

(height), + "Unsupported height. Max supported height is: {}", + P::ZERO_NODE_CST.unwrap().nodes.len() + ); NaiveMerkleTree { height, @@ -189,16 +192,18 @@ impl NaiveMerkleTree

{ // Iterate from the leaf up to the root, storing all intermediate hash values. let mut current_node = tree_index; while !is_root(current_node) { - let sibling_node = sibling(current_node).ok_or( - MerkleTreeError::Other("No sibling found for a non-root node".to_owned()))?; + let sibling_node = sibling(current_node).ok_or(MerkleTreeError::Other( + "No sibling found for a non-root node".to_owned(), + ))?; let sibling_hash = self.tree[sibling_node].clone(); if is_left_child(current_node) { path.push((sibling_hash, false)); } else { path.push((sibling_hash, true)); } - current_node = parent(current_node).ok_or( - MerkleTreeError::Other("No parent found for a non-root node".to_owned()))?; + current_node = parent(current_node).ok_or(MerkleTreeError::Other( + "No parent found for a non-root node".to_owned(), + ))?; } if path.len() > self.height { diff --git a/primitives/src/merkle_tree/field_based_mht/path.rs b/primitives/src/merkle_tree/field_based_mht/path.rs index f32124409..18468a745 100644 --- a/primitives/src/merkle_tree/field_based_mht/path.rs +++ b/primitives/src/merkle_tree/field_based_mht/path.rs @@ -159,13 +159,12 @@ impl FieldBasedMerkleTreePath for FieldBasedM fn random(rng: &mut R, height: usize) -> Self { // Generate random path let mut random_path = Vec::with_capacity(height); - + for _ in 0..height { // Generate random siblings - let siblings: Vec = - (0..T::MERKLE_ARITY - 1) - .map(|_| UniformRand::rand(rng)) - .collect(); + let siblings: Vec = (0..T::MERKLE_ARITY - 1) + .map(|_| UniformRand::rand(rng)) + .collect(); // Generate random position let position: usize = rng.gen_range(0..T::MERKLE_ARITY); @@ -173,7 +172,7 @@ impl FieldBasedMerkleTreePath for FieldBasedM // Push both to path random_path.push((siblings, position)); } - + FieldBasedMHTPath::::new(random_path) } } @@ -340,7 +339,7 @@ impl FieldBasedMerkleTreePath for FieldBasedB fn random(rng: &mut R, height: usize) -> Self { // Generate random path let mut random_path = Vec::with_capacity(height); - + for _ in 0..height { // Generate random sibling let sibling: T::Data = UniformRand::rand(rng); @@ -351,7 +350,7 @@ impl FieldBasedMerkleTreePath for FieldBasedB // Push both to path random_path.push((sibling, direction)); } - + FieldBasedBinaryMHTPath::::new(random_path) } } @@ -418,7 +417,6 @@ impl PartialEq> for FieldBasedBinaryMHTPath { fn eq(&self, other: &FieldBasedMHTPath) -> bool { - // Paths must have the same length if self.get_length() != other.get_length() { return false; @@ -427,21 +425,14 @@ impl PartialEq> // Iterate through both paths (NOTE: Could work also converting one of the two paths into // the other type and then calling the corresponding Eq, but you avoid iterating through // both paths again) - for ((sibling, direction), (nodes, position)) in - self - .get_raw_path() - .iter() - .zip( - other - .get_raw_path() - .iter() - ) + for ((sibling, direction), (nodes, position)) in + self.get_raw_path().iter().zip(other.get_raw_path().iter()) { // 'nodes' must be a single element vector equal to 'sibling' if nodes.len() != 1 && sibling != &nodes[0] { return false; } - + // 'position' must be either 0 or 1 and equal (in boolean) to 'direction' if &(*direction as usize) != position { return false; @@ -459,7 +450,10 @@ mod test { use crate::{ crh::{TweedleFrBatchPoseidonHash, TweedleFrPoseidonHash}, - merkle_tree::TWEEDLE_DEE_MHT_POSEIDON_PARAMETERS, FieldBasedMerkleTreeParameters, FieldBasedMerkleTreePrecomputedZeroConstants, BatchFieldBasedMerkleTreeParameters, FieldBasedMHTPath, FieldBasedBinaryMHTPath, FieldBasedMerkleTreePath, + merkle_tree::TWEEDLE_DEE_MHT_POSEIDON_PARAMETERS, + BatchFieldBasedMerkleTreeParameters, FieldBasedBinaryMHTPath, FieldBasedMHTPath, + FieldBasedMerkleTreeParameters, FieldBasedMerkleTreePath, + FieldBasedMerkleTreePrecomputedZeroConstants, }; use algebra::fields::tweedle::Fr; use rand::SeedableRng; @@ -484,8 +478,7 @@ mod test { #[test] fn test_path_eq_operators_tweedle_fr() { - - let rng= &mut XorShiftRng::seed_from_u64(1231275789u64); + let rng = &mut XorShiftRng::seed_from_u64(1231275789u64); let height1 = 10; let height2 = 11; @@ -494,7 +487,7 @@ mod test { let path1 = TestPath::random(rng, height1); let path2 = TestPath::random(rng, height1); let path3 = TestPath::random(rng, height2); - + assert_eq!(path1, path1); assert_ne!(path1, path2); assert_ne!(path1, path3); @@ -504,7 +497,7 @@ mod test { let binary_path1: TestBinaryPath = path1.clone().try_into().unwrap(); let binary_path2: TestBinaryPath = path2.clone().try_into().unwrap(); let binary_path3: TestBinaryPath = path3.clone().try_into().unwrap(); - + assert_eq!(binary_path1, binary_path1); assert_ne!(binary_path1, binary_path2); assert_ne!(binary_path1, binary_path3); @@ -515,10 +508,8 @@ mod test { assert_ne!(binary_path1, path2); assert_ne!(binary_path1, path3); assert_ne!(binary_path2, path3); - + assert_eq!(binary_path2 != path2, false); assert_eq!(binary_path1 == path2, false); - } - -} \ No newline at end of file +} diff --git a/primitives/src/merkle_tree/field_based_mht/smt/big_lazy_merkle_tree.rs b/primitives/src/merkle_tree/field_based_mht/smt/big_lazy_merkle_tree.rs index dd8e5f397..56a2531ff 100644 --- a/primitives/src/merkle_tree/field_based_mht/smt/big_lazy_merkle_tree.rs +++ b/primitives/src/merkle_tree/field_based_mht/smt/big_lazy_merkle_tree.rs @@ -10,8 +10,8 @@ use crate::{ ActionLeaf, Error, FieldBasedMerkleTree, FieldBasedSparseMerkleTree, }; -use std::collections::{HashMap, HashSet}; use crate::merkle_tree::NoPreComputedHashForFieldBasedMerkleTreeParameters; +use std::collections::{HashMap, HashSet}; /// An in-memory, sparse, Merkle Tree with lazy leaves evaluation. /// "Lazy" means that leaves are inserted/removed in batch, and the nodes @@ -59,9 +59,11 @@ impl FieldBasedSparseMHT { // If height is 0 it must not be possible to add any leaf, so we'll set width to 0. let width: u32 = if height != 0 { - T::MERKLE_ARITY.checked_pow(height as u32) + T::MERKLE_ARITY + .checked_pow(height as u32) .ok_or(MerkleTreeError::Other( - "Integer overflow when building FieldBasedSparseMHT: height too big".to_string() + "Integer overflow when building FieldBasedSparseMHT: height too big" + .to_string(), )) .unwrap() as u32 } else { @@ -100,9 +102,13 @@ impl FieldBasedSparseMHT { let leaf = self.leaves.get(&idx); Ok( - leaf.is_none() || leaf.unwrap().0 == T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[0], // Leaf waiting to be removed + leaf.is_none() + || leaf.unwrap().0 + == T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[0], // Leaf waiting to be removed ) } @@ -174,23 +180,24 @@ impl FieldBasedSparseMHT { // Collect leaves to be removed from leaves Map let mut leaves_to_be_removed = Vec::new(); - for (idx, (data, updated)) in self.leaves - .iter_mut() - .filter(|(_, (_, updated))| *updated) + for (idx, (data, updated)) in self.leaves.iter_mut().filter(|(_, (_, updated))| *updated) { + // Collect leaves whose value has changed since previous 'process_leaves' call, and set + // their state to unchanged. + modified_leaves_pos.insert(*idx); + *updated = false; + + // We interpret removal as a leaf with updated state but value set to be empty node. For + // such leaves, we need to actually remove them before proceeding in updating the tree. + if data + == &T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[0] { - // Collect leaves whose value has changed since previous 'process_leaves' call, and set - // their state to unchanged. - modified_leaves_pos.insert(*idx); - *updated = false; - - // We interpret removal as a leaf with updated state but value set to be empty node. For - // such leaves, we need to actually remove them before proceeding in updating the tree. - if data == &T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[0] { - leaves_to_be_removed.push(*idx); - } - }; + leaves_to_be_removed.push(*idx); + } + } nodes_to_recompute_by_level.push(modified_leaves_pos); @@ -353,13 +360,13 @@ impl FieldBasedMerkleTree for FieldBased fn get_merkle_path(&self, idx: u32) -> Option { // if root has changed then we cannot get valid merkle path until we finalize it if self.pending_changes() { - eprintln!("Identified pending changes: unable to get path before pending changes are applied to the tree."); + log::error!("Identified pending changes: unable to get path before pending changes are applied to the tree."); return None; } // check that the index of the leaf is less than the width of the Merkle tree if idx >= self.width { - eprintln!( + log::error!( "Leaf index out of range. Max: {}, got: {}", self.width - 1, idx @@ -434,9 +441,12 @@ impl FieldBasedSparseMerkleTree for Fiel let leaf_to_remove = self.leaves.get(&idx); if matches!(leaf.action, ActionLeaf::Remove) && (leaf_to_remove.is_none() - || leaf_to_remove.unwrap().0 == T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[0]) + || leaf_to_remove.unwrap().0 + == T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[0]) { return Err(MerkleTreeError::IncorrectLeafIndex( idx as usize, @@ -446,15 +456,16 @@ impl FieldBasedSparseMerkleTree for Fiel // For convenience, removal is performed by replacing the leaf value with the empty one, otherwise set it to the proper insertion value let val = if matches!(leaf.action, ActionLeaf::Remove) { - T::ZERO_NODE_CST.ok_or( - MerkleTreeError::from(NoPreComputedHashForFieldBasedMerkleTreeParameters::::new()) - )?.nodes[0] + T::ZERO_NODE_CST + .ok_or(MerkleTreeError::from( + NoPreComputedHashForFieldBasedMerkleTreeParameters::::new(), + ))? + .nodes[0] } else { - leaf.hash.ok_or( - MerkleTreeError::Other( - format!("No hash found in OperationalLeaf {:?}", leaf) - ) - )? + leaf.hash.ok_or(MerkleTreeError::Other(format!( + "No hash found in OperationalLeaf {:?}", + leaf + )))? }; // Update leaves Map accordingly diff --git a/primitives/src/merkle_tree/mod.rs b/primitives/src/merkle_tree/mod.rs index 09223b4e1..56b25257f 100644 --- a/primitives/src/merkle_tree/mod.rs +++ b/primitives/src/merkle_tree/mod.rs @@ -2,8 +2,8 @@ use crate::{crh::FixedLengthCRH, Error}; use algebra::bytes::ToBytes; use serde::{Deserialize, Serialize}; -use std::{fmt, rc::Rc}; use std::marker::PhantomData; +use std::{fmt, rc::Rc}; pub mod field_based_mht; pub use self::field_based_mht::*; @@ -256,16 +256,18 @@ impl MerkleHashTree

{ // Iterate from the leaf up to the root, storing all intermediate hash values. let mut current_node = tree_index; while !is_root(current_node) { - let sibling_node = sibling(current_node).ok_or( - MerkleTreeError::Other("No sibling found for a non-root node".to_owned()))?; + let sibling_node = sibling(current_node).ok_or(MerkleTreeError::Other( + "No sibling found for a non-root node".to_owned(), + ))?; let sibling_hash = self.tree[sibling_node].clone(); if is_left_child(current_node) { path.push((sibling_hash, false)); } else { path.push((sibling_hash, true)); } - current_node = parent(current_node).ok_or( - MerkleTreeError::Other("No parent found for a non-root node".to_owned()))?; + current_node = parent(current_node).ok_or(MerkleTreeError::Other( + "No parent found for a non-root node".to_owned(), + ))?; } if path.len() > Self::HEIGHT as usize { @@ -295,7 +297,7 @@ impl MerkleHashTree

{ // Type to represent the error occurring when trying to use // `FieldBaseDMerkleTreeParameters::ZeroNodeConst` but this const is set to None. // This type can be converted to a `MerkleTreeError` -struct NoPreComputedHashForFieldBasedMerkleTreeParameters{ +struct NoPreComputedHashForFieldBasedMerkleTreeParameters { phantom: PhantomData, } @@ -346,9 +348,14 @@ impl std::error::Error for MerkleTreeError { } } -impl From> for MerkleTreeError { +impl From> + for MerkleTreeError +{ fn from(_: NoPreComputedHashForFieldBasedMerkleTreeParameters) -> Self { - MerkleTreeError::Other(format!("No pre-computed hash for empty node found in {}", std::any::type_name::())) + MerkleTreeError::Other(format!( + "No pre-computed hash for empty node found in {}", + std::any::type_name::() + )) } } diff --git a/primitives/src/signature/schnorr/field_based_schnorr.rs b/primitives/src/signature/schnorr/field_based_schnorr.rs index fc407fc81..afd4f46c1 100644 --- a/primitives/src/signature/schnorr/field_based_schnorr.rs +++ b/primitives/src/signature/schnorr/field_based_schnorr.rs @@ -255,7 +255,7 @@ impl, H: FieldBasedHash // enforce that k != 0 to avoid leaking the secret key if k.is_zero() { - continue + continue; } //R = k * G diff --git a/primitives/src/signature/schnorr/mod.rs b/primitives/src/signature/schnorr/mod.rs index efee11636..8be34dac4 100644 --- a/primitives/src/signature/schnorr/mod.rs +++ b/primitives/src/signature/schnorr/mod.rs @@ -116,7 +116,7 @@ where let random_scalar: G::ScalarField = G::ScalarField::rand(rng); // enforce that `k != 0` to avoid leaking the secret key if random_scalar.is_zero() { - continue + continue; } // Commit to the random scalar via r := k ยท g. // This is the prover's first msg in the Sigma protocol. diff --git a/primitives/src/vrf/ecvrf/mod.rs b/primitives/src/vrf/ecvrf/mod.rs index aa42f8b29..7a592e580 100644 --- a/primitives/src/vrf/ecvrf/mod.rs +++ b/primitives/src/vrf/ecvrf/mod.rs @@ -18,7 +18,7 @@ use std::marker::PhantomData; mod nonce_generation; pub const CHALLENGE_DOMAIN_SEPARATOR: u8 = 2u8; -pub const PROOF_TO_HASH_DOMAIN_SEPARATOR: u8 = 3u8; +pub const PROOF_TO_HASH_DOMAIN_SEPARATOR: u8 = 3u8; pub struct FieldBasedEcVrf { _field: PhantomData, @@ -252,7 +252,7 @@ where fn get_public_key(sk: &Self::SecretKey) -> Self::PublicKey { FieldBasedEcVrfPk(G::prime_subgroup_generator().mul(sk)) } - + // Please note that due to the rejection sampling procedure employed for the nonce k, this // implementation is not constant time, though the timing should not reveal any // sensitive information @@ -289,14 +289,12 @@ where let mut counter = 0u8; let (c, s) = loop { //Choose random scalar - let r = Self::generate_nonce( - sk, message_on_curve, &vec![counter] - ); + let r = Self::generate_nonce(sk, message_on_curve, &vec![counter]); counter += 1; // enforce that `r != 0` to avoid leaking the secret key if r.is_zero() { - continue + continue; } //Compute a = g^r @@ -306,7 +304,8 @@ where let b = message_on_curve.mul(&r); //Compute c = H(CHALLENGE_DOMAIN_SEPARATOR||m||pk||gamma||a||b) - let hash_input = vec![FH::Data::from(CHALLENGE_DOMAIN_SEPARATOR as u128), message].into_iter() + let hash_input = vec![FH::Data::from(CHALLENGE_DOMAIN_SEPARATOR as u128), message] + .into_iter() .chain(pk.0.to_field_elements()?) .chain(gamma.to_field_elements()?) .chain(a.to_field_elements()?.into_iter()) @@ -315,9 +314,10 @@ where let c = { let mut digest = FH::init_constant_length(hash_input.len(), None); - hash_input.into_iter().fold(&mut digest, |digest, input| - digest.update(input) - ).finalize() + hash_input + .into_iter() + .fold(&mut digest, |digest, input| digest.update(input)) + .finalize() }?; let c_bits = c.write_bits(); @@ -370,7 +370,8 @@ where let v = message_on_curve.mul(&s_conv) - &proof.gamma.mul(&c_conv); //Compute c' = H(CHALLENGE_DOMAIN_SEPARATOR||m||pk||gamma||u||v) - let hash_input = vec![FH::Data::from(CHALLENGE_DOMAIN_SEPARATOR as u128), message].into_iter() + let hash_input = vec![FH::Data::from(CHALLENGE_DOMAIN_SEPARATOR as u128), message] + .into_iter() .chain(pk.0.to_field_elements()?.into_iter()) .chain(proof.gamma.to_field_elements()?.into_iter()) .chain(u.to_field_elements()?.into_iter()) @@ -379,35 +380,35 @@ where let c_prime = { let mut digest = FH::init_constant_length(hash_input.len(), None); - hash_input.into_iter().fold(&mut digest, |digest, input| - digest.update(input) - ).finalize() + hash_input + .into_iter() + .fold(&mut digest, |digest, input| digest.update(input)) + .finalize() }?; //Verify valid proof match proof.c == c_prime { false => Err(Box::new(CryptoError::FailedVerification)), - true => Self::proof_to_hash(message, proof) + true => Self::proof_to_hash(message, proof), } } - fn proof_to_hash( - message: Self::Data, - proof: &Self::Proof - ) -> Result { + fn proof_to_hash(message: Self::Data, proof: &Self::Proof) -> Result { let hash_input = vec![ FH::Data::from(PROOF_TO_HASH_DOMAIN_SEPARATOR as u128), message, - ].into_iter().chain( - proof.gamma.to_field_elements()?.into_iter() - ).collect::>(); + ] + .into_iter() + .chain(proof.gamma.to_field_elements()?.into_iter()) + .collect::>(); //Compute VRF output let output = { let mut digest = FH::init_constant_length(hash_input.len(), None); - hash_input.into_iter().fold(&mut digest, |digest, input| - digest.update(input) - ).finalize() + hash_input + .into_iter() + .fold(&mut digest, |digest, input| digest.update(input)) + .finalize() }?; //Return VRF output @@ -429,12 +430,15 @@ mod test { vrf::{ecvrf::FieldBasedEcVrf, FieldBasedVrf}, FixedLengthCRH, }; - use algebra::{curves::{ - mnt4753::G1Projective as MNT4G1Projective, mnt6753::G1Projective as MNT6G1Projective, - }, FpParameters}; use algebra::fields::{ mnt4753::fr::{Fr as MNT4Fr, FrParameters as MNT4FrParameters}, - mnt6753::fr::{Fr as MNT6Fr, FrParameters as MNT6FrParameters} + mnt6753::fr::{Fr as MNT6Fr, FrParameters as MNT6FrParameters}, + }; + use algebra::{ + curves::{ + mnt4753::G1Projective as MNT4G1Projective, mnt6753::G1Projective as MNT6G1Projective, + }, + FpParameters, }; use algebra::{to_bytes, FromBytes, FromBytesChecked, SemanticallyValid, ToBytes}; use rand::{thread_rng, Rng}; @@ -446,8 +450,10 @@ mod test { const NUM_WINDOWS: usize = 2; } - const BHMNT4_INPUT_SIZE: usize = ((MNT6FrParameters::MODULUS_BITS + MNT6FrParameters::REPR_SHAVE_BITS)/8) as usize; - const BHMNT6_INPUT_SIZE: usize = ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS)/8) as usize; + const BHMNT4_INPUT_SIZE: usize = + ((MNT6FrParameters::MODULUS_BITS + MNT6FrParameters::REPR_SHAVE_BITS) / 8) as usize; + const BHMNT6_INPUT_SIZE: usize = + ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS) / 8) as usize; type BHMNT4 = BoweHopwoodPedersenCRH; type BHMNT6 = BoweHopwoodPedersenCRH; diff --git a/primitives/src/vrf/ecvrf/nonce_generation.rs b/primitives/src/vrf/ecvrf/nonce_generation.rs index 30cd6cc5f..dcaad590d 100644 --- a/primitives/src/vrf/ecvrf/nonce_generation.rs +++ b/primitives/src/vrf/ecvrf/nonce_generation.rs @@ -1,17 +1,11 @@ +use super::FieldBasedEcVrf; +use crate::{FieldBasedHash, FixedLengthCRH}; +use algebra::{to_bytes, Field, PrimeField, ProjectiveCurve, ToBytes, ToConstraintField}; use hmac::{ - Hmac, - Mac, - digest::{ - Input, - BlockInput, - generic_array::GenericArray, - FixedOutput, Reset, - }, + digest::{generic_array::GenericArray, BlockInput, FixedOutput, Input, Reset}, + Hmac, Mac, }; use sha2::Sha256; -use algebra::{Field, PrimeField, ProjectiveCurve, to_bytes, ToConstraintField, ToBytes}; -use crate::{FieldBasedHash, FixedLengthCRH}; -use super::FieldBasedEcVrf; /* Implementation of HMacDrbg taken from rfc6979 crate, since such crate cannot currently be used as a @@ -21,8 +15,8 @@ algorithm found in RFC6979 (Section 3.2). */ struct HmacDrbg - where - D: Input + BlockInput + FixedOutput + Reset + Default + Clone, +where + D: Input + BlockInput + FixedOutput + Reset + Default + Clone, { /// HMAC key `K` (see RFC 6979 Section 3.2.c) k: Hmac, @@ -32,8 +26,8 @@ struct HmacDrbg } impl HmacDrbg - where - D: Input + BlockInput + FixedOutput + Reset + Default + Clone, +where + D: Input + BlockInput + FixedOutput + Reset + Default + Clone, { /// Initialize `HMAC_DRBG` fn new(entropy_input: &[u8], nonce: &[u8], additional_data: &[u8]) -> Self { @@ -70,36 +64,40 @@ impl HmacDrbg self.k.input(&self.v); self.k.input(&[0x00]); - self.k = - Hmac::new_varkey(&self.k.result_reset().code()).expect("HMAC error"); + self.k = Hmac::new_varkey(&self.k.result_reset().code()).expect("HMAC error"); self.k.input(&self.v); self.v = self.k.result_reset().code(); } } impl FieldBasedEcVrf - where - F: PrimeField, - G: ProjectiveCurve + ToConstraintField, - FH: FieldBasedHash, - GH: FixedLengthCRH, +where + F: PrimeField, + G: ProjectiveCurve + ToConstraintField, + FH: FieldBasedHash, + GH: FixedLengthCRH, { // Deterministic generation of the nonce employed to generate a VRF prove. // The generation is performed according to RFC6979#Section 3.2, taking into account the // variant reported in Section 3.6 which allows the usage of additional data - pub(super) fn generate_nonce(secret_key: &G::ScalarField, message_hash: G, additional_data: &[u8]) -> G::ScalarField { - let mut hmac = HmacDrbg::::new(to_bytes!(secret_key).unwrap().as_slice(), - to_bytes!(message_hash).unwrap().as_slice(), - additional_data, + pub(super) fn generate_nonce( + secret_key: &G::ScalarField, + message_hash: G, + additional_data: &[u8], + ) -> G::ScalarField { + let mut hmac = HmacDrbg::::new( + to_bytes!(secret_key).unwrap().as_slice(), + to_bytes!(message_hash).unwrap().as_slice(), + additional_data, ); - let mut nonce_bytes = vec![0u8; (F::size_in_bits() + 8 - 1)/8]; + let mut nonce_bytes = vec![0u8; (F::size_in_bits() + 8 - 1) / 8]; loop { hmac.fill_bytes(nonce_bytes.as_mut_slice()); let nonce = match G::ScalarField::from_random_bytes(nonce_bytes.as_slice()) { Some(nonce) => nonce, - None => continue + None => continue, }; // check that the generated nonce is a non-zero field element @@ -107,16 +105,16 @@ impl FieldBasedEcVrf continue; } - break nonce + break nonce; } } } #[cfg(test)] -mod test{ +mod test { use super::{HmacDrbg, Sha256}; - fn decode_hex(input: &str) -> Vec { + fn decode_hex(input: &str) -> Vec { (0..input.len()) .step_by(2) .map(|i| u8::from_str_radix(&input[i..i + 2], 16).unwrap()) @@ -135,14 +133,22 @@ mod test{ hmac.fill_bytes(nonce_bytes.as_mut_slice()); let mut nonce_string = "".to_owned(); - nonce_bytes.iter().for_each( - |b| nonce_string.push_str(format!("{:02X}", b).as_str()) - ); + nonce_bytes + .iter() + .for_each(|b| nonce_string.push_str(format!("{:02X}", b).as_str())); nonce_string }; - assert_eq!(compute_next_output(), "9305A46DE7FF8EB107194DEBD3FD48AA20D5E7656CBE0EA69D2A8D4E7C67314A"); - assert_eq!(compute_next_output(), "C70C78608A3B5BE9289BE90EF6E81A9E2C1516D5751D2F75F50033E45F73BDEB"); - assert_eq!(compute_next_output(), "475E80E992140567FCC3A50DAB90FE84BCD7BB03638E9C4656A06F37F6508A7C"); + assert_eq!( + compute_next_output(), + "9305A46DE7FF8EB107194DEBD3FD48AA20D5E7656CBE0EA69D2A8D4E7C67314A" + ); + assert_eq!( + compute_next_output(), + "C70C78608A3B5BE9289BE90EF6E81A9E2C1516D5751D2F75F50033E45F73BDEB" + ); + assert_eq!( + compute_next_output(), + "475E80E992140567FCC3A50DAB90FE84BCD7BB03638E9C4656A06F37F6508A7C" + ); } - -} \ No newline at end of file +} diff --git a/primitives/src/vrf/mod.rs b/primitives/src/vrf/mod.rs index dffbd9984..ba929728c 100644 --- a/primitives/src/vrf/mod.rs +++ b/primitives/src/vrf/mod.rs @@ -60,10 +60,7 @@ pub trait FieldBasedVrf { ) -> Result; /// Compute VRF Output from the proof and the input message - fn proof_to_hash( - message: Self::Data, - proof: &Self::Proof, - ) -> Result; + fn proof_to_hash(message: Self::Data, proof: &Self::Proof) -> Result; fn keyverify(pk: &Self::PublicKey) -> bool; } diff --git a/proof-systems/Cargo.toml b/proof-systems/Cargo.toml index a96748f23..543c9b907 100644 --- a/proof-systems/Cargo.toml +++ b/proof-systems/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "proof-systems" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", @@ -44,6 +44,8 @@ byteorder = { version = "1.4.3" } digest = { version = "0.8.1", optional = true } serde = { version = "1.0.130", features = ["derive"] } derivative = { version = "2.2.0", optional = true } +log = { version = "0.4.0", features = ["std"] } + [dev-dependencies] csv = { version = "1.1.6" } diff --git a/proof-systems/src/darlin/proof_aggregator.rs b/proof-systems/src/darlin/proof_aggregator.rs index 0cb46e35c..fb7e81ec4 100644 --- a/proof-systems/src/darlin/proof_aggregator.rs +++ b/proof-systems/src/darlin/proof_aggregator.rs @@ -36,7 +36,22 @@ where { let accumulators_time = start_timer!(|| "Compute accumulators"); - if pcds.is_empty() || vks.is_empty() || pcds.len() != vks.len() { + if pcds.is_empty() { + log::error!("No proof to aggregate"); + return Err(None); + } + + if vks.is_empty() { + log::error!("No vk specified"); + return Err(None); + } + + if pcds.len() != vks.len() { + log::error!( + "Proofs and vks length mismatch. Proofs: {}, Vks: {}", + pcds.len(), + vks.len() + ); return Err(None); } @@ -54,7 +69,14 @@ where // No need to trim the vk here to the specific segment size used // to generate the proof for this pcd, as the IPA succinct_check // function doesn't use vk.comm_key at all. - pcd.succinct_verify(&vk).map_err(|_| i) + pcd.succinct_verify(&vk).map_err(|e| { + log::error!( + "Failed verification (succint part) for proof with index {}: {:?}", + i, + e + ); + i + }) }) .partition(Result::is_ok); end_timer!(accumulators_time); @@ -114,7 +136,8 @@ where } else { Some( DLogItemAccumulator::::accumulate_items(g1_ck, accs_g1) - .map_err(|_| { + .map_err(|e| { + log::error!("Error during accumulation of proofs over G1: {:?}", e); end_timer!(accumulation_time); None })? @@ -127,7 +150,8 @@ where } else { Some( DLogItemAccumulator::::accumulate_items(g2_ck, accs_g2) - .map_err(|_| { + .map_err(|e| { + log::error!("Error during accumulation of proofs over G2: {:?}", e); end_timer!(accumulation_time); None })? @@ -180,7 +204,11 @@ where accumulation_proof_g1.as_ref().unwrap(), rng, ) - .map_err(|_| { + .map_err(|e| { + log::error!( + "Error during verification (hard part) of accumulated proof over G1: {:?}", + e + ); end_timer!(verification_time); None })? @@ -198,7 +226,11 @@ where accumulation_proof_g2.as_ref().unwrap(), rng, ) - .map_err(|_| { + .map_err(|e| { + log::error!( + "Error during verification (hard part) of accumulated proof over G2: {:?}", + e + ); end_timer!(verification_time); None })? @@ -231,7 +263,6 @@ where + ToConstraintField<::ScalarField>, { let verification_time = start_timer!(|| "Batch verify proofs"); - // Do the succinct verification of the PCDs and get their accumulators let (accs_g1, accs_g2) = get_accumulators::(pcds, vks, g1_vk, g2_vk).map_err(|e| { @@ -243,7 +274,11 @@ where let result_g1 = if accs_g1.is_empty() { true } else { - DLogItemAccumulator::::check_items::(g1_vk, &accs_g1, rng).map_err(|_| { + DLogItemAccumulator::::check_items::(g1_vk, &accs_g1, rng).map_err(|e| { + log::error!( + "Error during batch verification (hard part) of proofs over G1: {:?}", + e + ); end_timer!(verification_time); None })? @@ -252,7 +287,11 @@ where let result_g2 = if accs_g2.is_empty() { true } else { - DLogItemAccumulator::::check_items::(g2_vk, &accs_g2, rng).map_err(|_| { + DLogItemAccumulator::::check_items::(g2_vk, &accs_g2, rng).map_err(|e| { + log::error!( + "Error during batch verification (hard part) of proofs over G2: {:?}", + e + ); end_timer!(verification_time); None })? diff --git a/proof-systems/src/gm17/tests/mimc.rs b/proof-systems/src/gm17/tests/mimc.rs index 5589de8b5..ae6e5a7e8 100644 --- a/proof-systems/src/gm17/tests/mimc.rs +++ b/proof-systems/src/gm17/tests/mimc.rs @@ -32,11 +32,7 @@ use rand::{thread_rng, Rng}; use std::time::{Duration, Instant}; // Bring in some tools for using pairing-friendly curves -use algebra::{ - curves::bls12_381::Bls12_381, - fields::bls12_381::fr::Fr, - Field -}; +use algebra::{curves::bls12_381::Bls12_381, fields::bls12_381::fr::Fr, Field}; // We're going to use the BLS12-381 pairing-friendly elliptic curve. @@ -78,8 +74,8 @@ fn mimc(mut xl: F, mut xr: F, constants: &[F]) -> F { /// This is our demo circuit for proving knowledge of the /// preimage of a MiMC hash invocation. struct MiMCDemo<'a, F: Field> { - xl: Option, - xr: Option, + xl: Option, + xr: Option, constants: &'a [F], } @@ -87,7 +83,10 @@ struct MiMCDemo<'a, F: Field> { /// is used during paramgen and proving in order to /// synthesize the constraint system. impl<'a, F: Field> ConstraintSynthesizer for MiMCDemo<'a, F> { - fn generate_constraints>(self, cs: &mut CS) -> Result<(), SynthesisError> { + fn generate_constraints>( + self, + cs: &mut CS, + ) -> Result<(), SynthesisError> { assert_eq!(self.constants.len(), MIMC_ROUNDS); // Allocate the first component of the preimage. @@ -189,8 +188,8 @@ fn test_mimc_groth_maller_17() { // Create parameters for our circuit let params = { let c = MiMCDemo:: { - xl: None, - xr: None, + xl: None, + xr: None, constants: &constants, }; @@ -224,8 +223,8 @@ fn test_mimc_groth_maller_17() { // Create an instance of our circuit (with the // witness) let c = MiMCDemo { - xl: Some(xl), - xr: Some(xr), + xl: Some(xl), + xr: Some(xr), constants: &constants, }; diff --git a/proof-systems/src/groth16/r1cs_to_qap.rs b/proof-systems/src/groth16/r1cs_to_qap.rs index 6ec2b7e06..acaca5191 100644 --- a/proof-systems/src/groth16/r1cs_to_qap.rs +++ b/proof-systems/src/groth16/r1cs_to_qap.rs @@ -145,9 +145,9 @@ impl R1CStoQAP { .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; let domain_size = domain.size(); /* - println!("num_constraints: {}", num_constraints); - println!("num_inputs: {}", num_inputs); - println!("Domain H size: {}", domain_size); + println!("num_constraints: {}", num_constraints); + println!("num_inputs: {}", num_inputs); + println!("Domain H size: {}", domain_size); */ let mut a = vec![zero; domain_size]; let mut b = vec![zero; domain_size]; diff --git a/proof-systems/src/groth16/tests/mimc.rs b/proof-systems/src/groth16/tests/mimc.rs index 652449173..11fc50138 100644 --- a/proof-systems/src/groth16/tests/mimc.rs +++ b/proof-systems/src/groth16/tests/mimc.rs @@ -74,8 +74,8 @@ fn mimc(mut xl: F, mut xr: F, constants: &[F]) -> F { /// This is our demo circuit for proving knowledge of the /// preimage of a MiMC hash invocation. struct MiMCDemo<'a, F: Field> { - xl: Option, - xr: Option, + xl: Option, + xr: Option, constants: &'a [F], } @@ -188,8 +188,8 @@ fn test_mimc_groth_16() { // Create parameters for our circuit let params = { let c = MiMCDemo:: { - xl: None, - xr: None, + xl: None, + xr: None, constants: &constants, }; @@ -223,8 +223,8 @@ fn test_mimc_groth_16() { // Create an instance of our circuit (with the // witness) let c = MiMCDemo { - xl: Some(xl), - xr: Some(xr), + xl: Some(xl), + xr: Some(xr), constants: &constants, }; diff --git a/proof-systems/src/lib.rs b/proof-systems/src/lib.rs index 6af219cdf..ed31f03d5 100644 --- a/proof-systems/src/lib.rs +++ b/proof-systems/src/lib.rs @@ -19,7 +19,6 @@ clippy::many_single_char_names )] - #[macro_use] extern crate bench_utils; diff --git a/proof-systems/src/marlin/Cargo.toml b/proof-systems/src/marlin/Cargo.toml index c59fc48e0..d749536c1 100644 --- a/proof-systems/src/marlin/Cargo.toml +++ b/proof-systems/src/marlin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "marlin" -version = "0.6.0" +version = "0.6.1" authors = [ "Alessandro Chiesa ", "Mary Maller ", @@ -43,6 +43,7 @@ rayon = { version = "1.5.1" } rayon-core = { version = "1.9.1" } digest = { version = "0.8.1" } derivative = { version = "2.2.0", features = ["use_core"] } +log = { version = "0.4.0", features = ["std"] } [dev-dependencies] algebra = { path = "../../../algebra", features = ["tweedle", "derive"] } diff --git a/proof-systems/src/marlin/src/ahp/indexer.rs b/proof-systems/src/marlin/src/ahp/indexer.rs index f3e8e6b38..e80105f4f 100644 --- a/proof-systems/src/marlin/src/ahp/indexer.rs +++ b/proof-systems/src/marlin/src/ahp/indexer.rs @@ -243,13 +243,13 @@ impl AHPForR1CS { let nnz = num_non_zero(&mut ics); if num_constraints != num_formatted_input_variables + num_witness_variables { - eprintln!( + log::error!( "number of (formatted) input_variables: {}", num_formatted_input_variables ); - eprintln!("number of witness_variables: {}", num_witness_variables); - eprintln!("number of num_constraints: {}", num_constraints); - eprintln!("number of num_non_zero: {}", num_non_zero(&mut ics)); + log::error!("number of witness_variables: {}", num_witness_variables); + log::error!("number of num_constraints: {}", num_constraints); + log::error!("number of num_non_zero: {}", num_non_zero(&mut ics)); return Err(Error::NonSquareMatrix); } diff --git a/proof-systems/src/marlin/src/lib.rs b/proof-systems/src/marlin/src/lib.rs index 00d0294c8..9e5173e0c 100644 --- a/proof-systems/src/marlin/src/lib.rs +++ b/proof-systems/src/marlin/src/lib.rs @@ -364,7 +364,7 @@ impl, D: Digest> Marlin { if ahp_result.is_err() { end_timer!(verifier_time); - eprintln!("AHP Verification failed: {:?}", ahp_result.err()); + log::error!("AHP Verification failed: {:?}", ahp_result.err()); return Ok(false); } @@ -382,7 +382,7 @@ impl, D: Digest> Marlin { if opening_result.is_err() { end_timer!(verifier_time); - eprintln!( + log::error!( "Opening proof Verification failed: {:?}", opening_result.err() ); diff --git a/proof-systems/src/poly-commit/Cargo.toml b/proof-systems/src/poly-commit/Cargo.toml index a3399a6f9..d595d6493 100644 --- a/proof-systems/src/poly-commit/Cargo.toml +++ b/proof-systems/src/poly-commit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poly-commit" -version = "0.6.0" +version = "0.6.1" authors = [ "Alessandro Chiesa ", "Mary Maller ", @@ -44,6 +44,7 @@ digest = "0.8.1" rayon = { version = "1.5.1" } rayon-core = { version = "1.9.1" } derivative = { version = "2.2.0" } +log = { version = "0.4.0", features = ["std"] } [dev-dependencies] algebra = { path = "../../../algebra", features = [ diff --git a/proof-systems/src/poly-commit/src/ipa_pc/data_structures.rs b/proof-systems/src/poly-commit/src/ipa_pc/data_structures.rs index b673d1cae..37326bd60 100644 --- a/proof-systems/src/poly-commit/src/ipa_pc/data_structures.rs +++ b/proof-systems/src/poly-commit/src/ipa_pc/data_structures.rs @@ -457,7 +457,7 @@ impl CanonicalSerialize for Proof { // We know r_vec must be equal in size to l_vec, so no need to serialize it too if self.l_vec.len() != self.r_vec.len() { - return Err(SerializationError::InvalidData) + return Err(SerializationError::InvalidData); } // Save only one of the coordinates of the point and one byte of flags in order @@ -523,7 +523,7 @@ impl CanonicalSerialize for Proof { // We know r_vec must be equal in size to l_vec, so no need to serialize it too if self.l_vec.len() != self.r_vec.len() { - return Err(SerializationError::InvalidData) + return Err(SerializationError::InvalidData); } for p in self.r_vec.iter() { diff --git a/proof-systems/src/poly-commit/src/ipa_pc/mod.rs b/proof-systems/src/poly-commit/src/ipa_pc/mod.rs index 59b9dcc62..a0c888974 100644 --- a/proof-systems/src/poly-commit/src/ipa_pc/mod.rs +++ b/proof-systems/src/poly-commit/src/ipa_pc/mod.rs @@ -61,7 +61,7 @@ impl InnerProductArgPC { .map_err(|e| Error::IncorrectInputLength(e.to_string()))?; if randomizer.is_some() { if hiding_generator.is_none() { - return Err(Error::Other("Hiding generator is missing".to_owned())) + return Err(Error::Other("Hiding generator is missing".to_owned())); } comm += &hiding_generator.unwrap().mul(randomizer.unwrap()); } @@ -95,7 +95,7 @@ impl InnerProductArgPC { if ck.comm_key.len().next_power_of_two() != key_len { return Err(Error::Other( "Commiter key length is not power of 2".to_owned(), - )) + )); } let batch_time = start_timer!(|| "Compute and batch Bullet Polys and GFin commitments"); @@ -139,7 +139,7 @@ impl InnerProductArgPC { if key_len.next_power_of_two() != key_len { return Err(Error::Other( "Combined check poly length is not a power of 2".to_owned(), - )) + )); } let mut comm_key = &ck.comm_key[..key_len]; @@ -311,7 +311,7 @@ impl InnerProductArgPC { }); if degree_bound_len.is_some() != commitment.shifted_comm.is_some() { - return Err(Error::Other("Degree bound and shifted commitment must be both either present or not present".to_owned())) + return Err(Error::Other("Degree bound and shifted commitment must be both either present or not present".to_owned())); } if let Some(degree_bound_len) = degree_bound_len { @@ -340,7 +340,7 @@ impl InnerProductArgPC { return Err(Error::Other( "Hiding commitment and proof randomness must be both either present or not present" .to_owned(), - )) + )); } if proof.hiding_comm.is_some() { @@ -577,7 +577,7 @@ impl InnerProductArgPC { end_timer!(succinct_time); if !failed_checks.is_empty() { - return Err(Error::FailedSuccinctCheck) + return Err(Error::FailedSuccinctCheck); } let accumulators = accumulators @@ -926,7 +926,7 @@ impl PolynomialCommitment for InnerPr if key_len.next_power_of_two() != key_len { return Err(Error::Other( "Commiter key length is not power of 2".to_owned(), - )) + )); } let mut combined_polynomial = Polynomial::zero(); @@ -959,7 +959,7 @@ impl PolynomialCommitment for InnerPr labeled_commitment.label() ) .to_owned(), - )) + )); } Self::check_degrees_and_bounds(ck.comm_key.len() - 1, labeled_polynomial)?; @@ -987,13 +987,13 @@ impl PolynomialCommitment for InnerPr if degree_bound_len.is_some() != commitment.shifted_comm.is_some() { return Err(Error::Other( format!("shifted_comm mismatch for {}", label).to_owned(), - )) + )); } if degree_bound != labeled_commitment.degree_bound() { return Err(Error::Other( format!("labeled_comm degree bound mismatch for {}", label).to_owned(), - )) + )); } if hiding_bound.is_some() { @@ -1061,7 +1061,7 @@ impl PolynomialCommitment for InnerPr if shifted_rand.is_none() { return Err(Error::Other( format!("shifted_rand.is_none() for {}", label).to_owned(), - )) + )); } // randomness of p_shift(X) combined_rand += &(cur_challenge * &shifted_rand.unwrap()); @@ -1324,7 +1324,7 @@ impl PolynomialCommitment for InnerPr )], if has_hiding { if rng.is_none() { - return Err(Error::Other("Rng not set".to_owned())) + return Err(Error::Other("Rng not set".to_owned())); } Some(rng.as_mut().unwrap()) } else { diff --git a/proof-systems/src/poly-commit/src/lib.rs b/proof-systems/src/poly-commit/src/lib.rs index ea7917f69..897322d08 100644 --- a/proof-systems/src/poly-commit/src/lib.rs +++ b/proof-systems/src/poly-commit/src/lib.rs @@ -466,7 +466,7 @@ pub trait PolynomialCommitment: Sized { let BatchLCProof { proof, evals } = proof; if !evals.is_some() { - return Err(Error::IncorrectProof.into()) + return Err(Error::IncorrectProof.into()); } let lc_s = BTreeMap::from_iter(linear_combinations.into_iter().map(|lc| (lc.label(), lc))); @@ -501,7 +501,7 @@ pub trait PolynomialCommitment: Sized { actual_rhs += &(*coeff * eval); } if claimed_rhs != actual_rhs { - eprintln!("Claimed evaluation of {} is incorrect", lc.label()); + log::error!("Claimed evaluation of {} is incorrect", lc.label()); return Ok(false); } } @@ -517,7 +517,7 @@ pub trait PolynomialCommitment: Sized { )?; if !pc_result { - eprintln!("Evaluation proofs failed to verify"); + log::error!("Evaluation proofs failed to verify"); return Ok(false); } diff --git a/r1cs/core/Cargo.toml b/r1cs/core/Cargo.toml index bd81ddf32..200065dd2 100644 --- a/r1cs/core/Cargo.toml +++ b/r1cs/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "r1cs-core" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", diff --git a/r1cs/gadgets/crypto/Cargo.toml b/r1cs/gadgets/crypto/Cargo.toml index b29ae93c9..0acf4d654 100644 --- a/r1cs/gadgets/crypto/Cargo.toml +++ b/r1cs/gadgets/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "r1cs-crypto" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", @@ -47,6 +47,7 @@ rand = { version = "0.8.4" } derivative = "2.2.0" rayon = "1.5.1" rayon-core = "1.9.1" +log = { version = "0.4.0", features = ["std"] } [features] commitment = ["primitives/commitment", "prf"] diff --git a/r1cs/gadgets/crypto/src/commitment/injective_map/mod.rs b/r1cs/gadgets/crypto/src/commitment/injective_map/mod.rs index 4af769015..11dcb4cc7 100644 --- a/r1cs/gadgets/crypto/src/commitment/injective_map/mod.rs +++ b/r1cs/gadgets/crypto/src/commitment/injective_map/mod.rs @@ -31,7 +31,8 @@ where _crh: PedersenCommitmentGadget, } -impl CommitmentGadget, ConstraintF> +impl + CommitmentGadget, ConstraintF> for PedersenCommitmentCompressorGadget where G: Group, diff --git a/r1cs/gadgets/crypto/src/commitment/pedersen/mod.rs b/r1cs/gadgets/crypto/src/commitment/pedersen/mod.rs index cd614a63d..ee4d9dca2 100644 --- a/r1cs/gadgets/crypto/src/commitment/pedersen/mod.rs +++ b/r1cs/gadgets/crypto/src/commitment/pedersen/mod.rs @@ -1,7 +1,7 @@ use algebra::{to_bytes, Group, ToBytes}; use primitives::{ commitment::pedersen::{PedersenCommitment, PedersenParameters, PedersenRandomness}, - crh::pedersen::{PedersenWindow, PedersenCRH}, + crh::pedersen::{PedersenCRH, PedersenWindow}, }; use r1cs_core::{ConstraintSystemAbstract, SynthesisError}; @@ -25,13 +25,19 @@ pub struct PedersenCommitmentGadgetParameters); -pub struct PedersenCommitmentGadget, const N: usize>( +pub struct PedersenCommitmentGadget< + G: Group, + ConstraintF: Field, + GG: GroupGadget, + const N: usize, +>( #[doc(hidden)] PhantomData<*const G>, #[doc(hidden)] PhantomData<*const GG>, PhantomData, ); -impl CommitmentGadget, ConstraintF> +impl + CommitmentGadget, ConstraintF> for PedersenCommitmentGadget where ConstraintF: PrimeField, @@ -50,18 +56,15 @@ where r: &Self::RandomnessGadget, ) -> Result { PedersenCRH::::check_preconditions( - &primitives::crh::pedersen::PedersenParameters::{generators: parameters.params.generators.clone()} + &primitives::crh::pedersen::PedersenParameters:: { + generators: parameters.params.generators.clone(), + }, )?; // Check fixed size input if input.len() != N { return Err(SynthesisError::Other( - format!( - "incorrect input length {:?} expected {:?}", - input.len(), - N, - ) - .to_owned(), + format!("incorrect input length {:?} expected {:?}", input.len(), N,).to_owned(), )); } @@ -225,7 +228,8 @@ mod test { let parameters = PedersenCommitment::::setup(rng).unwrap(); let primitive_result = - PedersenCommitment::::commit(¶meters, &input, &randomness).unwrap(); + PedersenCommitment::::commit(¶meters, &input, &randomness) + .unwrap(); let input_bytes = UInt8::alloc_input_vec(cs.ns(|| "alloc input bytes as public input"), &input).unwrap(); diff --git a/r1cs/gadgets/crypto/src/crh/bowe_hopwood/mod.rs b/r1cs/gadgets/crypto/src/crh/bowe_hopwood/mod.rs index eebc8f230..352bdb1f3 100644 --- a/r1cs/gadgets/crypto/src/crh/bowe_hopwood/mod.rs +++ b/r1cs/gadgets/crypto/src/crh/bowe_hopwood/mod.rs @@ -40,7 +40,8 @@ pub struct BoweHopwoodPedersenCRHGadget< _engine: PhantomData, } -impl FixedLengthCRHGadget, ConstraintF> +impl + FixedLengthCRHGadget, ConstraintF> for BoweHopwoodPedersenCRHGadget where ConstraintF: Field, @@ -61,12 +62,7 @@ where // Check fixed size input if input.len() != N { return Err(SynthesisError::Other( - format!( - "incorrect input length {:?} expected {:?}", - input.len(), - N, - ) - .to_owned(), + format!("incorrect input length {:?} expected {:?}", input.len(), N,).to_owned(), )); } diff --git a/r1cs/gadgets/crypto/src/crh/injective_map/mod.rs b/r1cs/gadgets/crypto/src/crh/injective_map/mod.rs index 4d1d60c57..75bb578e5 100644 --- a/r1cs/gadgets/crypto/src/crh/injective_map/mod.rs +++ b/r1cs/gadgets/crypto/src/crh/injective_map/mod.rs @@ -102,7 +102,8 @@ where _crh: PedersenCRHGadget, } -impl FixedLengthCRHGadget, ConstraintF> +impl + FixedLengthCRHGadget, ConstraintF> for PedersenCRHCompressorGadget where G: Group, diff --git a/r1cs/gadgets/crypto/src/crh/pedersen/mod.rs b/r1cs/gadgets/crypto/src/crh/pedersen/mod.rs index 884c67e61..c283042d3 100644 --- a/r1cs/gadgets/crypto/src/crh/pedersen/mod.rs +++ b/r1cs/gadgets/crypto/src/crh/pedersen/mod.rs @@ -21,7 +21,12 @@ pub struct PedersenCRHGadgetParameters< _window: PhantomData, } -pub struct PedersenCRHGadget, const N: usize> { +pub struct PedersenCRHGadget< + G: Group, + ConstraintF: Field, + GG: GroupGadget, + const N: usize, +> { #[doc(hidden)] _group: PhantomData<*const G>, #[doc(hidden)] @@ -46,18 +51,12 @@ where parameters: &Self::ParametersGadget, input: &[UInt8], ) -> Result { - PedersenCRH::::check_preconditions(¶meters.params)?; // Check fixed size input if input.len() != N { return Err(SynthesisError::Other( - format!( - "incorrect input length {:?} expected {:?}", - input.len(), - N, - ) - .to_owned(), + format!("incorrect input length {:?} expected {:?}", input.len(), N,).to_owned(), )); } diff --git a/r1cs/gadgets/crypto/src/merkle_tree/mod.rs b/r1cs/gadgets/crypto/src/merkle_tree/mod.rs index 63f1c6aee..55309c309 100644 --- a/r1cs/gadgets/crypto/src/merkle_tree/mod.rs +++ b/r1cs/gadgets/crypto/src/merkle_tree/mod.rs @@ -262,8 +262,14 @@ mod test { const LENGTH: usize = 64; type H = PedersenCRHCompressor; - type HG = - PedersenCRHCompressorGadget; + type HG = PedersenCRHCompressorGadget< + JubJub, + TECompressor, + Fq, + JubJubGadget, + TECompressorGadget, + LENGTH, + >; struct JubJubMerkleTreeParams; @@ -316,9 +322,10 @@ mod test { ); // Allocate Leaf - let leaf_g = leaf.into_iter().map(|l| - UInt8::constant(*l) - ).collect::>(); + let leaf_g = leaf + .into_iter() + .map(|l| UInt8::constant(*l)) + .collect::>(); let constraints_from_leaf = cs.num_constraints() - constraints_from_parameters - constraints_from_digest; diff --git a/r1cs/gadgets/crypto/src/vrf/ecvrf/mod.rs b/r1cs/gadgets/crypto/src/vrf/ecvrf/mod.rs index 8a7111d83..0d2d59f26 100644 --- a/r1cs/gadgets/crypto/src/vrf/ecvrf/mod.rs +++ b/r1cs/gadgets/crypto/src/vrf/ecvrf/mod.rs @@ -14,12 +14,12 @@ use crate::{ crh::{FieldBasedHashGadget, FixedLengthCRHGadget}, vrf::FieldBasedVrfGadget, }; +use primitives::ecvrf::{CHALLENGE_DOMAIN_SEPARATOR, PROOF_TO_HASH_DOMAIN_SEPARATOR}; use primitives::vrf::ecvrf::FieldBasedEcVrfPk; use r1cs_core::{ConstraintSystemAbstract, SynthesisError, ToConstraintField}; use r1cs_std::bits::boolean::Boolean; -use std::{borrow::Borrow, marker::PhantomData}; -use primitives::ecvrf::{CHALLENGE_DOMAIN_SEPARATOR, PROOF_TO_HASH_DOMAIN_SEPARATOR}; use r1cs_std::prelude::ConstantGadget; +use std::{borrow::Borrow, marker::PhantomData}; #[derive(Derivative)] #[derivative( @@ -397,21 +397,38 @@ where .sub(cs.ns(|| "(s * mh) - (c * gamma"), &c_times_gamma)? }; - let gamma_fes = proof.gamma.to_field_gadget_elements(cs.ns(|| "gamma to fes")).unwrap(); + let gamma_fes = proof + .gamma + .to_field_gadget_elements(cs.ns(|| "gamma to fes")) + .unwrap(); // Check c' = H(CHALLENGE_DOMAIN_SEPARATOR||m||pk||gamma||u||v) // Best constraints-efficiency is achieved when m is one field element // (or an odd number of field elements). let hash_input = vec![ - FHG::DataGadget::from_value(cs.ns(|| "alloc challenge domain separator constant"), - &ConstraintF::from(CHALLENGE_DOMAIN_SEPARATOR as u128)), + FHG::DataGadget::from_value( + cs.ns(|| "alloc challenge domain separator constant"), + &ConstraintF::from(CHALLENGE_DOMAIN_SEPARATOR as u128), + ), message.clone(), - ].into_iter() - .chain(public_key.pk.to_field_gadget_elements(cs.ns(|| "pk to fes"))?.into_iter()) - .chain(gamma_fes.clone().into_iter()) - .chain(u.to_field_gadget_elements(cs.ns(|| "u to fes"))?.into_iter()) - .chain(v.to_field_gadget_elements(cs.ns(|| "v to fes"))?.into_iter()) - .collect::>(); + ] + .into_iter() + .chain( + public_key + .pk + .to_field_gadget_elements(cs.ns(|| "pk to fes"))? + .into_iter(), + ) + .chain(gamma_fes.clone().into_iter()) + .chain( + u.to_field_gadget_elements(cs.ns(|| "u to fes"))? + .into_iter(), + ) + .chain( + v.to_field_gadget_elements(cs.ns(|| "v to fes"))? + .into_iter(), + ) + .collect::>(); let c_prime = FHG::enforce_hash_constant_length(cs.ns(|| "check c_prime"), hash_input.as_slice())?; @@ -421,7 +438,10 @@ where //Check and return VRF output let mut hash_input = vec![ - FHG::DataGadget::from_value(cs.ns(|| "alloc proof to hash domain separator"), &ConstraintF::from(PROOF_TO_HASH_DOMAIN_SEPARATOR as u128)), + FHG::DataGadget::from_value( + cs.ns(|| "alloc proof to hash domain separator"), + &ConstraintF::from(PROOF_TO_HASH_DOMAIN_SEPARATOR as u128), + ), message, ]; hash_input.extend_from_slice(&gamma_fes); @@ -442,10 +462,16 @@ mod test { }, vrf::{ecvrf::FieldBasedEcVrfProofVerificationGadget, FieldBasedVrfGadget}, }; - use algebra::{curves::{ - mnt4753::G1Projective as MNT4G1Projective, mnt6753::G1Projective as MNT6G1Projective, - }, FpParameters}; - use algebra::fields::{mnt4753::{Fr as MNT4Fr, FqParameters as MNT4FrParameters}, mnt6753::{Fr as MNT6Fr, FqParameters as MNT6FrParameters}}; + use algebra::fields::{ + mnt4753::{FqParameters as MNT4FrParameters, Fr as MNT4Fr}, + mnt6753::{FqParameters as MNT6FrParameters, Fr as MNT6Fr}, + }; + use algebra::{ + curves::{ + mnt4753::G1Projective as MNT4G1Projective, mnt6753::G1Projective as MNT6G1Projective, + }, + FpParameters, + }; use primitives::{ crh::{ bowe_hopwood::{BoweHopwoodPedersenCRH, BoweHopwoodPedersenParameters}, @@ -476,14 +502,18 @@ mod test { const NUM_WINDOWS: usize = 2; } - const BHMNT4_INPUT_SIZE: usize = ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS)/8) as usize; - const BHMNT6_INPUT_SIZE: usize = ((MNT6FrParameters::MODULUS_BITS + MNT6FrParameters::REPR_SHAVE_BITS)/8) as usize; + const BHMNT4_INPUT_SIZE: usize = + ((MNT4FrParameters::MODULUS_BITS + MNT4FrParameters::REPR_SHAVE_BITS) / 8) as usize; + const BHMNT6_INPUT_SIZE: usize = + ((MNT6FrParameters::MODULUS_BITS + MNT6FrParameters::REPR_SHAVE_BITS) / 8) as usize; type BHMNT4 = BoweHopwoodPedersenCRH; type BHMNT6 = BoweHopwoodPedersenCRH; - type BHMNT4Gadget = BoweHopwoodPedersenCRHGadget; - type BHMNT6Gadget = BoweHopwoodPedersenCRHGadget; + type BHMNT4Gadget = + BoweHopwoodPedersenCRHGadget; + type BHMNT6Gadget = + BoweHopwoodPedersenCRHGadget; type BHMNT4Parameters = BoweHopwoodPedersenParameters; type BHMNT6Parameters = BoweHopwoodPedersenParameters; diff --git a/r1cs/gadgets/std/Cargo.toml b/r1cs/gadgets/std/Cargo.toml index 876538d29..c4a67887a 100644 --- a/r1cs/gadgets/std/Cargo.toml +++ b/r1cs/gadgets/std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "r1cs-std" -version = "0.6.0" +version = "0.6.1" authors = [ "Sean Bowe", "Alessandro Chiesa", @@ -36,6 +36,7 @@ num-traits = { version = "0.2.14", default-features = false, optional = true } num-bigint = { version = "0.4.3", default-features = false, optional = true } num-integer = { version = "0.1.44", default-features = false, optional = true } hex = "0.4.3" +log = { version = "0.4.0", features = ["std"] } [features] asm = ["algebra/asm"] diff --git a/r1cs/gadgets/std/src/bits/boolean.rs b/r1cs/gadgets/std/src/bits/boolean.rs index 11bc98293..b73f31adf 100644 --- a/r1cs/gadgets/std/src/bits/boolean.rs +++ b/r1cs/gadgets/std/src/bits/boolean.rs @@ -632,36 +632,37 @@ impl Boolean { } /// Enforces that all the booleans in `bits` are `false` - pub fn enforce_all_false(mut cs: CS, bits: &[Self]) -> Result<(), SynthesisError> - where - ConstraintF: Field, - CS: ConstraintSystemAbstract, + pub fn enforce_all_false( + mut cs: CS, + bits: &[Self], + ) -> Result<(), SynthesisError> + where + ConstraintF: Field, + CS: ConstraintSystemAbstract, { // if all bits are constants, then just check the input bits without enforcing any constraint - let or = bits.iter().fold(Some(false), |acc, b| - match (acc, b.is_constant()) { + let or = bits + .iter() + .fold(Some(false), |acc, b| match (acc, b.is_constant()) { (Some(acc), true) => Some(b.get_value().unwrap() || acc), _ => None, - } - ); + }); if let Some(or) = or { if or { Err(SynthesisError::Unsatisfiable)? } else { - return Ok(()) + return Ok(()); } } let coeff = ConstraintF::one(); - let lc = bits.iter() - .fold(LinearCombination::::zero(), - |lc, b| - lc + &b.lc(CS::one(), coeff) - ); + let lc = bits + .iter() + .fold(LinearCombination::::zero(), |lc, b| { + lc + &b.lc(CS::one(), coeff) + }); - cs.enforce(|| "enforce all false", |lc| lc, - |lc| lc, - |_| lc); + cs.enforce(|| "enforce all false", |lc| lc, |lc| lc, |_| lc); Ok(()) } @@ -984,7 +985,10 @@ mod test { use super::{AllocatedBit, Boolean}; use crate::prelude::*; use algebra::{fields::bls12_381::Fr, BitIterator, Field, PrimeField, ToBits, UniformRand}; - use r1cs_core::{ConstraintSystem, ConstraintSystemAbstract, ConstraintSystemDebugger, SynthesisError, SynthesisMode}; + use r1cs_core::{ + ConstraintSystem, ConstraintSystemAbstract, ConstraintSystemDebugger, SynthesisError, + SynthesisMode, + }; use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng; use std::str::FromStr; @@ -2224,34 +2228,52 @@ mod test { for mut b in 0..(1 << i) { let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); let expected = b == 0; - let bits = (0..i).map(|j| { - let bit = if all_constants { - Ok(Boolean::Constant(b & 1 == 1)) - } else { - match j % 3 { - 0 => Boolean::alloc(cs.ns(|| format!("bit gadget {}", j)), || Ok(b & 1 == 1)), - 1 => Boolean::alloc(cs.ns(|| format!("bit gadget {}", j)), || Ok(b & 1 == 0)).map(|b| b.not()), - 2 => Ok(Boolean::Constant(b & 1 == 1)), - _ => unreachable!(), - } - }; - b >>= 1; - bit - }).collect::, SynthesisError>>().unwrap(); + let bits = (0..i) + .map(|j| { + let bit = if all_constants { + Ok(Boolean::Constant(b & 1 == 1)) + } else { + match j % 3 { + 0 => Boolean::alloc( + cs.ns(|| format!("bit gadget {}", j)), + || Ok(b & 1 == 1), + ), + 1 => Boolean::alloc( + cs.ns(|| format!("bit gadget {}", j)), + || Ok(b & 1 == 0), + ) + .map(|b| b.not()), + 2 => Ok(Boolean::Constant(b & 1 == 1)), + _ => unreachable!(), + } + }; + b >>= 1; + bit + }) + .collect::, SynthesisError>>() + .unwrap(); - let res = Boolean::enforce_all_false(cs.ns(|| "enforce all false"), bits.as_slice()); + let res = + Boolean::enforce_all_false(cs.ns(|| "enforce all false"), bits.as_slice()); match (all_constants, expected) { (true, true) => res.unwrap(), - (true, false) => assert!(matches!(res.unwrap_err(), SynthesisError::Unsatisfiable)), + (true, false) => { + assert!(matches!(res.unwrap_err(), SynthesisError::Unsatisfiable)) + } (false, true) => { res.unwrap(); - assert!(cs.is_satisfied(), "failing constraint in round {}: {:?}", i, cs.which_is_unsatisfied()) - }, - (false, false) => { + assert!( + cs.is_satisfied(), + "failing constraint in round {}: {:?}", + i, + cs.which_is_unsatisfied() + ) + } + (false, false) => { res.unwrap(); assert!(!cs.is_satisfied()) - }, + } } } } diff --git a/r1cs/gadgets/std/src/fields/fp.rs b/r1cs/gadgets/std/src/fields/fp.rs index 0b3e2f169..5fc50e83e 100644 --- a/r1cs/gadgets/std/src/fields/fp.rs +++ b/r1cs/gadgets/std/src/fields/fp.rs @@ -492,7 +492,6 @@ impl ToBitsGadget for FpGadget { } } - impl FromBitsGadget for FpGadget { /// Pack a slice of Boolean gadgets into a FpGadget, bundling at most `F::Params::CAPACITY` many /// in the constructed field element (to allow efficient unpacking);The bundling procedure expects @@ -501,20 +500,17 @@ impl FromBitsGadget for FpGadget { mut cs: CS, bits: &[Boolean], ) -> Result { - // Pre checks if bits.is_empty() { return Err(SynthesisError::Other("Empty bits slice !".to_owned())); } if bits.len() > F::Params::CAPACITY as usize { - return Err( - SynthesisError::Other( - "You can reconstruct only 1 field element by calling this function: + return Err(SynthesisError::Other( + "You can reconstruct only 1 field element by calling this function: bits cannot be bigger than Field::CAPACITY" - .to_string() - ) - ); + .to_string(), + )); } let mut num = Self::zero(cs.ns(|| "alloc_lc_{}"))?; @@ -550,8 +546,7 @@ impl FromBitsGadget for FpGadget { fn many_from_bits>( mut cs: CS, bits: &[Boolean], - ) -> Result, SynthesisError> - { + ) -> Result, SynthesisError> { // Error if slice is empty if bits.is_empty() { return Err(SynthesisError::Other("Empty bits slice !".to_owned())); @@ -559,14 +554,8 @@ impl FromBitsGadget for FpGadget { // Reconstruct multiple fes from the bit slice let mut fes = Vec::new(); - for (i, bits_chunk) in bits - .chunks(F::Params::CAPACITY as usize) - .enumerate() - { - let fe = Self::from_bits( - cs.ns(|| format!("bits_chunk_{}_to_fe", i)), - bits_chunk - )?; + for (i, bits_chunk) in bits.chunks(F::Params::CAPACITY as usize).enumerate() { + let fe = Self::from_bits(cs.ns(|| format!("bits_chunk_{}_to_fe", i)), bits_chunk)?; fes.push(fe); } Ok(fes) diff --git a/r1cs/gadgets/std/src/fields/nonnative/nonnative_field_gadget.rs b/r1cs/gadgets/std/src/fields/nonnative/nonnative_field_gadget.rs index 477c8a6e9..b7d31a62b 100644 --- a/r1cs/gadgets/std/src/fields/nonnative/nonnative_field_gadget.rs +++ b/r1cs/gadgets/std/src/fields/nonnative/nonnative_field_gadget.rs @@ -304,22 +304,19 @@ impl bits: &[Boolean], params: NonNativeFieldParams, ) -> Result { - // Pre checks if bits.is_empty() { return Err(SynthesisError::Other("Empty bits slice !".to_owned())); } let len_normal_form = params.num_limbs * params.bits_per_limb; - + if bits.len() > len_normal_form { - return Err( - SynthesisError::Other( - "You can reconstruct only 1 non native field element by calling this function: + return Err(SynthesisError::Other( + "You can reconstruct only 1 non native field element by calling this function: bits cannot be bigger than len_normal_form" - .to_string() - ) - ); + .to_string(), + )); } // Pad big endian representation to length of normal form @@ -1419,8 +1416,7 @@ impl FieldGadget Result { let inverse = Self::alloc(cs.ns(|| "inverse"), || { - self - .get_value() + self.get_value() .get()? .inverse() .ok_or(SynthesisError::DivisionByZero) @@ -1480,26 +1476,19 @@ impl AllocGadget::alloc( - cs.ns(|| format!("alloc limb 0")), - || { - let elem = *(f()?.borrow()); - elem_representations = Self::get_limbs_representations(&elem)?; - Ok(elem_representations[0]) - } - )? - ); + cs.ns(|| format!("alloc limb 0")), + || { + let elem = *(f()?.borrow()); + elem_representations = Self::get_limbs_representations(&elem)?; + Ok(elem_representations[0]) + }, + )?); for i in 1..params.num_limbs { - limbs.push( - FpGadget::::alloc( - cs.ns(|| format!("alloc limb {}", i)), - || { - Ok( - elem_representations[i] - ) - }, - )? - ); + limbs.push(FpGadget::::alloc( + cs.ns(|| format!("alloc limb {}", i)), + || Ok(elem_representations[i]), + )?); } // We constrain all limbs to use at most `bits_per_limb` many bits @@ -1544,21 +1533,14 @@ impl AllocGadget::alloc_input( - cs.ns(|| format!("alloc limb {}", i)), - || { - Ok( - elem_representations[i] - ) - }, - )? - ); + limbs.push(FpGadget::::alloc_input( + cs.ns(|| format!("alloc limb {}", i)), + || Ok(elem_representations[i]), + )?); } Ok(Self { @@ -1568,9 +1550,14 @@ impl AllocGadget>(mut cs: CS, f: F) - -> Result - where F: FnOnce() -> Result, T: Borrow { + fn alloc_without_check>( + mut cs: CS, + f: F, + ) -> Result + where + F: FnOnce() -> Result, + T: Borrow, + { let params = get_params::(); let mut limbs = Vec::new(); @@ -1582,21 +1569,14 @@ impl AllocGadget::alloc_input( - cs.ns(|| format!("alloc limb {}", i)), - || { - Ok( - elem_representations[i] - ) - }, - )? - ); + limbs.push(FpGadget::::alloc_input( + cs.ns(|| format!("alloc limb {}", i)), + || Ok(elem_representations[i]), + )?); } Ok(Self { @@ -1705,7 +1685,6 @@ impl FromBitsGadget Result, SynthesisError> { - // Error if slice is empty if bits.is_empty() { return Err(SynthesisError::Other("Empty bits slice !".to_owned())); @@ -1716,13 +1695,10 @@ impl FromBitsGadget Self { + pub fn from_coords(x: F, y: F) -> Self { Self { x, y, @@ -93,11 +93,16 @@ where let lambda = if safe { // Check that neither self nor other are the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 // This is done below when we calculate inv (by F::inverse) - let inv = x2_minus_x1.inverse(cs.ns(|| "compute inv")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv = x2_minus_x1 + .inverse(cs.ns(|| "compute inv")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda"), || { Ok(y2_minus_y1.get_value().get()? * &inv.get_value().get()?) }) @@ -183,9 +188,14 @@ where // Allocate lambda_1 let lambda_1 = if safe { // Enforce that neither self nor other can be the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Enforce the extra constraint for x_2 - x_1 != 0 by using the inverse gadget - let inv_1 = x2_minus_x1.inverse(cs.ns(|| "enforce inv 1")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv_1 = x2_minus_x1 + .inverse(cs.ns(|| "enforce inv 1")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda_1"), || { Ok(y2_minus_y1.get_value().get()? * &inv_1.get_value().get()?) }) @@ -219,7 +229,9 @@ where let lambda_2 = if safe { // Set the extra constraint for x_1 - x_3 != 0 - let inv_2 = x1_minus_x3.inverse(cs.ns(|| "enforce inv 2")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv_2 = x1_minus_x3 + .inverse(cs.ns(|| "enforce inv 2")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda_2"), || { let lambda_val = lambda_1.get_value().get()?; let two_y1_val = two_y1.get_value().get()?; @@ -354,11 +366,11 @@ where #[inline] fn zero>(mut cs: CS) -> Result { - Ok(Self::new( - F::zero(cs.ns(|| "x zero"))?, - F::one(cs.ns(|| "y one"))?, - Boolean::constant(true), - )) + Ok(Self::new( + F::zero(cs.ns(|| "x zero"))?, + F::one(cs.ns(|| "y one"))?, + Boolean::constant(true), + )) } #[inline] @@ -403,13 +415,20 @@ where // So we need to check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 if other.is_zero() { - return Err(SynthesisError::Other("adding zero is not allowed".to_string())); + return Err(SynthesisError::Other( + "adding zero is not allowed".to_string(), + )); } let other = other.into_affine(); let other_x = other.x; let other_y = other.y; - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false)).unwrap(); + self.infinity + .enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + ) + .unwrap(); let x2_minus_x1 = self .x @@ -420,7 +439,9 @@ where .sub_constant(cs.ns(|| "y2 - y1"), &other_y)? .negate(cs.ns(|| "neg2"))?; - let inv = x2_minus_x1.inverse(cs.ns(|| "compute inv")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv = x2_minus_x1 + .inverse(cs.ns(|| "compute inv")) + .map_err(|_| SynthesisError::DivisionByZero)?; let lambda = F::alloc(cs.ns(|| "lambda"), || { Ok(y2_minus_y1.get_value().get()? * &inv.get_value().get()?) @@ -465,7 +486,10 @@ where mut cs: CS, ) -> Result<(), SynthesisError> { // enforce that self is not the infinity point - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false))?; + self.infinity.enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + )?; let a = P::COEFF_A; let x_squared = self.x.square(cs.ns(|| "x^2"))?; @@ -474,7 +498,8 @@ where let two = one.double(); let three = two + &one; - let three_x_squared_plus_a = x_squared.mul_by_constant(cs.ns(|| "3 * x^2"), &three)? + let three_x_squared_plus_a = x_squared + .mul_by_constant(cs.ns(|| "3 * x^2"), &three)? .add_constant(cs.ns(|| "3 * x^2 + a"), &a)?; let two_y = self.y.double(cs.ns(|| "2y"))?; @@ -483,7 +508,7 @@ where let y_doubled_inv = two_y.get_value().get()?.inverse(); match y_doubled_inv { Some(inv) => Ok(three_x_squared_plus_a.get_value().get()? * &inv), - None => Ok(P::BaseField::one()) + None => Ok(P::BaseField::one()), } })?; @@ -1076,11 +1101,11 @@ where mut cs: CS, other: &Self, ) -> Result { - let comparison_bits = vec![ + let comparison_bits = vec![ self.x.is_eq(cs.ns(|| "x"), &other.x)?, self.y.is_eq(cs.ns(|| "y"), &other.y)?, self.infinity.is_eq(cs.ns(|| "infinity"), &other.infinity)?, - ]; + ]; Boolean::kary_and(cs.ns(|| "equality bits"), comparison_bits.as_slice()) } @@ -1175,8 +1200,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation givne by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = F::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = F::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = F::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = F::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1340,8 +1375,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation givne by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = F::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = F::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = F::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = F::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1456,18 +1501,18 @@ where #[cfg(test)] pub(crate) mod test { - use rand::{Rng, SeedableRng, thread_rng}; - use rand_xorshift::XorShiftRng; + use super::*; + use crate::prelude::FieldGadget; use algebra::{PrimeField, SWModelParameters, UniformRand}; use r1cs_core::{ConstraintSystem, ConstraintSystemDebugger, SynthesisMode}; - use crate::prelude::FieldGadget; - use super::*; + use rand::{thread_rng, Rng, SeedableRng}; + use rand_xorshift::XorShiftRng; impl AffineGadget - where - P: SWModelParameters, - ConstraintF: PrimeField, - F: FieldGadget, + where + P: SWModelParameters, + ConstraintF: PrimeField, + F: FieldGadget, { #[allow(dead_code)] pub(crate) fn test_incomplete_double_and_add() { @@ -1509,15 +1554,21 @@ pub(crate) mod test { two_b.double_in_place(cs.ns(|| "2*b")).unwrap(); let four_b = b.double_and_add(cs.ns(|| "2*b+2*b"), &two_b).unwrap(); assert!(cs.is_satisfied()); - let two_b_b_b = two_b.add(cs.ns(|| "3*b"), &b).unwrap() - .add(cs.ns(|| "4*b"), &b).unwrap(); + let two_b_b_b = two_b + .add(cs.ns(|| "3*b"), &b) + .unwrap() + .add(cs.ns(|| "4*b"), &b) + .unwrap(); assert_eq!(four_b, two_b_b_b); let four_b_native = b_native.double().double(); assert_eq!(four_b_native, four_b.get_value().unwrap()); // safety checks on incomplete double_and_add - assert!(matches!(a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*a - 2*a let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1525,7 +1576,11 @@ pub(crate) mod test { let mut two_a = a.clone(); two_a.double_in_place(cs.ns(|| "2*b")).unwrap(); let neg_two_a = two_a.negate(cs.ns(|| "-2*a")).unwrap(); - assert!(matches!(a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a) + .unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*0 + b let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1541,8 +1596,6 @@ pub(crate) mod test { let _ = a.double_and_add(cs.ns(|| "2*a + 0"), &zero).unwrap(); assert!(!cs.is_satisfied()); } - } - } } diff --git a/r1cs/gadgets/std/src/groups/curves/short_weierstrass/short_weierstrass_projective.rs b/r1cs/gadgets/std/src/groups/curves/short_weierstrass/short_weierstrass_projective.rs index e51765192..d0cead4fa 100644 --- a/r1cs/gadgets/std/src/groups/curves/short_weierstrass/short_weierstrass_projective.rs +++ b/r1cs/gadgets/std/src/groups/curves/short_weierstrass/short_weierstrass_projective.rs @@ -56,7 +56,7 @@ where /// Construct `Self` from a pair of coordinates. The functions assumes that the provided /// coordinates correspond to a point in the curve, so it does not perform any validity check - pub fn from_coords(x:F, y: F) -> Self { + pub fn from_coords(x: F, y: F) -> Self { Self { x, y, @@ -93,11 +93,16 @@ where let lambda = if safe { // Check that neither self nor other are the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 // This is done below when we calculate inv (by F::inverse) - let inv = x2_minus_x1.inverse(cs.ns(|| "compute inv")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv = x2_minus_x1 + .inverse(cs.ns(|| "compute inv")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda"), || { Ok(y2_minus_y1.get_value().get()? * &inv.get_value().get()?) }) @@ -183,9 +188,14 @@ where // Allocate lambda_1 let lambda_1 = if safe { // Enforce that neither self nor other can be the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Enforce the extra constraint for x_2 - x_1 != 0 by using the inverse gadget - let inv_1 = x2_minus_x1.inverse(cs.ns(|| "enforce inv 1")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv_1 = x2_minus_x1 + .inverse(cs.ns(|| "enforce inv 1")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda_1"), || { Ok(y2_minus_y1.get_value().get()? * &inv_1.get_value().get()?) }) @@ -219,7 +229,9 @@ where let lambda_2 = if safe { // Set the extra constraint for x_1 - x_3 != 0 - let inv_2 = x1_minus_x3.inverse(cs.ns(|| "enforce inv 2")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv_2 = x1_minus_x3 + .inverse(cs.ns(|| "enforce inv 2")) + .map_err(|_| SynthesisError::DivisionByZero)?; F::alloc(cs.ns(|| "lambda_2"), || { let lambda_val = lambda_1.get_value().get()?; let two_y1_val = two_y1.get_value().get()?; @@ -354,11 +366,11 @@ where #[inline] fn zero>(mut cs: CS) -> Result { - Ok(Self::new( - F::zero(cs.ns(|| "x zero"))?, - F::one(cs.ns(|| "y one"))?, - Boolean::constant(true), - )) + Ok(Self::new( + F::zero(cs.ns(|| "x zero"))?, + F::one(cs.ns(|| "y one"))?, + Boolean::constant(true), + )) } #[inline] @@ -403,13 +415,20 @@ where // So we need to check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 if other.is_zero() { - return Err(SynthesisError::Other("adding zero is not allowed".to_string())); + return Err(SynthesisError::Other( + "adding zero is not allowed".to_string(), + )); } let other = other.into_affine(); let other_x = other.x; let other_y = other.y; - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false)).unwrap(); + self.infinity + .enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + ) + .unwrap(); let x2_minus_x1 = self .x @@ -420,7 +439,9 @@ where .sub_constant(cs.ns(|| "y2 - y1"), &other_y)? .negate(cs.ns(|| "neg2"))?; - let inv = x2_minus_x1.inverse(cs.ns(|| "compute inv")).map_err(|_| SynthesisError::DivisionByZero)?; + let inv = x2_minus_x1 + .inverse(cs.ns(|| "compute inv")) + .map_err(|_| SynthesisError::DivisionByZero)?; let lambda = F::alloc(cs.ns(|| "lambda"), || { Ok(y2_minus_y1.get_value().get()? * &inv.get_value().get()?) @@ -465,7 +486,10 @@ where mut cs: CS, ) -> Result<(), SynthesisError> { // enforce that self is not the infinity point - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false))?; + self.infinity.enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + )?; let a = P::COEFF_A; let x_squared = self.x.square(cs.ns(|| "x^2"))?; @@ -474,7 +498,8 @@ where let two = one.double(); let three = two + &one; - let three_x_squared_plus_a = x_squared.mul_by_constant(cs.ns(|| "3 * x^2"), &three)? + let three_x_squared_plus_a = x_squared + .mul_by_constant(cs.ns(|| "3 * x^2"), &three)? .add_constant(cs.ns(|| "3 * x^2 + a"), &a)?; let two_y = self.y.double(cs.ns(|| "2y"))?; @@ -483,7 +508,7 @@ where let y_doubled_inv = two_y.get_value().get()?.inverse(); match y_doubled_inv { Some(inv) => Ok(three_x_squared_plus_a.get_value().get()? * &inv), - None => Ok(P::BaseField::one()) + None => Ok(P::BaseField::one()), } })?; @@ -1076,11 +1101,11 @@ where mut cs: CS, other: &Self, ) -> Result { - let comparison_bits = vec![ + let comparison_bits = vec![ self.x.is_eq(cs.ns(|| "x"), &other.x)?, self.y.is_eq(cs.ns(|| "y"), &other.y)?, self.infinity.is_eq(cs.ns(|| "infinity"), &other.infinity)?, - ]; + ]; Boolean::kary_and(cs.ns(|| "equality bits"), comparison_bits.as_slice()) } @@ -1175,8 +1200,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation givne by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = F::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = F::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = F::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = F::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1340,8 +1375,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation givne by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = F::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = F::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = F::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = F::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1456,18 +1501,18 @@ where #[cfg(test)] pub(crate) mod test { - use rand::{Rng, SeedableRng, thread_rng}; - use rand_xorshift::XorShiftRng; + use super::*; + use crate::prelude::FieldGadget; use algebra::{PrimeField, SWModelParameters, UniformRand}; use r1cs_core::{ConstraintSystem, ConstraintSystemDebugger, SynthesisMode}; - use crate::prelude::FieldGadget; - use super::*; + use rand::{thread_rng, Rng, SeedableRng}; + use rand_xorshift::XorShiftRng; impl AffineGadget - where - P: SWModelParameters, - ConstraintF: PrimeField, - F: FieldGadget, + where + P: SWModelParameters, + ConstraintF: PrimeField, + F: FieldGadget, { #[allow(dead_code)] pub(crate) fn test_incomplete_double_and_add() { @@ -1509,15 +1554,21 @@ pub(crate) mod test { two_b.double_in_place(cs.ns(|| "2*b")).unwrap(); let four_b = b.double_and_add(cs.ns(|| "2*b+2*b"), &two_b).unwrap(); assert!(cs.is_satisfied()); - let two_b_b_b = two_b.add(cs.ns(|| "3*b"), &b).unwrap() - .add(cs.ns(|| "4*b"), &b).unwrap(); + let two_b_b_b = two_b + .add(cs.ns(|| "3*b"), &b) + .unwrap() + .add(cs.ns(|| "4*b"), &b) + .unwrap(); assert_eq!(four_b, two_b_b_b); let four_b_native = b_native.double().double(); assert_eq!(four_b_native, four_b.get_value().unwrap()); // safety checks on incomplete double_and_add - assert!(matches!(a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*a - 2*a let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1525,7 +1576,11 @@ pub(crate) mod test { let mut two_a = a.clone(); two_a.double_in_place(cs.ns(|| "2*b")).unwrap(); let neg_two_a = two_a.negate(cs.ns(|| "-2*a")).unwrap(); - assert!(matches!(a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a) + .unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*0 + b let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1541,8 +1596,6 @@ pub(crate) mod test { let _ = a.double_and_add(cs.ns(|| "2*a + 0"), &zero).unwrap(); assert!(!cs.is_satisfied()); } - } - } } diff --git a/r1cs/gadgets/std/src/groups/mod.rs b/r1cs/gadgets/std/src/groups/mod.rs index a6927e61e..aee90f2cc 100644 --- a/r1cs/gadgets/std/src/groups/mod.rs +++ b/r1cs/gadgets/std/src/groups/mod.rs @@ -474,11 +474,14 @@ pub(crate) mod test { BigInteger, EndoMulCurve, Field, FpParameters, Group, PrimeField, ProjectiveCurve, ToBits, UniformRand, }; - use r1cs_core::{ConstraintSystem, ConstraintSystemAbstract, ConstraintSystemDebugger, SynthesisError, SynthesisMode}; + use r1cs_core::{ + ConstraintSystem, ConstraintSystemAbstract, ConstraintSystemDebugger, SynthesisError, + SynthesisMode, + }; use crate::groups::EndoMulCurveGadget; use crate::prelude::*; - use rand::{Rng, SeedableRng, thread_rng}; + use rand::{thread_rng, Rng, SeedableRng}; use rand_xorshift::XorShiftRng; #[allow(dead_code)] @@ -557,7 +560,6 @@ pub(crate) mod test { let a = GG::alloc(&mut cs.ns(|| "generate_a"), || Ok(a_native)).unwrap(); let b = GG::alloc(&mut cs.ns(|| "generate_b"), || Ok(b_native)).unwrap(); - // a + b = b + a let a_b = a.add(cs.ns(|| "a_plus_b"), &b).unwrap(); let b_a = b.add(cs.ns(|| "b_plus_a"), &a).unwrap(); @@ -636,28 +638,47 @@ pub(crate) mod test { assert!(!cs.is_satisfied()); let (mut cs, a, b, _zero) = reinit_cs(); - assert!(matches!(b.add(cs.ns(|| "check that b+b fails"), &b).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + b.add(cs.ns(|| "check that b+b fails"), &b).unwrap_err(), + SynthesisError::DivisionByZero + )); let neg_a = a.negate(cs.ns(|| "-a")).unwrap(); - assert!(matches!(a.add(cs.ns(|| "check that a-a fails"), &neg_a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.add(cs.ns(|| "check that a-a fails"), &neg_a).unwrap_err(), + SynthesisError::DivisionByZero + )); let (mut cs, a, _b, _zero) = reinit_cs(); - assert!(a.add_constant(cs.ns(|| "check that a+0 fails"), &G::zero()) - .unwrap_err().to_string().contains("adding zero is not allowed")); + assert!(a + .add_constant(cs.ns(|| "check that a+0 fails"), &G::zero()) + .unwrap_err() + .to_string() + .contains("adding zero is not allowed")); let (mut cs, _a, _b, zero) = reinit_cs(); - let _ = zero.add_constant(cs.ns(|| "check that 0+b fails"), &b_native).unwrap(); + let _ = zero + .add_constant(cs.ns(|| "check that 0+b fails"), &b_native) + .unwrap(); assert!(!cs.is_satisfied()); let (mut cs, a, b, _zero) = reinit_cs(); - assert!(matches!(b.add_constant(cs.ns(|| "check that b+b fails"), &b_native) - .unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + b.add_constant(cs.ns(|| "check that b+b fails"), &b_native) + .unwrap_err(), + SynthesisError::DivisionByZero + )); - assert!(matches!(a.add_constant(cs.ns(|| "check that a-a fails"), &a_native.neg()) - .unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.add_constant(cs.ns(|| "check that a-a fails"), &a_native.neg()) + .unwrap_err(), + SynthesisError::DivisionByZero + )); let (mut cs, _a, _b, mut zero) = reinit_cs(); - let _ = zero.double_in_place(cs.ns(|| "cannot double zero")).unwrap(); + let _ = zero + .double_in_place(cs.ns(|| "cannot double zero")) + .unwrap(); assert!(!cs.is_satisfied()); } @@ -756,7 +777,8 @@ pub(crate) mod test { let a = G::ScalarField::rand(&mut rng); // Alloc its bits on the circuit - let mut a_bits = Vec::::alloc(cs.ns(|| "a bits"), || Ok(a.write_bits())).unwrap(); + let mut a_bits = + Vec::::alloc(cs.ns(|| "a bits"), || Ok(a.write_bits())).unwrap(); a_bits.reverse(); // Variable base scalar multiplication @@ -786,13 +808,22 @@ pub(crate) mod test { // safety checks on mul_bits let zero = GG::alloc(cs.ns(|| "Zero"), || Ok(G::zero())).unwrap(); - assert!(zero.mul_bits(cs.ns(|| "a * 0"), a_bits.iter()).unwrap_err().to_string().contains("Base point is trivial")); - - let zero_bits = Vec::::alloc(cs.ns(|| "alloc zero bits"), || - Ok(vec![false; G::ScalarField::size_in_bits()])).unwrap(); - assert!(gg.mul_bits(cs.ns(|| "0 * gg"), zero_bits.iter()).unwrap_err().to_string().contains("Scalar must not be zero")); + assert!(zero + .mul_bits(cs.ns(|| "a * 0"), a_bits.iter()) + .unwrap_err() + .to_string() + .contains("Base point is trivial")); + + let zero_bits = Vec::::alloc(cs.ns(|| "alloc zero bits"), || { + Ok(vec![false; G::ScalarField::size_in_bits()]) + }) + .unwrap(); + assert!(gg + .mul_bits(cs.ns(|| "0 * gg"), zero_bits.iter()) + .unwrap_err() + .to_string() + .contains("Scalar must not be zero")); } - } #[allow(dead_code)] @@ -888,7 +919,13 @@ pub(crate) mod test { let scalar: G::ScalarField = u128::rand(&mut thread_rng()).into(); - let b_native = scalar.into_repr().to_bits().into_iter().rev().take(128).collect::>(); + let b_native = scalar + .into_repr() + .to_bits() + .into_iter() + .rev() + .take(128) + .collect::>(); let b = b_native .iter() .map(|&bit| Boolean::constant(bit)) diff --git a/r1cs/gadgets/std/src/groups/nonnative/short_weierstrass/short_weierstrass_jacobian.rs b/r1cs/gadgets/std/src/groups/nonnative/short_weierstrass/short_weierstrass_jacobian.rs index ad015bf8f..dae74764b 100644 --- a/r1cs/gadgets/std/src/groups/nonnative/short_weierstrass/short_weierstrass_jacobian.rs +++ b/r1cs/gadgets/std/src/groups/nonnative/short_weierstrass/short_weierstrass_jacobian.rs @@ -85,7 +85,10 @@ where mut cs: CS, ) -> Result<(), SynthesisError> { // enforce that self is not the infinity point - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false))?; + self.infinity.enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + )?; let x_squared = self.x.mul_without_prereduce(cs.ns(|| "x^2"), &self.x)?; let three_x_squared_plus_a = x_squared @@ -176,13 +179,18 @@ where // So we need to check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 if other.is_zero() { - return Err(SynthesisError::Other("adding zero is not allowed".to_string())); + return Err(SynthesisError::Other( + "adding zero is not allowed".to_string(), + )); } let other = other.into_affine(); let other_x = other.x; let other_y = other.y; - self.infinity.enforce_equal(cs.ns(|| "enforce self is non-zero"), &Boolean::Constant(false))?; + self.infinity.enforce_equal( + cs.ns(|| "enforce self is non-zero"), + &Boolean::Constant(false), + )?; let x2_minus_x1 = self .x @@ -792,7 +800,10 @@ where let lambda = if safe { // Check that neither self nor other are the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Check that A.x - B.x != 0, which can be done by // enforcing I * (B.x - A.x) = 1 // This is done below when we calculate inv (by NonNativeFieldGadget::inverse) @@ -884,7 +895,10 @@ where // Allocate lambda_1 let lambda_1 = if safe { // Enforce that neither self nor other can be the infinity point - Boolean::enforce_all_false(cs.ns(|| "check no zero operand"), &vec![self.infinity, other.infinity])?; + Boolean::enforce_all_false( + cs.ns(|| "check no zero operand"), + &vec![self.infinity, other.infinity], + )?; // Enforce the extra constraint for x_2 - x_1 != 0 by using the inverse gadget let inv_1 = x2_minus_x1.inverse(cs.ns(|| "enforce inv 1"))?; NonNativeFieldGadget::alloc(cs.ns(|| "lambda_1"), || { @@ -1142,8 +1156,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation givne by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = NonNativeFieldGadget::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = NonNativeFieldGadget::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = NonNativeFieldGadget::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = NonNativeFieldGadget::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1310,8 +1334,18 @@ where // enforce that if infinity is true, then enforce the coordinates of the zero // representation given by Self::zero let zero = Self::zero(cs.ns(|| "alloc zero"))?; - let x = NonNativeFieldGadget::conditionally_select(cs.ns(|| "enforce x=0 in point at infinity"), &infinity, &zero.x, &x)?; - let y = NonNativeFieldGadget::conditionally_select(cs.ns(|| "enforce y=0 in point at infinity"), &infinity, &zero.y, &y)?; + let x = NonNativeFieldGadget::conditionally_select( + cs.ns(|| "enforce x=0 in point at infinity"), + &infinity, + &zero.x, + &x, + )?; + let y = NonNativeFieldGadget::conditionally_select( + cs.ns(|| "enforce y=0 in point at infinity"), + &infinity, + &zero.y, + &y, + )?; Ok(Self::new(x, y, infinity)) } @@ -1319,18 +1353,17 @@ where #[cfg(test)] pub(crate) mod test { - use rand::{Rng, SeedableRng, thread_rng}; - use rand_xorshift::XorShiftRng; + use super::*; use algebra::{PrimeField, SWModelParameters, UniformRand}; use r1cs_core::{ConstraintSystem, ConstraintSystemDebugger, SynthesisMode}; - use super::*; + use rand::{thread_rng, Rng, SeedableRng}; + use rand_xorshift::XorShiftRng; impl GroupAffineNonNativeGadget - where - P: SWModelParameters, - ConstraintF: PrimeField, - SimulationF: PrimeField + SquareRootField, - + where + P: SWModelParameters, + ConstraintF: PrimeField, + SimulationF: PrimeField + SquareRootField, { #[allow(dead_code)] pub(crate) fn test_incomplete_double_and_add() { @@ -1372,15 +1405,21 @@ pub(crate) mod test { two_b.double_in_place(cs.ns(|| "2*b")).unwrap(); let four_b = b.double_and_add(cs.ns(|| "2*b+2*b"), &two_b).unwrap(); assert!(cs.is_satisfied()); - let two_b_b_b = two_b.add(cs.ns(|| "3*b"), &b).unwrap() - .add(cs.ns(|| "4*b"), &b).unwrap(); + let two_b_b_b = two_b + .add(cs.ns(|| "3*b"), &b) + .unwrap() + .add(cs.ns(|| "4*b"), &b) + .unwrap(); assert_eq!(four_b, two_b_b_b); let four_b_native = b_native.double().double(); assert_eq!(four_b_native, four_b.get_value().unwrap()); // safety checks on incomplete double_and_add - assert!(matches!(a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a+a"), &a).unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*a - 2*a let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1388,7 +1427,11 @@ pub(crate) mod test { let mut two_a = a.clone(); two_a.double_in_place(cs.ns(|| "2*b")).unwrap(); let neg_two_a = two_a.negate(cs.ns(|| "-2*a")).unwrap(); - assert!(matches!(a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a).unwrap_err(), SynthesisError::DivisionByZero)); + assert!(matches!( + a.double_and_add(cs.ns(|| "2*a-2*a"), &neg_two_a) + .unwrap_err(), + SynthesisError::DivisionByZero + )); // 2*0 + b let mut cs = ConstraintSystem::::new(SynthesisMode::Debug); @@ -1405,6 +1448,5 @@ pub(crate) mod test { assert!(!cs.is_satisfied()); } } - } }