mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 00:03:10 +00:00
Merge pull request #195 from mir-protocol/partition_witness
Remove `CopyGenerator`s and add new `PartitionWitness`
This commit is contained in:
commit
cd1bd9e77b
@ -35,7 +35,7 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
},
|
||||
};
|
||||
|
||||
let inputs = PartialWitness::new(config.num_wires);
|
||||
let inputs = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let zero = builder.zero();
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::field::field_types::Field;
|
||||
use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS};
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::bits_u64;
|
||||
|
||||
@ -433,6 +433,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct QuotientGeneratorExtension<const D: usize> {
|
||||
numerator: ExtensionTarget<D>,
|
||||
denominator: ExtensionTarget<D>,
|
||||
@ -446,7 +447,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for QuotientGeneratorE
|
||||
deps
|
||||
}
|
||||
|
||||
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 num = witness.get_extension_target(self.numerator);
|
||||
let dem = witness.get_extension_target(self.denominator);
|
||||
let quotient = num / dem;
|
||||
@ -503,7 +504,7 @@ mod tests {
|
||||
use crate::field::extension_field::algebra::ExtensionAlgebra;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::verifier::verify;
|
||||
@ -516,7 +517,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let vs = FF::rand_vec(3);
|
||||
@ -551,7 +552,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_zk_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let x = FF::rand();
|
||||
@ -579,7 +580,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let x = FF::rand_vec(4);
|
||||
|
||||
@ -64,7 +64,7 @@ mod tests {
|
||||
type FF = QuarticCrandallField;
|
||||
let len = 1 << len_log;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let v = (0..len - 1)
|
||||
.map(|_| builder.constant_extension(FF::rand()))
|
||||
|
||||
@ -49,7 +49,7 @@ mod tests {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let len = 4;
|
||||
|
||||
@ -66,7 +66,7 @@ mod tests {
|
||||
type FF = QuarticCrandallField;
|
||||
let len = 1 << len_log;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let vec = FF::rand_vec(len);
|
||||
let v: Vec<_> = vec.iter().map(|x| builder.constant_extension(*x)).collect();
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::field::field_types::Field;
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
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;
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
@ -56,7 +56,7 @@ impl<F: Field> SimpleGenerator<F> for LowHighGenerator {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
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 integer_value = witness.get_target(self.integer).to_canonical_u64();
|
||||
let low = integer_value & ((1 << self.n_log) - 1);
|
||||
let high = integer_value >> self.n_log;
|
||||
|
||||
@ -43,7 +43,7 @@ mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::verifier::verify;
|
||||
@ -53,7 +53,7 @@ mod tests {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let (x, y) = (FF::rand(), FF::rand());
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::field::field_types::Field;
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
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;
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
@ -64,7 +64,7 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSumGenerator<B> {
|
||||
self.limbs.iter().map(|b| b.target).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 sum = self
|
||||
.limbs
|
||||
.iter()
|
||||
@ -97,7 +97,7 @@ mod tests {
|
||||
fn test_split_base() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let x = F::from_canonical_usize(0b110100000); // 416 = 1532 in base 6.
|
||||
let xt = builder.constant(x);
|
||||
@ -123,7 +123,7 @@ mod tests {
|
||||
fn test_base_sum() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let n = thread_rng().gen_range(0..(1 << 10));
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::field::field_types::Field;
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
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::ceil_div_usize;
|
||||
|
||||
@ -68,7 +68,7 @@ impl<F: Field> SimpleGenerator<F> for SplitGenerator {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
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 mut integer_value = witness.get_target(self.integer).to_canonical_u64();
|
||||
|
||||
for &b in &self.bits {
|
||||
@ -96,7 +96,7 @@ impl<F: Field> SimpleGenerator<F> for WireSplitGenerator {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
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 mut integer_value = witness.get_target(self.integer).to_canonical_u64();
|
||||
|
||||
for &gate in &self.gates {
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::field::extension_field::FieldExtension;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -138,7 +138,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct ArithmeticExtensionGenerator<F: Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
const_0: F,
|
||||
@ -157,7 +157,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ArithmeticExtensio
|
||||
.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 extract_extension = |range: Range<usize>| -> F::Extension {
|
||||
let t = ExtensionTarget::from_range(self.gate_index, range);
|
||||
witness.get_extension_target(t)
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::field::field_types::Field;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive};
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
@ -132,7 +132,7 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
||||
vec![Target::wire(self.gate_index, BaseSumGate::<B>::WIRE_SUM)]
|
||||
}
|
||||
|
||||
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 sum_value = witness
|
||||
.get_target(Target::wire(self.gate_index, BaseSumGate::<B>::WIRE_SUM))
|
||||
.to_canonical_u64() as usize;
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::PartitionWitness;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -85,7 +85,7 @@ impl<F: Field> SimpleGenerator<F> for ConstantGenerator<F> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
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 wire = Wire {
|
||||
gate: self.gate_index,
|
||||
input: ConstantGate::WIRE_OUTPUT,
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
@ -218,7 +218,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ExponentiationGene
|
||||
deps
|
||||
}
|
||||
|
||||
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 local_wire = |input| Wire {
|
||||
gate: self.gate_index,
|
||||
input,
|
||||
|
||||
@ -4,7 +4,7 @@ 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::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
@ -124,7 +124,7 @@ pub(crate) fn test_eval_fns<F: Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
let constants = F::Extension::rand_vec(gate.num_constants());
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let wires_t = builder.add_virtual_extension_targets(wires.len());
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::hash::gmimc::gmimc_automatic_constants;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -264,7 +264,7 @@ impl<F: Extendable<D>, const D: usize, const R: usize> SimpleGenerator<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 mut state = (0..W)
|
||||
.map(|i| {
|
||||
witness.get_wire(Wire {
|
||||
@ -331,8 +331,9 @@ mod tests {
|
||||
use crate::gates::gmimc::{GMiMCGate, W};
|
||||
use crate::hash::gmimc::gmimc_permute_naive;
|
||||
use crate::iop::generator::generate_partial_witness;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, PartitionWitness, Witness};
|
||||
use crate::util::timing::TimingTree;
|
||||
|
||||
#[test]
|
||||
@ -345,7 +346,7 @@ mod tests {
|
||||
|
||||
let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::<Vec<_>>();
|
||||
|
||||
let mut witness = PartialWitness::new(gate.num_wires());
|
||||
let mut witness = PartialWitness::new();
|
||||
witness.set_wire(
|
||||
Wire {
|
||||
gate: 0,
|
||||
@ -363,13 +364,17 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
let mut partition_witness = PartitionWitness::new(gate.num_wires(), gate.num_wires(), 1, 0);
|
||||
for input in 0..gate.num_wires() {
|
||||
partition_witness.add(Target::Wire(Wire { gate: 0, input }));
|
||||
}
|
||||
for (&t, &v) in witness.target_values.iter() {
|
||||
partition_witness.set_target(t, v);
|
||||
}
|
||||
let generators = gate.generators(0, &[]);
|
||||
generate_partial_witness(
|
||||
&mut witness,
|
||||
&mut partition_witness,
|
||||
&generators,
|
||||
gate.num_wires(),
|
||||
1,
|
||||
1,
|
||||
&mut TimingTree::default(),
|
||||
);
|
||||
|
||||
@ -377,7 +382,7 @@ mod tests {
|
||||
gmimc_permute_naive(permutation_inputs.try_into().unwrap(), constants);
|
||||
|
||||
for i in 0..W {
|
||||
let out = witness.get_wire(Wire {
|
||||
let out = partition_witness.get_wire(Wire {
|
||||
gate: 0,
|
||||
input: Gate::wire_output(i),
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@ use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -261,7 +261,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InsertionGenerator
|
||||
deps
|
||||
}
|
||||
|
||||
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 local_wire = |input| Wire {
|
||||
gate: self.gate_index,
|
||||
input,
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
@ -213,6 +213,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InterpolationGenerator<F: Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: InterpolationGate<F, D>,
|
||||
@ -239,7 +240,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGener
|
||||
deps
|
||||
}
|
||||
|
||||
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 n = self.gate.num_points;
|
||||
|
||||
let local_wire = |input| Wire {
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -208,7 +208,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for RandomAccessGenera
|
||||
deps
|
||||
}
|
||||
|
||||
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 local_wire = |input| Wire {
|
||||
gate: self.gate_index,
|
||||
input,
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::field::extension_field::FieldExtension;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -159,6 +159,7 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ReducingGenerator<const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: ReducingGate<D>,
|
||||
@ -173,7 +174,7 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for ReducingGenerator<
|
||||
.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 extract_extension = |range: Range<usize>| -> F::Extension {
|
||||
let t = ExtensionTarget::from_range(self.gate_index, range);
|
||||
witness.get_extension_target(t)
|
||||
|
||||
@ -78,7 +78,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
gate,
|
||||
input: swap_wire,
|
||||
});
|
||||
self.generate_copy(bit.target, swap_wire);
|
||||
self.route(bit.target, swap_wire);
|
||||
|
||||
let input_wires = (0..12)
|
||||
.map(|i| {
|
||||
@ -211,7 +211,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::hash::merkle_tree::MerkleTree;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::verifier::verify;
|
||||
@ -224,7 +224,7 @@ mod tests {
|
||||
fn test_recursive_merkle_proof() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let log_n = 8;
|
||||
|
||||
@ -330,7 +330,7 @@ mod tests {
|
||||
use crate::iop::challenger::{Challenger, RecursiveChallenger};
|
||||
use crate::iop::generator::generate_partial_witness;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::Witness;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::util::timing::TimingTree;
|
||||
@ -382,7 +382,6 @@ mod tests {
|
||||
num_routed_wires: 27,
|
||||
..CircuitConfig::default()
|
||||
};
|
||||
let mut witness = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config.clone());
|
||||
let mut recursive_challenger = RecursiveChallenger::new(&mut builder);
|
||||
let mut recursive_outputs_per_round: Vec<Vec<Target>> = Vec::new();
|
||||
@ -393,17 +392,15 @@ mod tests {
|
||||
);
|
||||
}
|
||||
let circuit = builder.build();
|
||||
let mut partition_witness = circuit.prover_only.partition_witness.clone();
|
||||
generate_partial_witness(
|
||||
&mut witness,
|
||||
&mut partition_witness,
|
||||
&circuit.prover_only.generators,
|
||||
config.num_wires,
|
||||
circuit.common.degree(),
|
||||
circuit.prover_only.num_virtual_targets,
|
||||
&mut TimingTree::default(),
|
||||
);
|
||||
let recursive_output_values_per_round: Vec<Vec<F>> = recursive_outputs_per_round
|
||||
.iter()
|
||||
.map(|outputs| witness.get_targets(outputs))
|
||||
.map(|outputs| partition_witness.get_targets(outputs))
|
||||
.collect();
|
||||
|
||||
assert_eq!(outputs_per_round, recursive_output_values_per_round);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use std::convert::identity;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
@ -7,35 +6,24 @@ use crate::field::field_types::Field;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::timed;
|
||||
use crate::util::timing::TimingTree;
|
||||
|
||||
/// Given a `PartialWitness` that has only inputs set, populates the rest of the witness using the
|
||||
/// Given a `PartitionWitness` that has only inputs set, populates the rest of the witness using the
|
||||
/// given set of generators.
|
||||
pub(crate) fn generate_partial_witness<F: Field>(
|
||||
witness: &mut PartialWitness<F>,
|
||||
witness: &mut PartitionWitness<F>,
|
||||
generators: &[Box<dyn WitnessGenerator<F>>],
|
||||
num_wires: usize,
|
||||
degree: usize,
|
||||
max_virtual_target: usize,
|
||||
timing: &mut TimingTree,
|
||||
) {
|
||||
let target_index = |t: Target| -> usize {
|
||||
match t {
|
||||
Target::Wire(Wire { gate, input }) => gate * num_wires + input,
|
||||
Target::VirtualTarget { index } => degree * num_wires + index,
|
||||
}
|
||||
};
|
||||
let max_target_index = target_index(Target::VirtualTarget {
|
||||
index: max_virtual_target,
|
||||
});
|
||||
let max_target_index = witness.forest.len();
|
||||
// Index generator indices by their watched targets.
|
||||
let mut generator_indices_by_watches = vec![Vec::new(); max_target_index];
|
||||
timed!(timing, "index generators by their watched targets", {
|
||||
for (i, generator) in generators.iter().enumerate() {
|
||||
for watch in generator.watch_list() {
|
||||
generator_indices_by_watches[target_index(watch)].push(i);
|
||||
generator_indices_by_watches[witness.target_index(watch)].push(i);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -46,11 +34,12 @@ pub(crate) fn generate_partial_witness<F: Field>(
|
||||
|
||||
// We also track a list of "expired" generators which have already returned false.
|
||||
let mut generator_is_expired = vec![false; generators.len()];
|
||||
let mut remaining_generators = generators.len();
|
||||
|
||||
let mut buffer = GeneratedValues::empty();
|
||||
|
||||
// Keep running generators until no generators are queued.
|
||||
while !pending_generator_indices.is_empty() {
|
||||
// Keep running generators until all generators have been run.
|
||||
while remaining_generators > 0 {
|
||||
let mut next_pending_generator_indices = Vec::new();
|
||||
|
||||
for &generator_idx in &pending_generator_indices {
|
||||
@ -61,29 +50,35 @@ pub(crate) fn generate_partial_witness<F: Field>(
|
||||
let finished = generators[generator_idx].run(&witness, &mut buffer);
|
||||
if finished {
|
||||
generator_is_expired[generator_idx] = true;
|
||||
remaining_generators -= 1;
|
||||
}
|
||||
|
||||
// Enqueue unfinished generators that were watching one of the newly populated targets.
|
||||
for &(watch, _) in &buffer.target_values {
|
||||
for &watching_generator_idx in &generator_indices_by_watches[target_index(watch)] {
|
||||
next_pending_generator_indices.push(watching_generator_idx);
|
||||
for &watching_generator_idx in
|
||||
&generator_indices_by_watches[witness.target_index(watch)]
|
||||
{
|
||||
if !generator_is_expired[watching_generator_idx] {
|
||||
next_pending_generator_indices.push(watching_generator_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
witness.extend(buffer.target_values.drain(..));
|
||||
}
|
||||
|
||||
pending_generator_indices = next_pending_generator_indices;
|
||||
// If we still need to run som generators, but none were enqueued, we enqueue all generators.
|
||||
pending_generator_indices =
|
||||
if remaining_generators > 0 && next_pending_generator_indices.is_empty() {
|
||||
(0..generators.len()).collect()
|
||||
} else {
|
||||
next_pending_generator_indices
|
||||
};
|
||||
}
|
||||
|
||||
assert!(
|
||||
generator_is_expired.into_iter().all(identity),
|
||||
"Some generators weren't run."
|
||||
);
|
||||
}
|
||||
|
||||
/// A generator participates in the generation of the witness.
|
||||
pub trait WitnessGenerator<F: Field>: 'static + Send + Sync {
|
||||
pub trait WitnessGenerator<F: Field>: 'static + Send + Sync + Debug {
|
||||
/// Targets to be "watched" by this generator. Whenever a target in the watch list is populated,
|
||||
/// the generator will be queued to run.
|
||||
fn watch_list(&self) -> Vec<Target>;
|
||||
@ -91,10 +86,11 @@ pub trait WitnessGenerator<F: Field>: 'static + Send + Sync {
|
||||
/// Run this generator, returning a flag indicating whether the generator is finished. If the
|
||||
/// flag is true, the generator will never be run again, otherwise it will be queued for another
|
||||
/// run next time a target in its watch list is populated.
|
||||
fn run(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool;
|
||||
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool;
|
||||
}
|
||||
|
||||
/// Values generated by a generator invocation.
|
||||
#[derive(Debug)]
|
||||
pub struct GeneratedValues<F: Field> {
|
||||
pub(crate) target_values: Vec<(Target, F)>,
|
||||
}
|
||||
@ -186,10 +182,10 @@ impl<F: Field> GeneratedValues<F> {
|
||||
}
|
||||
|
||||
/// A generator which runs once after a list of dependencies is present in the witness.
|
||||
pub trait SimpleGenerator<F: Field>: 'static + Send + Sync {
|
||||
pub trait SimpleGenerator<F: Field>: 'static + Send + Sync + Debug {
|
||||
fn dependencies(&self) -> Vec<Target>;
|
||||
|
||||
fn run_once(&self, witness: &PartialWitness<F>, out_buffer: &mut GeneratedValues<F>);
|
||||
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>);
|
||||
}
|
||||
|
||||
impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SG {
|
||||
@ -197,7 +193,7 @@ impl<F: Field, SG: SimpleGenerator<F>> WitnessGenerator<F> for SG {
|
||||
self.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.dependencies()) {
|
||||
self.run_once(witness, out_buffer);
|
||||
true
|
||||
@ -219,13 +215,14 @@ impl<F: Field> SimpleGenerator<F> for CopyGenerator {
|
||||
vec![self.src]
|
||||
}
|
||||
|
||||
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 value = witness.get_target(self.src);
|
||||
out_buffer.set_target(self.dst, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// A generator for including a random value
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct RandomValueGenerator {
|
||||
pub(crate) target: Target,
|
||||
}
|
||||
@ -235,7 +232,7 @@ impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
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 random_value = F::rand();
|
||||
|
||||
out_buffer.set_target(self.target, random_value);
|
||||
@ -243,6 +240,7 @@ impl<F: Field> SimpleGenerator<F> for RandomValueGenerator {
|
||||
}
|
||||
|
||||
/// A generator for testing if a value equals zero
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct NonzeroTestGenerator {
|
||||
pub(crate) to_test: Target,
|
||||
pub(crate) dummy: Target,
|
||||
@ -253,7 +251,7 @@ impl<F: Field> SimpleGenerator<F> for NonzeroTestGenerator {
|
||||
vec![self.to_test]
|
||||
}
|
||||
|
||||
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 to_test_value = witness.get_target(self.to_test);
|
||||
|
||||
let dummy_value = if to_test_value == F::ZERO {
|
||||
|
||||
@ -1,55 +1,31 @@
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::Field;
|
||||
use crate::gates::gate::GateInstance;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::hash::hash_types::{HashOut, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::plonk::copy_constraint::CopyConstraint;
|
||||
use crate::plonk::permutation_argument::ForestNode;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Witness<F: Field> {
|
||||
pub(crate) wire_values: Vec<Vec<F>>,
|
||||
}
|
||||
/// A witness holds information on the values of targets in a circuit.
|
||||
pub trait Witness<F: Field> {
|
||||
fn try_get_target(&self, target: Target) -> Option<F>;
|
||||
|
||||
impl<F: Field> Witness<F> {
|
||||
pub fn get_wire(&self, gate: usize, input: usize) -> F {
|
||||
self.wire_values[input][gate]
|
||||
}
|
||||
}
|
||||
fn set_target(&mut self, target: Target, value: F);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PartialWitness<F: Field> {
|
||||
pub(crate) wire_values: Vec<Vec<Option<F>>>,
|
||||
pub(crate) virtual_target_values: Vec<Option<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field> PartialWitness<F> {
|
||||
pub fn new(num_wires: usize) -> Self {
|
||||
PartialWitness {
|
||||
wire_values: vec![vec![None; num_wires]],
|
||||
virtual_target_values: vec![],
|
||||
}
|
||||
fn get_target(&self, target: Target) -> F {
|
||||
self.try_get_target(target).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_target(&self, target: Target) -> F {
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => self.wire_values[gate][input].unwrap(),
|
||||
Target::VirtualTarget { index } => self.virtual_target_values[index].unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_targets(&self, targets: &[Target]) -> Vec<F> {
|
||||
fn get_targets(&self, targets: &[Target]) -> Vec<F> {
|
||||
targets.iter().map(|&t| self.get_target(t)).collect()
|
||||
}
|
||||
|
||||
pub fn get_extension_target<const D: usize>(&self, et: ExtensionTarget<D>) -> F::Extension
|
||||
fn get_extension_target<const D: usize>(&self, et: ExtensionTarget<D>) -> F::Extension
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
@ -58,10 +34,7 @@ impl<F: Field> PartialWitness<F> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_extension_targets<const D: usize>(
|
||||
&self,
|
||||
ets: &[ExtensionTarget<D>],
|
||||
) -> Vec<F::Extension>
|
||||
fn get_extension_targets<const D: usize>(&self, ets: &[ExtensionTarget<D>]) -> Vec<F::Extension>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
@ -70,7 +43,7 @@ impl<F: Field> PartialWitness<F> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_bool_target(&self, target: BoolTarget) -> bool {
|
||||
fn get_bool_target(&self, target: BoolTarget) -> bool {
|
||||
let value = self.get_target(target.target).to_canonical_u64();
|
||||
match value {
|
||||
0 => false,
|
||||
@ -79,95 +52,43 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_hash_target(&self, ht: HashOutTarget) -> HashOut<F> {
|
||||
fn get_hash_target(&self, ht: HashOutTarget) -> HashOut<F> {
|
||||
HashOut {
|
||||
elements: self.get_targets(&ht.elements).try_into().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_get_target(&self, target: Target) -> Option<F> {
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => self.wire_values[gate][input],
|
||||
Target::VirtualTarget { index } => self.virtual_target_values[index],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_wire(&self, wire: Wire) -> F {
|
||||
fn get_wire(&self, wire: Wire) -> F {
|
||||
self.get_target(Target::Wire(wire))
|
||||
}
|
||||
|
||||
pub fn try_get_wire(&self, wire: Wire) -> Option<F> {
|
||||
fn try_get_wire(&self, wire: Wire) -> Option<F> {
|
||||
self.try_get_target(Target::Wire(wire))
|
||||
}
|
||||
|
||||
pub fn contains(&self, target: Target) -> bool {
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => {
|
||||
self.wire_values.len() > gate && self.wire_values[gate][input].is_some()
|
||||
}
|
||||
Target::VirtualTarget { index } => {
|
||||
self.virtual_target_values.len() > index
|
||||
&& self.virtual_target_values[index].is_some()
|
||||
}
|
||||
}
|
||||
fn contains(&self, target: Target) -> bool {
|
||||
self.try_get_target(target).is_some()
|
||||
}
|
||||
|
||||
pub fn contains_all(&self, targets: &[Target]) -> bool {
|
||||
fn contains_all(&self, targets: &[Target]) -> bool {
|
||||
targets.iter().all(|&t| self.contains(t))
|
||||
}
|
||||
|
||||
pub fn set_target(&mut self, target: Target, value: F) {
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => {
|
||||
if gate >= self.wire_values.len() {
|
||||
self.wire_values
|
||||
.resize(gate + 1, vec![None; self.wire_values[0].len()]);
|
||||
}
|
||||
if let Some(old_value) = self.wire_values[gate][input] {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target was set twice with different values: {:?}",
|
||||
target
|
||||
);
|
||||
} else {
|
||||
self.wire_values[gate][input] = Some(value);
|
||||
}
|
||||
}
|
||||
Target::VirtualTarget { index } => {
|
||||
if index >= self.virtual_target_values.len() {
|
||||
self.virtual_target_values.resize(index + 1, None);
|
||||
}
|
||||
if let Some(old_value) = self.virtual_target_values[index] {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target was set twice with different values: {:?}",
|
||||
target
|
||||
);
|
||||
} else {
|
||||
self.virtual_target_values[index] = Some(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut<F>) {
|
||||
fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut<F>) {
|
||||
ht.elements
|
||||
.iter()
|
||||
.zip(value.elements)
|
||||
.for_each(|(&t, x)| self.set_target(t, x));
|
||||
}
|
||||
|
||||
pub fn set_cap_target(&mut self, ct: &MerkleCapTarget, value: &MerkleCap<F>) {
|
||||
fn set_cap_target(&mut self, ct: &MerkleCapTarget, value: &MerkleCap<F>) {
|
||||
for (ht, h) in ct.0.iter().zip(&value.0) {
|
||||
self.set_hash_target(*ht, *h);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_extension_target<const D: usize>(
|
||||
&mut self,
|
||||
et: ExtensionTarget<D>,
|
||||
value: F::Extension,
|
||||
) where
|
||||
fn set_extension_target<const D: usize>(&mut self, et: ExtensionTarget<D>, value: F::Extension)
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
let limbs = value.to_basefield_array();
|
||||
@ -176,7 +97,7 @@ impl<F: Field> PartialWitness<F> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_extension_targets<const D: usize>(
|
||||
fn set_extension_targets<const D: usize>(
|
||||
&mut self,
|
||||
ets: &[ExtensionTarget<D>],
|
||||
values: &[F::Extension],
|
||||
@ -189,15 +110,15 @@ impl<F: Field> PartialWitness<F> {
|
||||
.for_each(|(&et, &v)| self.set_extension_target(et, v));
|
||||
}
|
||||
|
||||
pub fn set_bool_target(&mut self, target: BoolTarget, value: bool) {
|
||||
fn set_bool_target(&mut self, target: BoolTarget, value: bool) {
|
||||
self.set_target(target.target, F::from_bool(value))
|
||||
}
|
||||
|
||||
pub fn set_wire(&mut self, wire: Wire, value: F) {
|
||||
fn set_wire(&mut self, wire: Wire, value: F) {
|
||||
self.set_target(Target::Wire(wire), value)
|
||||
}
|
||||
|
||||
pub fn set_wires<W>(&mut self, wires: W, values: &[F])
|
||||
fn set_wires<W>(&mut self, wires: W, values: &[F])
|
||||
where
|
||||
W: IntoIterator<Item = Wire>,
|
||||
{
|
||||
@ -207,7 +128,7 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_ext_wires<W, const D: usize>(&mut self, wires: W, value: F::Extension)
|
||||
fn set_ext_wires<W, const D: usize>(&mut self, wires: W, value: F::Extension)
|
||||
where
|
||||
F: Extendable<D>,
|
||||
W: IntoIterator<Item = Wire>,
|
||||
@ -215,57 +136,104 @@ impl<F: Field> PartialWitness<F> {
|
||||
self.set_wires(wires, &value.to_basefield_array());
|
||||
}
|
||||
|
||||
pub fn extend<I: Iterator<Item = (Target, F)>>(&mut self, pairs: I) {
|
||||
fn extend<I: Iterator<Item = (Target, F)>>(&mut self, pairs: I) {
|
||||
for (t, v) in pairs {
|
||||
self.set_target(t, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn full_witness(self, degree: usize, num_wires: usize) -> Witness<F> {
|
||||
let mut wire_values = vec![vec![F::ZERO; degree]; num_wires];
|
||||
assert!(self.wire_values.len() <= degree);
|
||||
for i in 0..self.wire_values.len() {
|
||||
for j in 0..num_wires {
|
||||
wire_values[j][i] = self.wire_values[i][j].unwrap_or(F::ZERO);
|
||||
}
|
||||
}
|
||||
Witness { wire_values }
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MatrixWitness<F: Field> {
|
||||
pub(crate) wire_values: Vec<Vec<F>>,
|
||||
}
|
||||
|
||||
/// Checks that the copy constraints are satisfied in the witness.
|
||||
pub fn check_copy_constraints<const D: usize>(
|
||||
&self,
|
||||
copy_constraints: &[CopyConstraint],
|
||||
gate_instances: &[GateInstance<F, D>],
|
||||
) -> Result<()>
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
for CopyConstraint { pair: (a, b), name } in copy_constraints {
|
||||
let va = self.try_get_target(*a).unwrap_or(F::ZERO);
|
||||
let vb = self.try_get_target(*b).unwrap_or(F::ZERO);
|
||||
let desc = |t: &Target| -> String {
|
||||
match t {
|
||||
Target::Wire(Wire { gate, input }) => format!(
|
||||
"wire {} of gate #{} (`{}`)",
|
||||
input,
|
||||
gate,
|
||||
gate_instances[*gate].gate_ref.0.id()
|
||||
),
|
||||
Target::VirtualTarget { index } => format!("{}-th virtual target", index),
|
||||
}
|
||||
};
|
||||
ensure!(
|
||||
va == vb,
|
||||
"Copy constraint '{}' between {} and {} is not satisfied. \
|
||||
Got values of {} and {} respectively.",
|
||||
name,
|
||||
desc(a),
|
||||
desc(b),
|
||||
va,
|
||||
vb
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
impl<F: Field> MatrixWitness<F> {
|
||||
pub fn get_wire(&self, gate: usize, input: usize) -> F {
|
||||
self.wire_values[input][gate]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PartialWitness<F: Field> {
|
||||
pub(crate) target_values: HashMap<Target, F>,
|
||||
}
|
||||
|
||||
impl<F: Field> PartialWitness<F> {
|
||||
pub fn new() -> Self {
|
||||
PartialWitness {
|
||||
target_values: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Witness<F> for PartialWitness<F> {
|
||||
fn try_get_target(&self, target: Target) -> Option<F> {
|
||||
self.target_values.get(&target).copied()
|
||||
}
|
||||
|
||||
fn set_target(&mut self, target: Target, value: F) {
|
||||
let opt_old_value = self.target_values.insert(target, value);
|
||||
if let Some(old_value) = opt_old_value {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target {:?} was set twice with different values",
|
||||
target
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `PartitionWitness` holds a disjoint-set forest of the targets respecting a circuit's copy constraints.
|
||||
/// The value of a target is defined to be the value of its root in the forest.
|
||||
#[derive(Clone)]
|
||||
pub struct PartitionWitness<F: Field> {
|
||||
pub forest: Vec<ForestNode<Target, F>>,
|
||||
pub num_wires: usize,
|
||||
pub num_routed_wires: usize,
|
||||
pub degree: usize,
|
||||
}
|
||||
|
||||
impl<F: Field> Witness<F> for PartitionWitness<F> {
|
||||
fn try_get_target(&self, target: Target) -> Option<F> {
|
||||
let parent_index = self.forest[self.target_index(target)].parent;
|
||||
self.forest[parent_index].value
|
||||
}
|
||||
|
||||
fn set_target(&mut self, target: Target, value: F) {
|
||||
let parent_index = self.forest[self.target_index(target)].parent;
|
||||
let parent_value = &mut self.forest[parent_index].value;
|
||||
if let Some(old_value) = *parent_value {
|
||||
assert_eq!(
|
||||
value, old_value,
|
||||
"Partition containing {:?} was set twice with different values",
|
||||
target
|
||||
);
|
||||
} else {
|
||||
*parent_value = Some(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> PartitionWitness<F> {
|
||||
pub fn target_index(&self, target: Target) -> usize {
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => gate * self.num_wires + input,
|
||||
Target::VirtualTarget { index } => self.degree * self.num_wires + index,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn full_witness(self) -> MatrixWitness<F> {
|
||||
let mut wire_values = vec![vec![F::ZERO; self.degree]; self.num_wires];
|
||||
for i in 0..self.degree {
|
||||
for j in 0..self.num_wires {
|
||||
let t = Target::Wire(Wire { gate: i, input: j });
|
||||
if let Some(x) = self.try_get_target(t) {
|
||||
wire_values[j][i] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MatrixWitness { wire_values }
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,12 +19,12 @@ use crate::hash::hashing::hash_n_to_hash;
|
||||
use crate::iop::generator::{CopyGenerator, RandomValueGenerator, WitnessGenerator};
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartitionWitness;
|
||||
use crate::plonk::circuit_data::{
|
||||
CircuitConfig, CircuitData, CommonCircuitData, ProverCircuitData, ProverOnlyCircuitData,
|
||||
VerifierCircuitData, VerifierOnlyCircuitData,
|
||||
};
|
||||
use crate::plonk::copy_constraint::CopyConstraint;
|
||||
use crate::plonk::permutation_argument::TargetPartition;
|
||||
use crate::plonk::plonk_common::PlonkPolynomials;
|
||||
use crate::polynomial::polynomial::PolynomialValues;
|
||||
use crate::util::context_tree::ContextTree;
|
||||
@ -173,16 +173,13 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Shorthand for `generate_copy` and `assert_equal`.
|
||||
/// Both elements must be routable, otherwise this method will panic.
|
||||
pub fn route(&mut self, src: Target, dst: Target) {
|
||||
self.generate_copy(src, dst);
|
||||
self.assert_equal(src, dst);
|
||||
}
|
||||
|
||||
/// Same as `route` with a named copy constraint.
|
||||
pub fn named_route(&mut self, src: Target, dst: Target, name: String) {
|
||||
self.generate_copy(src, dst);
|
||||
self.named_assert_equal(src, dst, name);
|
||||
}
|
||||
|
||||
@ -502,30 +499,39 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn sigma_vecs(&self, k_is: &[F], subgroup: &[F]) -> Vec<PolynomialValues<F>> {
|
||||
fn sigma_vecs(
|
||||
&self,
|
||||
k_is: &[F],
|
||||
subgroup: &[F],
|
||||
) -> (Vec<PolynomialValues<F>>, PartitionWitness<F>) {
|
||||
let degree = self.gate_instances.len();
|
||||
let degree_log = log2_strict(degree);
|
||||
let mut target_partition = TargetPartition::new(|t| match t {
|
||||
Target::Wire(Wire { gate, input }) => gate * self.config.num_routed_wires + input,
|
||||
Target::VirtualTarget { index } => degree * self.config.num_routed_wires + index,
|
||||
});
|
||||
let mut partition_witness = PartitionWitness::new(
|
||||
self.config.num_wires,
|
||||
self.config.num_routed_wires,
|
||||
degree,
|
||||
self.virtual_target_index,
|
||||
);
|
||||
|
||||
for gate in 0..degree {
|
||||
for input in 0..self.config.num_routed_wires {
|
||||
target_partition.add(Target::Wire(Wire { gate, input }));
|
||||
for input in 0..self.config.num_wires {
|
||||
partition_witness.add(Target::Wire(Wire { gate, input }));
|
||||
}
|
||||
}
|
||||
|
||||
for index in 0..self.virtual_target_index {
|
||||
target_partition.add(Target::VirtualTarget { index });
|
||||
partition_witness.add(Target::VirtualTarget { index });
|
||||
}
|
||||
|
||||
for &CopyConstraint { pair: (a, b), .. } in &self.copy_constraints {
|
||||
target_partition.merge(a, b);
|
||||
partition_witness.merge(a, b);
|
||||
}
|
||||
|
||||
let wire_partition = target_partition.wire_partition();
|
||||
wire_partition.get_sigma_polys(degree_log, k_is, subgroup)
|
||||
let wire_partition = partition_witness.wire_partition();
|
||||
(
|
||||
wire_partition.get_sigma_polys(degree_log, k_is, subgroup),
|
||||
partition_witness,
|
||||
)
|
||||
}
|
||||
|
||||
/// Fill the remaining unused arithmetic operations with zeros, so that all
|
||||
@ -614,7 +620,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let constant_vecs = self.constant_polys(&prefixed_gates, num_constants);
|
||||
|
||||
let k_is = get_unique_coset_shifts(degree, self.config.num_routed_wires);
|
||||
let sigma_vecs = self.sigma_vecs(&k_is, &subgroup);
|
||||
let (sigma_vecs, partition_witness) = self.sigma_vecs(&k_is, &subgroup);
|
||||
|
||||
let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat();
|
||||
let constants_sigmas_commitment = PolynomialBatchCommitment::from_values(
|
||||
@ -635,11 +641,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
constants_sigmas_commitment,
|
||||
sigmas: transpose_poly_values(sigma_vecs),
|
||||
subgroup,
|
||||
copy_constraints: self.copy_constraints,
|
||||
gate_instances: self.gate_instances,
|
||||
public_inputs: self.public_inputs,
|
||||
marked_targets: self.marked_targets,
|
||||
num_virtual_targets: self.virtual_target_index,
|
||||
partition_witness,
|
||||
};
|
||||
|
||||
// The HashSet of gates will have a non-deterministic order. When converting to a Vec, we
|
||||
|
||||
@ -11,8 +11,7 @@ use crate::hash::hash_types::{HashOut, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::plonk::copy_constraint::CopyConstraint;
|
||||
use crate::iop::witness::{PartialWitness, PartitionWitness};
|
||||
use crate::plonk::proof::ProofWithPublicInputs;
|
||||
use crate::plonk::prover::prove;
|
||||
use crate::plonk::verifier::verify;
|
||||
@ -148,16 +147,14 @@ pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||
pub sigmas: Vec<Vec<F>>,
|
||||
/// Subgroup of order `degree`.
|
||||
pub subgroup: Vec<F>,
|
||||
/// The circuit's copy constraints.
|
||||
pub copy_constraints: Vec<CopyConstraint>,
|
||||
/// The concrete placement of each gate in the circuit.
|
||||
pub gate_instances: Vec<GateInstance<F, D>>,
|
||||
/// Targets to be made public.
|
||||
pub public_inputs: Vec<Target>,
|
||||
/// A vector of marked targets. The values assigned to these targets will be displayed by the prover.
|
||||
pub marked_targets: Vec<MarkedTargets<D>>,
|
||||
/// Number of virtual targets used in the circuit.
|
||||
pub num_virtual_targets: usize,
|
||||
/// Partial witness holding the copy constraints information.
|
||||
pub partition_witness: PartitionWitness<F>,
|
||||
}
|
||||
|
||||
/// Circuit data required by the verifier, but not the prover.
|
||||
|
||||
@ -1,52 +1,55 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::field::field_types::Field;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::iop::witness::PartitionWitness;
|
||||
use crate::polynomial::polynomial::PolynomialValues;
|
||||
|
||||
/// Node in the Disjoint Set Forest.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct ForestNode<T: Debug + Copy + Eq + PartialEq> {
|
||||
t: T,
|
||||
parent: usize,
|
||||
size: usize,
|
||||
index: usize,
|
||||
pub struct ForestNode<T: Debug + Copy + Eq + PartialEq, V: Field> {
|
||||
pub t: T,
|
||||
pub parent: usize,
|
||||
pub size: usize,
|
||||
pub index: usize,
|
||||
pub value: Option<V>,
|
||||
}
|
||||
|
||||
/// Disjoint Set Forest data-structure following https://en.wikipedia.org/wiki/Disjoint-set_data_structure.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TargetPartition<T: Debug + Copy + Eq + PartialEq + Hash, F: Fn(T) -> usize> {
|
||||
forest: Vec<ForestNode<T>>,
|
||||
/// Function to compute a node's index in the forest.
|
||||
indices: F,
|
||||
}
|
||||
|
||||
impl<T: Debug + Copy + Eq + PartialEq + Hash, F: Fn(T) -> usize> TargetPartition<T, F> {
|
||||
pub fn new(f: F) -> Self {
|
||||
impl<F: Field> PartitionWitness<F> {
|
||||
pub fn new(
|
||||
num_wires: usize,
|
||||
num_routed_wires: usize,
|
||||
degree: usize,
|
||||
num_virtual_targets: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
forest: Vec::new(),
|
||||
indices: f,
|
||||
forest: Vec::with_capacity(degree * num_wires + num_virtual_targets),
|
||||
num_wires,
|
||||
num_routed_wires,
|
||||
degree,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a new partition with a single member.
|
||||
pub fn add(&mut self, t: T) {
|
||||
pub fn add(&mut self, t: Target) {
|
||||
let index = self.forest.len();
|
||||
debug_assert_eq!((self.indices)(t), index);
|
||||
debug_assert_eq!(self.target_index(t), index);
|
||||
self.forest.push(ForestNode {
|
||||
t,
|
||||
parent: index,
|
||||
size: 1,
|
||||
index,
|
||||
value: None,
|
||||
});
|
||||
}
|
||||
|
||||
/// Path compression method, see https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Finding_set_representatives.
|
||||
pub fn find(&mut self, x: ForestNode<T>) -> ForestNode<T> {
|
||||
pub fn find(&mut self, x: ForestNode<Target, F>) -> ForestNode<Target, F> {
|
||||
if x.parent != x.index {
|
||||
let root = self.find(self.forest[x.parent]);
|
||||
self.forest[x.index].parent = root.index;
|
||||
@ -57,9 +60,9 @@ impl<T: Debug + Copy + Eq + PartialEq + Hash, F: Fn(T) -> usize> TargetPartition
|
||||
}
|
||||
|
||||
/// Merge two sets.
|
||||
pub fn merge(&mut self, tx: T, ty: T) {
|
||||
let mut x = self.forest[(self.indices)(tx)];
|
||||
let mut y = self.forest[(self.indices)(ty)];
|
||||
pub fn merge(&mut self, tx: Target, ty: Target) {
|
||||
let mut x = self.forest[self.target_index(tx)];
|
||||
let mut y = self.forest[self.target_index(ty)];
|
||||
|
||||
x = self.find(x);
|
||||
y = self.find(y);
|
||||
@ -79,44 +82,36 @@ impl<T: Debug + Copy + Eq + PartialEq + Hash, F: Fn(T) -> usize> TargetPartition
|
||||
self.forest[x.index] = x;
|
||||
self.forest[y.index] = y;
|
||||
}
|
||||
}
|
||||
impl<F: Fn(Target) -> usize> TargetPartition<Target, F> {
|
||||
pub fn wire_partition(&mut self) -> WirePartitions {
|
||||
|
||||
pub fn wire_partition(&mut self) -> WirePartition {
|
||||
let mut partition = HashMap::<_, Vec<_>>::new();
|
||||
let nodes = self.forest.clone();
|
||||
for x in nodes {
|
||||
let v = partition.entry(self.find(x).t).or_default();
|
||||
v.push(x.t);
|
||||
for gate in 0..self.degree {
|
||||
for input in 0..self.num_routed_wires {
|
||||
let w = Wire { gate, input };
|
||||
let t = Target::Wire(w);
|
||||
let x = self.forest[self.target_index(t)];
|
||||
partition.entry(self.find(x).t).or_default().push(w);
|
||||
}
|
||||
}
|
||||
// I'm not 100% sure this loop is needed, but I'm afraid removing it might lead to subtle bugs.
|
||||
for index in 0..self.forest.len() - self.degree * self.num_wires {
|
||||
let t = Target::VirtualTarget { index };
|
||||
let x = self.forest[self.target_index(t)];
|
||||
self.find(x);
|
||||
}
|
||||
|
||||
let mut indices = HashMap::new();
|
||||
// Here we keep just the Wire targets, filtering out everything else.
|
||||
let partition = partition
|
||||
.into_values()
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
.filter_map(|t| match t {
|
||||
Target::Wire(w) => Some(w),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
partition.iter().enumerate().for_each(|(i, v)| {
|
||||
v.iter().for_each(|t| {
|
||||
indices.insert(*t, i);
|
||||
});
|
||||
});
|
||||
let partition = partition.into_values().collect::<Vec<_>>();
|
||||
|
||||
WirePartitions { partition }
|
||||
WirePartition { partition }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WirePartitions {
|
||||
pub struct WirePartition {
|
||||
partition: Vec<Vec<Wire>>,
|
||||
}
|
||||
|
||||
impl WirePartitions {
|
||||
impl WirePartition {
|
||||
pub(crate) fn get_sigma_polys<F: Field>(
|
||||
&self,
|
||||
degree_log: usize,
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hashing::hash_n_to_hash;
|
||||
use crate::iop::challenger::Challenger;
|
||||
use crate::iop::generator::generate_partial_witness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::iop::witness::{MatrixWitness, PartialWitness, Witness};
|
||||
use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
|
||||
use crate::plonk::plonk_common::PlonkPolynomials;
|
||||
use crate::plonk::plonk_common::ZeroPolyOnCoset;
|
||||
@ -28,44 +28,39 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
) -> Result<ProofWithPublicInputs<F, D>> {
|
||||
let mut timing = TimingTree::new("prove", Level::Debug);
|
||||
let config = &common_data.config;
|
||||
let num_wires = config.num_wires;
|
||||
let num_challenges = config.num_challenges;
|
||||
let quotient_degree = common_data.quotient_degree();
|
||||
let degree = common_data.degree();
|
||||
|
||||
let mut partial_witness = inputs;
|
||||
let mut partition_witness = prover_data.partition_witness.clone();
|
||||
timed!(
|
||||
timing,
|
||||
"fill partition witness",
|
||||
for (t, v) in inputs.target_values.into_iter() {
|
||||
partition_witness.set_target(t, v);
|
||||
}
|
||||
);
|
||||
|
||||
timed!(
|
||||
timing,
|
||||
&format!("run {} generators", prover_data.generators.len()),
|
||||
generate_partial_witness(
|
||||
&mut partial_witness,
|
||||
&prover_data.generators,
|
||||
config.num_wires,
|
||||
degree,
|
||||
prover_data.num_virtual_targets,
|
||||
&mut timing
|
||||
)
|
||||
generate_partial_witness(&mut partition_witness, &prover_data.generators, &mut timing)
|
||||
);
|
||||
|
||||
let public_inputs = partial_witness.get_targets(&prover_data.public_inputs);
|
||||
let public_inputs = partition_witness.get_targets(&prover_data.public_inputs);
|
||||
let public_inputs_hash = hash_n_to_hash(public_inputs.clone(), true);
|
||||
|
||||
// Display the marked targets for debugging purposes.
|
||||
for m in &prover_data.marked_targets {
|
||||
m.display(&partial_witness);
|
||||
if cfg!(debug_assertions) {
|
||||
// Display the marked targets for debugging purposes.
|
||||
for m in &prover_data.marked_targets {
|
||||
m.display(&partition_witness);
|
||||
}
|
||||
}
|
||||
|
||||
timed!(
|
||||
timing,
|
||||
"check copy constraints",
|
||||
partial_witness
|
||||
.check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)?
|
||||
);
|
||||
|
||||
let witness = timed!(
|
||||
timing,
|
||||
"compute full witness",
|
||||
partial_witness.full_witness(degree, num_wires)
|
||||
partition_witness.full_witness()
|
||||
);
|
||||
|
||||
let wires_values: Vec<PolynomialValues<F>> = timed!(
|
||||
@ -222,7 +217,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
|
||||
/// Compute the partial products used in the `Z` polynomials.
|
||||
fn all_wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
witness: &Witness<F>,
|
||||
witness: &MatrixWitness<F>,
|
||||
betas: &[F],
|
||||
gammas: &[F],
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
@ -245,7 +240,7 @@ fn all_wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
/// Returns the polynomials interpolating `partial_products(f / g)`
|
||||
/// where `f, g` are the products in the definition of `Z`: `Z(g^i) = f / g`.
|
||||
fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
witness: &Witness<F>,
|
||||
witness: &MatrixWitness<F>,
|
||||
beta: F,
|
||||
gamma: F,
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
@ -259,14 +254,12 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
.enumerate()
|
||||
.map(|(i, &x)| {
|
||||
let s_sigmas = &prover_data.sigmas[i];
|
||||
let numerators = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = witness.get_wire(i, j);
|
||||
let k_i = k_is[j];
|
||||
let s_id = k_i * x;
|
||||
wire_value + beta * s_id + gamma
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let numerators = (0..common_data.config.num_routed_wires).map(|j| {
|
||||
let wire_value = witness.get_wire(i, j);
|
||||
let k_i = k_is[j];
|
||||
let s_id = k_i * x;
|
||||
wire_value + beta * s_id + gamma
|
||||
});
|
||||
let denominators = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = witness.get_wire(i, j);
|
||||
@ -276,7 +269,6 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
.collect::<Vec<_>>();
|
||||
let denominator_invs = F::batch_multiplicative_inverse(&denominators);
|
||||
let quotient_values = numerators
|
||||
.into_iter()
|
||||
.zip(denominator_invs)
|
||||
.map(|(num, den_inv)| num * den_inv)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -137,7 +137,7 @@ mod tests {
|
||||
use crate::fri::FriConfig;
|
||||
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
|
||||
use crate::hash::merkle_proofs::MerkleProofTarget;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
use crate::plonk::proof::{OpeningSetTarget, Proof, ProofTarget, ProofWithPublicInputs};
|
||||
use crate::plonk::verifier::verify;
|
||||
use crate::util::log2_strict;
|
||||
@ -386,7 +386,7 @@ mod tests {
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.prove(PartialWitness::new())?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
@ -394,7 +394,7 @@ mod tests {
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
@ -442,7 +442,7 @@ mod tests {
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.prove(PartialWitness::new())?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
@ -450,7 +450,7 @@ mod tests {
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
@ -468,7 +468,7 @@ mod tests {
|
||||
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut pw = PartialWitness::new();
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
|
||||
/// Enum representing all types of targets, so that they can be marked.
|
||||
#[derive(Clone)]
|
||||
@ -36,7 +36,7 @@ impl<M: Into<Markable<D>>, const D: usize> From<Vec<M>> for Markable<D> {
|
||||
|
||||
impl<const D: usize> Markable<D> {
|
||||
/// Display a `Markable` by querying a partial witness.
|
||||
fn print_markable<F: Extendable<D>>(&self, pw: &PartialWitness<F>) {
|
||||
fn print_markable<F: Extendable<D>>(&self, pw: &PartitionWitness<F>) {
|
||||
match self {
|
||||
Markable::Target(t) => println!("{}", pw.get_target(*t)),
|
||||
Markable::ExtensionTarget(et) => println!("{}", pw.get_extension_target(*et)),
|
||||
@ -55,7 +55,7 @@ pub struct MarkedTargets<const D: usize> {
|
||||
|
||||
impl<const D: usize> MarkedTargets<D> {
|
||||
/// Display the collection of targets along with its name by querying a partial witness.
|
||||
pub fn display<F: Extendable<D>>(&self, pw: &PartialWitness<F>) {
|
||||
pub fn display<F: Extendable<D>>(&self, pw: &PartitionWitness<F>) {
|
||||
println!("Values for {}:", self.name);
|
||||
self.targets.print_markable(pw);
|
||||
println!("End of values for {}", self.name);
|
||||
|
||||
@ -200,7 +200,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let alpha = FF::rand();
|
||||
@ -228,7 +228,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let alpha = FF::rand();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user