diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index f29c6d08..626668e6 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; -use plonky2_field::extension_field::Extendable; +use plonky2_field::extension_field::{Extendable, FieldExtension}; use plonky2_field::field_types::Field; use plonky2_field::polynomial::PolynomialCoeffs; @@ -35,6 +35,11 @@ impl ReducingFactor { self.base * x } + fn mul_ext, const D: usize>(&mut self, x: FE) -> FE { + self.count += 1; + x.scalar_mul(self.base) + } + fn mul_poly(&mut self, p: &mut PolynomialCoeffs) { self.count += 1; *p *= self.base; @@ -45,6 +50,14 @@ impl ReducingFactor { .fold(F::ZERO, |acc, x| self.mul(acc) + *x.borrow()) } + pub fn reduce_ext, const D: usize>( + &mut self, + iter: impl DoubleEndedIterator>, + ) -> FE { + iter.rev() + .fold(FE::ZERO, |acc, x| self.mul_ext(acc) + *x.borrow()) + } + pub fn reduce_polys( &mut self, polys: impl DoubleEndedIterator>>, diff --git a/starky/src/permutation.rs b/starky/src/permutation.rs index 1113094d..dad4b661 100644 --- a/starky/src/permutation.rs +++ b/starky/src/permutation.rs @@ -11,6 +11,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::target::Target; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; +use plonky2::util::reducing::{ReducingFactor, ReducingFactorTarget}; use rayon::prelude::*; use crate::config::StarkConfig; @@ -283,19 +284,15 @@ pub(crate) fn eval_permutation_checks, Vec<_>) = column_pairs + .iter() + .map(|&(i, j)| (vars.local_values[i], vars.local_values[j])) + .unzip(); + ( + factor.reduce_ext(lhs.into_iter()) + FE::from_basefield(*gamma), + factor.reduce_ext(rhs.into_iter()) + FE::from_basefield(*gamma), + ) }) .unzip(); let constraint = next_zs[i] * reduced_rhs.into_iter().product() @@ -353,19 +350,17 @@ pub(crate) fn eval_permutation_checks_recursively( let zero = builder.zero_extension(); let beta_ext = builder.convert_to_ext(*beta); let gamma_ext = builder.convert_to_ext(*gamma); - let mut reduced = - column_pairs - .iter() - .rev() - .fold((zero, zero), |(lhs, rhs), &(i, j)| { - ( - builder.mul_add_extension(lhs, beta_ext, vars.local_values[i]), - builder.mul_add_extension(rhs, beta_ext, vars.local_values[j]), - ) - }); - reduced.0 = builder.add_extension(reduced.0, gamma_ext); - reduced.1 = builder.add_extension(reduced.1, gamma_ext); - reduced + let mut factor = ReducingFactorTarget::new(beta_ext); + let (lhs, rhs): (Vec<_>, Vec<_>) = column_pairs + .iter() + .map(|&(i, j)| (vars.local_values[i], vars.local_values[j])) + .unzip(); + let reduced_lhs = factor.reduce(&lhs, builder); + let reduced_rhs = factor.reduce(&rhs, builder); + ( + builder.add_extension(reduced_lhs, gamma_ext), + builder.add_extension(reduced_rhs, gamma_ext), + ) }) .unzip(); let reduced_lhs_product = builder.mul_many_extension(&reduced_lhs);