diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index 94b37eaa..f7b8eee5 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -5,7 +5,7 @@ use crate::field::extension_field::FieldExtension; use crate::field::extension_field::{Extendable, OEF}; use crate::field::field_types::Field; use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; -use crate::iop::generator::{GeneratedValues, SimpleGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, Yo}; use crate::iop::target::Target; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -433,6 +433,7 @@ impl, const D: usize> CircuitBuilder { } } +#[derive(Debug)] struct QuotientGeneratorExtension { numerator: ExtensionTarget, denominator: ExtensionTarget, @@ -446,7 +447,7 @@ impl, const D: usize> SimpleGenerator for QuotientGeneratorE deps } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let num = witness.get_extension_target(self.numerator); let dem = witness.get_extension_target(self.denominator); let quotient = num / dem; diff --git a/src/gadgets/range_check.rs b/src/gadgets/range_check.rs index be7eaf2e..c03dae7b 100644 --- a/src/gadgets/range_check.rs +++ b/src/gadgets/range_check.rs @@ -1,7 +1,7 @@ use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::base_sum::BaseSumGate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, Yo}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -56,7 +56,7 @@ impl SimpleGenerator for LowHighGenerator { vec![self.integer] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { 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; diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index 69cfa377..cca2a166 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -3,7 +3,7 @@ use std::borrow::Borrow; use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::base_sum::BaseSumGate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, Yo}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -68,7 +68,7 @@ impl SimpleGenerator for BaseSumGenerator { self.limbs.iter().map(|b| b.target).collect() } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let sum = self .limbs .iter() diff --git a/src/gadgets/split_join.rs b/src/gadgets/split_join.rs index 71c171f0..875ead00 100644 --- a/src/gadgets/split_join.rs +++ b/src/gadgets/split_join.rs @@ -1,7 +1,7 @@ use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::base_sum::BaseSumGate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, Yo}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -68,7 +68,7 @@ impl SimpleGenerator for SplitGenerator { vec![self.integer] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let mut integer_value = witness.get_target(self.integer).to_canonical_u64(); for &b in &self.bits { @@ -96,7 +96,7 @@ impl SimpleGenerator for WireSplitGenerator { vec![self.integer] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let mut integer_value = witness.get_target(self.integer).to_canonical_u64(); for &gate in &self.gates { diff --git a/src/gates/arithmetic.rs b/src/gates/arithmetic.rs index dcabcee8..159628e1 100644 --- a/src/gates/arithmetic.rs +++ b/src/gates/arithmetic.rs @@ -4,7 +4,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::extension_field::FieldExtension; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -138,7 +138,7 @@ impl, const D: usize> Gate for ArithmeticExtensionGate } } -#[derive(Clone)] +#[derive(Debug)] struct ArithmeticExtensionGenerator, const D: usize> { gate_index: usize, const_0: F, @@ -157,7 +157,7 @@ impl, const D: usize> SimpleGenerator for ArithmeticExtensio .collect() } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let extract_extension = |range: Range| -> F::Extension { let t = ExtensionTarget::from_range(self.gate_index, range); witness.get_extension_target(t) diff --git a/src/gates/base_sum.rs b/src/gates/base_sum.rs index fe4e51a2..c46bfee1 100644 --- a/src/gates/base_sum.rs +++ b/src/gates/base_sum.rs @@ -4,7 +4,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -132,7 +132,7 @@ impl SimpleGenerator for BaseSplitGenerator { vec![Target::wire(self.gate_index, BaseSumGate::::WIRE_SUM)] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let sum_value = witness .get_target(Target::wire(self.gate_index, BaseSumGate::::WIRE_SUM)) .to_canonical_u64() as usize; diff --git a/src/gates/constant.rs b/src/gates/constant.rs index 0cc22b22..94d5fa03 100644 --- a/src/gates/constant.rs +++ b/src/gates/constant.rs @@ -2,7 +2,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -85,7 +85,7 @@ impl SimpleGenerator for ConstantGenerator { Vec::new() } - fn run_once(&self, _witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, _witness: &Yo, out_buffer: &mut GeneratedValues) { let wire = Wire { gate: self.gate_index, input: ConstantGate::WIRE_OUTPUT, diff --git a/src/gates/exponentiation.rs b/src/gates/exponentiation.rs index 468f58e2..69827907 100644 --- a/src/gates/exponentiation.rs +++ b/src/gates/exponentiation.rs @@ -4,7 +4,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -218,7 +218,7 @@ impl, const D: usize> SimpleGenerator for ExponentiationGene deps } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let local_wire = |input| Wire { gate: self.gate_index, input, diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index 1830b9c7..2e0f652f 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -5,7 +5,7 @@ use crate::field::extension_field::Extendable; use crate::field::field_types::Field; use crate::gates::gate::Gate; use crate::hash::gmimc::gmimc_automatic_constants; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -264,7 +264,7 @@ impl, const D: usize, const R: usize> SimpleGenerator .collect() } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let mut state = (0..W) .map(|i| { witness.get_wire(Wire { @@ -317,89 +317,89 @@ impl, const D: usize, const R: usize> SimpleGenerator } } -#[cfg(test)] -mod tests { - use std::convert::TryInto; - use std::sync::Arc; - - use anyhow::Result; - - use crate::field::crandall_field::CrandallField; - use crate::field::field_types::Field; - use crate::gates::gate::Gate; - 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::iop::generator::generate_partial_witness; - use crate::iop::wire::Wire; - use crate::iop::witness::PartialWitness; - use crate::util::timing::TimingTree; - - #[test] - fn generated_output() { - type F = CrandallField; - const R: usize = 101; - let constants = Arc::new([F::TWO; R]); - type Gate = GMiMCGate; - let gate = Gate::new(constants.clone()); - - let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - - let mut witness = PartialWitness::new(gate.num_wires()); - witness.set_wire( - Wire { - gate: 0, - input: Gate::WIRE_SWAP, - }, - F::ZERO, - ); - for i in 0..W { - witness.set_wire( - Wire { - gate: 0, - input: Gate::wire_input(i), - }, - permutation_inputs[i], - ); - } - - let generators = gate.generators(0, &[]); - generate_partial_witness( - &mut witness, - &generators, - gate.num_wires(), - 1, - 1, - &mut TimingTree::default(), - ); - - let expected_outputs: [F; W] = - gmimc_permute_naive(permutation_inputs.try_into().unwrap(), constants); - - for i in 0..W { - let out = witness.get_wire(Wire { - gate: 0, - input: Gate::wire_output(i), - }); - assert_eq!(out, expected_outputs[i]); - } - } - - #[test] - fn low_degree() { - type F = CrandallField; - const R: usize = 101; - let constants = Arc::new([F::TWO; R]); - let gate = GMiMCGate::::new(constants); - test_low_degree(gate) - } - - #[test] - fn eval_fns() -> Result<()> { - type F = CrandallField; - const R: usize = 101; - let constants = Arc::new([F::TWO; R]); - let gate = GMiMCGate::::new(constants); - test_eval_fns(gate) - } -} +// #[cfg(test)] +// mod tests { +// use std::convert::TryInto; +// use std::sync::Arc; +// +// use anyhow::Result; +// +// use crate::field::crandall_field::CrandallField; +// use crate::field::field_types::Field; +// use crate::gates::gate::Gate; +// 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::iop::generator::generate_partial_witness; +// use crate::iop::wire::Wire; +// use crate::iop::witness::PartialWitness; +// use crate::util::timing::TimingTree; +// +// #[test] +// fn generated_output() { +// type F = CrandallField; +// const R: usize = 101; +// let constants = Arc::new([F::TWO; R]); +// type Gate = GMiMCGate; +// let gate = Gate::new(constants.clone()); +// +// let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); +// +// let mut witness = PartialWitness::new(gate.num_wires()); +// witness.set_wire( +// Wire { +// gate: 0, +// input: Gate::WIRE_SWAP, +// }, +// F::ZERO, +// ); +// for i in 0..W { +// witness.set_wire( +// Wire { +// gate: 0, +// input: Gate::wire_input(i), +// }, +// permutation_inputs[i], +// ); +// } +// +// let generators = gate.generators(0, &[]); +// generate_partial_witness( +// &mut witness, +// &generators, +// gate.num_wires(), +// 1, +// 1, +// &mut TimingTree::default(), +// ); +// +// let expected_outputs: [F; W] = +// gmimc_permute_naive(permutation_inputs.try_into().unwrap(), constants); +// +// for i in 0..W { +// let out = witness.get_wire(Wire { +// gate: 0, +// input: Gate::wire_output(i), +// }); +// assert_eq!(out, expected_outputs[i]); +// } +// } +// +// #[test] +// fn low_degree() { +// type F = CrandallField; +// const R: usize = 101; +// let constants = Arc::new([F::TWO; R]); +// let gate = GMiMCGate::::new(constants); +// test_low_degree(gate) +// } +// +// #[test] +// fn eval_fns() -> Result<()> { +// type F = CrandallField; +// const R: usize = 101; +// let constants = Arc::new([F::TWO; R]); +// let gate = GMiMCGate::::new(constants); +// test_eval_fns(gate) +// } +// } diff --git a/src/gates/insertion.rs b/src/gates/insertion.rs index 7a42be41..d1c2ea22 100644 --- a/src/gates/insertion.rs +++ b/src/gates/insertion.rs @@ -6,7 +6,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; use crate::field::field_types::Field; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -261,7 +261,7 @@ impl, const D: usize> SimpleGenerator for InsertionGenerator deps } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let local_wire = |input| Wire { gate: self.gate_index, input, diff --git a/src/gates/interpolation.rs b/src/gates/interpolation.rs index 9356d428..a9cd7d38 100644 --- a/src/gates/interpolation.rs +++ b/src/gates/interpolation.rs @@ -8,7 +8,7 @@ use crate::field::extension_field::{Extendable, FieldExtension}; use crate::field::interpolation::interpolant; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -213,6 +213,7 @@ impl, const D: usize> Gate for InterpolationGate { } } +#[derive(Debug)] struct InterpolationGenerator, const D: usize> { gate_index: usize, gate: InterpolationGate, @@ -239,7 +240,7 @@ impl, const D: usize> SimpleGenerator for InterpolationGener deps } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let n = self.gate.num_points; let local_wire = |input| Wire { diff --git a/src/gates/random_access.rs b/src/gates/random_access.rs index 0dd008f0..561bfbfd 100644 --- a/src/gates/random_access.rs +++ b/src/gates/random_access.rs @@ -5,7 +5,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; use crate::field::field_types::Field; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::PartialWitness; @@ -208,7 +208,7 @@ impl, const D: usize> SimpleGenerator for RandomAccessGenera deps } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let local_wire = |input| Wire { gate: self.gate_index, input, diff --git a/src/gates/reducing.rs b/src/gates/reducing.rs index 8bfdc0c4..64987e79 100644 --- a/src/gates/reducing.rs +++ b/src/gates/reducing.rs @@ -4,7 +4,7 @@ use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::field::extension_field::FieldExtension; use crate::gates::gate::Gate; -use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator, Yo}; use crate::iop::target::Target; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; @@ -159,6 +159,7 @@ impl, const D: usize> Gate for ReducingGate { } } +#[derive(Debug)] struct ReducingGenerator { gate_index: usize, gate: ReducingGate, @@ -173,7 +174,7 @@ impl, const D: usize> SimpleGenerator for ReducingGenerator< .collect() } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let extract_extension = |range: Range| -> F::Extension { let t = ExtensionTarget::from_range(self.gate_index, range); witness.get_extension_target(t) diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index 70c7e310..13e16035 100644 --- a/src/iop/challenger.rs +++ b/src/iop/challenger.rs @@ -353,89 +353,89 @@ impl RecursiveChallenger { } } -#[cfg(test)] -mod tests { - use crate::field::crandall_field::CrandallField; - use crate::field::field_types::Field; - 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::plonk::circuit_builder::CircuitBuilder; - use crate::plonk::circuit_data::CircuitConfig; - use crate::util::timing::TimingTree; - - #[test] - fn no_duplicate_challenges() { - type F = CrandallField; - let mut challenger = Challenger::new(); - let mut challenges = Vec::new(); - - for i in 1..10 { - challenges.extend(challenger.get_n_challenges(i)); - challenger.observe_element(F::rand()); - } - - let dedup_challenges = { - let mut dedup = challenges.clone(); - dedup.dedup(); - dedup - }; - assert_eq!(dedup_challenges, challenges); - } - - /// Tests for consistency between `Challenger` and `RecursiveChallenger`. - #[test] - fn test_consistency() { - type F = CrandallField; - - // These are mostly arbitrary, but we want to test some rounds with enough inputs/outputs to - // trigger multiple absorptions/squeezes. - let num_inputs_per_round = vec![2, 5, 3]; - let num_outputs_per_round = vec![1, 2, 4]; - - // Generate random input messages. - let inputs_per_round: Vec> = num_inputs_per_round - .iter() - .map(|&n| F::rand_vec(n)) - .collect(); - - let mut challenger = Challenger::new(); - let mut outputs_per_round: Vec> = Vec::new(); - for (r, inputs) in inputs_per_round.iter().enumerate() { - challenger.observe_elements(inputs); - outputs_per_round.push(challenger.get_n_challenges(num_outputs_per_round[r])); - } - - let config = CircuitConfig { - num_wires: 12 + 12 + 1 + 101, - num_routed_wires: 27, - ..CircuitConfig::default() - }; - let mut witness = PartialWitness::new(config.num_wires); - let mut builder = CircuitBuilder::::new(config.clone()); - let mut recursive_challenger = RecursiveChallenger::new(&mut builder); - let mut recursive_outputs_per_round: Vec> = Vec::new(); - for (r, inputs) in inputs_per_round.iter().enumerate() { - recursive_challenger.observe_elements(&builder.constants(inputs)); - recursive_outputs_per_round.push( - recursive_challenger.get_n_challenges(&mut builder, num_outputs_per_round[r]), - ); - } - let circuit = builder.build(); - generate_partial_witness( - &mut 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> = recursive_outputs_per_round - .iter() - .map(|outputs| witness.get_targets(outputs)) - .collect(); - - assert_eq!(outputs_per_round, recursive_output_values_per_round); - } -} +// #[cfg(test)] +// mod tests { +// use crate::field::crandall_field::CrandallField; +// use crate::field::field_types::Field; +// 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::plonk::circuit_builder::CircuitBuilder; +// use crate::plonk::circuit_data::CircuitConfig; +// use crate::util::timing::TimingTree; +// +// #[test] +// fn no_duplicate_challenges() { +// type F = CrandallField; +// let mut challenger = Challenger::new(); +// let mut challenges = Vec::new(); +// +// for i in 1..10 { +// challenges.extend(challenger.get_n_challenges(i)); +// challenger.observe_element(F::rand()); +// } +// +// let dedup_challenges = { +// let mut dedup = challenges.clone(); +// dedup.dedup(); +// dedup +// }; +// assert_eq!(dedup_challenges, challenges); +// } +// +// /// Tests for consistency between `Challenger` and `RecursiveChallenger`. +// #[test] +// fn test_consistency() { +// type F = CrandallField; +// +// // These are mostly arbitrary, but we want to test some rounds with enough inputs/outputs to +// // trigger multiple absorptions/squeezes. +// let num_inputs_per_round = vec![2, 5, 3]; +// let num_outputs_per_round = vec![1, 2, 4]; +// +// // Generate random input messages. +// let inputs_per_round: Vec> = num_inputs_per_round +// .iter() +// .map(|&n| F::rand_vec(n)) +// .collect(); +// +// let mut challenger = Challenger::new(); +// let mut outputs_per_round: Vec> = Vec::new(); +// for (r, inputs) in inputs_per_round.iter().enumerate() { +// challenger.observe_elements(inputs); +// outputs_per_round.push(challenger.get_n_challenges(num_outputs_per_round[r])); +// } +// +// let config = CircuitConfig { +// num_wires: 12 + 12 + 1 + 101, +// num_routed_wires: 27, +// ..CircuitConfig::default() +// }; +// let mut witness = PartialWitness::new(config.num_wires); +// let mut builder = CircuitBuilder::::new(config.clone()); +// let mut recursive_challenger = RecursiveChallenger::new(&mut builder); +// let mut recursive_outputs_per_round: Vec> = Vec::new(); +// for (r, inputs) in inputs_per_round.iter().enumerate() { +// recursive_challenger.observe_elements(&builder.constants(inputs)); +// recursive_outputs_per_round.push( +// recursive_challenger.get_n_challenges(&mut builder, num_outputs_per_round[r]), +// ); +// } +// let circuit = builder.build(); +// generate_partial_witness( +// &mut 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> = recursive_outputs_per_round +// .iter() +// .map(|outputs| witness.get_targets(outputs)) +// .collect(); +// +// assert_eq!(outputs_per_round, recursive_output_values_per_round); +// } +// } diff --git a/src/iop/generator.rs b/src/iop/generator.rs index 6ab1b412..71b9aa3a 100644 --- a/src/iop/generator.rs +++ b/src/iop/generator.rs @@ -1,41 +1,199 @@ -use std::convert::identity; +use std::convert::{identity, TryInto}; use std::fmt::Debug; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; use crate::field::field_types::Field; -use crate::hash::hash_types::{HashOut, HashOutTarget}; -use crate::iop::target::Target; +use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget}; +use crate::hash::merkle_tree::MerkleCap; +use crate::iop::target::{BoolTarget, Target}; use crate::iop::wire::Wire; -use crate::iop::witness::PartialWitness; +use crate::iop::witness::{PartialWitness, Witness}; +use crate::plonk::permutation_argument::ForestNode; use crate::timed; use crate::util::timing::TimingTree; +pub struct Yo( + pub Vec>, + pub Box usize>, +); +impl Yo { + pub fn get_target(&self, target: Target) -> F { + self.0[self.0[self.1(target)].parent].value.unwrap() + } + + pub fn get_targets(&self, targets: &[Target]) -> Vec { + targets.iter().map(|&t| self.get_target(t)).collect() + } + + pub fn get_extension_target(&self, et: ExtensionTarget) -> F::Extension + where + F: Extendable, + { + F::Extension::from_basefield_array( + self.get_targets(&et.to_target_array()).try_into().unwrap(), + ) + } + + pub fn get_extension_targets( + &self, + ets: &[ExtensionTarget], + ) -> Vec + where + F: Extendable, + { + ets.iter() + .map(|&et| self.get_extension_target(et)) + .collect() + } + + pub fn get_bool_target(&self, target: BoolTarget) -> bool { + let value = self.get_target(target.target).to_canonical_u64(); + match value { + 0 => false, + 1 => true, + _ => panic!("not a bool"), + } + } + + pub fn get_hash_target(&self, ht: HashOutTarget) -> HashOut { + HashOut { + elements: self.get_targets(&ht.elements).try_into().unwrap(), + } + } + + pub fn try_get_target(&self, target: Target) -> Option { + self.0[self.0[self.1(target)].parent].value + } + + pub fn get_wire(&self, wire: Wire) -> F { + self.get_target(Target::Wire(wire)) + } + + pub fn try_get_wire(&self, wire: Wire) -> Option { + self.try_get_target(Target::Wire(wire)) + } + + pub fn contains(&self, target: Target) -> bool { + self.0[self.0[self.1(target)].parent].value.is_some() + } + + pub fn contains_all(&self, targets: &[Target]) -> bool { + targets.iter().all(|&t| self.contains(t)) + } + + pub fn set_target(&mut self, target: Target, value: F) { + let i = self.0[self.1(target)].parent; + self.0[i].value = Some(value); + } + + pub fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut) { + 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) { + for (ht, h) in ct.0.iter().zip(&value.0) { + self.set_hash_target(*ht, *h); + } + } + + pub fn set_extension_target( + &mut self, + et: ExtensionTarget, + value: F::Extension, + ) where + F: Extendable, + { + let limbs = value.to_basefield_array(); + (0..D).for_each(|i| { + self.set_target(et.0[i], limbs[i]); + }); + } + + pub fn set_extension_targets( + &mut self, + ets: &[ExtensionTarget], + values: &[F::Extension], + ) where + F: Extendable, + { + debug_assert_eq!(ets.len(), values.len()); + ets.iter() + .zip(values) + .for_each(|(&et, &v)| self.set_extension_target(et, v)); + } + + pub 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) { + self.set_target(Target::Wire(wire), value) + } + + pub fn set_wires(&mut self, wires: W, values: &[F]) + where + W: IntoIterator, + { + // If we used itertools, we could use zip_eq for extra safety. + for (wire, &value) in wires.into_iter().zip(values) { + self.set_wire(wire, value); + } + } + + pub fn set_ext_wires(&mut self, wires: W, value: F::Extension) + where + F: Extendable, + W: IntoIterator, + { + self.set_wires(wires, &value.to_basefield_array()); + } + + pub fn extend>(&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 { + let mut wire_values = vec![vec![F::ZERO; degree]; num_wires]; + // assert!(self.wire_values.len() <= degree); + for i in 0..degree { + for j in 0..num_wires { + let t = Target::Wire(Wire { gate: i, input: j }); + wire_values[j][i] = self.0[self.0[self.1(t)].parent].value.unwrap_or(F::ZERO); + } + } + Witness { wire_values } + } +} + /// Given a `PartialWitness` that has only inputs set, populates the rest of the witness using the /// given set of generators. pub(crate) fn generate_partial_witness( - witness: &mut PartialWitness, + witness: &mut Yo, generators: &[Box>], 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 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 = witness.0.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.1(watch)].push(i); } } }); @@ -65,7 +223,7 @@ pub(crate) fn generate_partial_witness( // 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)] { + for &watching_generator_idx in &generator_indices_by_watches[witness.1(watch)] { next_pending_generator_indices.push(watching_generator_idx); } } @@ -76,6 +234,19 @@ pub(crate) fn generate_partial_witness( pending_generator_indices = next_pending_generator_indices; } + for i in 0..degree { + for j in 0..num_wires { + if !witness.contains(Target::Wire(Wire { gate: i, input: j })) { + println!("{} {}", i, j); + } + } + } + // for i in 0..generator_is_expired.len() { + // if !generator_is_expired[i] { + // println!("{:?}", generators[i]); + // println!("{:?}", generators[i].watch_list()); + // } + // } assert!( generator_is_expired.into_iter().all(identity), "Some generators weren't run." @@ -83,7 +254,7 @@ pub(crate) fn generate_partial_witness( } /// A generator participates in the generation of the witness. -pub trait WitnessGenerator: 'static + Send + Sync { +pub trait WitnessGenerator: '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; @@ -91,7 +262,7 @@ pub trait WitnessGenerator: '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, out_buffer: &mut GeneratedValues) -> bool; + fn run(&self, witness: &Yo, out_buffer: &mut GeneratedValues) -> bool; } /// Values generated by a generator invocation. @@ -186,10 +357,10 @@ impl GeneratedValues { } /// A generator which runs once after a list of dependencies is present in the witness. -pub trait SimpleGenerator: 'static + Send + Sync { +pub trait SimpleGenerator: 'static + Send + Sync + Debug { fn dependencies(&self) -> Vec; - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues); + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues); } impl> WitnessGenerator for SG { @@ -197,7 +368,7 @@ impl> WitnessGenerator for SG { self.dependencies() } - fn run(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) -> bool { + fn run(&self, witness: &Yo, out_buffer: &mut GeneratedValues) -> bool { if witness.contains_all(&self.dependencies()) { self.run_once(witness, out_buffer); true @@ -219,13 +390,14 @@ impl SimpleGenerator for CopyGenerator { vec![self.src] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { 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 +407,7 @@ impl SimpleGenerator for RandomValueGenerator { Vec::new() } - fn run_once(&self, _witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, _witness: &Yo, out_buffer: &mut GeneratedValues) { let random_value = F::rand(); out_buffer.set_target(self.target, random_value); @@ -243,6 +415,7 @@ impl SimpleGenerator 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 +426,7 @@ impl SimpleGenerator for NonzeroTestGenerator { vec![self.to_test] } - fn run_once(&self, witness: &PartialWitness, out_buffer: &mut GeneratedValues) { + fn run_once(&self, witness: &Yo, out_buffer: &mut GeneratedValues) { let to_test_value = witness.get_target(self.to_test); let dummy_value = if to_test_value == F::ZERO { diff --git a/src/iop/witness.rs b/src/iop/witness.rs index 51b5a182..cfcf5950 100644 --- a/src/iop/witness.rs +++ b/src/iop/witness.rs @@ -28,6 +28,7 @@ impl Witness { pub struct PartialWitness { pub(crate) wire_values: Vec>>, pub(crate) virtual_target_values: Vec>, + pub(crate) set_targets: Vec<(Target, F)>, } impl PartialWitness { @@ -35,6 +36,7 @@ impl PartialWitness { PartialWitness { wire_values: vec![vec![None; num_wires]], virtual_target_values: vec![], + set_targets: vec![], } } @@ -148,6 +150,7 @@ impl PartialWitness { } } } + self.set_targets.push((target, value)); } pub fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut) { diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index 8afec0e4..1fb70bad 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -24,7 +24,7 @@ use crate::plonk::circuit_data::{ VerifierCircuitData, VerifierOnlyCircuitData, }; use crate::plonk::copy_constraint::CopyConstraint; -use crate::plonk::permutation_argument::TargetPartition; +use crate::plonk::permutation_argument::{ForestNode, TargetPartition}; use crate::plonk::plonk_common::PlonkPolynomials; use crate::polynomial::polynomial::PolynomialValues; use crate::util::context_tree::ContextTree; @@ -176,13 +176,13 @@ impl, const D: usize> CircuitBuilder { /// 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.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.generate_copy(src, dst); self.named_assert_equal(src, dst, name); } @@ -263,10 +263,14 @@ impl, const D: usize> CircuitBuilder { } pub fn add_generators(&mut self, generators: Vec>>) { + // for g in &generators { + // println!("{:?}", g); + // } self.generators.extend(generators); } pub fn add_generator>(&mut self, generator: G) { + // println!("{:?}", generator); self.generators.push(Box::new(generator)); } @@ -502,7 +506,11 @@ impl, const D: usize> CircuitBuilder { .collect() } - fn sigma_vecs(&self, k_is: &[F], subgroup: &[F]) -> Vec> { + fn sigma_vecs( + &self, + k_is: &[F], + subgroup: &[F], + ) -> (Vec>, Vec>) { let degree = self.gate_instances.len(); let degree_log = log2_strict(degree); let mut target_partition = TargetPartition::new(|t| match t { @@ -524,8 +532,11 @@ impl, const D: usize> CircuitBuilder { target_partition.merge(a, b); } - let wire_partition = target_partition.wire_partition(); - wire_partition.get_sigma_polys(degree_log, k_is, subgroup) + let (wire_partition, partition) = target_partition.wire_partition(); + ( + wire_partition.get_sigma_polys(degree_log, k_is, subgroup), + partition, + ) } /// Fill the remaining unused arithmetic operations with zeros, so that all @@ -614,7 +625,7 @@ impl, const D: usize> CircuitBuilder { 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) = self.sigma_vecs(&k_is, &subgroup); let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); let constants_sigmas_commitment = PolynomialBatchCommitment::from_values( @@ -640,6 +651,7 @@ impl, const D: usize> CircuitBuilder { public_inputs: self.public_inputs, marked_targets: self.marked_targets, num_virtual_targets: self.virtual_target_index, + partition, }; // The HashSet of gates will have a non-deterministic order. When converting to a Vec, we diff --git a/src/plonk/circuit_data.rs b/src/plonk/circuit_data.rs index e4353c70..f3d13fb4 100644 --- a/src/plonk/circuit_data.rs +++ b/src/plonk/circuit_data.rs @@ -13,6 +13,7 @@ use crate::iop::generator::WitnessGenerator; use crate::iop::target::Target; use crate::iop::witness::PartialWitness; use crate::plonk::copy_constraint::CopyConstraint; +use crate::plonk::permutation_argument::ForestNode; use crate::plonk::proof::ProofWithPublicInputs; use crate::plonk::prover::prove; use crate::plonk::verifier::verify; @@ -155,6 +156,8 @@ pub(crate) struct ProverOnlyCircuitData, const D: usize> { pub marked_targets: Vec>, /// Number of virtual targets used in the circuit. pub num_virtual_targets: usize, + + pub partition: Vec>, } /// Circuit data required by the verifier, but not the prover. diff --git a/src/plonk/permutation_argument.rs b/src/plonk/permutation_argument.rs index 08ebcd48..3a9a93aa 100644 --- a/src/plonk/permutation_argument.rs +++ b/src/plonk/permutation_argument.rs @@ -11,22 +11,25 @@ use crate::polynomial::polynomial::PolynomialValues; /// Node in the Disjoint Set Forest. #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct ForestNode { - t: T, - parent: usize, - size: usize, - index: usize, +pub struct ForestNode { + pub t: T, + pub parent: usize, + pub size: usize, + pub index: usize, + pub value: Option, } /// Disjoint Set Forest data-structure following https://en.wikipedia.org/wiki/Disjoint-set_data_structure. #[derive(Debug, Clone)] -pub struct TargetPartition usize> { - forest: Vec>, +pub struct TargetPartition usize> { + forest: Vec>, /// Function to compute a node's index in the forest. indices: F, } -impl usize> TargetPartition { +impl usize> + TargetPartition +{ pub fn new(f: F) -> Self { Self { forest: Vec::new(), @@ -42,11 +45,12 @@ impl usize> TargetPartition 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) -> ForestNode { + pub fn find(&mut self, x: ForestNode) -> ForestNode { if x.parent != x.index { let root = self.find(self.forest[x.parent]); self.forest[x.index].parent = root.index; @@ -80,8 +84,8 @@ impl usize> TargetPartition self.forest[y.index] = y; } } -impl usize> TargetPartition { - pub fn wire_partition(&mut self) -> WirePartitions { +impl usize> TargetPartition { + pub fn wire_partition(mut self) -> (WirePartitions, Vec>) { let mut partition = HashMap::<_, Vec<_>>::new(); let nodes = self.forest.clone(); for x in nodes { @@ -89,7 +93,7 @@ impl usize> TargetPartition { v.push(x.t); } - let mut indices = HashMap::new(); + // let mut indices = HashMap::new(); // Here we keep just the Wire targets, filtering out everything else. let partition = partition .into_values() @@ -102,13 +106,13 @@ impl usize> TargetPartition { .collect::>() }) .collect::>(); - partition.iter().enumerate().for_each(|(i, v)| { - v.iter().for_each(|t| { - indices.insert(*t, i); - }); - }); + // partition.iter().enumerate().for_each(|(i, v)| { + // v.iter().for_each(|t| { + // indices.insert(*t, i); + // }); + // }); - WirePartitions { partition } + (WirePartitions { partition }, self.forest) } } diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 0d66daa8..431a3441 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -7,9 +7,12 @@ use crate::fri::commitment::PolynomialBatchCommitment; 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::generator::{generate_partial_witness, Yo}; +use crate::iop::target::Target; +use crate::iop::wire::Wire; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData}; +use crate::plonk::permutation_argument::ForestNode; use crate::plonk::plonk_common::PlonkPolynomials; use crate::plonk::plonk_common::ZeroPolyOnCoset; use crate::plonk::proof::{Proof, ProofWithPublicInputs}; @@ -32,8 +35,44 @@ pub(crate) fn prove, const D: usize>( let num_challenges = config.num_challenges; let quotient_degree = common_data.quotient_degree(); let degree = common_data.degree(); + println!("{}", prover_data.gate_instances[0].gate_ref.0.id()); + println!("{}", prover_data.gate_instances[1].gate_ref.0.id()); - let mut partial_witness = inputs; + let nrw = config.num_routed_wires; + let nw = config.num_wires; + let nvt = prover_data.num_virtual_targets; + let target_index = move |t: Target| -> usize { + match t { + Target::Wire(Wire { gate, input }) if input < nrw => gate * nrw + input, + Target::Wire(Wire { gate, input }) if input >= nrw => { + degree * nrw + nvt + gate * (nw - nrw) + input - nrw + } + Target::VirtualTarget { index } => degree * nrw + index, + _ => unreachable!(), + } + }; + let mut partial_witness = prover_data.partition.clone(); + let n = partial_witness.len(); + timed!(timing, "fill partition", { + partial_witness.reserve_exact(degree * (config.num_wires - config.num_routed_wires)); + for i in 0..degree * (config.num_wires - config.num_routed_wires) { + partial_witness.push(ForestNode { + t: Target::Wire(Wire { gate: 0, input: 0 }), + parent: n + i, + size: 0, + index: n + i, + value: None, + }) + } + for &(t, v) in &inputs.set_targets { + // println!("{:?} {} {}", t, target_index(t), partial_witness.len()); + let parent = partial_witness[target_index(t)].parent; + // println!("{} {}", parent, partial_witness.len()); + partial_witness[parent].value = Some(v); + } + }); + // let mut partial_witness = inputs; + let mut partial_witness = Yo(partial_witness, Box::new(target_index)); timed!( timing, &format!("run {} generators", prover_data.generators.len()), @@ -50,17 +89,17 @@ pub(crate) fn prove, const D: usize>( let public_inputs = partial_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); - } - - timed!( - timing, - "check copy constraints", - partial_witness - .check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)? - ); + // // Display the marked targets for debugging purposes. + // for m in &prover_data.marked_targets { + // m.display(&partial_witness); + // } + // + // timed!( + // timing, + // "check copy constraints", + // partial_witness + // .check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)? + // ); let witness = timed!( timing,