Bit of verifier work (#54)

* Bit of verifier work

* Minor

* next_plonk_zs now available after William's changes
This commit is contained in:
Daniel Lubarov 2021-06-08 21:23:52 -07:00 committed by GitHub
parent 2b5b5f87e1
commit 72c2e19bc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 146 additions and 72 deletions

View File

@ -9,7 +9,6 @@ use crate::circuit_data::{
};
use crate::field::cosets::get_unique_coset_shifts;
use crate::field::extension_field::Extendable;
use crate::field::field::Field;
use crate::gates::constant::ConstantGate;
use crate::gates::gate::{GateInstance, GateRef};
use crate::gates::noop::NoopGate;

View File

@ -167,7 +167,7 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
let openings = os
.constants
.iter()
.chain(&os.plonk_sigmas)
.chain(&os.plonk_s_sigmas)
.chain(&os.quotient_polys);
let numerator = izip!(evals, openings, &mut alpha_powers)
.map(|(e, &o, a)| a * (e - o))

View File

@ -21,14 +21,12 @@ use crate::witness::PartialWitness;
/// to evaluate the interpolant at. It computes the interpolant and outputs its evaluation at the
/// given point.
#[derive(Clone, Debug)]
pub(crate) struct InterpolationGate<F: Extendable<D>, const D: usize>
{
pub(crate) struct InterpolationGate<F: Extendable<D>, const D: usize> {
num_points: usize,
_phantom: PhantomData<F>,
}
impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D>
{
impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D> {
pub fn new(num_points: usize) -> GateRef<F, D> {
let gate = Self {
num_points,
@ -95,8 +93,7 @@ impl<F: Extendable<D>, const D: usize> InterpolationGate<F, D>
}
}
impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D>
{
impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
fn id(&self) -> String {
format!("{:?}<D={}>", self, D)
}
@ -193,15 +190,13 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D>
}
}
struct InterpolationGenerator<F: Extendable<D>, const D: usize>
{
struct InterpolationGenerator<F: Extendable<D>, const D: usize> {
gate_index: usize,
gate: InterpolationGate<F, D>,
_phantom: PhantomData<F>,
}
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGenerator<F, D>
{
impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGenerator<F, D> {
fn dependencies(&self) -> Vec<Target> {
let local_target = |input| {
Target::Wire(Wire {

View File

@ -67,7 +67,7 @@ impl<F: Field> Challenger<F> {
{
let OpeningSet {
constants,
plonk_sigmas,
plonk_s_sigmas,
wires,
plonk_zs,
plonk_zs_right,
@ -75,7 +75,7 @@ impl<F: Field> Challenger<F> {
} = os;
for v in &[
constants,
plonk_sigmas,
plonk_s_sigmas,
wires,
plonk_zs,
plonk_zs_right,

View File

@ -1,4 +1,5 @@
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::field::Field;
@ -6,6 +7,105 @@ use crate::gates::gate::GateRef;
use crate::target::Target;
use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
/// Evaluate the vanishing polynomial at `x`. In this context, the vanishing polynomial is a random
/// linear combination of gate constraints, plus some other terms relating to the permutation
/// argument. All such terms should vanish on `H`.
pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
common_data: &CommonCircuitData<F, D>,
x: F::Extension,
vars: EvaluationVars<F, D>,
local_plonk_zs: &[F::Extension],
next_plonk_zs: &[F::Extension],
s_sigmas: &[F::Extension],
betas: &[F],
gammas: &[F],
alphas: &[F],
) -> Vec<F::Extension> {
let constraint_terms =
evaluate_gate_constraints(&common_data.gates, common_data.num_gate_constraints, vars);
// The L_1(x) (Z(x) - 1) vanishing terms.
let mut vanishing_z_1_terms = Vec::new();
// The Z(x) f'(x) - g'(x) Z(g x) terms.
let mut vanishing_v_shift_terms = Vec::new();
for i in 0..common_data.config.num_challenges {
let z_x = local_plonk_zs[i];
let z_gz = next_plonk_zs[i];
vanishing_z_1_terms.push(eval_l_1(common_data.degree(), x) * (z_x - F::Extension::ONE));
let mut f_prime = F::Extension::ONE;
let mut g_prime = F::Extension::ONE;
for j in 0..common_data.config.num_routed_wires {
let wire_value = vars.local_wires[j];
let k_i = common_data.k_is[j];
let s_id = x * k_i.into();
let s_sigma = s_sigmas[j];
f_prime *= wire_value + s_id * betas[i].into() + gammas[i].into();
g_prime *= wire_value + s_sigma * betas[i].into() + gammas[i].into();
}
vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz);
}
let vanishing_terms = [
vanishing_z_1_terms,
vanishing_v_shift_terms,
constraint_terms,
]
.concat();
let alphas = &alphas.iter().map(|&a| a.into()).collect::<Vec<_>>();
reduce_with_powers_multi(&vanishing_terms, alphas)
}
/// Like `eval_vanishing_poly`, but specialized for base field points.
pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, const D: usize>(
common_data: &CommonCircuitData<F, D>,
x: F,
vars: EvaluationVarsBase<F>,
local_plonk_zs: &[F],
next_plonk_zs: &[F],
s_sigmas: &[F],
betas: &[F],
gammas: &[F],
alphas: &[F],
) -> Vec<F> {
let constraint_terms =
evaluate_gate_constraints_base(&common_data.gates, common_data.num_gate_constraints, vars);
// The L_1(x) (Z(x) - 1) vanishing terms.
let mut vanishing_z_1_terms = Vec::new();
// The Z(x) f'(x) - g'(x) Z(g x) terms.
let mut vanishing_v_shift_terms = Vec::new();
for i in 0..common_data.config.num_challenges {
let z_x = local_plonk_zs[i];
let z_gz = next_plonk_zs[i];
vanishing_z_1_terms.push(eval_l_1(common_data.degree(), x) * (z_x - F::ONE));
let mut f_prime = F::ONE;
let mut g_prime = F::ONE;
for j in 0..common_data.config.num_routed_wires {
let wire_value = vars.local_wires[j];
let k_i = common_data.k_is[j];
let s_id = k_i * x;
let s_sigma = s_sigmas[j];
f_prime *= wire_value + betas[i] * s_id + gammas[i];
g_prime *= wire_value + betas[i] * s_sigma + gammas[i];
}
vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz);
}
let vanishing_terms = [
vanishing_z_1_terms,
vanishing_v_shift_terms,
constraint_terms,
]
.concat();
reduce_with_powers_multi(&vanishing_terms, alphas)
}
/// Evaluates all gate constraints.
///
/// `num_gate_constraints` is the largest number of constraints imposed by any gate. It is not

View File

@ -126,7 +126,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
poly_count += 1;
&(&acc * alpha) + &p.to_extension()
});
let composition_eval = [&os.constants, &os.plonk_sigmas, &os.quotient_polys]
let composition_eval = [&os.constants, &os.plonk_s_sigmas, &os.quotient_polys]
.iter()
.flat_map(|v| v.iter())
.rev()

View File

@ -140,7 +140,7 @@ pub struct FriProofTarget {
/// The purported values of each polynomial at a single point.
pub struct OpeningSet<F: Field + Extendable<D>, const D: usize> {
pub constants: Vec<F::Extension>,
pub plonk_sigmas: Vec<F::Extension>,
pub plonk_s_sigmas: Vec<F::Extension>,
pub wires: Vec<F::Extension>,
pub plonk_zs: Vec<F::Extension>,
pub plonk_zs_right: Vec<F::Extension>,
@ -165,7 +165,7 @@ impl<F: Field + Extendable<D>, const D: usize> OpeningSet<F, D> {
};
Self {
constants: eval_commitment(z, constant_commitment),
plonk_sigmas: eval_commitment(z, plonk_sigmas_commitment),
plonk_s_sigmas: eval_commitment(z, plonk_sigmas_commitment),
wires: eval_commitment(z, wires_commitment),
plonk_zs: eval_commitment(z, plonk_zs_commitment),
plonk_zs_right: eval_commitment(g * z, plonk_zs_commitment),

View File

@ -9,7 +9,7 @@ use crate::field::fft::ifft;
use crate::field::field::Field;
use crate::generator::generate_partial_witness;
use crate::plonk_challenger::Challenger;
use crate::plonk_common::{eval_l_1, evaluate_gate_constraints_base, reduce_with_powers_multi};
use crate::plonk_common::eval_vanishing_poly_base;
use crate::polynomial::commitment::ListPolynomialCommitment;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::proof::Proof;
@ -115,7 +115,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
let zeta = challenger.get_extension_challenge();
let (opening_proof, openings) = timed!(
let (opening_proof, mut openings) = timed!(
ListPolynomialCommitment::open_plonk(
&[
&prover_data.constants_commitment,
@ -192,7 +192,7 @@ fn compute_vanishing_polys<F: Extendable<D>, const D: usize>(
local_constants,
local_wires,
};
compute_vanishing_poly_entry(
eval_vanishing_poly_base(
common_data,
x,
vars,
@ -212,56 +212,6 @@ fn compute_vanishing_polys<F: Extendable<D>, const D: usize>(
.collect()
}
/// Evaluate the vanishing polynomial at `x`. In this context, the vanishing polynomial is a random
/// linear combination of gate constraints, plus some other terms relating to the permutation
/// argument. All such terms should vanish on `H`.
fn compute_vanishing_poly_entry<F: Extendable<D>, const D: usize>(
common_data: &CommonCircuitData<F, D>,
x: F,
vars: EvaluationVarsBase<F>,
local_plonk_zs: &[F],
next_plonk_zs: &[F],
s_sigmas: &[F],
betas: &[F],
gammas: &[F],
alphas: &[F],
) -> Vec<F> {
let constraint_terms =
evaluate_gate_constraints_base(&common_data.gates, common_data.num_gate_constraints, vars);
// The L_1(x) (Z(x) - 1) vanishing terms.
let mut vanishing_z_1_terms = Vec::new();
// The Z(x) f'(x) - g'(x) Z(g x) terms.
let mut vanishing_v_shift_terms = Vec::new();
for i in 0..common_data.config.num_challenges {
let z_x = local_plonk_zs[i];
let z_gz = next_plonk_zs[i];
vanishing_z_1_terms.push(eval_l_1(common_data.degree(), x) * (z_x - F::ONE));
let mut f_prime = F::ONE;
let mut g_prime = F::ONE;
for j in 0..common_data.config.num_routed_wires {
let wire_value = vars.local_wires[j];
let k_i = common_data.k_is[j];
let s_id = k_i * x;
let s_sigma = s_sigmas[j];
f_prime *= wire_value + betas[i] * s_id + gammas[i];
g_prime *= wire_value + betas[i] * s_sigma + gammas[i];
}
vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz);
}
let vanishing_terms = [
vanishing_z_1_terms,
vanishing_v_shift_terms,
constraint_terms,
]
.concat();
reduce_with_powers_multi(&vanishing_terms, alphas)
}
fn compute_wire_polynomial<F: Field>(
input: usize,
witness: &PartialWitness<F>,

View File

@ -1,9 +1,11 @@
use anyhow::Result;
use anyhow::{ensure, Result};
use crate::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
use crate::field::extension_field::Extendable;
use crate::plonk_challenger::Challenger;
use crate::plonk_common::{eval_vanishing_poly, eval_zero_poly};
use crate::proof::Proof;
use crate::vars::EvaluationVars;
pub(crate) fn verify<F: Extendable<D>, const D: usize>(
proof: Proof<F, D>,
@ -29,7 +31,35 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
challenger.observe_hash(&proof.quotient_polys_root);
let zeta = challenger.get_extension_challenge();
// TODO: Compute PI(zeta), Z_H(zeta), etc. and check the identity at zeta.
let local_constants = &proof.openings.constants;
let local_wires = &proof.openings.wires;
let vars = EvaluationVars {
local_constants,
local_wires,
};
let local_plonk_zs = &proof.openings.plonk_zs;
let next_plonk_zs = &proof.openings.plonk_zs_right;
let s_sigmas = &proof.openings.plonk_s_sigmas;
// Evaluate the vanishing polynomial at our challenge point, zeta.
let vanishing_polys_zeta = eval_vanishing_poly(
common_data,
zeta,
vars,
local_plonk_zs,
next_plonk_zs,
s_sigmas,
&betas,
&gammas,
&alphas,
);
// Check each polynomial identity, of the form `vanishing(x) = Z_H(x) quotient(x)`, at zeta.
let quotient_polys_zeta = proof.openings.quotient_polys;
let z_h_zeta = eval_zero_poly(common_data.degree(), zeta);
for i in 0..num_challenges {
ensure!(vanishing_polys_zeta[i] == z_h_zeta * quotient_polys_zeta[i]);
}
let evaluations = todo!();