Remove openings at the Frobenius of zeta

This commit is contained in:
wborgeaud 2021-07-19 16:45:38 +02:00
parent 35c8643681
commit 52cc7c79f5
3 changed files with 9 additions and 68 deletions

View File

@ -1,5 +1,4 @@
use crate::circuit_builder::CircuitBuilder;
use crate::circuit_data::CircuitConfig;
use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::target::{flatten_target, ExtensionTarget};
use crate::field::extension_field::Extendable;
@ -164,11 +163,11 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
// We will add three terms to `sum`:
// - one for polynomials opened at `x` only
// - one for polynomials opened at `x` and `g x`
// - one for polynomials opened at `x` and `x.frobenius()`
// Polynomials opened at `x`, i.e., the constants, sigmas, quotient and partial products polynomials.
// Polynomials opened at `x`, i.e., the constants-sigmas, wires, quotient and partial products polynomials.
let single_evals = [
PlonkPolynomials::CONSTANTS_SIGMAS,
PlonkPolynomials::WIRES,
PlonkPolynomials::QUOTIENT,
]
.iter()
@ -183,6 +182,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
.constants
.iter()
.chain(&os.plonk_sigmas)
.chain(&os.wires)
.chain(&os.quotient_polys)
.chain(&os.partial_products)
.copied()
@ -221,27 +221,6 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
sum = alpha.shift(sum, self);
sum = self.add_extension(sum, zs_quotient);
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
let wire_evals = proof
.unsalted_evals(PlonkPolynomials::WIRES, config.zero_knowledge)
.iter()
.map(|&e| self.convert_to_ext(e))
.collect::<Vec<_>>();
let wire_composition_eval = alpha.clone().reduce(&wire_evals, self);
let mut alpha_frob = alpha.repeated_frobenius(D - 1, self);
let wire_eval = alpha.reduce(&os.wires, self);
let wire_eval_frob = alpha_frob.reduce(&os.wires, self);
let wire_eval_frob = wire_eval_frob.frobenius(self);
let zeta_frob = zeta.frobenius(self);
let wire_interpol_val =
self.interpolate2([(zeta, wire_eval), (zeta_frob, wire_eval_frob)], subgroup_x);
let wire_numerator = self.sub_extension(wire_composition_eval, wire_interpol_val);
let vanish_zeta_frob = self.sub_extension(subgroup_x, zeta_frob);
let wire_denominator = self.mul_extension(vanish_zeta, vanish_zeta_frob);
let wire_quotient = self.div_unsafe_extension(wire_numerator, wire_denominator);
sum = alpha.shift(sum, self);
sum = self.add_extension(sum, wire_quotient);
sum
}

View File

@ -1,7 +1,7 @@
use anyhow::{ensure, Result};
use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::{flatten, Extendable, FieldExtension, Frobenius};
use crate::field::extension_field::{flatten, Extendable, FieldExtension};
use crate::field::field::Field;
use crate::field::interpolation::{barycentric_weights, interpolate, interpolate2};
use crate::fri::FriConfig;
@ -161,11 +161,11 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
// We will add three terms to `sum`:
// - one for various polynomials which are opened at a single point `x`
// - one for Zs, which are opened at `x` and `g x`
// - one for wire polynomials, which are opened at `x` and `x.frobenius()`
// Polynomials opened at `x`, i.e., the constants, sigmas, quotient and partial products polynomials.
// Polynomials opened at `x`, i.e., the constants-sigmas, wires, quotient and partial products polynomials.
let single_evals = [
PlonkPolynomials::CONSTANTS_SIGMAS,
PlonkPolynomials::WIRES,
PlonkPolynomials::QUOTIENT,
]
.iter()
@ -179,6 +179,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
.constants
.iter()
.chain(&os.plonk_sigmas)
.chain(&os.wires)
.chain(&os.quotient_polys)
.chain(&os.partial_products);
let single_diffs = single_evals
@ -211,27 +212,6 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
sum = alpha.shift(sum);
sum += zs_numerator / zs_denominator;
// Polynomials opened at `x` and `x.frobenius()`, i.e., the wires polynomials.
let wire_evals = proof
.unsalted_evals(PlonkPolynomials::WIRES, config.zero_knowledge)
.iter()
.map(|&e| F::Extension::from_basefield(e));
let wire_composition_eval = alpha.clone().reduce(wire_evals);
let zeta_frob = zeta.frobenius();
let mut alpha_frob = alpha.repeated_frobenius(D - 1);
let wire_eval = alpha.reduce(os.wires.iter());
// 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 wire_eval_frob = alpha_frob.reduce(os.wires.iter()).frobenius();
let wire_interpol = interpolate2([(zeta, wire_eval), (zeta_frob, wire_eval_frob)], subgroup_x);
let wire_numerator = wire_composition_eval - wire_interpol;
let wire_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_frob);
sum = alpha.shift(sum);
sum += wire_numerator / wire_denominator;
sum
}

View File

@ -6,7 +6,6 @@ use crate::circuit_builder::CircuitBuilder;
use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::field::extension_field::{FieldExtension, Frobenius};
use crate::field::field::Field;
use crate::fri::{prover::fri_proof, verifier::verify_fri_proof};
use crate::merkle_tree::MerkleTree;
@ -161,6 +160,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
// Polynomials opened at a single point.
let single_polys = [
PlonkPolynomials::CONSTANTS_SIGMAS,
PlonkPolynomials::WIRES,
PlonkPolynomials::QUOTIENT,
]
.iter()
@ -180,26 +180,8 @@ impl<F: Field> ListPolynomialCommitment<F> {
alpha.shift_poly(&mut final_poly);
final_poly += zs_quotient;
// 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
// a polynomial `f` is over the base field iff `f(z).frobenius()=f(z.frobenius())` with high probability.
let wire_polys = commitments[PlonkPolynomials::WIRES.index]
.polynomials
.iter()
.map(|p| p.to_extension());
let wire_composition_poly = alpha.reduce_polys(wire_polys);
let wires_quotient =
Self::compute_quotient([zeta, zeta.frobenius()], wire_composition_poly);
alpha.shift_poly(&mut final_poly);
final_poly += wires_quotient;
let lde_final_poly = final_poly.lde(config.rate_bits);
let lde_final_values = lde_final_poly
.clone()
.coset_fft(F::Extension::from_basefield(
F::MULTIPLICATIVE_GROUP_GENERATOR,
));
let lde_final_values = lde_final_poly.clone().coset_fft(F::coset_shift().into());
let fri_proof = fri_proof(
&commitments