mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 01:03:08 +00:00
Merge pull request #88 from mir-protocol/finish-verifier
Working verifier
This commit is contained in:
commit
7ab21a4f13
@ -392,6 +392,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
/// Builds a "full circuit", with both prover and verifier data.
|
||||
pub fn build(mut self) -> CircuitData<F, D> {
|
||||
let quotient_degree_factor = 7; // TODO: add this as a parameter.
|
||||
let start = Instant::now();
|
||||
info!(
|
||||
"Degree before blinding & padding: {}",
|
||||
@ -403,7 +404,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
let gates = self.gates.iter().cloned().collect();
|
||||
let (gate_tree, max_filtered_constraint_degree, num_constants) = Tree::from_gates(gates);
|
||||
let max_filtered_constraint_degree = max_filtered_constraint_degree.max(3);
|
||||
assert!(
|
||||
max_filtered_constraint_degree <= quotient_degree_factor + 1,
|
||||
"Constraints are too high degree."
|
||||
);
|
||||
let prefixed_gates = PrefixedGate::from_tree(gate_tree);
|
||||
|
||||
let degree_bits = log2_strict(degree);
|
||||
@ -446,10 +450,8 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.max()
|
||||
.expect("No gates?");
|
||||
|
||||
let num_partial_products = num_partial_products(
|
||||
self.config.num_routed_wires,
|
||||
max_filtered_constraint_degree - 1,
|
||||
);
|
||||
let num_partial_products =
|
||||
num_partial_products(self.config.num_routed_wires, quotient_degree_factor);
|
||||
|
||||
// TODO: This should also include an encoding of gate constraints.
|
||||
let circuit_digest_parts = [
|
||||
@ -462,7 +464,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
config: self.config,
|
||||
degree_bits,
|
||||
gates: prefixed_gates,
|
||||
max_filtered_constraint_degree,
|
||||
quotient_degree_factor,
|
||||
num_gate_constraints,
|
||||
num_constants,
|
||||
k_is,
|
||||
|
||||
@ -145,8 +145,8 @@ pub struct CommonCircuitData<F: Extendable<D>, const D: usize> {
|
||||
/// The types of gates used in this circuit, along with their prefixes.
|
||||
pub(crate) gates: Vec<PrefixedGate<F, D>>,
|
||||
|
||||
/// The maximum degree of a filter times a constraint by any gate.
|
||||
pub(crate) max_filtered_constraint_degree: usize,
|
||||
/// The degree of the PLONK quotient polynomial.
|
||||
pub(crate) quotient_degree_factor: usize,
|
||||
|
||||
/// The largest number of constraints imposed by any gate.
|
||||
pub(crate) num_gate_constraints: usize,
|
||||
@ -188,7 +188,7 @@ impl<F: Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
}
|
||||
|
||||
pub fn quotient_degree(&self) -> usize {
|
||||
(self.max_filtered_constraint_degree - 1) * self.degree()
|
||||
self.quotient_degree_factor * self.degree()
|
||||
}
|
||||
|
||||
pub fn total_constraints(&self) -> usize {
|
||||
|
||||
@ -438,6 +438,7 @@ mod tests {
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field::Field;
|
||||
use crate::fri::FriConfig;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
#[test]
|
||||
@ -461,5 +462,7 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field::Field;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
fn real_insert<const D: usize>(
|
||||
@ -113,6 +114,8 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -66,6 +66,7 @@ mod tests {
|
||||
use crate::field::extension_field::FieldExtension;
|
||||
use crate::field::field::Field;
|
||||
use crate::field::interpolation::{interpolant, interpolate};
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
#[test]
|
||||
@ -103,6 +104,8 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -135,5 +138,7 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +118,7 @@ mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field::Field;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
fn real_rotate<const D: usize>(
|
||||
@ -150,6 +151,8 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -41,6 +41,7 @@ mod tests {
|
||||
use crate::circuit_data::CircuitConfig;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::field::Field;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
#[test]
|
||||
@ -67,5 +68,7 @@ mod tests {
|
||||
let data = builder.build();
|
||||
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
|
||||
gammas: &[F],
|
||||
alphas: &[F],
|
||||
) -> Vec<F::Extension> {
|
||||
let max_degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let max_degree = common_data.quotient_degree_factor;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let constraint_terms =
|
||||
@ -160,7 +160,7 @@ pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, const D: usize>(
|
||||
alphas: &[F],
|
||||
z_h_on_coset: &ZeroPolyOnCoset<F>,
|
||||
) -> Vec<F> {
|
||||
let max_degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let max_degree = common_data.quotient_degree_factor;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let constraint_terms =
|
||||
|
||||
@ -331,7 +331,7 @@ mod tests {
|
||||
},
|
||||
degree_bits: 0,
|
||||
gates: vec![],
|
||||
max_filtered_constraint_degree: 0,
|
||||
quotient_degree_factor: 0,
|
||||
num_gate_constraints: 0,
|
||||
num_constants: 4,
|
||||
k_is: vec![F::ONE; 6],
|
||||
|
||||
@ -80,7 +80,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let gammas = challenger.get_n_challenges(num_challenges);
|
||||
|
||||
assert!(
|
||||
common_data.max_filtered_constraint_degree<=common_data.config.num_routed_wires,
|
||||
common_data.quotient_degree_factor + 1 <=common_data.config.num_routed_wires,
|
||||
"When the number of routed wires is smaller that the degree, we should change the logic to avoid computing partial products."
|
||||
);
|
||||
let mut partial_products = timed!(
|
||||
@ -213,7 +213,7 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Vec<PolynomialValues<F>> {
|
||||
let degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let degree = common_data.quotient_degree_factor;
|
||||
let subgroup = &prover_data.subgroup;
|
||||
let k_is = &common_data.k_is;
|
||||
let values = subgroup
|
||||
@ -286,22 +286,21 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
alphas: &[F],
|
||||
) -> Vec<PolynomialCoeffs<F>> {
|
||||
let num_challenges = common_data.config.num_challenges;
|
||||
let max_filtered_constraint_degree_bits = log2_ceil(common_data.max_filtered_constraint_degree);
|
||||
let max_degree_bits = log2_ceil(common_data.quotient_degree_factor + 1);
|
||||
assert!(
|
||||
max_filtered_constraint_degree_bits <= common_data.config.rate_bits,
|
||||
max_degree_bits <= common_data.config.rate_bits,
|
||||
"Having constraints of degree higher than the rate is not supported yet. \
|
||||
If we need this in the future, we can precompute the larger LDE before computing the `ListPolynomialCommitment`s."
|
||||
);
|
||||
|
||||
// We reuse the LDE computed in `ListPolynomialCommitment` and extract every `step` points to get
|
||||
// an LDE matching `max_filtered_constraint_degree`.
|
||||
let step = 1 << (common_data.config.rate_bits - max_filtered_constraint_degree_bits);
|
||||
let step = 1 << (common_data.config.rate_bits - max_degree_bits);
|
||||
// When opening the `Z`s polys at the "next" point in Plonk, need to look at the point `next_step`
|
||||
// steps away since we work on an LDE of degree `max_filtered_constraint_degree`.
|
||||
let next_step = 1 << max_filtered_constraint_degree_bits;
|
||||
let next_step = 1 << max_degree_bits;
|
||||
|
||||
let points =
|
||||
F::two_adic_subgroup(common_data.degree_bits + max_filtered_constraint_degree_bits);
|
||||
let points = F::two_adic_subgroup(common_data.degree_bits + max_degree_bits);
|
||||
let lde_size = points.len();
|
||||
|
||||
// Retrieve the LDE values at index `i`.
|
||||
@ -309,8 +308,7 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
comm.get_lde_values(i * step)
|
||||
};
|
||||
|
||||
let z_h_on_coset =
|
||||
ZeroPolyOnCoset::new(common_data.degree_bits, max_filtered_constraint_degree_bits);
|
||||
let z_h_on_coset = ZeroPolyOnCoset::new(common_data.degree_bits, max_degree_bits);
|
||||
|
||||
let quotient_values: Vec<Vec<F>> = points
|
||||
.into_par_iter()
|
||||
|
||||
@ -174,6 +174,7 @@ mod tests {
|
||||
use crate::circuit_data::CircuitConfig;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
fn test_reduce_gadget(n: usize) {
|
||||
@ -205,6 +206,8 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new());
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -2,8 +2,9 @@ use anyhow::{ensure, Result};
|
||||
|
||||
use crate::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData};
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field::Field;
|
||||
use crate::plonk_challenger::Challenger;
|
||||
use crate::plonk_common::{eval_vanishing_poly, eval_zero_poly};
|
||||
use crate::plonk_common::{eval_vanishing_poly, eval_zero_poly, reduce_with_powers};
|
||||
use crate::proof::Proof;
|
||||
use crate::vars::EvaluationVars;
|
||||
|
||||
@ -57,9 +58,13 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
|
||||
|
||||
// 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 zeta_pow_deg = zeta.exp_power_of_2(common_data.degree_bits);
|
||||
let z_h_zeta = zeta_pow_deg - F::Extension::ONE;
|
||||
for (i, chunk) in quotient_polys_zeta
|
||||
.chunks(common_data.quotient_degree_factor)
|
||||
.enumerate()
|
||||
{
|
||||
ensure!(vanishing_polys_zeta[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg));
|
||||
}
|
||||
|
||||
let evaluations = proof.openings.clone();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user