From dea6db00ac54e24389870ed953f3ad7a66e4f5e8 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 10 Jun 2021 17:45:45 +0200 Subject: [PATCH] Rotation gadgets --- src/field/extension_field/algebra.rs | 1 - src/fri/recursive_verifier.rs | 2 +- src/fri/verifier.rs | 2 +- src/gadgets/mod.rs | 1 + src/gadgets/rotate.rs | 66 ++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/gadgets/rotate.rs diff --git a/src/field/extension_field/algebra.rs b/src/field/extension_field/algebra.rs index eac0bbd8..f61f173b 100644 --- a/src/field/extension_field/algebra.rs +++ b/src/field/extension_field/algebra.rs @@ -218,7 +218,6 @@ mod tests { let y = ExtensionAlgebra::from_basefield_array(arr1); let z = x * y; - dbg!(z.0, mul_mle(ts.clone())); assert_eq!(z.0, mul_mle(ts)); } diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index 25fb7687..4f8c3864 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -326,7 +326,7 @@ impl, const D: usize> CircuitBuilder { } } domain_size = next_domain_size; - old_x_index = x_index; + old_x_index = low_x_index; x_index = high_x_index; } diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index 41baa84e..6275ada6 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -279,7 +279,7 @@ fn fri_verifier_query_round, const D: usize>( } } domain_size = next_domain_size; - old_x_index = x_index; + old_x_index = x_index & (arity - 1); x_index >>= arity_bits; } diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index 636f8afc..137b991e 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -3,5 +3,6 @@ pub mod hash; pub mod interpolation; pub mod polynomial; pub mod range_check; +pub mod rotate; pub mod split_base; pub(crate) mod split_join; diff --git a/src/gadgets/rotate.rs b/src/gadgets/rotate.rs new file mode 100644 index 00000000..fa5579f7 --- /dev/null +++ b/src/gadgets/rotate.rs @@ -0,0 +1,66 @@ +use crate::circuit_builder::CircuitBuilder; +use crate::field::extension_field::Extendable; +use crate::field::field::Field; +use crate::gates::base_sum::BaseSumGate; +use crate::generator::SimpleGenerator; +use crate::target::Target; +use crate::witness::PartialWitness; + +impl, const D: usize> CircuitBuilder { + /// Selects `x` or `y` based on `b`, which is assumed to be binary. + /// In particular, this returns `if b { x } else { y }`. + /// Note: This does not range-check `b`. + pub fn select(&mut self, b: Target, x: Target, y: Target) -> Target { + let b_y_minus_y = self.mul_sub(b, y, y); + self.mul_sub(b, x, b_y_minus_y) + } + + /// Left-rotates an array if `b=1` else return the same array. + pub fn rotate_once(&mut self, b: Target, v: Vec, len: usize) -> Vec { + debug_assert_eq!(v.len(), len); + let mut res = Vec::new(); + + for i in 0..len { + res.push(self.select(b, v[(i + 1) % len], v[i])); + } + + res + } + + pub fn split_unary(&mut self, x: Target, len: usize) -> Vec { + todo!() + } + + /// Left-rotates an array by `num_rotation`. Assumes that `num_rotation` is range-checked to be + /// less than `len`. + pub fn rotate(&mut self, num_rotation: Target, v: Vec, len: usize) -> Vec { + // Decompose `num_rotation` into `len` 1-ary limbs, possibly with a new gate. + // Then apply `rotate_once` `len` time using the 1-ary limbs. + todo!() + } +} + +#[derive(Debug)] +struct UnaryBaseGenerator { + integer: Target, + len: usize, + limbs: Vec, +} + +impl SimpleGenerator for UnaryBaseGenerator { + fn dependencies(&self) -> Vec { + vec![self.integer] + } + + fn run_once(&self, witness: &PartialWitness) -> PartialWitness { + let mut integer_value = witness.get_target(self.integer).to_canonical_u64(); + let low = integer_value & ((1 << self.n_log) - 1); + let high = integer_value >> self.n_log; + + let mut result = PartialWitness::new(); + result.set_target(self.low, F::from_canonical_u64(low)); + result.set_target(self.high, F::from_canonical_u64(high)); + + result + } +}