diff --git a/src/field/extension_field/target.rs b/src/field/extension_field/target.rs index c00470ac..7efd0f3b 100644 --- a/src/field/extension_field/target.rs +++ b/src/field/extension_field/target.rs @@ -19,10 +19,12 @@ impl ExtensionTarget { pub fn frobenius>(&self, builder: &mut CircuitBuilder) -> Self { let arr = self.to_target_array(); let k = (F::ORDER - 1) / (D as u64); - let zs = (0..D as u64).map(|i| builder.constant(F::Extension::W.exp(k * i))); + let zs = (0..D as u64) + .map(|i| builder.constant(F::Extension::W.exp(k * i))) + .collect::>(); let mut res = Vec::with_capacity(D); - for (z, a) in zs.zip(arr) { + for (z, a) in zs.into_iter().zip(arr) { res.push(builder.mul(z, a)); } diff --git a/src/gadgets/rotate.rs b/src/gadgets/rotate.rs index acc78734..19230dc0 100644 --- a/src/gadgets/rotate.rs +++ b/src/gadgets/rotate.rs @@ -16,8 +16,7 @@ impl, const D: usize> CircuitBuilder { } /// Left-rotates an array `k` times if `b=1` else return the same array. - pub fn rotate_fixed(&mut self, b: Target, k: usize, v: Vec, len: usize) -> Vec { - debug_assert_eq!(v.len(), len); + pub fn rotate_fixed(&mut self, b: Target, k: usize, v: &[Target], len: usize) -> Vec { let mut res = Vec::new(); for i in 0..len { @@ -30,13 +29,56 @@ impl, const D: usize> CircuitBuilder { /// 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?). - pub fn rotate(&mut self, num_rotation: Target, mut v: Vec, len: usize) -> Vec { + pub fn rotate(&mut self, num_rotation: Target, v: &[Target], len: usize) -> Vec { + debug_assert_eq!(v.len(), len); let bits = self.split_le_base::<2>(num_rotation, 3); - v = self.rotate_fixed(bits[0], 1, v, len); - v = self.rotate_fixed(bits[1], 2, v, len); - v = self.rotate_fixed(bits[2], 4, v, len); + let v = self.rotate_fixed(bits[0], 1, v, len); + let v = self.rotate_fixed(bits[1], 2, &v, len); + let v = self.rotate_fixed(bits[2], 4, &v, len); v } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::circuit_data::CircuitConfig; + use crate::field::crandall_field::CrandallField; + + fn real_rotate(num_rotation: usize, v: &[Target]) -> Vec { + let mut res = v.to_vec(); + res.rotate_left(num_rotation); + res + } + + fn test_rotate_given_len(len: usize) { + type F = CrandallField; + let config = CircuitConfig::large_config(); + let mut builder = CircuitBuilder::::new(config); + let v = (0..len) + .map(|_| builder.constant(F::rand())) + .collect::>(); // 416 = 1532 in base 6. + + for i in 0..len { + let it = builder.constant(F::from_canonical_usize(i)); + let rotated = real_rotate(i, &v); + let purported_rotated = builder.rotate(it, &v, len); + + for (x, y) in rotated.into_iter().zip(purported_rotated) { + builder.assert_equal(x, y); + } + } + + let data = builder.build(); + let proof = data.prove(PartialWitness::new()); + } + + #[test] + fn test_rotate() { + for i_log in 1..4 { + test_rotate_given_len(1 << i_log); + } + } +} diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index 94d3c3bc..f10de655 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -71,10 +71,6 @@ mod tests { use super::*; use crate::circuit_data::CircuitConfig; use crate::field::crandall_field::CrandallField; - use crate::fri::FriConfig; - use crate::prover::PLONK_BLINDING; - use crate::verifier::verify; - use anyhow::Result; #[test] fn test_split_base() {