diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index a135f5f0..45c94173 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -196,6 +196,11 @@ fn fri_combine_initial, const D: usize>( let wire_composition_eval = reduce_with_iter(wire_evals, alpha_powers.clone()); let zeta_frob = zeta.frobenius(); let wire_eval = reduce_with_iter(&os.wires, alpha_powers.clone()); + // We want to compute `sum a^i*phi(w_i)`, where `phi` denotes the Frobenius automorphism. + // Since `phi^D=id` and `phi` is a field automorphism, we have the following equalities: + // `sum a^i*phi(w_i) = sum phi(phi^(D-1)(a^i)*w_i) = phi(sum phi^(D-1)(a)^i*w_i)` + // So we can compute the original sum using only one call to the `D-1`-repeated Frobenius of alpha, + // and one call at the end of the sum. let alpha_powers_frob = alpha_powers.repeated_frobenius(D - 1); let wire_eval_frob = reduce_with_iter(&os.wires, alpha_powers_frob).frobenius(); let wires_interpol = interpolant(&[(zeta, wire_eval), (zeta_frob, wire_eval_frob)]); diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index 50a5e579..10189841 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -18,7 +18,7 @@ impl, const D: usize> CircuitBuilder { Target::wires_from_range( gate, - BaseSumGate::::WIRE_LIMBS_START..BaseSumGate::::WIRE_LIMBS_START + num_limbs, + BaseSumGate::::START_LIMBS..BaseSumGate::::START_LIMBS + num_limbs, ) } diff --git a/src/gadgets/split_join.rs b/src/gadgets/split_join.rs index 647b0ef5..2a388e35 100644 --- a/src/gadgets/split_join.rs +++ b/src/gadgets/split_join.rs @@ -29,7 +29,7 @@ impl, const D: usize> CircuitBuilder { /// Verifies that the decomposition is correct by using `k` `BaseSum<2>` gates /// with `k` such that `k*num_routed_wires>=num_bits`. pub(crate) fn split_le(&mut self, integer: Target, num_bits: usize) -> Vec { - let num_limbs = self.config.num_routed_wires - BaseSumGate::<2>::WIRE_LIMBS_START; + let num_limbs = self.config.num_routed_wires - BaseSumGate::<2>::START_LIMBS; let k = ceil_div_usize(num_bits, num_limbs); let gates = (0..k) .map(|_| self.add_gate_no_constants(BaseSumGate::<2>::new(num_limbs))) @@ -39,7 +39,7 @@ impl, const D: usize> CircuitBuilder { for &gate in &gates { bits.extend(Target::wires_from_range( gate, - BaseSumGate::<2>::WIRE_LIMBS_START..BaseSumGate::<2>::WIRE_LIMBS_START + num_limbs, + BaseSumGate::<2>::START_LIMBS..BaseSumGate::<2>::START_LIMBS + num_limbs, )); } bits.drain(num_bits..); diff --git a/src/gates/base_sum.rs b/src/gates/base_sum.rs index 150a492e..0792ea7a 100644 --- a/src/gates/base_sum.rs +++ b/src/gates/base_sum.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use crate::circuit_builder::CircuitBuilder; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; @@ -8,9 +10,8 @@ use crate::plonk_common::{reduce_with_powers, reduce_with_powers_recursive}; use crate::target::Target; use crate::vars::{EvaluationTargets, EvaluationVars}; use crate::witness::PartialWitness; -use std::ops::Range; -/// A gate which can sum base W limbs and the reversed limbs. +/// A gate which can sum base B limbs and the reversed limbs. #[derive(Debug)] pub struct BaseSumGate { num_limbs: usize, @@ -23,11 +24,11 @@ impl BaseSumGate { pub const WIRE_SUM: usize = 0; pub const WIRE_REVERSED_SUM: usize = 1; - pub const WIRE_LIMBS_START: usize = 2; + pub const START_LIMBS: usize = 2; /// Returns the index of the `i`th limb wire. pub fn limbs(&self) -> Range { - Self::WIRE_LIMBS_START..Self::WIRE_LIMBS_START + self.num_limbs + Self::START_LIMBS..Self::START_LIMBS + self.num_limbs } } @@ -66,10 +67,10 @@ impl, const D: usize, const B: usize> Gate for BaseSumGat let mut limbs = vars.local_wires[self.limbs()].to_vec(); let computed_sum = reduce_with_powers_recursive(builder, &limbs, base); limbs.reverse(); - let reversed_computed_sum = reduce_with_powers_recursive(builder, &limbs, base); + let computed_reversed_sum = reduce_with_powers_recursive(builder, &limbs, base); let mut constraints = vec![ builder.sub_extension(computed_sum, sum), - builder.sub_extension(reversed_computed_sum, reversed_sum), + builder.sub_extension(computed_reversed_sum, reversed_sum), ]; for limb in limbs { constraints.push({ @@ -138,8 +139,7 @@ impl SimpleGenerator for BaseSplitGenerator { "Integer too large to fit in given number of limbs" ); - let limbs = (BaseSumGate::::WIRE_LIMBS_START - ..BaseSumGate::::WIRE_LIMBS_START + self.num_limbs) + let limbs = (BaseSumGate::::START_LIMBS..BaseSumGate::::START_LIMBS + self.num_limbs) .map(|i| Target::wire(self.gate_index, i)); let limbs_value = (0..self.num_limbs) .scan(sum_value, |acc, _| {