mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
First impl
This commit is contained in:
parent
fbbe5398d6
commit
f27620ca90
@ -9,6 +9,7 @@ use crate::merkle_proofs::verify_merkle_proof;
|
||||
use crate::plonk_challenger::Challenger;
|
||||
use crate::plonk_common::reduce_with_iter;
|
||||
use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, Hash, OpeningSet};
|
||||
use crate::util::scaling::ScalingFactor;
|
||||
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
|
||||
|
||||
/// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity
|
||||
@ -151,7 +152,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let degree_log = proof.evals_proofs[0].1.siblings.len() - config.rate_bits;
|
||||
let subgroup_x = F::Extension::from_basefield(subgroup_x);
|
||||
let mut alpha_powers = alpha.powers();
|
||||
let mut alpha = ScalingFactor::new(alpha);
|
||||
let mut sum = F::Extension::ZERO;
|
||||
|
||||
// We will add three terms to `sum`:
|
||||
@ -160,53 +161,56 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
// - one for wire polynomials, which are opened at `x` and its conjugate
|
||||
|
||||
// Polynomials opened at `x`, i.e., the constants, sigmas and quotient polynomials.
|
||||
let single_evals = [0, 1, 4]
|
||||
.iter()
|
||||
.flat_map(|&i| proof.unsalted_evals(i, config))
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let single_evals = &proof
|
||||
.unsalted_evals(0, config)
|
||||
.into_iter()
|
||||
.chain(proof.unsalted_evals(1, config))
|
||||
.chain(proof.unsalted_evals(4, config))
|
||||
.map(|e| F::Extension::from_basefield(e));
|
||||
let single_openings = os
|
||||
.constants
|
||||
.iter()
|
||||
.chain(&os.plonk_s_sigmas)
|
||||
.chain(&os.quotient_polys);
|
||||
let single_diffs = single_evals.zip(single_openings).map(|(e, &o)| e - o);
|
||||
let single_numerator = reduce_with_iter(single_diffs, &mut alpha_powers);
|
||||
.clone()
|
||||
.into_iter()
|
||||
.chain(os.plonk_s_sigmas.clone())
|
||||
.chain(os.quotient_polys.clone());
|
||||
let single_diffs = single_evals.zip(single_openings).map(|(e, o)| e - o);
|
||||
dbg!(single_diffs.rev());
|
||||
let single_numerator = alpha.scale(single_diffs);
|
||||
let single_denominator = subgroup_x - zeta;
|
||||
sum += single_numerator / single_denominator;
|
||||
alpha.shift(sum);
|
||||
|
||||
// Polynomials opened at `x` and `g x`, i.e., the Zs polynomials.
|
||||
let zs_evals = proof
|
||||
.unsalted_evals(3, config)
|
||||
.iter()
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let zs_composition_eval = reduce_with_iter(zs_evals, alpha_powers.clone());
|
||||
let zs_composition_eval = alpha.clone().scale(zs_evals);
|
||||
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta;
|
||||
let zs_interpol = interpolant(&[
|
||||
(zeta, reduce_with_iter(&os.plonk_zs, alpha_powers.clone())),
|
||||
(
|
||||
zeta_right,
|
||||
reduce_with_iter(&os.plonk_zs_right, &mut alpha_powers),
|
||||
),
|
||||
(zeta, alpha.clone().scale(&os.plonk_zs)),
|
||||
(zeta_right, alpha.scale(&os.plonk_zs_right)),
|
||||
]);
|
||||
let zs_numerator = zs_composition_eval - zs_interpol.eval(subgroup_x);
|
||||
let zs_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_right);
|
||||
sum += zs_numerator / zs_denominator;
|
||||
alpha.shift(sum);
|
||||
|
||||
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
|
||||
let wire_evals = proof
|
||||
.unsalted_evals(2, config)
|
||||
.iter()
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let wire_composition_eval = reduce_with_iter(wire_evals, alpha_powers.clone());
|
||||
let wire_composition_eval = alpha.clone().scale(wire_evals);
|
||||
let zeta_frob = zeta.frobenius();
|
||||
let wire_eval = reduce_with_iter(&os.wires, alpha_powers.clone());
|
||||
let wire_eval = alpha.clone().scale(&os.wires);
|
||||
// We want to compute `sum a^i*phi(w_i)`, where `phi` denotes the Frobenius automorphism.
|
||||
// Since `phi^D=id` and `phi` is a field automorphism, we have the following equalities:
|
||||
// `sum a^i*phi(w_i) = sum phi(phi^(D-1)(a^i)*w_i) = phi(sum phi^(D-1)(a)^i*w_i)`
|
||||
// So we can compute the original sum using only one call to the `D-1`-repeated Frobenius of alpha,
|
||||
// and one call at the end of the sum.
|
||||
let alpha_powers_frob = alpha_powers.repeated_frobenius(D - 1);
|
||||
let wire_eval_frob = reduce_with_iter(&os.wires, alpha_powers_frob).frobenius();
|
||||
let mut alpha_frob = alpha.repeated_frobenius(D - 1);
|
||||
let wire_eval_frob = alpha_frob.scale(&os.wires).frobenius();
|
||||
let wire_interpol = interpolant(&[(zeta, wire_eval), (zeta_frob, wire_eval_frob)]);
|
||||
let wire_numerator = wire_composition_eval - wire_interpol.eval(subgroup_x);
|
||||
let wire_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_frob);
|
||||
|
||||
@ -99,9 +99,9 @@ pub struct FriInitialTreeProof<F: Field> {
|
||||
}
|
||||
|
||||
impl<F: Field> FriInitialTreeProof<F> {
|
||||
pub(crate) fn unsalted_evals(&self, i: usize, config: &FriConfig) -> &[F] {
|
||||
pub(crate) fn unsalted_evals(&self, i: usize, config: &FriConfig) -> Vec<F> {
|
||||
let evals = &self.evals_proofs[i].0;
|
||||
&evals[..evals.len() - config.salt_size(i)]
|
||||
evals[..evals.len() - config.salt_size(i)].to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
pub mod scaling;
|
||||
pub(crate) mod timing;
|
||||
|
||||
use crate::field::field::Field;
|
||||
|
||||
41
src/util/scaling.rs
Normal file
41
src/util/scaling.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use std::borrow::Borrow;
|
||||
|
||||
use crate::field::extension_field::Frobenius;
|
||||
use crate::field::field::Field;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ScalingFactor<F: Field> {
|
||||
base: F,
|
||||
count: u64,
|
||||
}
|
||||
|
||||
impl<F: Field> ScalingFactor<F> {
|
||||
pub fn new(base: F) -> Self {
|
||||
Self { base, count: 0 }
|
||||
}
|
||||
|
||||
pub fn mul(&mut self, x: F) -> F {
|
||||
self.count += 1;
|
||||
self.base * x
|
||||
}
|
||||
|
||||
pub fn scale(&mut self, iter: impl DoubleEndedIterator<Item = impl Borrow<F>>) -> F {
|
||||
iter.rev().fold(F::ZERO, |acc, x| self.mul(acc) + x)
|
||||
}
|
||||
|
||||
pub fn shift(&mut self, x: F) -> F {
|
||||
let tmp = self.base.exp(self.count) * x;
|
||||
self.count = 0;
|
||||
tmp
|
||||
}
|
||||
|
||||
pub fn repeated_frobenius<const D: usize>(&self, count: usize) -> Self
|
||||
where
|
||||
F: Frobenius<D>,
|
||||
{
|
||||
Self {
|
||||
base: self.base.repeated_frobenius(count),
|
||||
count: self.count,
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user