From 341b8e0229f32c1235c2617dc0510d862ae066e3 Mon Sep 17 00:00:00 2001 From: moana Date: Tue, 14 Dec 2021 10:07:38 +0100 Subject: [PATCH 1/5] Blind polynomials --- rust-toolchain | 2 +- src/constraint_system/composer.rs | 4 +- src/permutation.rs | 48 ++--- src/proof_system/preprocess.rs | 184 +++++++++--------- src/proof_system/prover.rs | 57 ++++-- src/proof_system/quotient_poly.rs | 179 +++++++---------- src/proof_system/widget.rs | 18 +- .../widget/permutation/proverkey.rs | 2 +- 8 files changed, 246 insertions(+), 248 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 2e625890..5d5883e8 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-11-17 +nightly-2021-10-28 diff --git a/src/constraint_system/composer.rs b/src/constraint_system/composer.rs index 29a7539e..ec90755a 100644 --- a/src/constraint_system/composer.rs +++ b/src/constraint_system/composer.rs @@ -1007,7 +1007,7 @@ mod tests { #[test] fn test_plonkup_proof() -> Result<(), Error> { - let public_parameters = PublicParameters::setup(1 << 8, &mut OsRng)?; + let public_parameters = PublicParameters::setup(1 << 9, &mut OsRng)?; // Create a prover struct let mut prover = Prover::new(b"test"); @@ -1021,7 +1021,7 @@ mod tests { verifier.cs.lookup_table.insert_multi_mul(0, 3); // Commit and verifier key - let (ck, vk) = public_parameters.trim(1 << 7)?; + let (ck, vk) = public_parameters.trim(1 << 8)?; // Preprocess circuit prover.preprocess(&ck)?; diff --git a/src/permutation.rs b/src/permutation.rs index 808c9069..0ba72210 100644 --- a/src/permutation.rs +++ b/src/permutation.rs @@ -212,14 +212,14 @@ impl Permutation { // Uses a rayon multizip to allow more code flexibility while remaining // parallelizable. This can be adapted into a general product argument // for any number of wires. - pub(crate) fn compute_permutation_poly( + pub(crate) fn compute_permutation_vec( &self, domain: &EvaluationDomain, wires: [&[BlsScalar]; 4], beta: &BlsScalar, gamma: &BlsScalar, sigma_polys: [&Polynomial; 4], - ) -> Polynomial { + ) -> Vec { let n = domain.size(); // Constants defining cosets H, k1H, k2H, etc @@ -296,10 +296,10 @@ impl Permutation { assert_eq!(n, z.len()); - Polynomial::from_coefficients_vec(domain.ifft(&z)) + z } - pub(crate) fn compute_lookup_permutation_poly( + pub(crate) fn compute_lookup_permutation_vec( &self, domain: &EvaluationDomain, f: &[BlsScalar], @@ -308,7 +308,7 @@ impl Permutation { h_2: &[BlsScalar], delta: &BlsScalar, epsilon: &BlsScalar, - ) -> Polynomial { + ) -> Vec { let n = domain.size(); assert_eq!(f.len(), domain.size()); @@ -375,7 +375,7 @@ impl Permutation { assert_eq!(n, p.len()); - Polynomial::from_coefficients_vec(domain.ifft(&p)) + p } } @@ -419,7 +419,7 @@ mod test { use rand_core::OsRng; #[test] - fn test_compute_lookup_permutation_poly() -> Result<(), Error> { + fn test_compute_lookup_permutation_vec() -> Result<(), Error> { // FIXME: use `usize` everywhere for such things const SIZE: u32 = 4; @@ -449,9 +449,11 @@ mod test { let domain = EvaluationDomain::new(SIZE as usize)?; let perm = Permutation::new(); - let poly = perm.compute_lookup_permutation_poly( - &domain, &f.0, &t.0, &h_1.0, &h_2.0, &delta, &epsilon, - ); + let poly = Polynomial::from_coefficients_vec(domain.ifft( + &perm.compute_lookup_permutation_vec( + &domain, &f.0, &t.0, &h_1.0, &h_2.0, &delta, &epsilon, + ), + )); const TEST_VECTORS: [&str; 4] = [ "0x0eaa2fe1c155cfb88bf91f7800c3b855fc67989c949da6cc87a68c9499680d1c", @@ -888,18 +890,20 @@ mod test { .map(|v| Polynomial::from_coefficients_vec(domain.ifft(v))) .collect(); - let mz = cs.perm.compute_permutation_poly( - &domain, - [&a_w_scalar, &b_w_scalar, &c_w_scalar, &d_w_scalar], - &beta, - &gamma, - [ - &sigma_polys[0], - &sigma_polys[1], - &sigma_polys[2], - &sigma_polys[3], - ], - ); + let mz = Polynomial::from_coefficients_vec(domain.ifft( + &cs.perm.compute_permutation_vec( + &domain, + [&a_w_scalar, &b_w_scalar, &c_w_scalar, &d_w_scalar], + &beta, + &gamma, + [ + &sigma_polys[0], + &sigma_polys[1], + &sigma_polys[2], + &sigma_polys[3], + ], + ), + )); let old_z = Polynomial::from_coefficients_vec(domain.ifft( &compute_fast_permutation_poly( diff --git a/src/proof_system/preprocess.rs b/src/proof_system/preprocess.rs index c6aa8cda..2bd59ba0 100644 --- a/src/proof_system/preprocess.rs +++ b/src/proof_system/preprocess.rs @@ -121,135 +121,135 @@ impl TurboComposer { let (_, selectors, preprocessed_table, domain) = self.preprocess_shared(commit_key, transcript)?; - let domain_4n = EvaluationDomain::new(4 * domain.size())?; - let q_m_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_m), - domain_4n, + let domain_8n = EvaluationDomain::new(8 * domain.size())?; + let q_m_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_m), + domain_8n, ); - let q_l_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_l), - domain_4n, + let q_l_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_l), + domain_8n, ); - let q_r_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_r), - domain_4n, + let q_r_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_r), + domain_8n, ); - let q_o_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_o), - domain_4n, + let q_o_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_o), + domain_8n, ); - let q_c_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_c), - domain_4n, + let q_c_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_c), + domain_8n, ); - let q_4_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_4), - domain_4n, + let q_4_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_4), + domain_8n, ); - let q_k_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_k), - domain_4n, + let q_k_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_k), + domain_8n, ); - let q_arith_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_arith), - domain_4n, + let q_arith_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_arith), + domain_8n, ); - let q_range_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_range), - domain_4n, + let q_range_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_range), + domain_8n, ); - let q_logic_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_logic), - domain_4n, + let q_logic_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_logic), + domain_8n, ); - let q_fixed_group_add_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_fixed_group_add), - domain_4n, + let q_fixed_group_add_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_fixed_group_add), + domain_8n, ); - let q_variable_group_add_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.q_variable_group_add), - domain_4n, + let q_variable_group_add_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_variable_group_add), + domain_8n, ); - let s_sigma_1_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.s_sigma_1), - domain_4n, + let s_sigma_1_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.s_sigma_1), + domain_8n, ); - let s_sigma_2_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.s_sigma_2), - domain_4n, + let s_sigma_2_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.s_sigma_2), + domain_8n, ); - let s_sigma_3_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.s_sigma_3), - domain_4n, + let s_sigma_3_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.s_sigma_3), + domain_8n, ); - let s_sigma_4_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&selectors.s_sigma_4), - domain_4n, + let s_sigma_4_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.s_sigma_4), + domain_8n, ); - let table_1_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&preprocessed_table.t_1.2), - domain_4n, + let table_1_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&preprocessed_table.t_1.2), + domain_8n, ); - let table_2_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&preprocessed_table.t_2.2), - domain_4n, + let table_2_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&preprocessed_table.t_2.2), + domain_8n, ); - let table_3_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&preprocessed_table.t_3.2), - domain_4n, + let table_3_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&preprocessed_table.t_3.2), + domain_8n, ); - let table_4_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&preprocessed_table.t_4.2), - domain_4n, + let table_4_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&preprocessed_table.t_4.2), + domain_8n, ); // XXX: Remove this and compute it on the fly - let linear_eval_4n = Evaluations::from_vec_and_domain( - domain_4n.coset_fft(&[BlsScalar::zero(), BlsScalar::one()]), - domain_4n, + let linear_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&[BlsScalar::zero(), BlsScalar::one()]), + domain_8n, ); // Prover Key for arithmetic circuits let arithmetic_prover_key = widget::arithmetic::ProverKey { - q_m: (selectors.q_m, q_m_eval_4n), - q_l: (selectors.q_l.clone(), q_l_eval_4n.clone()), - q_r: (selectors.q_r.clone(), q_r_eval_4n.clone()), - q_o: (selectors.q_o, q_o_eval_4n), - q_c: (selectors.q_c.clone(), q_c_eval_4n.clone()), - q_4: (selectors.q_4, q_4_eval_4n), - q_arith: (selectors.q_arith, q_arith_eval_4n), + q_m: (selectors.q_m, q_m_eval_8n), + q_l: (selectors.q_l.clone(), q_l_eval_8n.clone()), + q_r: (selectors.q_r.clone(), q_r_eval_8n.clone()), + q_o: (selectors.q_o, q_o_eval_8n), + q_c: (selectors.q_c.clone(), q_c_eval_8n.clone()), + q_4: (selectors.q_4, q_4_eval_8n), + q_arith: (selectors.q_arith, q_arith_eval_8n), }; // Prover Key for range circuits let range_prover_key = widget::range::ProverKey { - q_range: (selectors.q_range, q_range_eval_4n), + q_range: (selectors.q_range, q_range_eval_8n), }; // Prover Key for logic circuits let logic_prover_key = widget::logic::ProverKey { - q_c: (selectors.q_c.clone(), q_c_eval_4n.clone()), - q_logic: (selectors.q_logic, q_logic_eval_4n), + q_c: (selectors.q_c.clone(), q_c_eval_8n.clone()), + q_logic: (selectors.q_logic, q_logic_eval_8n), }; // Prover Key for ecc circuits let ecc_prover_key = widget::ecc::scalar_mul::fixed_base::ProverKey { - q_l: (selectors.q_l, q_l_eval_4n), - q_r: (selectors.q_r, q_r_eval_4n), - q_c: (selectors.q_c, q_c_eval_4n), + q_l: (selectors.q_l, q_l_eval_8n), + q_r: (selectors.q_r, q_r_eval_8n), + q_c: (selectors.q_c, q_c_eval_8n), q_fixed_group_add: ( selectors.q_fixed_group_add, - q_fixed_group_add_eval_4n, + q_fixed_group_add_eval_8n, ), }; // Prover Key for permutation argument let permutation_prover_key = widget::permutation::ProverKey { - s_sigma_1: (selectors.s_sigma_1, s_sigma_1_eval_4n), - s_sigma_2: (selectors.s_sigma_2, s_sigma_2_eval_4n), - s_sigma_3: (selectors.s_sigma_3, s_sigma_3_eval_4n), - s_sigma_4: (selectors.s_sigma_4, s_sigma_4_eval_4n), - linear_evaluations: linear_eval_4n, + s_sigma_1: (selectors.s_sigma_1, s_sigma_1_eval_8n), + s_sigma_2: (selectors.s_sigma_2, s_sigma_2_eval_8n), + s_sigma_3: (selectors.s_sigma_3, s_sigma_3_eval_8n), + s_sigma_4: (selectors.s_sigma_4, s_sigma_4_eval_8n), + linear_evaluations: linear_eval_8n, }; // Prover Key for curve addition @@ -257,32 +257,32 @@ impl TurboComposer { widget::ecc::curve_addition::ProverKey { q_variable_group_add: ( selectors.q_variable_group_add, - q_variable_group_add_eval_4n, + q_variable_group_add_eval_8n, ), }; // Prover key for lookup operations let lookup_prover_key = widget::lookup::ProverKey { - q_k: (selectors.q_k, q_k_eval_4n), + q_k: (selectors.q_k, q_k_eval_8n), table_1: ( preprocessed_table.t_1.0, preprocessed_table.t_1.2, - table_1_eval_4n, + table_1_eval_8n, ), table_2: ( preprocessed_table.t_2.0, preprocessed_table.t_2.2, - table_2_eval_4n, + table_2_eval_8n, ), table_3: ( preprocessed_table.t_3.0, preprocessed_table.t_3.2, - table_3_eval_4n, + table_3_eval_8n, ), table_4: ( preprocessed_table.t_4.0, preprocessed_table.t_4.2, - table_4_eval_4n, + table_4_eval_8n, ), }; @@ -295,8 +295,8 @@ impl TurboComposer { variable_base: curve_addition_prover_key, fixed_base: ecc_prover_key, lookup: lookup_prover_key, - // Compute 4n evaluations for X^n -1 - v_h_coset_4n: domain_4n + // Compute 8n evaluations for X^n -1 + v_h_coset_8n: domain_8n .compute_vanishing_poly_over_coset(domain.size() as u64), }; @@ -305,7 +305,7 @@ impl TurboComposer { /// The verifier only requires the commitments in order to verify a /// [`Proof`](super::Proof) We can therefore speed up preprocessing for the - /// verifier by skipping the FFTs needed to compute the 4n evaluations. + /// verifier by skipping the FFTs needed to compute the 8n evaluations. pub(crate) fn preprocess_verifier( &mut self, commit_key: &CommitKey, diff --git a/src/proof_system/prover.rs b/src/proof_system/prover.rs index ad3c684e..62399522 100644 --- a/src/proof_system/prover.rs +++ b/src/proof_system/prover.rs @@ -145,6 +145,31 @@ impl Prover { self.preprocessed_transcript.append_message(label, message); } + /// Adds the blinding scalars to a given vector. Always the same elements + /// of 'w_vec' are modified at the beginning of it, and appended at the end: + /// if hiding degree = 1: (b2*X(n+1) + b1*X^n - b2*X - b1) + w_vec + /// if hiding degree = 2: (b3*X^(n+2) + b2*X(n+1) + b1*X^n - b3*X^2 - b2*X + /// - b1) + w_vec + pub(crate) fn blind_poly( + w_vec: &Vec, + hiding_degree: usize, + domain: &EvaluationDomain, + ) -> Polynomial { + let mut w_vec_i = domain.ifft(w_vec); + + for i in 0..hiding_degree + 1 { + // we declare and randomly select a blinding scalar + // TODO: implement randomness + //let blinding_scalar = util::random_scalar(&mut rand_core::OsRng); + let blinding_scalar = BlsScalar::from(1234); // TO BE RANDOM! + w_vec_i[i] = w_vec_i[i] - blinding_scalar; // modify the first elements of the vector + w_vec_i.push(blinding_scalar); // append last elements at the end of + // the vector + } + + Polynomial::from_coefficients_vec(w_vec_i) + } + /// Creates a [`Proof]` that demonstrates that a circuit is satisfied. /// /// # Note @@ -184,14 +209,10 @@ impl Prover { // Wires are now in evaluation form, convert them to coefficients so // that we may commit to them - let a_w_poly = - Polynomial::from_coefficients_vec(domain.ifft(a_w_scalar)); - let b_w_poly = - Polynomial::from_coefficients_vec(domain.ifft(b_w_scalar)); - let c_w_poly = - Polynomial::from_coefficients_vec(domain.ifft(c_w_scalar)); - let d_w_poly = - Polynomial::from_coefficients_vec(domain.ifft(d_w_scalar)); + let a_w_poly = Prover::blind_poly(&a_w_scalar, 1, &domain); + let b_w_poly = Prover::blind_poly(&b_w_scalar, 1, &domain); + let c_w_poly = Prover::blind_poly(&c_w_scalar, 1, &domain); + let d_w_poly = Prover::blind_poly(&d_w_scalar, 1, &domain); // Commit to wire polynomials // ([a(x)]_1, [b(x)]_1, [c(x)]_1, [d(x)]_1) @@ -265,9 +286,7 @@ impl Prover { ); // Compute long query poly - let f_poly = Polynomial::from_coefficients_vec( - domain.ifft(&compressed_f_multiset.0), - ); + let f_poly = Prover::blind_poly(&compressed_f_multiset.0, 1, &domain); // Commit to query polynomial let f_poly_commit = commit_key.commit(&f_poly)?; @@ -284,8 +303,8 @@ impl Prover { let (h_1, h_2) = s.halve_alternating(); // Compute h polys - let h_1_poly = Polynomial::from_coefficients_vec(domain.ifft(&h_1.0)); - let h_2_poly = Polynomial::from_coefficients_vec(domain.ifft(&h_2.0)); + let h_1_poly = Prover::blind_poly(&h_1.0, 2, &domain); + let h_2_poly = Prover::blind_poly(&h_2.0, 1, &domain); // Commit to h polys let h_1_poly_commit = commit_key.commit(&h_1_poly).unwrap(); @@ -303,8 +322,8 @@ impl Prover { let delta = transcript.challenge_scalar(b"delta"); let epsilon = transcript.challenge_scalar(b"epsilon"); - let z_1_poly = Polynomial::from_coefficients_slice( - &self.cs.perm.compute_permutation_poly( + let z_1_poly = Prover::blind_poly( + &self.cs.perm.compute_permutation_vec( &domain, [a_w_scalar, b_w_scalar, c_w_scalar, d_w_scalar], &beta, @@ -316,6 +335,8 @@ impl Prover { &prover_key.permutation.s_sigma_4.0, ], ), + 2, + &domain, ); // Commit to permutation polynomial @@ -325,8 +346,8 @@ impl Prover { transcript.append_commitment(b"z_1", &z_1_poly_commit); // Compute lookup permutation poly - let z_2_poly = Polynomial::from_coefficients_slice( - &self.cs.perm.compute_lookup_permutation_poly( + let z_2_poly = Prover::blind_poly( + &self.cs.perm.compute_lookup_permutation_vec( &domain, &compressed_f_multiset.0, &compressed_t_multiset.0, @@ -335,6 +356,8 @@ impl Prover { &delta, &epsilon, ), + 2, + &domain, ); // Commit to permutation polynomial diff --git a/src/proof_system/quotient_poly.rs b/src/proof_system/quotient_poly.rs index d2e9637b..206b5039 100644 --- a/src/proof_system/quotient_poly.rs +++ b/src/proof_system/quotient_poly.rs @@ -58,63 +58,34 @@ pub(crate) fn compute( BlsScalar, ), ) -> Result { - // Compute 4n eval of z(X) - let domain_4n = EvaluationDomain::new(4 * domain.size())?; - let mut z_eval_4n = domain_4n.coset_fft(z_poly); - z_eval_4n.push(z_eval_4n[0]); - z_eval_4n.push(z_eval_4n[1]); - z_eval_4n.push(z_eval_4n[2]); - z_eval_4n.push(z_eval_4n[3]); + // Compute 8n evals + let domain_8n = EvaluationDomain::new(8 * domain.size())?; - // Compute 4n eval of p(X) - let mut p_eval_4n = domain_4n.coset_fft(p_poly); - p_eval_4n.push(p_eval_4n[0]); - p_eval_4n.push(p_eval_4n[1]); - p_eval_4n.push(p_eval_4n[2]); - p_eval_4n.push(p_eval_4n[3]); + let mut z_eval_8n = domain_8n.coset_fft(z_poly); + let mut p_eval_8n = domain_8n.coset_fft(p_poly); + let mut t_eval_8n = domain_8n.coset_fft(t_poly); - // Compute 4n evals of table poly, t(x) - let mut t_eval_4n = domain_4n.coset_fft(t_poly); - t_eval_4n.push(t_eval_4n[0]); - t_eval_4n.push(t_eval_4n[1]); - t_eval_4n.push(t_eval_4n[2]); - t_eval_4n.push(t_eval_4n[3]); + let f_eval_8n = domain_8n.coset_fft(f_poly); - // Compute f(x) - let f_eval_4n = domain_4n.coset_fft(f_poly); + let mut h_1_eval_8n = domain_8n.coset_fft(h_1_poly); + let mut h_2_eval_8n = domain_8n.coset_fft(h_2_poly); - // Compute 4n eval of h_1 - let mut h_1_eval_4n = domain_4n.coset_fft(h_1_poly); - h_1_eval_4n.push(h_1_eval_4n[0]); - h_1_eval_4n.push(h_1_eval_4n[1]); - h_1_eval_4n.push(h_1_eval_4n[2]); - h_1_eval_4n.push(h_1_eval_4n[3]); + let mut a_w_eval_8n = domain_8n.coset_fft(a_w_poly); + let mut b_w_eval_8n = domain_8n.coset_fft(b_w_poly); + let c_w_eval_8n = domain_8n.coset_fft(c_w_poly); + let mut d_w_eval_8n = domain_8n.coset_fft(d_w_poly); - // Compute 4n eval of h_2 - let mut h_2_eval_4n = domain_4n.coset_fft(h_2_poly); - h_2_eval_4n.push(h_2_eval_4n[0]); - h_2_eval_4n.push(h_2_eval_4n[1]); - h_2_eval_4n.push(h_2_eval_4n[2]); - h_2_eval_4n.push(h_2_eval_4n[3]); - - // Compute 4n evaluations of the wire polynomials - let mut a_w_eval_4n = domain_4n.coset_fft(a_w_poly); - a_w_eval_4n.push(a_w_eval_4n[0]); - a_w_eval_4n.push(a_w_eval_4n[1]); - a_w_eval_4n.push(a_w_eval_4n[2]); - a_w_eval_4n.push(a_w_eval_4n[3]); - let mut b_w_eval_4n = domain_4n.coset_fft(b_w_poly); - b_w_eval_4n.push(b_w_eval_4n[0]); - b_w_eval_4n.push(b_w_eval_4n[1]); - b_w_eval_4n.push(b_w_eval_4n[2]); - b_w_eval_4n.push(b_w_eval_4n[3]); - let c_w_eval_4n = domain_4n.coset_fft(c_w_poly); - - let mut d_w_eval_4n = domain_4n.coset_fft(d_w_poly); - d_w_eval_4n.push(d_w_eval_4n[0]); - d_w_eval_4n.push(d_w_eval_4n[1]); - d_w_eval_4n.push(d_w_eval_4n[2]); - d_w_eval_4n.push(d_w_eval_4n[3]); + for i in 0..8 { + z_eval_8n.push(z_eval_8n[i]); + p_eval_8n.push(p_eval_8n[i]); + t_eval_8n.push(t_eval_8n[i]); + h_1_eval_8n.push(h_1_eval_8n[i]); + h_2_eval_8n.push(h_2_eval_8n[i]); + a_w_eval_8n.push(a_w_eval_8n[i]); + b_w_eval_8n.push(b_w_eval_8n[i]); + // c_w_eval_8n push not required + d_w_eval_8n.push(d_w_eval_8n[i]); + } let t_1 = compute_circuit_satisfiability_equation( domain, @@ -126,41 +97,41 @@ pub(crate) fn compute( lookup_challenge, ), prover_key, - (&a_w_eval_4n, &b_w_eval_4n, &c_w_eval_4n, &d_w_eval_4n), + (&a_w_eval_8n, &b_w_eval_8n, &c_w_eval_8n, &d_w_eval_8n), public_inputs_poly, zeta, (delta, epsilon), - &f_eval_4n, - &p_eval_4n, - &t_eval_4n, - &h_1_eval_4n, - &h_2_eval_4n, + &f_eval_8n, + &p_eval_8n, + &t_eval_8n, + &h_1_eval_8n, + &h_2_eval_8n, ); let t_2 = compute_permutation_checks( domain, prover_key, - (&a_w_eval_4n, &b_w_eval_4n, &c_w_eval_4n, &d_w_eval_4n), - &z_eval_4n, + (&a_w_eval_8n, &b_w_eval_8n, &c_w_eval_8n, &d_w_eval_8n), + &z_eval_8n, (alpha, beta, gamma), ); #[cfg(not(feature = "std"))] - let range = (0..domain_4n.size()).into_iter(); + let range = (0..domain_8n.size()).into_iter(); #[cfg(feature = "std")] - let range = (0..domain_4n.size()).into_par_iter(); + let range = (0..domain_8n.size()).into_par_iter(); let quotient: Vec<_> = range .map(|i| { let numerator = t_1[i] + t_2[i]; - let denominator = prover_key.v_h_coset_4n()[i]; + let denominator = prover_key.v_h_coset_8n()[i]; numerator * denominator.invert().unwrap() }) .collect(); Ok(Polynomial::from_coefficients_vec( - domain_4n.coset_ifft("ient), + domain_8n.coset_ifft("ient), )) } @@ -176,7 +147,7 @@ fn compute_circuit_satisfiability_equation( lookup_challenge, ): (&BlsScalar, &BlsScalar, &BlsScalar, &BlsScalar, &BlsScalar), prover_key: &ProverKey, - (a_w_eval_4n, b_w_eval_4n, c_w_eval_4n, d_w_eval_4n): ( + (a_w_eval_8n, b_w_eval_8n, c_w_eval_8n, d_w_eval_8n): ( &[BlsScalar], &[BlsScalar], &[BlsScalar], @@ -185,45 +156,45 @@ fn compute_circuit_satisfiability_equation( pi_poly: &Polynomial, zeta: &BlsScalar, (delta, epsilon): (&BlsScalar, &BlsScalar), - f_eval_4n: &[BlsScalar], - p_eval_4n: &[BlsScalar], - t_eval_4n: &[BlsScalar], - h_1_eval_4n: &[BlsScalar], - h_2_eval_4n: &[BlsScalar], + f_eval_8n: &[BlsScalar], + p_eval_8n: &[BlsScalar], + t_eval_8n: &[BlsScalar], + h_1_eval_8n: &[BlsScalar], + h_2_eval_8n: &[BlsScalar], ) -> Vec { - let domain_4n = EvaluationDomain::new(4 * domain.size()).unwrap(); - let public_eval_4n = domain_4n.coset_fft(pi_poly); + let domain_8n = EvaluationDomain::new(8 * domain.size()).unwrap(); + let public_eval_8n = domain_8n.coset_fft(pi_poly); - let l1_eval_4n = domain_4n.coset_fft(&compute_first_lagrange_poly_scaled( + let l1_eval_8n = domain_8n.coset_fft(&compute_first_lagrange_poly_scaled( domain, BlsScalar::one(), )); #[cfg(not(feature = "std"))] - let range = (0..domain_4n.size()).into_iter(); + let range = (0..domain_8n.size()).into_iter(); #[cfg(feature = "std")] - let range = (0..domain_4n.size()).into_par_iter(); + let range = (0..domain_8n.size()).into_par_iter(); let t: Vec<_> = range .map(|i| { - let a_w = &a_w_eval_4n[i]; - let b_w = &b_w_eval_4n[i]; - let c_w = &c_w_eval_4n[i]; - let d_w = &d_w_eval_4n[i]; - let a_w_next = &a_w_eval_4n[i + 4]; - let b_w_next = &b_w_eval_4n[i + 4]; - let d_w_next = &d_w_eval_4n[i + 4]; - let pi = &public_eval_4n[i]; - let p = &p_eval_4n[i]; - let p_next = &p_eval_4n[i + 4]; - let fi = &f_eval_4n[i]; - let ti = &t_eval_4n[i]; - let ti_next = &t_eval_4n[i + 4]; - let h1 = &h_1_eval_4n[i]; - let h2 = &h_2_eval_4n[i]; - let h1_next = &h_1_eval_4n[i + 4]; - let l1i = &l1_eval_4n[i]; + let a_w = &a_w_eval_8n[i]; + let b_w = &b_w_eval_8n[i]; + let c_w = &c_w_eval_8n[i]; + let d_w = &d_w_eval_8n[i]; + let a_w_next = &a_w_eval_8n[i + 8]; + let b_w_next = &b_w_eval_8n[i + 8]; + let d_w_next = &d_w_eval_8n[i + 8]; + let pi = &public_eval_8n[i]; + let p = &p_eval_8n[i]; + let p_next = &p_eval_8n[i + 8]; + let fi = &f_eval_8n[i]; + let ti = &t_eval_8n[i]; + let ti_next = &t_eval_8n[i + 8]; + let h1 = &h_1_eval_8n[i]; + let h2 = &h_2_eval_8n[i]; + let h1_next = &h_1_eval_8n[i + 8]; + let l1i = &l1_eval_8n[i]; let a = prover_key .arithmetic @@ -304,36 +275,36 @@ fn compute_circuit_satisfiability_equation( fn compute_permutation_checks( domain: &EvaluationDomain, prover_key: &ProverKey, - (a_w_eval_4n, b_w_eval_4n, c_w_eval_4n, d_w_eval_4n): ( + (a_w_eval_8n, b_w_eval_8n, c_w_eval_8n, d_w_eval_8n): ( &[BlsScalar], &[BlsScalar], &[BlsScalar], &[BlsScalar], ), - z_eval_4n: &[BlsScalar], + z_eval_8n: &[BlsScalar], (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar), ) -> Vec { - let domain_4n = EvaluationDomain::new(4 * domain.size()).unwrap(); + let domain_8n = EvaluationDomain::new(8 * domain.size()).unwrap(); let l1_poly_alpha = compute_first_lagrange_poly_scaled(domain, alpha.square()); - let l1_alpha_sq_evals = domain_4n.coset_fft(&l1_poly_alpha.coeffs); + let l1_alpha_sq_evals = domain_8n.coset_fft(&l1_poly_alpha.coeffs); #[cfg(not(feature = "std"))] - let range = (0..domain_4n.size()).into_iter(); + let range = (0..domain_8n.size()).into_iter(); #[cfg(feature = "std")] - let range = (0..domain_4n.size()).into_par_iter(); + let range = (0..domain_8n.size()).into_par_iter(); let t: Vec<_> = range .map(|i| { prover_key.permutation.compute_quotient_i( i, - &a_w_eval_4n[i], - &b_w_eval_4n[i], - &c_w_eval_4n[i], - &d_w_eval_4n[i], - &z_eval_4n[i], - &z_eval_4n[i + 4], + &a_w_eval_8n[i], + &b_w_eval_8n[i], + &c_w_eval_8n[i], + &d_w_eval_8n[i], + &z_eval_8n[i], + &z_eval_8n[i + 8], alpha, &l1_alpha_sq_evals[i], beta, diff --git a/src/proof_system/widget.rs b/src/proof_system/widget.rs index 2caaf91a..b816f7b9 100644 --- a/src/proof_system/widget.rs +++ b/src/proof_system/widget.rs @@ -253,12 +253,12 @@ pub(crate) mod alloc { pub(crate) lookup: lookup::ProverKey, /// ProverKey for permutation checks pub(crate) permutation: permutation::ProverKey, - // Pre-processes the 4n Evaluations for the vanishing polynomial, so + // Pre-processes the 8n Evaluations for the vanishing polynomial, so // they do not need to be computed at the proving stage. // Note: With this, we can combine all parts of the quotient polynomial // in their evaluation phase and divide by the quotient // polynomial without having to perform IFFT - pub(crate) v_h_coset_4n: Evaluations, + pub(crate) v_h_coset_8n: Evaluations, } impl ProverKey { @@ -421,7 +421,7 @@ pub(crate) mod alloc { writer.write(&self.permutation.linear_evaluations.to_var_bytes()); - writer.write(&self.v_h_coset_4n.to_var_bytes()); + writer.write(&self.v_h_coset_8n.to_var_bytes()); bytes } @@ -565,7 +565,7 @@ pub(crate) mod alloc { let perm_linear_evaluations = evals_from_reader(&mut buffer)?; - let v_h_coset_4n = evals_from_reader(&mut buffer)?; + let v_h_coset_8n = evals_from_reader(&mut buffer)?; let arithmetic = arithmetic::ProverKey { q_m, @@ -620,14 +620,14 @@ pub(crate) mod alloc { variable_base, lookup, permutation, - v_h_coset_4n, + v_h_coset_8n, }; Ok(prover_key) } - pub(crate) fn v_h_coset_4n(&self) -> &Evaluations { - &self.v_h_coset_4n + pub(crate) fn v_h_coset_8n(&self) -> &Evaluations { + &self.v_h_coset_8n } } } @@ -698,7 +698,7 @@ mod test { let table_3 = rand_multiset(n); let table_4 = rand_multiset(n); - let v_h_coset_4n = rand_evaluations(n); + let v_h_coset_8n = rand_evaluations(n); let arithmetic = arithmetic::ProverKey { q_m, @@ -753,7 +753,7 @@ mod test { variable_base, lookup, permutation, - v_h_coset_4n, + v_h_coset_8n, }; let prover_key_bytes = prover_key.to_var_bytes(); diff --git a/src/proof_system/widget/permutation/proverkey.rs b/src/proof_system/widget/permutation/proverkey.rs index a179a8c8..00992a6a 100644 --- a/src/proof_system/widget/permutation/proverkey.rs +++ b/src/proof_system/widget/permutation/proverkey.rs @@ -142,7 +142,7 @@ impl ProverKey { &self.s_sigma_4.0, ); - let domain = EvaluationDomain::new(z_poly.degree()).unwrap(); + let domain = EvaluationDomain::new(z_poly.degree() - 2).unwrap(); let c = self.compute_linearizer_check_is_one( &domain, z_challenge, From 8efda59b0c07821c4a1ee66f7172143326b28b48 Mon Sep 17 00:00:00 2001 From: xevisalle Date: Sat, 5 Mar 2022 19:45:33 +0100 Subject: [PATCH 2/5] Fix benchmarks --- README.md | 6 +++--- benches/plonk.rs | 2 +- src/circuit.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ba4570e1..a18e42cb 100644 --- a/README.md +++ b/README.md @@ -155,11 +155,11 @@ There are two main types of documentation in this repository: ## Performance -Benchmarks taken on `Intel(R) Core(TM) i9-9900X CPU @ 3.50GHz` +Benchmarks taken on `Apple M1` For a circuit-size of `2^16` constraints/gates: -- Proving time: `5.46s` -- Verification time: `9.34ms`. **(This time will not vary depending on the circuit-size.)** +- Proving time: `17.392s` +- Verification time: `10.475ms`. **(This time will not vary depending on the circuit-size.)** For more results, please run `cargo bench` to get a full report of benchmarks in respect of constraint numbers. diff --git a/benches/plonk.rs b/benches/plonk.rs index e259953e..741624c6 100644 --- a/benches/plonk.rs +++ b/benches/plonk.rs @@ -84,7 +84,7 @@ fn constraint_system_benchmark(c: &mut Criterion) { let rng = &mut rand_core::OsRng; let label = b"dusk-network"; - let pp = PublicParameters::setup(1 << (final_degree - 1), rng) + let pp = PublicParameters::setup(1 << final_degree, rng) .expect("Failed to create PP"); let data: Vec<(BenchCircuit, ProverKey, VerifierData, Proof)> = diff --git a/src/circuit.rs b/src/circuit.rs index 7551649d..2cd98e2c 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -256,7 +256,7 @@ where pub_params: &PublicParameters, ) -> Result<(ProverKey, VerifierData), Error> { // Setup PublicParams - let (ck, _) = pub_params.trim(self.padded_gates())?; + let (ck, _) = pub_params.trim(self.padded_gates() + 6)?; // Generate & save `ProverKey` with some random values. let mut prover = Prover::new(b"CircuitCompilation"); @@ -296,7 +296,7 @@ where prover_key: &ProverKey, transcript_init: &'static [u8], ) -> Result { - let (ck, _) = pub_params.trim(self.padded_gates())?; + let (ck, _) = pub_params.trim(self.padded_gates() + 6)?; // New Prover instance let mut prover = Prover::new(transcript_init); From 23ea8a3f3f55d97ddd54f82bb4fa20f9f9cac939 Mon Sep 17 00:00:00 2001 From: xevisalle Date: Sat, 5 Mar 2022 20:48:09 +0100 Subject: [PATCH 3/5] Add randomness --- README.md | 2 +- benches/plonk.rs | 3 ++- src/circuit.rs | 8 +++++--- src/constraint_system/composer.rs | 6 +++--- src/constraint_system/helper.rs | 4 ++-- src/proof_system/prover.rs | 32 +++++++++++++++++-------------- tests/circuit.rs | 2 +- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index a18e42cb..85fe42a4 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ let proof = { dusk_jubjub::GENERATOR_EXTENDED * JubJubScalar::from(2u64), ), }; - circuit.prove(&pp, &pk, b"Test").unwrap() + circuit.prove(&pp, &pk, b"Test", &mut OsRng).unwrap() }; // Verifier POV diff --git a/benches/plonk.rs b/benches/plonk.rs index 741624c6..28d0ab23 100644 --- a/benches/plonk.rs +++ b/benches/plonk.rs @@ -8,6 +8,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use dusk_plonk::prelude::*; +use rand_core::OsRng; #[derive(Debug, Clone, Copy)] struct BenchCircuit { @@ -74,7 +75,7 @@ fn constraint_system_prove( label: &'static [u8], ) -> Proof { circuit - .prove(pp, pk, label) + .prove(pp, pk, label, &mut OsRng) .expect("Failed to prove bench circuit!") } diff --git a/src/circuit.rs b/src/circuit.rs index 2cd98e2c..cb376776 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -16,6 +16,7 @@ use canonical_derive::Canon; use dusk_bls12_381::BlsScalar; use dusk_bytes::{DeserializableSlice, Serializable, Write}; use dusk_jubjub::{JubJubAffine, JubJubExtended, JubJubScalar}; +use rand_core::{CryptoRng, RngCore}; #[derive(Default, Debug, Clone)] #[cfg_attr(feature = "canon", derive(Canon))] @@ -218,7 +219,7 @@ impl VerifierData { /// ), /// }; /// -/// circuit.prove(&pp, &pk, b"Test") +/// circuit.prove(&pp, &pk, b"Test", &mut OsRng) /// }?; /// /// // Verifier POV @@ -290,11 +291,12 @@ where /// Generates a proof using the provided `CircuitInputs` & `ProverKey` /// instances. - fn prove( + fn prove( &mut self, pub_params: &PublicParameters, prover_key: &ProverKey, transcript_init: &'static [u8], + mut rng: &mut R, ) -> Result { let (ck, _) = pub_params.trim(self.padded_gates() + 6)?; @@ -306,7 +308,7 @@ where // Add ProverKey to Prover prover.prover_key = Some(prover_key.clone()); - prover.prove(&ck) + prover.prove(&ck, &mut rng) } /// Verify the provided proof for the compiled verifier data diff --git a/src/constraint_system/composer.rs b/src/constraint_system/composer.rs index ec90755a..4f1acbce 100644 --- a/src/constraint_system/composer.rs +++ b/src/constraint_system/composer.rs @@ -934,7 +934,7 @@ mod tests { // Compute multiple proofs for _ in 0..3 { - proofs.push(prover.prove(&ck).unwrap()); + proofs.push(prover.prove(&ck, &mut OsRng).unwrap()); // Add another witness instance dummy_gadget(10, prover.composer_mut()); @@ -1001,7 +1001,7 @@ mod tests { // So pre-fetch these before calling Prove let public_inputs = prover.cs.to_dense_public_inputs(); - prover.prove(&ck).unwrap(); + prover.prove(&ck, &mut OsRng).unwrap(); drop(public_inputs); } @@ -1029,7 +1029,7 @@ mod tests { let public_inputs = prover.cs.to_dense_public_inputs(); - let proof = prover.prove(&ck)?; + let proof = prover.prove(&ck, &mut OsRng)?; assert!(verifier.verify(&proof, &vk, &public_inputs).is_ok()); diff --git a/src/constraint_system/helper.rs b/src/constraint_system/helper.rs index 5f57abe8..e0265bcf 100644 --- a/src/constraint_system/helper.rs +++ b/src/constraint_system/helper.rs @@ -70,7 +70,7 @@ pub(crate) fn gadget_tester( let public_inputs = prover.cs.to_dense_public_inputs(); // Compute Proof - (prover.prove(&ck)?, public_inputs) + (prover.prove(&ck, &mut OsRng)?, public_inputs) }; // Verifiers view // @@ -130,7 +130,7 @@ pub(crate) fn gadget_plonkup_tester( let public_inputs = prover.cs.to_dense_public_inputs(); // Compute Proof - (prover.prove(&ck)?, public_inputs) + (prover.prove(&ck, &mut OsRng)?, public_inputs) }; // Verifiers view // diff --git a/src/proof_system/prover.rs b/src/proof_system/prover.rs index 62399522..553d79e3 100644 --- a/src/proof_system/prover.rs +++ b/src/proof_system/prover.rs @@ -14,10 +14,12 @@ use crate::{ linearization_poly, proof::Proof, quotient_poly, ProverKey, }, transcript::TranscriptProtocol, + util, }; use alloc::vec::Vec; use dusk_bls12_381::BlsScalar; use merlin::Transcript; +use rand_core::{CryptoRng, RngCore}; /// Abstraction structure designed to construct a circuit and generate /// [`Proof`]s for it. @@ -150,18 +152,17 @@ impl Prover { /// if hiding degree = 1: (b2*X(n+1) + b1*X^n - b2*X - b1) + w_vec /// if hiding degree = 2: (b3*X^(n+2) + b2*X(n+1) + b1*X^n - b3*X^2 - b2*X /// - b1) + w_vec - pub(crate) fn blind_poly( + pub(crate) fn blind_poly( w_vec: &Vec, hiding_degree: usize, domain: &EvaluationDomain, + mut rng: &mut R, ) -> Polynomial { let mut w_vec_i = domain.ifft(w_vec); for i in 0..hiding_degree + 1 { // we declare and randomly select a blinding scalar - // TODO: implement randomness - //let blinding_scalar = util::random_scalar(&mut rand_core::OsRng); - let blinding_scalar = BlsScalar::from(1234); // TO BE RANDOM! + let blinding_scalar = util::random_scalar(&mut rng); w_vec_i[i] = w_vec_i[i] - blinding_scalar; // modify the first elements of the vector w_vec_i.push(blinding_scalar); // append last elements at the end of // the vector @@ -178,10 +179,11 @@ impl Prover { /// after calling this method, the user should then call /// [`Prover::clear_witness`]. /// This is automatically done when [`Prover::prove`] is called. - pub fn prove_with_preprocessed( + pub fn prove_with_preprocessed( &self, commit_key: &CommitKey, prover_key: &ProverKey, + mut rng: &mut R, ) -> Result { // make sure the domain is big enough to handle the circuit as well as // the lookup table @@ -209,10 +211,10 @@ impl Prover { // Wires are now in evaluation form, convert them to coefficients so // that we may commit to them - let a_w_poly = Prover::blind_poly(&a_w_scalar, 1, &domain); - let b_w_poly = Prover::blind_poly(&b_w_scalar, 1, &domain); - let c_w_poly = Prover::blind_poly(&c_w_scalar, 1, &domain); - let d_w_poly = Prover::blind_poly(&d_w_scalar, 1, &domain); + let a_w_poly = Prover::blind_poly(&a_w_scalar, 1, &domain, &mut rng); + let b_w_poly = Prover::blind_poly(&b_w_scalar, 1, &domain, &mut rng); + let c_w_poly = Prover::blind_poly(&c_w_scalar, 1, &domain, &mut rng); + let d_w_poly = Prover::blind_poly(&d_w_scalar, 1, &domain, &mut rng); // Commit to wire polynomials // ([a(x)]_1, [b(x)]_1, [c(x)]_1, [d(x)]_1) @@ -286,7 +288,7 @@ impl Prover { ); // Compute long query poly - let f_poly = Prover::blind_poly(&compressed_f_multiset.0, 1, &domain); + let f_poly = Prover::blind_poly(&compressed_f_multiset.0, 1, &domain, &mut rng); // Commit to query polynomial let f_poly_commit = commit_key.commit(&f_poly)?; @@ -303,8 +305,8 @@ impl Prover { let (h_1, h_2) = s.halve_alternating(); // Compute h polys - let h_1_poly = Prover::blind_poly(&h_1.0, 2, &domain); - let h_2_poly = Prover::blind_poly(&h_2.0, 1, &domain); + let h_1_poly = Prover::blind_poly(&h_1.0, 2, &domain, &mut rng); + let h_2_poly = Prover::blind_poly(&h_2.0, 1, &domain, &mut rng); // Commit to h polys let h_1_poly_commit = commit_key.commit(&h_1_poly).unwrap(); @@ -337,6 +339,7 @@ impl Prover { ), 2, &domain, + &mut rng ); // Commit to permutation polynomial @@ -358,6 +361,7 @@ impl Prover { ), 2, &domain, + &mut rng ); // Commit to permutation polynomial @@ -594,7 +598,7 @@ impl Prover { /// Proves a circuit is satisfied, then clears the witness variables /// If the circuit is not pre-processed, then the preprocessed circuit will /// also be computed. - pub fn prove(&mut self, commit_key: &CommitKey) -> Result { + pub fn prove(&mut self, commit_key: &CommitKey, mut rng: &mut R) -> Result { let prover_key: &ProverKey; if self.prover_key.is_none() { @@ -609,7 +613,7 @@ impl Prover { prover_key = self.prover_key.as_ref().unwrap(); - let proof = self.prove_with_preprocessed(commit_key, prover_key)?; + let proof = self.prove_with_preprocessed(commit_key, prover_key, &mut rng)?; // Clear witness and reset composer variables self.clear_witness(); diff --git a/tests/circuit.rs b/tests/circuit.rs index 735c61bb..c6f1e219 100644 --- a/tests/circuit.rs +++ b/tests/circuit.rs @@ -121,7 +121,7 @@ fn test_full() -> Result<()> { ), }; - circuit.prove(&pp, &pk, b"Test") + circuit.prove(&pp, &pk, b"Test", &mut OsRng) }?; // Verifier POV From de1db6290f4364cdede04e3041ed8eec37538156 Mon Sep 17 00:00:00 2001 From: xevisalle Date: Sat, 5 Mar 2022 21:04:34 +0100 Subject: [PATCH 4/5] Fix fmt --- src/proof_system/prover.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/proof_system/prover.rs b/src/proof_system/prover.rs index 553d79e3..3fdd8a9a 100644 --- a/src/proof_system/prover.rs +++ b/src/proof_system/prover.rs @@ -288,7 +288,8 @@ impl Prover { ); // Compute long query poly - let f_poly = Prover::blind_poly(&compressed_f_multiset.0, 1, &domain, &mut rng); + let f_poly = + Prover::blind_poly(&compressed_f_multiset.0, 1, &domain, &mut rng); // Commit to query polynomial let f_poly_commit = commit_key.commit(&f_poly)?; @@ -339,7 +340,7 @@ impl Prover { ), 2, &domain, - &mut rng + &mut rng, ); // Commit to permutation polynomial @@ -361,7 +362,7 @@ impl Prover { ), 2, &domain, - &mut rng + &mut rng, ); // Commit to permutation polynomial @@ -598,7 +599,11 @@ impl Prover { /// Proves a circuit is satisfied, then clears the witness variables /// If the circuit is not pre-processed, then the preprocessed circuit will /// also be computed. - pub fn prove(&mut self, commit_key: &CommitKey, mut rng: &mut R) -> Result { + pub fn prove( + &mut self, + commit_key: &CommitKey, + mut rng: &mut R, + ) -> Result { let prover_key: &ProverKey; if self.prover_key.is_none() { @@ -613,7 +618,8 @@ impl Prover { prover_key = self.prover_key.as_ref().unwrap(); - let proof = self.prove_with_preprocessed(commit_key, prover_key, &mut rng)?; + let proof = + self.prove_with_preprocessed(commit_key, prover_key, &mut rng)?; // Clear witness and reset composer variables self.clear_witness(); From 6b5e281424c9c08e9631bc9ecfbfaaeeb9d70eae Mon Sep 17 00:00:00 2001 From: xevisalle Date: Mon, 7 Mar 2022 12:49:28 +0100 Subject: [PATCH 5/5] Fix minor issues --- src/circuit.rs | 13 ++++-- src/permutation.rs | 4 +- src/proof_system/preprocess.rs | 4 ++ src/proof_system/prover.rs | 45 ++++++++++--------- .../widget/permutation/proverkey.rs | 1 + 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index 8263fa3c..1050670d 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -246,6 +246,9 @@ where { /// Circuit identifier associated constant. const CIRCUIT_ID: [u8; 32]; + /// Extra size needed for the circuit parameters. + 6 because adding the + /// blinding factors requires some extra elements for the SRS + const PARAMS_EXTRA_SIZE: usize = 6; /// Gadget implementation used to fill the composer. fn gadget(&mut self, composer: &mut TurboComposer) -> Result<(), Error>; @@ -257,7 +260,8 @@ where pub_params: &PublicParameters, ) -> Result<(ProverKey, VerifierData), Error> { // Setup PublicParams - let (ck, _) = pub_params.trim(self.padded_gates() + 6)?; + let (ck, _) = + pub_params.trim(self.padded_gates() + Self::PARAMS_EXTRA_SIZE)?; // Generate & save `ProverKey` with some random values. let mut prover = Prover::new(b"CircuitCompilation"); @@ -296,9 +300,10 @@ where pub_params: &PublicParameters, prover_key: &ProverKey, transcript_init: &'static [u8], - mut rng: &mut R, + rng: &mut R, ) -> Result { - let (ck, _) = pub_params.trim(self.padded_gates() + 6)?; + let (ck, _) = + pub_params.trim(self.padded_gates() + Self::PARAMS_EXTRA_SIZE)?; // New Prover instance let mut prover = Prover::new(transcript_init); @@ -308,7 +313,7 @@ where // Add ProverKey to Prover prover.prover_key = Some(prover_key.clone()); - prover.prove(&ck, &mut rng) + prover.prove(&ck, rng) } /// Verify the provided proof for the compiled verifier data diff --git a/src/permutation.rs b/src/permutation.rs index 0ba72210..915c66f8 100644 --- a/src/permutation.rs +++ b/src/permutation.rs @@ -219,7 +219,7 @@ impl Permutation { beta: &BlsScalar, gamma: &BlsScalar, sigma_polys: [&Polynomial; 4], - ) -> Vec { + ) -> Vec { let n = domain.size(); // Constants defining cosets H, k1H, k2H, etc @@ -308,7 +308,7 @@ impl Permutation { h_2: &[BlsScalar], delta: &BlsScalar, epsilon: &BlsScalar, - ) -> Vec { + ) -> Vec { let n = domain.size(); assert_eq!(f.len(), domain.size()); diff --git a/src/proof_system/preprocess.rs b/src/proof_system/preprocess.rs index 2bd59ba0..a951d4d9 100644 --- a/src/proof_system/preprocess.rs +++ b/src/proof_system/preprocess.rs @@ -121,6 +121,10 @@ impl TurboComposer { let (_, selectors, preprocessed_table, domain) = self.preprocess_shared(commit_key, transcript)?; + // The polynomial needs an evaluation domain of 4n. + // Plus, adding the blinding factors translates to + // the polynomial not fitting in 4n, so now we need + // 8n, the next power of 2 let domain_8n = EvaluationDomain::new(8 * domain.size())?; let q_m_eval_8n = Evaluations::from_vec_and_domain( domain_8n.coset_fft(&selectors.q_m), diff --git a/src/proof_system/prover.rs b/src/proof_system/prover.rs index 3fdd8a9a..54755716 100644 --- a/src/proof_system/prover.rs +++ b/src/proof_system/prover.rs @@ -149,26 +149,27 @@ impl Prover { /// Adds the blinding scalars to a given vector. Always the same elements /// of 'w_vec' are modified at the beginning of it, and appended at the end: - /// if hiding degree = 1: (b2*X(n+1) + b1*X^n - b2*X - b1) + w_vec - /// if hiding degree = 2: (b3*X^(n+2) + b2*X(n+1) + b1*X^n - b3*X^2 - b2*X + /// if hiding degree = 1: (b2*X^(n+1) + b1*X^n - b2*X - b1) + w_vec + /// if hiding degree = 2: (b3*X^(n+2) + b2*X^(n+1) + b1*X^n - b3*X^2 - b2*X /// - b1) + w_vec pub(crate) fn blind_poly( - w_vec: &Vec, + w_vec: &Vec, hiding_degree: usize, domain: &EvaluationDomain, - mut rng: &mut R, + rng: &mut R, ) -> Polynomial { - let mut w_vec_i = domain.ifft(w_vec); + let mut w_vec_inverse = domain.ifft(w_vec); for i in 0..hiding_degree + 1 { // we declare and randomly select a blinding scalar - let blinding_scalar = util::random_scalar(&mut rng); - w_vec_i[i] = w_vec_i[i] - blinding_scalar; // modify the first elements of the vector - w_vec_i.push(blinding_scalar); // append last elements at the end of - // the vector + let blinding_scalar = util::random_scalar(rng); + // modify the first elements of the vector + w_vec_inverse[i] = w_vec_inverse[i] - blinding_scalar; + // append last elements at the end of the vector + w_vec_inverse.push(blinding_scalar); } - Polynomial::from_coefficients_vec(w_vec_i) + Polynomial::from_coefficients_vec(w_vec_inverse) } /// Creates a [`Proof]` that demonstrates that a circuit is satisfied. @@ -183,7 +184,7 @@ impl Prover { &self, commit_key: &CommitKey, prover_key: &ProverKey, - mut rng: &mut R, + rng: &mut R, ) -> Result { // make sure the domain is big enough to handle the circuit as well as // the lookup table @@ -211,10 +212,10 @@ impl Prover { // Wires are now in evaluation form, convert them to coefficients so // that we may commit to them - let a_w_poly = Prover::blind_poly(&a_w_scalar, 1, &domain, &mut rng); - let b_w_poly = Prover::blind_poly(&b_w_scalar, 1, &domain, &mut rng); - let c_w_poly = Prover::blind_poly(&c_w_scalar, 1, &domain, &mut rng); - let d_w_poly = Prover::blind_poly(&d_w_scalar, 1, &domain, &mut rng); + let a_w_poly = Prover::blind_poly(&a_w_scalar, 1, &domain, rng); + let b_w_poly = Prover::blind_poly(&b_w_scalar, 1, &domain, rng); + let c_w_poly = Prover::blind_poly(&c_w_scalar, 1, &domain, rng); + let d_w_poly = Prover::blind_poly(&d_w_scalar, 1, &domain, rng); // Commit to wire polynomials // ([a(x)]_1, [b(x)]_1, [c(x)]_1, [d(x)]_1) @@ -289,7 +290,7 @@ impl Prover { // Compute long query poly let f_poly = - Prover::blind_poly(&compressed_f_multiset.0, 1, &domain, &mut rng); + Prover::blind_poly(&compressed_f_multiset.0, 1, &domain, rng); // Commit to query polynomial let f_poly_commit = commit_key.commit(&f_poly)?; @@ -306,8 +307,8 @@ impl Prover { let (h_1, h_2) = s.halve_alternating(); // Compute h polys - let h_1_poly = Prover::blind_poly(&h_1.0, 2, &domain, &mut rng); - let h_2_poly = Prover::blind_poly(&h_2.0, 1, &domain, &mut rng); + let h_1_poly = Prover::blind_poly(&h_1.0, 2, &domain, rng); + let h_2_poly = Prover::blind_poly(&h_2.0, 1, &domain, rng); // Commit to h polys let h_1_poly_commit = commit_key.commit(&h_1_poly).unwrap(); @@ -340,7 +341,7 @@ impl Prover { ), 2, &domain, - &mut rng, + rng, ); // Commit to permutation polynomial @@ -362,7 +363,7 @@ impl Prover { ), 2, &domain, - &mut rng, + rng, ); // Commit to permutation polynomial @@ -602,7 +603,7 @@ impl Prover { pub fn prove( &mut self, commit_key: &CommitKey, - mut rng: &mut R, + rng: &mut R, ) -> Result { let prover_key: &ProverKey; @@ -619,7 +620,7 @@ impl Prover { prover_key = self.prover_key.as_ref().unwrap(); let proof = - self.prove_with_preprocessed(commit_key, prover_key, &mut rng)?; + self.prove_with_preprocessed(commit_key, prover_key, rng)?; // Clear witness and reset composer variables self.clear_witness(); diff --git a/src/proof_system/widget/permutation/proverkey.rs b/src/proof_system/widget/permutation/proverkey.rs index 00992a6a..e07847f7 100644 --- a/src/proof_system/widget/permutation/proverkey.rs +++ b/src/proof_system/widget/permutation/proverkey.rs @@ -142,6 +142,7 @@ impl ProverKey { &self.s_sigma_4.0, ); + // the poly is increased by 2 after blinding it let domain = EvaluationDomain::new(z_poly.degree() - 2).unwrap(); let c = self.compute_linearizer_check_is_one( &domain,