mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-07-27 09:43:15 +00:00
Working commitments and verifier
This commit is contained in:
parent
100ab6ce48
commit
fe9cd3f76b
@ -168,17 +168,22 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
|||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|&p| proof.unsalted_evals(p))
|
.flat_map(|&p| proof.unsalted_evals(p))
|
||||||
.map(|&e| F::Extension::from_basefield(e));
|
.map(|&e| F::Extension::from_basefield(e))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let single_openings = os
|
let single_openings = os
|
||||||
.constants
|
.constants
|
||||||
.iter()
|
.iter()
|
||||||
.chain(&os.plonk_s_sigmas)
|
.chain(&os.plonk_s_sigmas)
|
||||||
.chain(&os.quotient_polys);
|
.chain(&os.quotient_polys)
|
||||||
let single_diffs = single_evals.zip(single_openings).map(|(e, &o)| e - o);
|
.collect::<Vec<_>>();
|
||||||
let single_numerator = reduce_with_iter(single_diffs, &mut alpha_powers);
|
let single_diffs = single_evals
|
||||||
|
.into_iter()
|
||||||
|
.zip(single_openings)
|
||||||
|
.map(|(e, &o)| e - o);
|
||||||
|
let single_numerator = alpha.scale(single_diffs);
|
||||||
let single_denominator = subgroup_x - zeta;
|
let single_denominator = subgroup_x - zeta;
|
||||||
sum += single_numerator / single_denominator;
|
sum += single_numerator / single_denominator;
|
||||||
alpha.shift(sum);
|
alpha.reset();
|
||||||
|
|
||||||
// Polynomials opened at `x` and `g x`, i.e., the Zs polynomials.
|
// Polynomials opened at `x` and `g x`, i.e., the Zs polynomials.
|
||||||
let zs_evals = proof
|
let zs_evals = proof
|
||||||
@ -188,13 +193,13 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
|||||||
let zs_composition_eval = alpha.clone().scale(zs_evals);
|
let zs_composition_eval = alpha.clone().scale(zs_evals);
|
||||||
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta;
|
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta;
|
||||||
let zs_interpol = interpolant(&[
|
let zs_interpol = interpolant(&[
|
||||||
(zeta, alpha.clone().scale(&os.plonk_zs)),
|
(zeta, alpha.clone().scale(os.plonk_zs.iter())),
|
||||||
(zeta_right, alpha.scale(&os.plonk_zs_right)),
|
(zeta_right, alpha.scale(os.plonk_zs_right.iter())),
|
||||||
]);
|
]);
|
||||||
let zs_numerator = zs_composition_eval - zs_interpol.eval(subgroup_x);
|
let zs_numerator = zs_composition_eval - zs_interpol.eval(subgroup_x);
|
||||||
let zs_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_right);
|
let zs_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_right);
|
||||||
|
sum = alpha.shift(sum);
|
||||||
sum += zs_numerator / zs_denominator;
|
sum += zs_numerator / zs_denominator;
|
||||||
alpha.shift(sum);
|
|
||||||
|
|
||||||
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
|
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
|
||||||
let wire_evals = proof
|
let wire_evals = proof
|
||||||
@ -203,17 +208,18 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
|||||||
.map(|&e| F::Extension::from_basefield(e));
|
.map(|&e| F::Extension::from_basefield(e));
|
||||||
let wire_composition_eval = alpha.clone().scale(wire_evals);
|
let wire_composition_eval = alpha.clone().scale(wire_evals);
|
||||||
let zeta_frob = zeta.frobenius();
|
let zeta_frob = zeta.frobenius();
|
||||||
let wire_eval = alpha.clone().scale(&os.wires);
|
let wire_eval = alpha.clone().scale(os.wires.iter());
|
||||||
// We want to compute `sum a^i*phi(w_i)`, where `phi` denotes the Frobenius automorphism.
|
// 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:
|
// 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)`
|
// `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,
|
// 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.
|
// and one call at the end of the sum.
|
||||||
let mut alpha_frob = alpha.repeated_frobenius(D - 1);
|
let mut alpha_frob = alpha.repeated_frobenius(D - 1);
|
||||||
let wire_eval_frob = alpha_frob.scale(&os.wires).frobenius();
|
let wire_eval_frob = alpha_frob.scale(os.wires.iter()).frobenius();
|
||||||
let wire_interpol = interpolant(&[(zeta, wire_eval), (zeta_frob, wire_eval_frob)]);
|
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_numerator = wire_composition_eval - wire_interpol.eval(subgroup_x);
|
||||||
let wire_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_frob);
|
let wire_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_frob);
|
||||||
|
sum = alpha_frob.shift(sum);
|
||||||
sum += wire_numerator / wire_denominator;
|
sum += wire_numerator / wire_denominator;
|
||||||
|
|
||||||
sum
|
sum
|
||||||
|
|||||||
@ -8,10 +8,11 @@ use crate::field::lagrange::interpolant;
|
|||||||
use crate::fri::{prover::fri_proof, verifier::verify_fri_proof, FriConfig};
|
use crate::fri::{prover::fri_proof, verifier::verify_fri_proof, FriConfig};
|
||||||
use crate::merkle_tree::MerkleTree;
|
use crate::merkle_tree::MerkleTree;
|
||||||
use crate::plonk_challenger::Challenger;
|
use crate::plonk_challenger::Challenger;
|
||||||
use crate::plonk_common::{reduce_polys_with_iter, reduce_with_iter};
|
use crate::plonk_common::{reduce_polys_with_iter, reduce_with_iter, PlonkPolynomials};
|
||||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||||
use crate::proof::{FriProof, FriProofTarget, Hash, OpeningSet};
|
use crate::proof::{FriProof, FriProofTarget, Hash, OpeningSet};
|
||||||
use crate::timed;
|
use crate::timed;
|
||||||
|
use crate::util::scaling::ScalingFactor;
|
||||||
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
|
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
|
||||||
|
|
||||||
pub const SALT_SIZE: usize = 2;
|
pub const SALT_SIZE: usize = 2;
|
||||||
@ -110,20 +111,24 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
challenger.observe_opening_set(&os);
|
challenger.observe_opening_set(&os);
|
||||||
|
|
||||||
let alpha = challenger.get_extension_challenge();
|
let alpha = challenger.get_extension_challenge();
|
||||||
let mut alpha_powers = alpha.powers();
|
let mut alpha = ScalingFactor::new(alpha);
|
||||||
|
|
||||||
// Final low-degree polynomial that goes into FRI.
|
// Final low-degree polynomial that goes into FRI.
|
||||||
let mut final_poly = PolynomialCoeffs::empty();
|
let mut final_poly = PolynomialCoeffs::empty();
|
||||||
|
|
||||||
// Polynomials opened at a single point.
|
// Polynomials opened at a single point.
|
||||||
let single_polys = [0, 1, 4]
|
let single_polys = [
|
||||||
.iter()
|
PlonkPolynomials::CONSTANTS,
|
||||||
.flat_map(|&i| &commitments[i].polynomials)
|
PlonkPolynomials::SIGMAS,
|
||||||
.map(|p| p.to_extension());
|
PlonkPolynomials::QUOTIENT,
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.flat_map(|&p| &commitments[p.index].polynomials)
|
||||||
|
.map(|p| p.to_extension());
|
||||||
let single_os = [&os.constants, &os.plonk_s_sigmas, &os.quotient_polys];
|
let single_os = [&os.constants, &os.plonk_s_sigmas, &os.quotient_polys];
|
||||||
let single_evals = single_os.iter().flat_map(|v| v.iter());
|
let single_evals = single_os.iter().flat_map(|v| v.iter());
|
||||||
let single_composition_poly = reduce_polys_with_iter(single_polys, alpha_powers.clone());
|
let single_composition_poly = alpha.clone().scale_polys(single_polys);
|
||||||
let single_composition_eval = reduce_with_iter(single_evals, &mut alpha_powers);
|
let single_composition_eval = alpha.scale(single_evals);
|
||||||
|
|
||||||
let single_quotient = Self::compute_quotient(
|
let single_quotient = Self::compute_quotient(
|
||||||
&[zeta],
|
&[zeta],
|
||||||
@ -131,13 +136,17 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
&single_composition_poly,
|
&single_composition_poly,
|
||||||
);
|
);
|
||||||
final_poly = &final_poly + &single_quotient;
|
final_poly = &final_poly + &single_quotient;
|
||||||
|
alpha.reset();
|
||||||
|
|
||||||
// Zs polynomials are opened at `zeta` and `g*zeta`.
|
// Zs polynomials are opened at `zeta` and `g*zeta`.
|
||||||
let zs_polys = commitments[3].polynomials.iter().map(|p| p.to_extension());
|
let zs_polys = commitments[PlonkPolynomials::ZS.index]
|
||||||
let zs_composition_poly = reduce_polys_with_iter(zs_polys, alpha_powers.clone());
|
.polynomials
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.to_extension());
|
||||||
|
let zs_composition_poly = alpha.clone().scale_polys(zs_polys);
|
||||||
let zs_composition_evals = [
|
let zs_composition_evals = [
|
||||||
reduce_with_iter(&os.plonk_zs, alpha_powers.clone()),
|
alpha.clone().scale(os.plonk_zs.iter()),
|
||||||
reduce_with_iter(&os.plonk_zs_right, &mut alpha_powers),
|
alpha.scale(os.plonk_zs_right.iter()),
|
||||||
];
|
];
|
||||||
|
|
||||||
let zs_quotient = Self::compute_quotient(
|
let zs_quotient = Self::compute_quotient(
|
||||||
@ -145,17 +154,21 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
&zs_composition_evals,
|
&zs_composition_evals,
|
||||||
&zs_composition_poly,
|
&zs_composition_poly,
|
||||||
);
|
);
|
||||||
|
final_poly = alpha.shift_poly(final_poly);
|
||||||
final_poly = &final_poly + &zs_quotient;
|
final_poly = &final_poly + &zs_quotient;
|
||||||
|
|
||||||
// When working in an extension field, need to check that wires are in the base field.
|
// When working in an extension field, need to check that wires are in the base field.
|
||||||
// Check this by opening the wires polynomials at `zeta` and `zeta.frobenius()` and using the fact that
|
// Check this by opening the wires polynomials at `zeta` and `zeta.frobenius()` and using the fact that
|
||||||
// a polynomial `f` is over the base field iff `f(z).frobenius()=f(z.frobenius())` with high probability.
|
// a polynomial `f` is over the base field iff `f(z).frobenius()=f(z.frobenius())` with high probability.
|
||||||
let wire_polys = commitments[2].polynomials.iter().map(|p| p.to_extension());
|
let wire_polys = commitments[PlonkPolynomials::WIRES.index]
|
||||||
let wire_composition_poly = reduce_polys_with_iter(wire_polys, alpha_powers.clone());
|
.polynomials
|
||||||
let wire_evals_frob = os.wires.iter().map(|e| e.frobenius()).collect::<Vec<_>>();
|
.iter()
|
||||||
|
.map(|p| p.to_extension());
|
||||||
|
let wire_composition_poly = alpha.clone().scale_polys(wire_polys);
|
||||||
|
let mut alpha_frob = alpha.repeated_frobenius(D - 1);
|
||||||
let wire_composition_evals = [
|
let wire_composition_evals = [
|
||||||
reduce_with_iter(&os.wires, alpha_powers.clone()),
|
alpha.clone().scale(os.wires.iter()),
|
||||||
reduce_with_iter(&wire_evals_frob, alpha_powers),
|
alpha_frob.scale(os.wires.iter()).frobenius(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let wires_quotient = Self::compute_quotient(
|
let wires_quotient = Self::compute_quotient(
|
||||||
@ -163,6 +176,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
|||||||
&wire_composition_evals,
|
&wire_composition_evals,
|
||||||
&wire_composition_poly,
|
&wire_composition_poly,
|
||||||
);
|
);
|
||||||
|
final_poly = alpha_frob.shift_poly(final_poly);
|
||||||
final_poly = &final_poly + &wires_quotient;
|
final_poly = &final_poly + &wires_quotient;
|
||||||
|
|
||||||
let lde_final_poly = final_poly.lde(config.rate_bits);
|
let lde_final_poly = final_poly.lde(config.rate_bits);
|
||||||
|
|||||||
@ -2,8 +2,9 @@ use std::borrow::Borrow;
|
|||||||
|
|
||||||
use crate::field::extension_field::Frobenius;
|
use crate::field::extension_field::Frobenius;
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ScalingFactor<F: Field> {
|
pub struct ScalingFactor<F: Field> {
|
||||||
base: F,
|
base: F,
|
||||||
count: u64,
|
count: u64,
|
||||||
@ -14,13 +15,28 @@ impl<F: Field> ScalingFactor<F> {
|
|||||||
Self { base, count: 0 }
|
Self { base, count: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul(&mut self, x: F) -> F {
|
fn mul(&mut self, x: F) -> F {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
self.base * x
|
self.base * x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mul_poly(&mut self, p: PolynomialCoeffs<F>) -> PolynomialCoeffs<F> {
|
||||||
|
self.count += 1;
|
||||||
|
&p * self.base
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scale(&mut self, iter: impl DoubleEndedIterator<Item = impl Borrow<F>>) -> F {
|
pub fn scale(&mut self, iter: impl DoubleEndedIterator<Item = impl Borrow<F>>) -> F {
|
||||||
iter.rev().fold(F::ZERO, |acc, x| self.mul(acc) + x)
|
iter.rev()
|
||||||
|
.fold(F::ZERO, |acc, x| self.mul(acc) + *x.borrow())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scale_polys(
|
||||||
|
&mut self,
|
||||||
|
polys: impl DoubleEndedIterator<Item = impl Borrow<PolynomialCoeffs<F>>>,
|
||||||
|
) -> PolynomialCoeffs<F> {
|
||||||
|
polys.rev().fold(PolynomialCoeffs::empty(), |acc, x| {
|
||||||
|
&self.mul_poly(acc) + x.borrow()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shift(&mut self, x: F) -> F {
|
pub fn shift(&mut self, x: F) -> F {
|
||||||
@ -29,6 +45,16 @@ impl<F: Field> ScalingFactor<F> {
|
|||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shift_poly(&mut self, p: PolynomialCoeffs<F>) -> PolynomialCoeffs<F> {
|
||||||
|
let tmp = &p * self.base.exp(self.count);
|
||||||
|
self.count = 0;
|
||||||
|
tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn repeated_frobenius<const D: usize>(&self, count: usize) -> Self
|
pub fn repeated_frobenius<const D: usize>(&self, count: usize) -> Self
|
||||||
where
|
where
|
||||||
F: Frobenius<D>,
|
F: Frobenius<D>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user