Add eval_filtered methods

This commit is contained in:
wborgeaud 2021-06-22 17:10:36 +02:00
parent 5acbb674ad
commit 680d7a6389
4 changed files with 55 additions and 13 deletions

View File

@ -297,8 +297,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
config: self.config,
degree_bits,
gates,
gate_prefixes,
num_gate_constraints,
k_is,
circuit_digest,

View File

@ -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<F: Extendable<D>, const D: usize> {
/// The types of gates used in this circuit.
pub(crate) gates: Vec<GateRef<F, D>>,
/// The gate prefixes used to construct the selector polynomials.
pub(crate) gate_prefixes: GatePrefixes<F, D>,
/// The largest number of constraints imposed by any gate.
pub(crate) num_gate_constraints: usize,

View File

@ -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<F: Extendable<D>, const D: usize>: 'static + Send + Sync {
vars: EvaluationTargets<D>,
) -> Vec<ExtensionTarget<D>>;
fn eval_filtered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
// TODO: Filter
fn eval_filtered(&self, vars: EvaluationVars<F, D>, prefix: &[bool]) -> Vec<F::Extension> {
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<F>) -> Vec<F> {
// TODO: Filter
fn eval_filtered_base(&self, vars: EvaluationVarsBase<F>, prefix: &[bool]) -> Vec<F> {
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(

View File

@ -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<F: Extendable<D>, const D: usize>(
gammas: &[F],
alphas: &[F],
) -> Vec<F::Extension> {
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<F: Extendable<D>, const D: usize>(
gammas: &[F],
alphas: &[F],
) -> Vec<F> {
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<F: Extendable<D>, const D: usize>(
gates: &[GateRef<F, D>],
num_gate_constraints: usize,
vars: EvaluationVars<F, D>,
prefixes: &GatePrefixes<F, D>,
) -> Vec<F::Extension> {
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<F: Extendable<D>, const D: usize>(
gates: &[GateRef<F, D>],
num_gate_constraints: usize,
vars: EvaluationVarsBase<F>,
prefixes: &GatePrefixes<F, D>,
) -> Vec<F> {
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,