Merge pull request #145 from mir-protocol/test_eval_fns

Test `eval_unfiltered_*` functions
This commit is contained in:
wborgeaud 2021-08-02 19:50:27 +02:00 committed by GitHub
commit 730962ceac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 162 additions and 61 deletions

View File

@ -250,12 +250,18 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ArithmeticExtensio
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::gates::arithmetic::ArithmeticExtensionGate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
#[test]
fn low_degree() {
test_low_degree::<CrandallField, _, 4>(ArithmeticExtensionGate)
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(ArithmeticExtensionGate)
}
}

View File

@ -184,12 +184,19 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::gates::base_sum::BaseSumGate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
#[test]
fn low_degree() {
test_low_degree::<CrandallField, _, 4>(BaseSumGate::<6>::new(11))
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(BaseSumGate::<6>::new(11))
}
}

View File

@ -96,12 +96,19 @@ impl<F: Field> SimpleGenerator<F> for ConstantGenerator<F> {
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::gates::constant::ConstantGate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
#[test]
fn low_degree() {
test_low_degree::<CrandallField, _, 4>(ConstantGate)
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(ConstantGate)
}
}

View File

@ -262,6 +262,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ExponentiationGene
mod tests {
use std::marker::PhantomData;
use anyhow::Result;
use rand::Rng;
use crate::field::crandall_field::CrandallField;
@ -269,7 +270,7 @@ mod tests {
use crate::field::field_types::Field;
use crate::gates::exponentiation::ExponentiationGate;
use crate::gates::gate::Gate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::hash::hash_types::HashOut;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::vars::EvaluationVars;
@ -303,6 +304,11 @@ mod tests {
test_low_degree::<CrandallField, _, 4>(ExponentiationGate::new(config));
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(ExponentiationGate::new(CircuitConfig::large_config()))
}
#[test]
fn test_gate_constraint() {
type F = CrandallField;

View File

@ -1,8 +1,14 @@
use crate::field::extension_field::Extendable;
use anyhow::{ensure, Result};
use crate::field::extension_field::{Extendable, FieldExtension};
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::hash::hash_types::HashOut;
use crate::plonk::vars::EvaluationVars;
use crate::hash::hash_types::{HashOut, HashOutTarget};
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
use crate::plonk::verifier::verify;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::util::{log2_ceil, transpose};
@ -75,3 +81,77 @@ fn random_low_degree_values<F: Field>(rate_bits: usize) -> Vec<F> {
.fft()
.values
}
pub(crate) fn test_eval_fns<F: Extendable<D>, G: Gate<F, D>, const D: usize>(
gate: G,
) -> Result<()> {
// Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent.
let wires_base = F::rand_vec(gate.num_wires());
let constants_base = F::rand_vec(gate.num_constants());
let wires = wires_base
.iter()
.map(|&x| F::Extension::from_basefield(x))
.collect::<Vec<_>>();
let constants = constants_base
.iter()
.map(|&x| F::Extension::from_basefield(x))
.collect::<Vec<_>>();
let public_inputs_hash = HashOut::rand();
let vars_base = EvaluationVarsBase {
local_constants: &constants_base,
local_wires: &wires_base,
public_inputs_hash: &public_inputs_hash,
};
let vars = EvaluationVars {
local_constants: &constants,
local_wires: &wires,
public_inputs_hash: &public_inputs_hash,
};
let evals_base = gate.eval_unfiltered_base(vars_base);
let evals = gate.eval_unfiltered(vars);
ensure!(
evals
== evals_base
.into_iter()
.map(F::Extension::from_basefield)
.collect::<Vec<_>>()
);
// Test that `eval_unfiltered` and `eval_unfiltered_recursively` are coherent.
let wires = F::Extension::rand_vec(gate.num_wires());
let constants = F::Extension::rand_vec(gate.num_constants());
let config = CircuitConfig::large_config();
let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::new();
let wires_t = builder.add_virtual_extension_targets(wires.len());
let constants_t = builder.add_virtual_extension_targets(constants.len());
pw.set_extension_targets(&wires_t, &wires);
pw.set_extension_targets(&constants_t, &constants);
let public_inputs_hash_t = builder.add_virtual_hash();
pw.set_hash_target(public_inputs_hash_t, public_inputs_hash);
let vars = EvaluationVars {
local_constants: &constants,
local_wires: &wires,
public_inputs_hash: &HashOut {
elements: [F::ZERO; 4],
},
};
let evals = gate.eval_unfiltered(vars);
let vars_t = EvaluationTargets {
local_constants: &constants_t,
local_wires: &wires_t,
public_inputs_hash: &public_inputs_hash_t,
};
let evals_t = gate.eval_unfiltered_recursively(&mut builder, vars_t);
pw.set_extension_targets(&evals_t, &evals);
let data = builder.build();
let proof = data.prove(pw)?;
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -333,17 +333,12 @@ mod tests {
use crate::field::extension_field::quartic::QuarticCrandallField;
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::gmimc::{GMiMCGate, W};
use crate::hash::gmimc::gmimc_permute_naive;
use crate::hash::hash_types::HashOut;
use crate::iop::generator::generate_partial_witness;
use crate::iop::wire::Wire;
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::vars::{EvaluationTargets, EvaluationVars};
use crate::plonk::verifier::verify;
#[test]
fn generated_output() {
@ -398,52 +393,11 @@ mod tests {
}
#[test]
fn test_evals() -> Result<()> {
fn eval_fns() -> Result<()> {
type F = CrandallField;
type FF = QuarticCrandallField;
const R: usize = 101;
let config = CircuitConfig::large_config();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut pw = PartialWitness::<F>::new();
let constants = Arc::new([F::TWO; R]);
type Gate = GMiMCGate<F, 4, R>;
let gate = Gate::new(constants);
let wires = FF::rand_vec(Gate::end());
let public_inputs_hash = &HashOut::rand();
let vars = EvaluationVars {
local_constants: &[],
local_wires: &wires,
public_inputs_hash,
};
let ev = gate.eval_unfiltered(vars);
let wires_t = builder.add_virtual_extension_targets(Gate::end());
for i in 0..Gate::end() {
pw.set_extension_target(wires_t[i], wires[i]);
}
let public_inputs_hash_t = builder.add_virtual_hash();
pw.set_hash_target(public_inputs_hash_t, *public_inputs_hash);
let vars_t = EvaluationTargets {
local_constants: &[],
local_wires: &wires_t,
public_inputs_hash: &public_inputs_hash_t,
};
let ev_t = gate.eval_unfiltered_recursively(&mut builder, vars_t);
assert_eq!(ev.len(), ev_t.len());
for (e, e_t) in ev.into_iter().zip(ev_t) {
let e_c = builder.constant_extension(e);
builder.assert_equal_extension(e_c, e_t);
}
let data = builder.build();
let proof = data.prove(pw)?;
verify(proof, &data.verifier_only, &data.common)
let gate = GMiMCGate::<F, 4, R>::new(constants);
test_eval_fns(gate)
}
}

View File

@ -319,11 +319,13 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InsertionGenerator
mod tests {
use std::marker::PhantomData;
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::quartic::QuarticCrandallField;
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::insertion::InsertionGate;
use crate::hash::hash_types::HashOut;
use crate::plonk::vars::EvaluationVars;
@ -352,6 +354,11 @@ mod tests {
test_low_degree::<CrandallField, _, 4>(InsertionGate::new(4));
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(InsertionGate::new(4))
}
#[test]
fn test_gate_constraint() {
type F = CrandallField;

View File

@ -286,11 +286,13 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGener
mod tests {
use std::marker::PhantomData;
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::quartic::QuarticCrandallField;
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::interpolation::InterpolationGate;
use crate::hash::hash_types::HashOut;
use crate::plonk::vars::EvaluationVars;
@ -321,6 +323,11 @@ mod tests {
test_low_degree::<CrandallField, _, 4>(InterpolationGate::new(4));
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(InterpolationGate::new(4))
}
#[test]
fn test_gate_constraint() {
type F = CrandallField;

View File

@ -56,12 +56,19 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::noop::NoopGate;
#[test]
fn low_degree() {
test_low_degree::<CrandallField, _, 4>(NoopGate)
}
#[test]
fn eval_fns() -> anyhow::Result<()> {
test_eval_fns::<CrandallField, _, 4>(NoopGate)
}
}

View File

@ -213,12 +213,19 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ReducingGenerator<
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::gates::gate_testing::test_low_degree;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::reducing::ReducingGate;
#[test]
fn low_degree() {
test_low_degree::<CrandallField, _, 4>(ReducingGate::new(22));
}
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<CrandallField, _, 4>(ReducingGate::new(22))
}
}

View File

@ -115,6 +115,19 @@ impl<F: Field> PartialWitness<F> {
});
}
pub fn set_extension_targets<const D: usize>(
&mut self,
ets: &[ExtensionTarget<D>],
values: &[F::Extension],
) where
F: Extendable<D>,
{
debug_assert_eq!(ets.len(), values.len());
ets.iter()
.zip(values)
.for_each(|(&et, &v)| self.set_extension_target(et, v));
}
pub fn set_wire(&mut self, wire: Wire, value: F) {
self.set_target(Target::Wire(wire), value)
}