From 680d7a6389a7e6553c0433a44e60973ec32c5751 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 22 Jun 2021 17:10:36 +0200 Subject: [PATCH] Add `eval_filtered` methods --- src/circuit_builder.rs | 4 +++- src/circuit_data.rs | 5 ++++- src/gates/gate.rs | 35 +++++++++++++++++++++++++++++++---- src/plonk_common.rs | 24 +++++++++++++++++------- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/circuit_builder.rs b/src/circuit_builder.rs index c91ef470..e6a1e296 100644 --- a/src/circuit_builder.rs +++ b/src/circuit_builder.rs @@ -297,8 +297,9 @@ impl, const D: usize> CircuitBuilder { let gates = self.gates.iter().cloned().collect(); let gate_tree = Tree::from_gates(gates); + let gate_prefixes = gate_tree.into(); - let constant_vecs = self.constant_polys(&gate_tree.into()); + let constant_vecs = self.constant_polys(&gate_prefixes); let constants_commitment = ListPolynomialCommitment::new( constant_vecs.into_iter().map(|v| v.ifft()).collect(), self.config.fri_config.rate_bits, @@ -348,6 +349,7 @@ impl, const D: usize> CircuitBuilder { config: self.config, degree_bits, gates, + gate_prefixes, num_gate_constraints, k_is, circuit_digest, diff --git a/src/circuit_data.rs b/src/circuit_data.rs index c8477464..3b314281 100644 --- a/src/circuit_data.rs +++ b/src/circuit_data.rs @@ -3,7 +3,7 @@ use anyhow::Result; use crate::field::extension_field::Extendable; use crate::field::field::Field; use crate::fri::FriConfig; -use crate::gates::gate::GateRef; +use crate::gates::gate::{GatePrefixes, GateRef}; use crate::generator::WitnessGenerator; use crate::polynomial::commitment::ListPolynomialCommitment; use crate::proof::{Hash, HashTarget, Proof}; @@ -139,6 +139,9 @@ pub(crate) struct CommonCircuitData, const D: usize> { /// The types of gates used in this circuit. pub(crate) gates: Vec>, + /// The gate prefixes used to construct the selector polynomials. + pub(crate) gate_prefixes: GatePrefixes, + /// The largest number of constraints imposed by any gate. pub(crate) num_gate_constraints: usize, diff --git a/src/gates/gate.rs b/src/gates/gate.rs index cf939d9d..2ab410d4 100644 --- a/src/gates/gate.rs +++ b/src/gates/gate.rs @@ -9,6 +9,7 @@ use std::sync::Arc; use crate::circuit_builder::CircuitBuilder; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; +use crate::field::field::Field; use crate::gates::gate_tree::Tree; use crate::generator::WitnessGenerator; use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; @@ -57,15 +58,41 @@ pub trait Gate, const D: usize>: 'static + Send + Sync { vars: EvaluationTargets, ) -> Vec>; - fn eval_filtered(&self, vars: EvaluationVars) -> Vec { - // TODO: Filter + fn eval_filtered(&self, vars: EvaluationVars, prefix: &[bool]) -> Vec { + let filter: F::Extension = prefix + .iter() + .enumerate() + .map(|(i, &b)| { + if b { + vars.local_constants[i] + } else { + F::Extension::ONE - vars.local_constants[i] + } + }) + .product(); self.eval_unfiltered(vars) + .into_iter() + .map(|c| filter * c) + .collect() } /// Like `eval_filtered`, but specialized for points in the base field. - fn eval_filtered_base(&self, vars: EvaluationVarsBase) -> Vec { - // TODO: Filter + fn eval_filtered_base(&self, vars: EvaluationVarsBase, prefix: &[bool]) -> Vec { + let filter = prefix + .iter() + .enumerate() + .map(|(i, &b)| { + if b { + vars.local_constants[i] + } else { + F::ONE - vars.local_constants[i] + } + }) + .product(); self.eval_unfiltered_base(vars) + .into_iter() + .map(|c| c * filter) + .collect() } fn eval_filtered_recursively( diff --git a/src/plonk_common.rs b/src/plonk_common.rs index c9f11b74..2edd2add 100644 --- a/src/plonk_common.rs +++ b/src/plonk_common.rs @@ -5,7 +5,7 @@ use crate::circuit_data::CommonCircuitData; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::field::Field; -use crate::gates::gate::GateRef; +use crate::gates::gate::{GatePrefixes, GateRef}; use crate::polynomial::commitment::SALT_SIZE; use crate::polynomial::polynomial::PolynomialCoeffs; use crate::target::Target; @@ -76,8 +76,12 @@ pub(crate) fn eval_vanishing_poly, const D: usize>( gammas: &[F], alphas: &[F], ) -> Vec { - let constraint_terms = - evaluate_gate_constraints(&common_data.gates, common_data.num_gate_constraints, vars); + let constraint_terms = evaluate_gate_constraints( + &common_data.gates, + common_data.num_gate_constraints, + vars, + &common_data.gate_prefixes, + ); // The L_1(x) (Z(x) - 1) vanishing terms. let mut vanishing_z_1_terms = Vec::new(); @@ -125,8 +129,12 @@ pub(crate) fn eval_vanishing_poly_base, const D: usize>( gammas: &[F], alphas: &[F], ) -> Vec { - let constraint_terms = - evaluate_gate_constraints_base(&common_data.gates, common_data.num_gate_constraints, vars); + let constraint_terms = evaluate_gate_constraints_base( + &common_data.gates, + common_data.num_gate_constraints, + vars, + &common_data.gate_prefixes, + ); // The L_1(x) (Z(x) - 1) vanishing terms. let mut vanishing_z_1_terms = Vec::new(); @@ -170,10 +178,11 @@ pub fn evaluate_gate_constraints, const D: usize>( gates: &[GateRef], num_gate_constraints: usize, vars: EvaluationVars, + prefixes: &GatePrefixes, ) -> Vec { let mut constraints = vec![F::Extension::ZERO; num_gate_constraints]; for gate in gates { - let gate_constraints = gate.0.eval_filtered(vars); + let gate_constraints = gate.0.eval_filtered(vars, &prefixes[gate]); for (i, c) in gate_constraints.into_iter().enumerate() { debug_assert!( i < num_gate_constraints, @@ -189,10 +198,11 @@ pub fn evaluate_gate_constraints_base, const D: usize>( gates: &[GateRef], num_gate_constraints: usize, vars: EvaluationVarsBase, + prefixes: &GatePrefixes, ) -> Vec { let mut constraints = vec![F::ZERO; num_gate_constraints]; for gate in gates { - let gate_constraints = gate.0.eval_filtered_base(vars); + let gate_constraints = gate.0.eval_filtered_base(vars, &prefixes[gate]); for (i, c) in gate_constraints.into_iter().enumerate() { debug_assert!( i < num_gate_constraints,