From f7c4a463fc8b9bac049f9f578992accafec61dc7 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Wed, 30 Jun 2021 18:54:28 +0200 Subject: [PATCH] Progress --- src/circuit_data.rs | 12 ++++++- src/plonk_common.rs | 69 ++++++++++++++++++++++++++++-------- src/prover.rs | 34 ++++++++++-------- src/util/partial_products.rs | 10 +++--- 4 files changed, 89 insertions(+), 36 deletions(-) diff --git a/src/circuit_data.rs b/src/circuit_data.rs index 6f352832..06a6700f 100644 --- a/src/circuit_data.rs +++ b/src/circuit_data.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use std::ops::{Range, RangeFrom}; use anyhow::Result; @@ -201,6 +201,16 @@ impl, const D: usize> CommonCircuitData { pub fn sigmas_range(&self) -> Range { self.num_constants..self.num_constants + self.config.num_routed_wires } + + /// Range of the constants polynomials in the `constants_sigmas_commitment`. + pub fn zs_range(&self) -> Range { + 0..self.config.num_challenges + } + + /// Range of the sigma polynomials in the `constants_sigmas_commitment`. + pub fn partial_products_range(&self) -> RangeFrom { + self.config.num_challenges.. + } } /// The `Target` version of `VerifierCircuitData`, for use inside recursive circuits. Note that this diff --git a/src/plonk_common.rs b/src/plonk_common.rs index db304c0a..3b271101 100644 --- a/src/plonk_common.rs +++ b/src/plonk_common.rs @@ -9,6 +9,7 @@ use crate::gates::gate::{GateRef, PrefixedGate}; use crate::polynomial::commitment::SALT_SIZE; use crate::polynomial::polynomial::PolynomialCoeffs; use crate::target::Target; +use crate::util::partial_products::partial_products; use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// Holds the Merkle tree index and blinding flag of a set of polynomials used in FRI. @@ -114,8 +115,9 @@ pub(crate) fn eval_vanishing_poly_base, const D: usize>( index: usize, x: F, vars: EvaluationVarsBase, - local_plonk_zs: &[F], - next_plonk_zs: &[F], + local_zs: &[F], + next_zs: &[F], + local_partial_products: &[F], s_sigmas: &[F], betas: &[F], gammas: &[F], @@ -127,29 +129,66 @@ pub(crate) fn eval_vanishing_poly_base, const D: usize>( // The L_1(x) (Z(x) - 1) vanishing terms. let mut vanishing_z_1_terms = Vec::new(); + // The terms checking the partial products. + let mut vanishing_partial_products_terms = Vec::new(); // The Z(x) f'(x) - g'(x) Z(g x) terms. let mut vanishing_v_shift_terms = Vec::new(); for i in 0..common_data.config.num_challenges { - let z_x = local_plonk_zs[i]; - let z_gz = next_plonk_zs[i]; + let z_x = local_zs[i]; + let z_gz = next_zs[i]; vanishing_z_1_terms.push(z_h_on_coset.eval_l1(index, x) * (z_x - F::ONE)); - let mut f_prime = F::ONE; - let mut g_prime = F::ONE; - for j in 0..common_data.config.num_routed_wires { - let wire_value = vars.local_wires[j]; - let k_i = common_data.k_is[j]; - let s_id = k_i * x; - let s_sigma = s_sigmas[j]; - f_prime *= wire_value + betas[i] * s_id + gammas[i]; - g_prime *= wire_value + betas[i] * s_sigma + gammas[i]; - } - vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz); + let numerator_values = (0..common_data.config.num_routed_wires) + .map(|j| { + let wire_value = vars.local_wires[j]; + let k_i = common_data.k_is[j]; + let s_id = k_i * x; + wire_value + betas[i] * s_id + gammas[i] + }) + .collect::>(); + let denominator_values = (0..common_data.config.num_routed_wires) + .map(|j| { + let wire_value = vars.local_wires[j]; + let s_sigma = s_sigmas[j]; + wire_value + betas[i] * s_sigma + gammas[i] + }) + .collect::>(); + let numerator_partial_products = + partial_products(numerator_values, common_data.max_filtered_constraint_degree); + let denominator_partial_products = partial_products( + denominator_values, + common_data.max_filtered_constraint_degree, + ); + + dbg!(numerator_partial_products + .clone() + .0 + .into_iter() + .chain(denominator_partial_products.clone().0) + .zip(local_partial_products) + .map(|(a, &b)| a - b) + .collect::>(),); + vanishing_partial_products_terms.append( + &mut numerator_partial_products + .0 + .into_iter() + .chain(denominator_partial_products.0) + .zip(local_partial_products) + .map(|(a, &b)| a - b) + .collect::>(), + ); + dbg!(&numerator_partial_products.1); + dbg!(&denominator_partial_products.1); + dbg!(common_data.max_filtered_constraint_degree); + let f_prime: F = numerator_partial_products.1.into_iter().product(); + let g_prime: F = denominator_partial_products.1.into_iter().product(); + // vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz); } let vanishing_terms = [ vanishing_z_1_terms, + vanishing_partial_products_terms, vanishing_v_shift_terms, constraint_terms, ] diff --git a/src/prover.rs b/src/prover.rs index e909c923..de5c972c 100644 --- a/src/prover.rs +++ b/src/prover.rs @@ -90,9 +90,10 @@ pub(crate) fn prove, const D: usize>( "to compute Z's" ); + let zs_partial_products = [plonk_z_vecs, partial_products.concat()].concat(); let plonk_zs_commitment = timed!( ListPolynomialCommitment::new( - plonk_z_vecs, + zs_partial_products, fri_config.rate_bits, PlonkPolynomials::ZS.blinding ), @@ -123,7 +124,7 @@ pub(crate) fn prove, const D: usize>( .flat_map(|mut quotient_poly| { quotient_poly.trim(); quotient_poly.pad(quotient_degree).expect( - "The quotient polynomial doesn't have the right degree.\ + "The quotient polynomial doesn't have the right degree. \ This may be because the `Z`s polynomials are still too high degree.", ); // Split t into degree-n chunks. @@ -202,12 +203,9 @@ fn wires_permutation_partial_products, const D: usize>( prover_data: &ProverOnlyCircuitData, common_data: &CommonCircuitData, ) -> Vec> { - let vanish_degree = common_data - .max_filtered_constraint_degree - .next_power_of_two(); - let num_polys = ceil_div_usize(common_data.config.num_routed_wires, vanish_degree); + let degree = common_data.max_filtered_constraint_degree; let subgroup = &prover_data.subgroup; - let mut values = vec![vec![F::ONE; 2 * num_polys]]; + let mut values = Vec::new(); let k_is = &common_data.k_is; for i in 1..common_data.degree() { let x = subgroup[i - 1]; @@ -228,13 +226,14 @@ fn wires_permutation_partial_products, const D: usize>( }) .collect::>(); let partials = [ - partial_products(numerator_values, vanish_degree), - partial_products(denominator_values, vanish_degree), + partial_products(numerator_values, degree).0, + partial_products(denominator_values, degree).0, ] .concat(); values.push(partials); } + values.insert(0, vec![F::ONE; values[0].len()]); transpose(&values) .into_par_iter() .map(PolynomialValues::new) @@ -280,7 +279,7 @@ fn compute_quotient_polys<'a, F: Extendable, const D: usize>( common_data: &CommonCircuitData, prover_data: &'a ProverOnlyCircuitData, wires_commitment: &'a ListPolynomialCommitment, - plonk_zs_commitment: &'a ListPolynomialCommitment, + zs_partial_products_commitment: &'a ListPolynomialCommitment, betas: &[F], gammas: &[F], alphas: &[F], @@ -322,11 +321,15 @@ fn compute_quotient_polys<'a, F: Extendable, const D: usize>( let local_constants = &local_constants_sigmas[common_data.constants_range()]; let s_sigmas = &local_constants_sigmas[common_data.sigmas_range()]; let local_wires = get_at_index(wires_commitment, i); - let local_plonk_zs = get_at_index(plonk_zs_commitment, i); - let next_plonk_zs = get_at_index(plonk_zs_commitment, i_next); + let local_zs_partial_products = get_at_index(zs_partial_products_commitment, i); + let local_zs = &local_zs_partial_products[common_data.zs_range()]; + let next_zs = + &get_at_index(zs_partial_products_commitment, i_next)[common_data.zs_range()]; + let local_partial_products = + &local_zs_partial_products[common_data.partial_products_range()]; debug_assert_eq!(local_wires.len(), common_data.config.num_wires); - debug_assert_eq!(local_plonk_zs.len(), num_challenges); + debug_assert_eq!(local_zs.len(), num_challenges); let vars = EvaluationVarsBase { local_constants, @@ -337,8 +340,9 @@ fn compute_quotient_polys<'a, F: Extendable, const D: usize>( i, shifted_x, vars, - local_plonk_zs, - next_plonk_zs, + local_zs, + next_zs, + local_partial_products, s_sigmas, betas, gammas, diff --git a/src/util/partial_products.rs b/src/util/partial_products.rs index 0546d133..c31fbff6 100644 --- a/src/util/partial_products.rs +++ b/src/util/partial_products.rs @@ -1,19 +1,19 @@ use std::iter::Product; -pub fn partial_products(v: Vec, max_degree: usize) -> Vec { +pub fn partial_products(v: Vec, max_degree: usize) -> (Vec, Vec) { let mut res = Vec::new(); let mut remainder = v; - while remainder.len() > max_degree { + while remainder.len() >= max_degree { let new_partials = remainder .chunks(max_degree) - .filter(|chunk| chunk.len() != 1) // Don't need to compute the product in this case. + // TODO: If `chunk.len()=1`, there's some redundant data. .map(|chunk| chunk.iter().copied().product()) .collect::>(); res.extend_from_slice(&new_partials); remainder = new_partials; } - res + (res, remainder) } #[cfg(test)] @@ -24,7 +24,7 @@ mod tests { fn test_partial_products() { assert_eq!( partial_products(vec![1, 2, 3, 4, 5, 6], 2), - vec![2, 12, 30, 24] + (vec![2, 12, 30, 24, 30], vec![24, 30]) ); } }