This commit is contained in:
Daniel Lubarov 2021-09-02 15:03:03 -07:00 committed by Nicholas Ward
parent d1fea5cfd3
commit f89f49249a
17 changed files with 83 additions and 54 deletions

View File

@ -413,7 +413,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
) -> ExtensionTarget<D> {
let inv = self.add_virtual_extension_target();
let one = self.one_extension();
self.add_generator(QuotientGeneratorExtension {
self.add_simple_generator(QuotientGeneratorExtension {
numerator: one,
denominator: y,
quotient: inv,

View File

@ -6,7 +6,7 @@ use crate::field::{extension_field::Extendable, field_types::Field};
use crate::gates::switch::SwitchGate;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::{BoolTarget, Target};
use crate::iop::witness::PartialWitness;
use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::util::bimap::bimap_from_lists;
@ -28,7 +28,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
// Two singleton lists are permutations of one another as long as their items are equal.
1 => {
for e in 0..chunk_size {
self.assert_equal(a[0][e], b[0][e])
self.connect(a[0][e], b[0][e])
}
}
2 => {
@ -57,8 +57,8 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let (switch, gate_out1, gate_out2) = self.create_switch(a1, a2);
for e in 0..chunk_size {
self.route(b1[e], gate_out1[e]);
self.route(b2[e], gate_out2[e]);
self.connect(b1[e], gate_out1[e]);
self.connect(b2[e], gate_out2[e]);
}
}
@ -91,11 +91,11 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let mut c = Vec::new();
let mut d = Vec::new();
for e in 0..chunk_size {
self.route(
self.connect(
a1[e],
Target::wire(gate_index, gate.wire_first_input(next_copy, e)),
);
self.route(
self.connect(
a2[e],
Target::wire(gate_index, gate.wire_second_input(next_copy, e)),
);
@ -176,7 +176,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.assert_permutation(child_1_a, child_1_b);
self.assert_permutation(child_2_a, child_2_b);
self.add_generator(PermutationGenerator::<F> {
self.add_simple_generator(PermutationGenerator::<F> {
chunk_size,
a,
b,
@ -192,7 +192,7 @@ fn route<F: Field>(
b_values: Vec<Vec<F>>,
a_switches: Vec<Target>,
b_switches: Vec<Target>,
witness: &PartialWitness<F>,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) {
assert_eq!(a_values.len(), b_values.len());
@ -221,7 +221,7 @@ fn route<F: Field>(
// After we route a wire on one side, we find the corresponding wire on the other side and check
// if it still needs to be routed. If so, we add it to partial_routes.
let enqueue_other_side = |partial_routes: &mut [BTreeMap<usize, bool>],
witness: &PartialWitness<F>,
witness: &PartitionWitness<F>,
newly_set: &mut [Vec<bool>],
side: usize,
this_i: usize,
@ -272,7 +272,7 @@ fn route<F: Field>(
}
let mut route_switch = |partial_routes: &mut [BTreeMap<usize, bool>],
witness: &PartialWitness<F>,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
side: usize,
switch_index: usize,
@ -351,6 +351,8 @@ fn route<F: Field>(
}
}
}
#[derive(Debug)]
struct PermutationGenerator<F: Field> {
chunk_size: usize,
a: Vec<Vec<Target>>,
@ -370,7 +372,7 @@ impl<F: Field> SimpleGenerator<F> for PermutationGenerator<F> {
.collect()
}
fn run_once(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>) {
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
let a_values = self
.a
.iter()
@ -406,9 +408,10 @@ mod tests {
#[test]
fn test_permutation_2x2() -> Result<()> {
type F = CrandallField;
let config = CircuitConfig::large_config();
let pw = PartialWitness::new(config.num_wires);
let mut builder = CircuitBuilder::<F, 4>::new(config);
let config = CircuitConfig::large_zk_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, D>::new(config);
let one = F::ONE;
let two = F::from_canonical_usize(2);
@ -432,9 +435,10 @@ mod tests {
#[test]
fn test_permutation_4x4() -> Result<()> {
type F = CrandallField;
let config = CircuitConfig::large_config();
let pw = PartialWitness::new(config.num_wires);
let mut builder = CircuitBuilder::<F, 4>::new(config);
let config = CircuitConfig::large_zk_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, D>::new(config);
let one = F::ONE;
let two = F::from_canonical_usize(2);

View File

@ -28,7 +28,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let high_gate = self.add_gate(BaseSumGate::<2>::new(num_bits - n_log), vec![]);
let low = Target::wire(low_gate, BaseSumGate::<2>::WIRE_SUM);
let high = Target::wire(high_gate, BaseSumGate::<2>::WIRE_SUM);
self.add_generator(LowHighGenerator {
self.add_simple_generator(LowHighGenerator {
integer: x,
n_log,
low,

View File

@ -44,7 +44,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.connect(limb.borrow().target, Target::wire(gate_index, wire));
}
self.add_generator(BaseSumGenerator::<2> {
self.add_simple_generator(BaseSumGenerator::<2> {
gate_index,
limbs: bits.map(|l| *l.borrow()).collect(),
});

View File

@ -47,7 +47,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
self.connect(acc, integer);
self.add_generator(WireSplitGenerator {
self.add_simple_generator(WireSplitGenerator {
integer,
gates,
num_limbs: bits_per_gate,

View File

@ -110,12 +110,15 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D>
) -> Vec<Box<dyn WitnessGenerator<F>>> {
(0..NUM_ARITHMETIC_OPS)
.map(|i| {
let g: Box<dyn WitnessGenerator<F>> = Box::new(ArithmeticExtensionGenerator {
gate_index,
const_0: local_constants[0],
const_1: local_constants[1],
i,
});
let g: Box<dyn WitnessGenerator<F>> = Box::new(
ArithmeticExtensionGenerator {
gate_index,
const_0: local_constants[0],
const_1: local_constants[1],
i,
}
.adapter(),
);
g
})
.collect::<Vec<_>>()

View File

@ -105,7 +105,7 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
gate_index,
num_limbs: self.num_limbs,
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
// 1 for the sum then `num_limbs` for the limbs.

View File

@ -54,7 +54,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
gate_index,
constant: local_constants[0],
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -184,7 +184,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
gate_index,
gate: self.clone(),
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -217,7 +217,7 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
gate_index,
constants: self.constants.clone(),
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -220,7 +220,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
gate_index,
gate: self.clone(),
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -189,7 +189,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
gate: self.clone(),
_phantom: PhantomData,
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -167,7 +167,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
gate_index,
gate: self.clone(),
};
vec![Box::new(gen)]
vec![Box::new(gen.adapter())]
}
fn num_wires(&self) -> usize {

View File

@ -136,10 +136,13 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
gate_index: usize,
_local_constants: &[F],
) -> Vec<Box<dyn WitnessGenerator<F>>> {
vec![Box::new(ReducingGenerator {
gate_index,
gate: self.clone(),
})]
vec![Box::new(
ReducingGenerator {
gate_index,
gate: self.clone(),
}
.adapter(),
)]
}
fn num_wires(&self) -> usize {

View File

@ -228,7 +228,7 @@ impl<F: Extendable<D>, const D: usize> SwitchGenerator<F, D> {
deps
}
fn run_in_out(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>) {
fn run_in_out(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
let local_wire = |input| Wire {
gate: self.gate_index,
input,
@ -253,7 +253,7 @@ impl<F: Extendable<D>, const D: usize> SwitchGenerator<F, D> {
}
}
fn run_in_switch(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>) {
fn run_in_switch(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
let local_wire = |input| Wire {
gate: self.gate_index,
input,
@ -288,7 +288,7 @@ impl<F: Extendable<D>, const D: usize> WitnessGenerator<F> for SwitchGenerator<F
.union(self.in_switch_dependencies())
}
fn run(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool {
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool {
if witness.contains_all(&self.in_out_dependencies()) {
self.run_in_out(witness, out_buffer);
true

View File

@ -1,4 +1,5 @@
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::{Extendable, FieldExtension};
@ -186,16 +187,32 @@ pub trait SimpleGenerator<F: Field>: 'static + Send + Sync + Debug {
fn dependencies(&self) -> Vec<Target>;
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>);
fn adapter(self) -> SimpleGeneratorAdapter<F, Self>
where
Self: Sized,
{
SimpleGeneratorAdapter {
inner: self,
_phantom: PhantomData,
}
}
}
impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SG {
#[derive(Debug)]
pub struct SimpleGeneratorAdapter<F: Field, SG: SimpleGenerator<F> + ?Sized> {
_phantom: PhantomData<F>,
inner: SG,
}
impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SimpleGeneratorAdapter<F, SG> {
fn watch_list(&self) -> Vec<Target> {
self.dependencies()
self.inner.dependencies()
}
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool {
if witness.contains_all(&self.dependencies()) {
self.run_once(witness, out_buffer);
if witness.contains_all(&self.inner.dependencies()) {
self.inner.run_once(witness, out_buffer);
true
} else {
false

View File

@ -17,7 +17,9 @@ use crate::gates::public_input::PublicInputGate;
use crate::gates::switch::SwitchGate;
use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget};
use crate::hash::hashing::hash_n_to_hash;
use crate::iop::generator::{CopyGenerator, RandomValueGenerator, WitnessGenerator};
use crate::iop::generator::{
CopyGenerator, RandomValueGenerator, SimpleGenerator, WitnessGenerator,
};
use crate::iop::target::{BoolTarget, Target};
use crate::iop::wire::Wire;
use crate::iop::witness::PartitionWitness;
@ -188,7 +190,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Adds a generator which will copy `src` to `dst`.
pub fn generate_copy(&mut self, src: Target, dst: Target) {
self.add_generator(CopyGenerator { src, dst });
self.add_simple_generator(CopyGenerator { src, dst });
}
/// Uses Plonk's permutation argument to require that two elements be equal.
@ -215,8 +217,8 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.generators.extend(generators);
}
pub fn add_generator<G: WitnessGenerator<F>>(&mut self, generator: G) {
self.generators.push(Box::new(generator));
pub fn add_simple_generator<G: SimpleGenerator<F>>(&mut self, generator: G) {
self.generators.push(Box::new(generator.adapter()));
}
/// Returns a routable target with a value of 0.
@ -389,7 +391,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
for _ in 0..regular_poly_openings {
let gate = self.add_gate(NoopGate, vec![]);
for w in 0..num_wires {
self.add_generator(RandomValueGenerator {
self.add_simple_generator(RandomValueGenerator {
target: Target::Wire(Wire { gate, input: w }),
});
}
@ -403,7 +405,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let gate_2 = self.add_gate(NoopGate, vec![]);
for w in 0..num_routed_wires {
self.add_generator(RandomValueGenerator {
self.add_simple_generator(RandomValueGenerator {
target: Target::Wire(Wire {
gate: gate_1,
input: w,
@ -528,9 +530,9 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let wire_second_input =
Target::wire(gate_index, gate.wire_second_input(copy, element));
let wire_switch_bool = Target::wire(gate_index, gate.wire_switch_bool(copy));
self.route(zero, wire_first_input);
self.route(zero, wire_second_input);
self.route(zero, wire_switch_bool);
self.connect(zero, wire_first_input);
self.connect(zero, wire_second_input);
self.connect(zero, wire_switch_bool);
}
}
}