diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index a424dee0..4219aefc 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -1,22 +1,16 @@ -use anyhow::{ensure, Result}; use itertools::izip; use crate::circuit_builder::CircuitBuilder; use crate::field::extension_field::target::{flatten_target, ExtensionTarget}; -use crate::field::extension_field::{flatten, Extendable, FieldExtension, OEF}; +use crate::field::extension_field::Extendable; use crate::field::field::Field; -use crate::field::lagrange::{barycentric_weights, interpolant, interpolate}; use crate::fri::FriConfig; -use crate::hash::hash_n_to_1; -use crate::merkle_proofs::verify_merkle_proof; -use crate::plonk_challenger::{Challenger, RecursiveChallenger}; -use crate::plonk_common::reduce_with_iter; +use crate::plonk_challenger::RecursiveChallenger; use crate::proof::{ - FriInitialTreeProof, FriInitialTreeProofTarget, FriProof, FriProofTarget, FriQueryRound, - FriQueryRoundTarget, Hash, HashTarget, OpeningSet, OpeningSetTarget, + FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, HashTarget, OpeningSetTarget, }; use crate::target::Target; -use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; +use crate::util::{log2_strict, reverse_index_bits_in_place}; impl, const D: usize> CircuitBuilder { /// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity @@ -180,7 +174,7 @@ impl, const D: usize> CircuitBuilder { } let denominator = self.sub_extension(subgroup_x, zeta); let quotient = self.div_unsafe_extension(numerator, denominator); - let sum = self.add_extension(sum, quotient); + sum = self.add_extension(sum, quotient); let evs = proof .unsalted_evals(3, config) @@ -213,7 +207,7 @@ impl, const D: usize> CircuitBuilder { let vanish_right = self.sub_extension(subgroup_x, zeta_right); let denominator = self.mul_extension(vanish, vanish_right); let quotient = self.div_unsafe_extension(numerator, denominator); - let sum = self.add_extension(sum, quotient); + sum = self.add_extension(sum, quotient); let evs = proof .unsalted_evals(2, config) @@ -245,7 +239,7 @@ impl, const D: usize> CircuitBuilder { let vanish_frob = self.sub_extension(subgroup_x, zeta_frob); let denominator = self.mul_extension(vanish, vanish_frob); let quotient = self.div_unsafe_extension(numerator, denominator); - let sum = self.add_extension(sum, quotient); + sum = self.add_extension(sum, quotient); sum } @@ -285,7 +279,6 @@ impl, const D: usize> CircuitBuilder { let mut subgroup_x = self.mul(g, phi); for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() { - let arity = 1 << arity_bits; let next_domain_size = domain_size >> arity_bits; let e_x = if i == 0 { self.fri_combine_initial( @@ -309,8 +302,7 @@ impl, const D: usize> CircuitBuilder { let mut evals = round_proof.steps[i].evals.clone(); // Insert P(y) into the evaluation vector, since it wasn't included by the prover. let (low_x_index, high_x_index) = self.split_low_high(x_index, arity_bits); - // TODO: Uncomment this. - // evals.insert(x_index & (arity - 1), e_x); + evals = self.insert(low_x_index, e_x, evals); evaluations.push(evals); self.verify_merkle_proof( flatten_target(&evaluations[i]), diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs new file mode 100644 index 00000000..e8a1f6a4 --- /dev/null +++ b/src/gadgets/insert.rs @@ -0,0 +1,29 @@ +use crate::circuit_builder::CircuitBuilder; +use crate::field::extension_field::target::ExtensionTarget; +use crate::field::extension_field::Extendable; +use crate::target::Target; +use crate::util::log2_strict; + +impl, const D: usize> CircuitBuilder { + /// Inserts a `Target` in a vector at a non-deterministic index. This is done by rotating to the + /// left, inserting at 0 and then rotating to the right. + /// Note: `index` is not range-checked. + pub fn insert( + &mut self, + index: Target, + element: ExtensionTarget, + mut v: Vec>, + ) -> Vec> { + let n = v.len(); + debug_assert!(n.is_power_of_two()); + let n_log = log2_strict(n); + + v.push(self.zero_extension()); + let mut v = self.rotate_left(index, &v, n_log); + + v.insert(0, element); + v.pop().unwrap(); + + self.rotate_right(index, &v, n_log) + } +} diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index 137b991e..a1e041fc 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -1,5 +1,6 @@ pub mod arithmetic; pub mod hash; +pub mod insert; pub mod interpolation; pub mod polynomial; pub mod range_check; diff --git a/src/gadgets/rotate.rs b/src/gadgets/rotate.rs index 12bf3bc0..cc3c7fce 100644 --- a/src/gadgets/rotate.rs +++ b/src/gadgets/rotate.rs @@ -37,6 +37,22 @@ impl, const D: usize> CircuitBuilder { res } + pub fn rotate_right_fixed( + &mut self, + b: Target, + k: usize, + v: &[ExtensionTarget], + len: usize, + ) -> Vec> { + let mut res = Vec::new(); + + for i in 0..len { + res.push(self.select(b, v[(i - k) % len], v[i])); + } + + res + } + /// Left-rotates an array by `num_rotation`. Assumes that `num_rotation` is range-checked to be /// less than `len`. /// Note: We assume `len` is less than 8 since we won't use any arity greater than 8 in FRI (maybe?). @@ -58,6 +74,24 @@ impl, const D: usize> CircuitBuilder { v } + pub fn rotate_right_from_bits( + &mut self, + num_rotation_bits: &[Target], + v: &[ExtensionTarget], + len_log: usize, + ) -> Vec> { + debug_assert_eq!(num_rotation_bits.len(), len_log); + let len = 1 << len_log; + debug_assert_eq!(v.len(), len); + let mut v = v.to_vec(); + + for i in 0..len_log { + v = self.rotate_right_fixed(num_rotation_bits[i], 1 << i, &v, len); + } + + v + } + /// Left-rotates an array by `num_rotation`. Assumes that `num_rotation` is range-checked to be /// less than `len`. /// Note: We assume `len` is a power of two less than or equal to 8, since we won't use any @@ -74,6 +108,19 @@ impl, const D: usize> CircuitBuilder { self.rotate_left_from_bits(&bits, v, len_log) } + + pub fn rotate_right( + &mut self, + num_rotation: Target, + v: &[ExtensionTarget], + len_log: usize, + ) -> Vec> { + let len = 1 << len_log; + debug_assert_eq!(v.len(), len); + let bits = self.split_le(num_rotation, len_log); + + self.rotate_right_from_bits(&bits, v, len_log) + } } #[cfg(test)] diff --git a/src/gates/base_sum.rs b/src/gates/base_sum.rs index e3b69618..150a492e 100644 --- a/src/gates/base_sum.rs +++ b/src/gates/base_sum.rs @@ -1,5 +1,4 @@ use crate::circuit_builder::CircuitBuilder; -use crate::circuit_data::CircuitConfig; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::field::Field; @@ -8,7 +7,6 @@ use crate::generator::{SimpleGenerator, WitnessGenerator}; use crate::plonk_common::{reduce_with_powers, reduce_with_powers_recursive}; use crate::target::Target; use crate::vars::{EvaluationTargets, EvaluationVars}; -use crate::wire::Wire; use crate::witness::PartialWitness; use std::ops::Range; diff --git a/src/gates/noop.rs b/src/gates/noop.rs index eddd0361..a12df932 100644 --- a/src/gates/noop.rs +++ b/src/gates/noop.rs @@ -5,7 +5,7 @@ use crate::gates::gate::{Gate, GateRef}; use crate::generator::WitnessGenerator; use crate::vars::{EvaluationTargets, EvaluationVars}; -/// A gate which takes a single constant parameter and outputs that value. +/// A gate which does nothing. pub struct NoopGate; impl NoopGate {