Started query round

This commit is contained in:
wborgeaud 2021-06-08 19:32:23 +02:00
parent c6c71ef574
commit e1e4bb36db
2 changed files with 122 additions and 99 deletions

View File

@ -228,3 +228,22 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
ExtensionTarget(arr) ExtensionTarget(arr)
} }
} }
/// Flatten the slice by sending every extension target to its D-sized canonical representation.
pub fn flatten_target<const D: usize>(l: &[ExtensionTarget<D>]) -> Vec<Target> {
l.iter()
.flat_map(|x| x.to_target_array().to_vec())
.collect()
}
/// Batch every D-sized chunks into extension targets.
pub fn unflatten_target<const D: usize>(l: &[Target]) -> Vec<ExtensionTarget<D>> {
debug_assert_eq!(l.len() % D, 0);
l.chunks_exact(D)
.map(|c| {
let mut arr = Default::default();
arr.copy_from_slice(c);
ExtensionTarget(arr)
})
.collect()
}

View File

@ -2,7 +2,7 @@ use anyhow::{ensure, Result};
use itertools::izip; use itertools::izip;
use crate::circuit_builder::CircuitBuilder; use crate::circuit_builder::CircuitBuilder;
use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::target::{flatten_target, ExtensionTarget};
use crate::field::extension_field::{flatten, Extendable, FieldExtension, OEF}; use crate::field::extension_field::{flatten, Extendable, FieldExtension, OEF};
use crate::field::field::Field; use crate::field::field::Field;
use crate::field::lagrange::{barycentric_weights, interpolant, interpolate}; use crate::field::lagrange::{barycentric_weights, interpolant, interpolate};
@ -12,8 +12,8 @@ use crate::merkle_proofs::verify_merkle_proof;
use crate::plonk_challenger::{Challenger, RecursiveChallenger}; use crate::plonk_challenger::{Challenger, RecursiveChallenger};
use crate::plonk_common::reduce_with_iter; use crate::plonk_common::reduce_with_iter;
use crate::proof::{ use crate::proof::{
FriInitialTreeProof, FriInitialTreeProofTarget, FriProof, FriProofTarget, FriQueryRound, Hash, FriInitialTreeProof, FriInitialTreeProofTarget, FriProof, FriProofTarget, FriQueryRound,
HashTarget, OpeningSet, OpeningSetTarget, FriQueryRoundTarget, Hash, HashTarget, OpeningSet, OpeningSetTarget,
}; };
use crate::target::Target; use crate::target::Target;
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
@ -21,7 +21,7 @@ use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> { 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 /// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity
/// and P' is the FRI reduced polynomial. /// and P' is the FRI reduced polynomial.
fn compute_evaluation() { fn compute_evaluation(&mut self) {
todo!(); todo!();
// debug_assert_eq!(last_evals.len(), 1 << arity_bits); // debug_assert_eq!(last_evals.len(), 1 << arity_bits);
// //
@ -243,99 +243,103 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
sum sum
} }
//
// fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>( fn fri_verifier_query_round(
// os: &OpeningSet<F, D>, &mut self,
// zeta: F::Extension, os: &OpeningSetTarget<D>,
// alpha: F::Extension, zeta: ExtensionTarget<D>,
// initial_merkle_roots: &[Hash<F>], alpha: ExtensionTarget<D>,
// proof: &FriProof<F, D>, initial_merkle_roots: &[HashTarget],
// challenger: &mut Challenger<F>, proof: &FriProofTarget<D>,
// n: usize, challenger: &mut RecursiveChallenger,
// betas: &[F::Extension], n: usize,
// round_proof: &FriQueryRound<F, D>, betas: &[ExtensionTarget<D>],
// config: &FriConfig, round_proof: &FriQueryRoundTarget<D>,
// ) -> Result<()> { config: &FriConfig,
// let mut evaluations: Vec<Vec<F::Extension>> = Vec::new(); ) -> Result<()> {
// let x = challenger.get_challenge(); let mut evaluations: Vec<Vec<ExtensionTarget<D>>> = Vec::new();
// let mut domain_size = n; // TODO: Do we need to range check `x_index` to a target smaller than `p`?
// let mut x_index = x.to_canonical_u64() as usize % n; let mut x_index = challenger.get_challenge(self);
// fri_verify_initial_proof( let mut domain_size = n;
// x_index, self.fri_verify_initial_proof(
// &round_proof.initial_trees_proof, x_index,
// initial_merkle_roots, &round_proof.initial_trees_proof,
// )?; initial_merkle_roots,
// let mut old_x_index = 0; );
// // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain. let mut old_x_index = self.zero();
// let log_n = log2_strict(n); // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
// let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR let log_n = log2_strict(n);
// * F::primitive_root_of_unity(log_n).exp(reverse_bits(x_index, log_n) as u64); // TODO: The verifier will need to check these constants at some point (out of circuit).
// for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() { let g = self.constant(F::MULTIPLICATIVE_GROUP_GENERATOR);
// let arity = 1 << arity_bits; let phi = self.constant(F::primitive_root_of_unity(log_n));
// let next_domain_size = domain_size >> arity_bits; // TODO: Gate for this.
// let e_x = if i == 0 { let reversed_x = self.reverse_bits(x_index, log_n);
// fri_combine_initial( let phi = self.exp(phi, reversed_x);
// &round_proof.initial_trees_proof, let mut subgroup_x = self.mul(g, phi);
// alpha, for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() {
// os, let arity = 1 << arity_bits;
// zeta, let next_domain_size = domain_size >> arity_bits;
// subgroup_x, let e_x = if i == 0 {
// config, self.fri_combine_initial(
// ) &round_proof.initial_trees_proof,
// } else { alpha,
// let last_evals = &evaluations[i - 1]; os,
// // Infer P(y) from {P(x)}_{x^arity=y}. zeta,
// compute_evaluation( subgroup_x,
// subgroup_x, )
// old_x_index, } else {
// config.reduction_arity_bits[i - 1], let last_evals = &evaluations[i - 1];
// last_evals, // Infer P(y) from {P(x)}_{x^arity=y}.
// betas[i - 1], self.compute_evaluation(
// ) subgroup_x,
// }; old_x_index,
// let mut evals = round_proof.steps[i].evals.clone(); config.reduction_arity_bits[i - 1],
// // Insert P(y) into the evaluation vector, since it wasn't included by the prover. last_evals,
// evals.insert(x_index & (arity - 1), e_x); betas[i - 1],
// evaluations.push(evals); )
// verify_merkle_proof( };
// flatten(&evaluations[i]), let mut evals = round_proof.steps[i].evals.clone();
// x_index >> arity_bits, // Insert P(y) into the evaluation vector, since it wasn't included by the prover.
// proof.commit_phase_merkle_roots[i], evals.insert(x_index & (arity - 1), e_x);
// &round_proof.steps[i].merkle_proof, evaluations.push(evals);
// false, self.verify_merkle_proof(
// )?; flatten_target(&evaluations[i]),
// x_index >> arity_bits,
// if i > 0 { proof.commit_phase_merkle_roots[i],
// // Update the point x to x^arity. &round_proof.steps[i].merkle_proof,
// for _ in 0..config.reduction_arity_bits[i - 1] { )?;
// subgroup_x = subgroup_x.square();
// } if i > 0 {
// } // Update the point x to x^arity.
// domain_size = next_domain_size; for _ in 0..config.reduction_arity_bits[i - 1] {
// old_x_index = x_index; subgroup_x = self.mul(subgroup_x, subgroup_x);
// x_index >>= arity_bits; }
// } }
// domain_size = next_domain_size;
// let last_evals = evaluations.last().unwrap(); old_x_index = x_index;
// let final_arity_bits = *config.reduction_arity_bits.last().unwrap(); x_index >>= arity_bits;
// let purported_eval = compute_evaluation( }
// subgroup_x,
// old_x_index, let last_evals = evaluations.last().unwrap();
// final_arity_bits, let final_arity_bits = *config.reduction_arity_bits.last().unwrap();
// last_evals, let purported_eval = self.compute_evaluation(
// *betas.last().unwrap(), subgroup_x,
// ); old_x_index,
// for _ in 0..final_arity_bits { final_arity_bits,
// subgroup_x = subgroup_x.square(); last_evals,
// } *betas.last().unwrap(),
// );
// // Final check of FRI. After all the reductions, we check that the final polynomial is equal for _ in 0..final_arity_bits {
// // to the one sent by the prover. subgroup_x = self.mul(subgroup_x, subgroup_x);
// ensure!( }
// proof.final_poly.eval(subgroup_x.into()) == purported_eval,
// "Final polynomial evaluation is invalid." // Final check of FRI. After all the reductions, we check that the final polynomial is equal
// ); // to the one sent by the prover.
// ensure!(
// Ok(()) proof.final_poly.eval(subgroup_x.into()) == purported_eval,
// } "Final polynomial evaluation is invalid."
);
Ok(())
}
} }