mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 15:53:10 +00:00
Add insert gadget to insert inferred leaf in FRI query rounds
This commit is contained in:
parent
fa229d9a27
commit
cfa5807556
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
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]),
|
||||
|
||||
29
src/gadgets/insert.rs
Normal file
29
src/gadgets/insert.rs
Normal file
@ -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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// 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<D>,
|
||||
mut v: Vec<ExtensionTarget<D>>,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pub mod arithmetic;
|
||||
pub mod hash;
|
||||
pub mod insert;
|
||||
pub mod interpolation;
|
||||
pub mod polynomial;
|
||||
pub mod range_check;
|
||||
|
||||
@ -37,6 +37,22 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn rotate_right_fixed(
|
||||
&mut self,
|
||||
b: Target,
|
||||
k: usize,
|
||||
v: &[ExtensionTarget<D>],
|
||||
len: usize,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
v
|
||||
}
|
||||
|
||||
pub fn rotate_right_from_bits(
|
||||
&mut self,
|
||||
num_rotation_bits: &[Target],
|
||||
v: &[ExtensionTarget<D>],
|
||||
len_log: usize,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
self.rotate_left_from_bits(&bits, v, len_log)
|
||||
}
|
||||
|
||||
pub fn rotate_right(
|
||||
&mut self,
|
||||
num_rotation: Target,
|
||||
v: &[ExtensionTarget<D>],
|
||||
len_log: usize,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
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)]
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user