From 52cc7c79f5a08b866d3389c766545c3bd27008a7 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 19 Jul 2021 16:45:38 +0200 Subject: [PATCH] Remove openings at the Frobenius of zeta --- src/fri/recursive_verifier.rs | 27 +++------------------------ src/fri/verifier.rs | 28 ++++------------------------ src/polynomial/commitment.rs | 22 ++-------------------- 3 files changed, 9 insertions(+), 68 deletions(-) diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index bf4956a4..32f5763d 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -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, const D: usize> CircuitBuilder { // 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, const D: usize> CircuitBuilder { .constants .iter() .chain(&os.plonk_sigmas) + .chain(&os.wires) .chain(&os.quotient_polys) .chain(&os.partial_products) .copied() @@ -221,27 +221,6 @@ impl, const D: usize> CircuitBuilder { 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::>(); - 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 } diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index c13a0500..04374763 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -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, 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, 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, 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 } diff --git a/src/polynomial/commitment.rs b/src/polynomial/commitment.rs index 756fec0a..83333b5e 100644 --- a/src/polynomial/commitment.rs +++ b/src/polynomial/commitment.rs @@ -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 ListPolynomialCommitment { // Polynomials opened at a single point. let single_polys = [ PlonkPolynomials::CONSTANTS_SIGMAS, + PlonkPolynomials::WIRES, PlonkPolynomials::QUOTIENT, ] .iter() @@ -180,26 +180,8 @@ impl ListPolynomialCommitment { 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