From 92974aa105b5d1f411a083bfcc36deae540da896 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 22 Nov 2022 07:37:43 -0800 Subject: [PATCH] A few more cyclic recursion changes In preparation for adding the zkEVM aggregation circuit. Mainly, - Adds a `WitnessWrite` trait, a sub-trait of `Witness`, and move the write methods to it. `GeneratedValues` impls `WitnessWrite`, which lets generators like `DummyProofGenerator` access all our write methods like `set_proof_with_pis_target`. Also removes some duplication. - Remove `set_cyclic_recursion_data_target` - now that dummy proof data is automatically populated, all that remains is populating `condition` and the cyclic proof + VK. I think it's easy enough for callers to do this; the steps are the same as with `conditionally_verify_proof`. This way there's no cyclic-recursion-specific API to learn about. - Split `cyclic_recursion` into two variants, one which checks the current circuit or a dummy, and a more general one which checks the current circuit or some other circuit. We can use the latter to build a more efficient aggregation circuit, where we check another aggregation proof or an EVM proof, with no dummy proofs involved. --- ecdsa/src/gadgets/glv.rs | 2 +- ecdsa/src/gadgets/nonnative.rs | 2 +- evm/src/recursive_verifier.rs | 7 +- evm/src/stark_testing.rs | 2 +- insertion/src/insertion_gate.rs | 2 +- plonky2/examples/bench_recursion.rs | 2 +- plonky2/examples/factorial.rs | 2 +- plonky2/examples/fibonacci.rs | 2 +- plonky2/examples/square_root.rs | 2 +- plonky2/src/fri/witness_util.rs | 4 +- plonky2/src/gadgets/arithmetic.rs | 2 +- plonky2/src/gadgets/arithmetic_extension.rs | 6 +- plonky2/src/gadgets/range_check.rs | 2 +- plonky2/src/gadgets/select.rs | 4 +- plonky2/src/gadgets/split_base.rs | 2 +- plonky2/src/gadgets/split_join.rs | 2 +- plonky2/src/gates/arithmetic_base.rs | 2 +- plonky2/src/gates/arithmetic_extension.rs | 2 +- plonky2/src/gates/base_sum.rs | 2 +- plonky2/src/gates/exponentiation.rs | 2 +- plonky2/src/gates/gate_testing.rs | 2 +- .../src/gates/high_degree_interpolation.rs | 2 +- plonky2/src/gates/low_degree_interpolation.rs | 2 +- plonky2/src/gates/multiplication_extension.rs | 2 +- plonky2/src/gates/poseidon.rs | 4 +- plonky2/src/gates/poseidon_mds.rs | 2 +- plonky2/src/gates/random_access.rs | 2 +- plonky2/src/gates/reducing.rs | 2 +- plonky2/src/gates/reducing_extension.rs | 2 +- plonky2/src/hash/merkle_proofs.rs | 9 +- plonky2/src/iop/generator.rs | 68 +---- plonky2/src/iop/witness.rs | 160 +++++----- plonky2/src/plonk/circuit_builder.rs | 20 +- plonky2/src/plonk/circuit_data.rs | 2 +- .../conditional_recursive_verifier.rs | 124 ++++---- plonky2/src/recursion/cyclic_recursion.rs | 286 ++++++------------ plonky2/src/recursion/dummy_circuit.rs | 100 +++++- plonky2/src/recursion/mod.rs | 2 +- plonky2/src/recursion/recursive_verifier.rs | 2 +- plonky2/src/util/reducing.rs | 2 +- starky/src/stark_testing.rs | 2 +- u32/src/gates/add_many_u32.rs | 2 +- u32/src/gates/arithmetic_u32.rs | 2 +- u32/src/gates/comparison.rs | 2 +- u32/src/gates/range_check_u32.rs | 2 +- u32/src/gates/subtraction_u32.rs | 2 +- u32/src/witness.rs | 2 +- waksman/src/gates/assert_le.rs | 2 +- waksman/src/gates/switch.rs | 2 +- waksman/src/permutation.rs | 2 +- waksman/src/sorting.rs | 2 +- 51 files changed, 425 insertions(+), 445 deletions(-) diff --git a/ecdsa/src/gadgets/glv.rs b/ecdsa/src/gadgets/glv.rs index 063dee35..8ffa9c8e 100644 --- a/ecdsa/src/gadgets/glv.rs +++ b/ecdsa/src/gadgets/glv.rs @@ -8,7 +8,7 @@ use plonky2::field::types::{Field, PrimeField}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; -use plonky2::iop::witness::PartitionWitness; +use plonky2::iop::witness::{PartitionWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use crate::curve::glv::{decompose_secp256k1_scalar, GLV_BETA, GLV_S}; diff --git a/ecdsa/src/gadgets/nonnative.rs b/ecdsa/src/gadgets/nonnative.rs index 27dd1c65..f1c8f03b 100644 --- a/ecdsa/src/gadgets/nonnative.rs +++ b/ecdsa/src/gadgets/nonnative.rs @@ -8,7 +8,7 @@ use plonky2::field::types::{Field, PrimeField}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; -use plonky2::iop::witness::PartitionWitness; +use plonky2::iop::witness::{PartitionWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::util::ceil_div_usize; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index bc1357a9..0f713e32 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -18,7 +18,7 @@ use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2::util::reducing::ReducingFactorTarget; use plonky2::with_context; -use crate::all_stark::{AllStark, Table, NUM_TABLES}; +use crate::all_stark::{all_cross_table_lookups, AllStark, Table, NUM_TABLES}; use crate::config::StarkConfig; use crate::constraint_consumer::RecursiveConstraintConsumer; use crate::cpu::cpu_stark::CpuStark; @@ -162,7 +162,6 @@ impl, C: GenericConfig, const D: usize> builder: &mut CircuitBuilder, recursive_all_proof_target: RecursiveAllProofTargetWithData, verifier_data: &[VerifierCircuitData; NUM_TABLES], - cross_table_lookups: Vec>, inner_config: &StarkConfig, ) where [(); C::Hasher::HASH_SIZE]:, @@ -219,7 +218,7 @@ impl, C: GenericConfig, const D: usize> let degrees_bits = std::array::from_fn(|i| verifier_data[i].common.degree_bits()); verify_cross_table_lookups_circuit::( builder, - cross_table_lookups, + all_cross_table_lookups(), pis.map(|p| p.ctl_zs_last), degrees_bits, ctl_challenges, @@ -842,7 +841,7 @@ pub(crate) mod tests { use plonky2::hash::hash_types::RichField; use plonky2::hash::hashing::SPONGE_WIDTH; use plonky2::iop::challenger::RecursiveChallenger; - use plonky2::iop::witness::{PartialWitness, Witness}; + use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData}; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; diff --git a/evm/src/stark_testing.rs b/evm/src/stark_testing.rs index da628403..df1352a6 100644 --- a/evm/src/stark_testing.rs +++ b/evm/src/stark_testing.rs @@ -3,7 +3,7 @@ use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use plonky2::field::types::{Field, Sample}; use plonky2::hash::hash_types::RichField; -use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, Hasher}; diff --git a/insertion/src/insertion_gate.rs b/insertion/src/insertion_gate.rs index 8019649a..f9dc5fce 100644 --- a/insertion/src/insertion_gate.rs +++ b/insertion/src/insertion_gate.rs @@ -14,7 +14,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index 059ca963..0ad12e76 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -12,7 +12,7 @@ use log::{info, Level, LevelFilter}; use maybe_rayon::rayon; use plonky2::gates::noop::NoopGate; use plonky2::hash::hash_types::RichField; -use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{ CircuitConfig, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index 80bfacb9..019a7aa5 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -1,6 +1,6 @@ use anyhow::Result; use plonky2::field::types::Field; -use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 6609fc1d..28403862 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -1,6 +1,6 @@ use anyhow::Result; use plonky2::field::types::Field; -use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 512c842c..b20eecc5 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -5,7 +5,7 @@ use plonky2::field::types::{PrimeField, Sample}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; -use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/fri/witness_util.rs b/plonky2/src/fri/witness_util.rs index 670319de..ce47e7cb 100644 --- a/plonky2/src/fri/witness_util.rs +++ b/plonky2/src/fri/witness_util.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use crate::field::extension::Extendable; use crate::fri::proof::{FriProof, FriProofTarget}; use crate::hash::hash_types::RichField; -use crate::iop::witness::Witness; +use crate::iop::witness::WitnessWrite; use crate::plonk::config::AlgebraicHasher; /// Set the targets in a `FriProofTarget` to their corresponding values in a `FriProof`. @@ -13,7 +13,7 @@ pub fn set_fri_proof_target( fri_proof: &FriProof, ) where F: RichField + Extendable, - W: Witness + ?Sized, + W: WitnessWrite + ?Sized, H: AlgebraicHasher, { witness.set_target(fri_proof_target.pow_witness, fri_proof.pow_witness); diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index 3e42fa11..39755bd4 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -9,7 +9,7 @@ use crate::gates::exponentiation::ExponentiationGate; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; impl, const D: usize> CircuitBuilder { diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index e37d4deb..6fcab718 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -10,7 +10,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::bits_u64; @@ -573,7 +573,7 @@ mod tests { use crate::field::extension::algebra::ExtensionAlgebra; use crate::field::types::Sample; use crate::iop::ext_target::ExtensionAlgebraTarget; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig}; @@ -588,7 +588,7 @@ mod tests { let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::::new(); let mut builder = CircuitBuilder::::new(config); let vs = FF::rand_vec(3); diff --git a/plonky2/src/gadgets/range_check.rs b/plonky2/src/gadgets/range_check.rs index 22977bc1..4c22009d 100644 --- a/plonky2/src/gadgets/range_check.rs +++ b/plonky2/src/gadgets/range_check.rs @@ -5,7 +5,7 @@ use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; impl, const D: usize> CircuitBuilder { diff --git a/plonky2/src/gadgets/select.rs b/plonky2/src/gadgets/select.rs index c2531488..b34092ed 100644 --- a/plonky2/src/gadgets/select.rs +++ b/plonky2/src/gadgets/select.rs @@ -41,7 +41,7 @@ mod tests { use anyhow::Result; use crate::field::types::Sample; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; @@ -54,7 +54,7 @@ mod tests { type F = >::F; type FF = >::FE; let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::::new(); let mut builder = CircuitBuilder::::new(config); let (x, y) = (FF::rand(), FF::rand()); diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index c462d5bf..5fbe8053 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -10,7 +10,7 @@ use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::log_floor; diff --git a/plonky2/src/gadgets/split_join.rs b/plonky2/src/gadgets/split_join.rs index 1a1575c0..56e469b9 100644 --- a/plonky2/src/gadgets/split_join.rs +++ b/plonky2/src/gadgets/split_join.rs @@ -6,7 +6,7 @@ use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::ceil_div_usize; diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 34d6e244..13b4a2c5 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -12,7 +12,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{ diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index ee7f96be..4632dbd4 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -11,7 +11,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index 27eb2c69..5883d71c 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -14,7 +14,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index 138ec3c9..218f77e8 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -16,7 +16,7 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{ diff --git a/plonky2/src/gates/gate_testing.rs b/plonky2/src/gates/gate_testing.rs index c6cae2bb..f16d2950 100644 --- a/plonky2/src/gates/gate_testing.rs +++ b/plonky2/src/gates/gate_testing.rs @@ -8,7 +8,7 @@ use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::field::types::{Field, Sample}; use crate::gates::gate::Gate; use crate::hash::hash_types::{HashOut, RichField}; -use crate::iop::witness::{PartialWitness, Witness}; +use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::GenericConfig; diff --git a/plonky2/src/gates/high_degree_interpolation.rs b/plonky2/src/gates/high_degree_interpolation.rs index 65573898..f7e3be1f 100644 --- a/plonky2/src/gates/high_degree_interpolation.rs +++ b/plonky2/src/gates/high_degree_interpolation.rs @@ -18,7 +18,7 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index f4f3286c..15d0e56a 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -19,7 +19,7 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 02243450..1f900441 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -11,7 +11,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index c02eec84..6754f04b 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -17,7 +17,7 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; @@ -514,7 +514,7 @@ mod tests { use crate::hash::poseidon::Poseidon; use crate::iop::generator::generate_partial_witness; use crate::iop::wire::Wire; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index 94c1486c..db517ef1 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -16,7 +16,7 @@ use crate::hash::poseidon::Poseidon; use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 52972cd3..80874505 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -17,7 +17,7 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::vars::{ diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index 64a1a986..9bdadce8 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -11,7 +11,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 27483e1f..0ad48bb0 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -11,7 +11,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; -use crate::iop::witness::{PartitionWitness, Witness}; +use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index 69d7299f..cd696e55 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -2,6 +2,7 @@ use alloc::vec; use alloc::vec::Vec; use anyhow::{ensure, Result}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use crate::field::extension::Extendable; @@ -145,6 +146,12 @@ impl, const D: usize> CircuitBuilder { self.connect(x.elements[i], y.elements[i]); } } + + pub fn connect_merkle_caps(&mut self, x: &MerkleCapTarget, y: &MerkleCapTarget) { + for (h0, h1) in x.0.iter().zip_eq(&y.0) { + self.connect_hashes(*h0, *h1); + } + } } #[cfg(test)] @@ -156,7 +163,7 @@ mod tests { use super::*; use crate::field::types::Field; use crate::hash::merkle_tree::MerkleTree; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 86a4d923..a65d1748 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -3,13 +3,13 @@ use alloc::vec::Vec; use core::fmt::Debug; use core::marker::PhantomData; -use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::extension::Extendable; use crate::field::types::Field; -use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; +use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::target::{BoolTarget, Target}; +use crate::iop::target::Target; use crate::iop::wire::Wire; -use crate::iop::witness::{PartialWitness, PartitionWitness, Witness}; +use crate::iop::witness::{PartialWitness, PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData}; use crate::plonk::config::GenericConfig; @@ -120,6 +120,12 @@ impl From> for GeneratedValues { } } +impl WitnessWrite for GeneratedValues { + fn set_target(&mut self, target: Target, value: F) { + self.target_values.push((target, value)); + } +} + impl GeneratedValues { pub fn with_capacity(capacity: usize) -> Self { Vec::with_capacity(capacity).into() @@ -137,10 +143,6 @@ impl GeneratedValues { vec![(target, value)].into() } - pub fn clear(&mut self) { - self.target_values.clear(); - } - pub fn singleton_extension_target( et: ExtensionTarget, value: F::Extension, @@ -152,56 +154,6 @@ impl GeneratedValues { witness.set_extension_target(et, value); witness } - - pub fn set_target(&mut self, target: Target, value: F) { - self.target_values.push((target, value)) - } - - pub fn set_bool_target(&mut self, target: BoolTarget, value: bool) { - self.set_target(target.target, F::from_bool(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_extension_target( - &mut self, - et: ExtensionTarget, - value: F::Extension, - ) where - F: RichField + Extendable, - { - let limbs = value.to_basefield_array(); - (0..D).for_each(|i| { - self.set_target(et.0[i], limbs[i]); - }); - } - - 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: RichField + Extendable, - W: IntoIterator, - { - self.set_wires(wires, &value.to_basefield_array()); - } } /// A generator which runs once after a list of dependencies is present in the witness. diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index fe6b9473..e9ade3d2 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -17,71 +17,9 @@ use crate::plonk::circuit_data::{VerifierCircuitTarget, VerifierOnlyCircuitData} use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{Proof, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget}; -/// A witness holds information on the values of targets in a circuit. -pub trait Witness { - fn try_get_target(&self, target: Target) -> Option; - +pub trait WitnessWrite { fn set_target(&mut self, target: Target, value: F); - fn get_target(&self, target: Target) -> F { - self.try_get_target(target).unwrap() - } - - fn get_targets(&self, targets: &[Target]) -> Vec { - targets.iter().map(|&t| self.get_target(t)).collect() - } - - fn get_extension_target(&self, et: ExtensionTarget) -> F::Extension - where - F: RichField + Extendable, - { - F::Extension::from_basefield_array( - self.get_targets(&et.to_target_array()).try_into().unwrap(), - ) - } - - fn get_extension_targets(&self, ets: &[ExtensionTarget]) -> Vec - where - F: RichField + Extendable, - { - ets.iter() - .map(|&et| self.get_extension_target(et)) - .collect() - } - - fn get_bool_target(&self, target: BoolTarget) -> bool { - let value = self.get_target(target.target); - if value.is_zero() { - return false; - } - if value.is_one() { - return true; - } - panic!("not a bool") - } - - fn get_hash_target(&self, ht: HashOutTarget) -> HashOut { - HashOut { - elements: self.get_targets(&ht.elements).try_into().unwrap(), - } - } - - fn get_wire(&self, wire: Wire) -> F { - self.get_target(Target::Wire(wire)) - } - - fn try_get_wire(&self, wire: Wire) -> Option { - self.try_get_target(Target::Wire(wire)) - } - - fn contains(&self, target: Target) -> bool { - self.try_get_target(target).is_some() - } - - fn contains_all(&self, targets: &[Target]) -> bool { - targets.iter().all(|&t| self.contains(t)) - } - fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut) { ht.elements .iter() @@ -239,6 +177,70 @@ pub trait Witness { } } +/// A witness holds information on the values of targets in a circuit. +pub trait Witness: WitnessWrite { + fn try_get_target(&self, target: Target) -> Option; + + fn get_target(&self, target: Target) -> F { + self.try_get_target(target).unwrap() + } + + fn get_targets(&self, targets: &[Target]) -> Vec { + targets.iter().map(|&t| self.get_target(t)).collect() + } + + fn get_extension_target(&self, et: ExtensionTarget) -> F::Extension + where + F: RichField + Extendable, + { + F::Extension::from_basefield_array( + self.get_targets(&et.to_target_array()).try_into().unwrap(), + ) + } + + fn get_extension_targets(&self, ets: &[ExtensionTarget]) -> Vec + where + F: RichField + Extendable, + { + ets.iter() + .map(|&et| self.get_extension_target(et)) + .collect() + } + + fn get_bool_target(&self, target: BoolTarget) -> bool { + let value = self.get_target(target.target); + if value.is_zero() { + return false; + } + if value.is_one() { + return true; + } + panic!("not a bool") + } + + fn get_hash_target(&self, ht: HashOutTarget) -> HashOut { + HashOut { + elements: self.get_targets(&ht.elements).try_into().unwrap(), + } + } + + fn get_wire(&self, wire: Wire) -> F { + self.get_target(Target::Wire(wire)) + } + + fn try_get_wire(&self, wire: Wire) -> Option { + self.try_get_target(Target::Wire(wire)) + } + + fn contains(&self, target: Target) -> bool { + self.try_get_target(target).is_some() + } + + fn contains_all(&self, targets: &[Target]) -> bool { + targets.iter().all(|&t| self.contains(t)) + } +} + #[derive(Clone, Debug)] pub struct MatrixWitness { pub(crate) wire_values: Vec>, @@ -263,23 +265,25 @@ impl PartialWitness { } } -impl Witness for PartialWitness { - fn try_get_target(&self, target: Target) -> Option { - self.target_values.get(&target).copied() - } - +impl WitnessWrite for PartialWitness { 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 + value, old_value, + "Target {:?} was set twice with different values: {} != {}", + target, old_value, value ); } } } +impl Witness for PartialWitness { + fn try_get_target(&self, target: Target) -> Option { + self.target_values.get(&target).copied() + } +} + /// `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)] @@ -308,8 +312,8 @@ impl<'a, F: Field> PartitionWitness<'a, F> { if let Some(old_value) = *rep_value { assert_eq!( value, old_value, - "Partition containing {:?} was set twice with different values", - target + "Partition containing {:?} was set twice with different values: {} != {}", + target, old_value, value ); None } else { @@ -337,13 +341,15 @@ impl<'a, F: Field> PartitionWitness<'a, F> { } } +impl<'a, F: Field> WitnessWrite for PartitionWitness<'a, F> { + fn set_target(&mut self, target: Target, value: F) { + self.set_target_returning_rep(target, value); + } +} + impl<'a, F: Field> Witness for PartitionWitness<'a, F> { fn try_get_target(&self, target: Target) -> Option { let rep_index = self.representative_map[self.target_index(target)]; self.values[rep_index] } - - fn set_target(&mut self, target: Target, value: F) { - self.set_target_returning_rep(target, value); - } } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 6bad9296..9017a059 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -40,7 +40,7 @@ use crate::plonk::circuit_data::{ CircuitConfig, CircuitData, CommonCircuitData, ProverCircuitData, ProverOnlyCircuitData, VerifierCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; -use crate::plonk::config::{GenericConfig, GenericHashOut, Hasher}; +use crate::plonk::config::{AlgebraicHasher, GenericConfig, GenericHashOut, Hasher}; use crate::plonk::copy_constraint::CopyConstraint; use crate::plonk::permutation_argument::Forest; use crate::plonk::plonk_common::PlonkOracle; @@ -247,7 +247,7 @@ impl, const D: usize> CircuitBuilder { /// Add a virtual verifier data, register it as a public input and set it to `self.verifier_data_public_input`. /// WARNING: Do not register any public input after calling this! TODO: relax this - pub fn add_verifier_data_public_inputs(&mut self) { + pub fn add_verifier_data_public_inputs(&mut self) -> VerifierCircuitTarget { assert!( self.verifier_data_public_input.is_none(), "add_verifier_data_public_inputs only needs to be called once" @@ -263,7 +263,8 @@ impl, const D: usize> CircuitBuilder { self.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); } - self.verifier_data_public_input = Some(verifier_data); + self.verifier_data_public_input = Some(verifier_data.clone()); + verifier_data } /// Adds a gate to the circuit, and returns its index. @@ -436,6 +437,19 @@ impl, const D: usize> CircuitBuilder { MerkleCapTarget(cap.0.iter().map(|h| self.constant_hash(*h)).collect()) } + pub fn constant_verifier_data>( + &mut self, + verifier_data: &VerifierOnlyCircuitData, + ) -> VerifierCircuitTarget + where + C::Hasher: AlgebraicHasher, + { + VerifierCircuitTarget { + constants_sigmas_cap: self.constant_merkle_cap(&verifier_data.constants_sigmas_cap), + circuit_digest: self.constant_hash(verifier_data.circuit_digest), + } + } + /// If the given target is a constant (i.e. it was created by the `constant(F)` method), returns /// its constant value. Otherwise, returns `None`. pub fn target_as_constant(&self, target: Target) -> Option { diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index df455a3a..6df986fa 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -470,7 +470,7 @@ impl, const D: usize> CommonCircuitData { /// is intentionally missing certain fields, such as `CircuitConfig`, because we support only a /// limited form of dynamic inner circuits. We can't practically make things like the wire count /// dynamic, at least not without setting a maximum wire count and paying for the worst case. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct VerifierCircuitTarget { /// A commitment to each constant polynomial and each permutation polynomial. pub constants_sigmas_cap: MerkleCapTarget, diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index be7ed028..ace47cab 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -31,6 +31,55 @@ impl, const D: usize> CircuitBuilder { ) where C::Hasher: AlgebraicHasher, { + let selected_proof = + self.select_proof_with_pis(condition, proof_with_pis0, proof_with_pis1); + let selected_verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: self.select_cap( + condition, + &inner_verifier_data0.constants_sigmas_cap, + &inner_verifier_data1.constants_sigmas_cap, + ), + circuit_digest: self.select_hash( + condition, + inner_verifier_data0.circuit_digest, + inner_verifier_data1.circuit_digest, + ), + }; + + self.verify_proof::(&selected_proof, &selected_verifier_data, inner_common_data); + } + + /// Conditionally verify a proof with a new generated dummy proof. + pub fn conditionally_verify_proof_or_dummy + 'static>( + &mut self, + condition: BoolTarget, + proof_with_pis: &ProofWithPublicInputsTarget, + inner_verifier_data: &VerifierCircuitTarget, + inner_common_data: &CommonCircuitData, + ) -> anyhow::Result<()> + where + C::Hasher: AlgebraicHasher, + { + let (dummy_proof_with_pis_target, dummy_verifier_data_target) = + self.dummy_proof_and_vk::(inner_common_data)?; + self.conditionally_verify_proof::( + condition, + proof_with_pis, + inner_verifier_data, + &dummy_proof_with_pis_target, + &dummy_verifier_data_target, + inner_common_data, + ); + Ok(()) + } + + /// Computes `if b { proof_with_pis0 } else { proof_with_pis1 }`. + fn select_proof_with_pis( + &mut self, + b: BoolTarget, + proof_with_pis0: &ProofWithPublicInputsTarget, + proof_with_pis1: &ProofWithPublicInputsTarget, + ) -> ProofWithPublicInputsTarget { let ProofWithPublicInputsTarget { proof: ProofTarget { @@ -53,20 +102,19 @@ impl, const D: usize> CircuitBuilder { }, public_inputs: public_inputs1, } = proof_with_pis1; - - let selected_proof = with_context!(self, "select proof", { - let selected_wires_cap = self.select_cap(condition, wires_cap0, wires_cap1); + with_context!(self, "select proof", { + let selected_wires_cap = self.select_cap(b, wires_cap0, wires_cap1); let selected_plonk_zs_partial_products_cap = self.select_cap( - condition, + b, plonk_zs_partial_products_cap0, plonk_zs_partial_products_cap1, ); let selected_quotient_polys_cap = - self.select_cap(condition, quotient_polys_cap0, quotient_polys_cap1); - let selected_openings = self.select_opening_set(condition, openings0, openings1); + self.select_cap(b, quotient_polys_cap0, quotient_polys_cap1); + let selected_openings = self.select_opening_set(b, openings0, openings1); let selected_opening_proof = - self.select_opening_proof(condition, opening_proof0, opening_proof1); - let selected_public_inputs = self.select_vec(condition, public_inputs0, public_inputs1); + self.select_opening_proof(b, opening_proof0, opening_proof1); + let selected_public_inputs = self.select_vec(b, public_inputs0, public_inputs1); ProofWithPublicInputsTarget { proof: ProofTarget { wires_cap: selected_wires_cap, @@ -77,52 +125,10 @@ impl, const D: usize> CircuitBuilder { }, public_inputs: selected_public_inputs, } - }); - let selected_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: self.select_cap( - condition, - &inner_verifier_data0.constants_sigmas_cap, - &inner_verifier_data1.constants_sigmas_cap, - ), - circuit_digest: self.select_hash( - condition, - inner_verifier_data0.circuit_digest, - inner_verifier_data1.circuit_digest, - ), - }; - - self.verify_proof::(&selected_proof, &selected_verifier_data, inner_common_data); - } - - /// Conditionally verify a proof with a new generated dummy proof. - pub fn conditionally_verify_proof_or_dummy>( - &mut self, - condition: BoolTarget, - proof_with_pis: &ProofWithPublicInputsTarget, - inner_verifier_data: &VerifierCircuitTarget, - inner_common_data: &CommonCircuitData, - ) -> (ProofWithPublicInputsTarget, VerifierCircuitTarget) - where - C::Hasher: AlgebraicHasher, - { - let dummy_proof = self.add_virtual_proof_with_pis::(inner_common_data); - let dummy_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: self - .add_virtual_cap(inner_common_data.config.fri_config.cap_height), - circuit_digest: self.add_virtual_hash(), - }; - self.conditionally_verify_proof::( - condition, - proof_with_pis, - inner_verifier_data, - &dummy_proof, - &dummy_verifier_data, - inner_common_data, - ); - - (dummy_proof, dummy_verifier_data) + }) } + /// Computes `if b { v0 } else { v1 }`. fn select_vec(&mut self, b: BoolTarget, v0: &[Target], v1: &[Target]) -> Vec { v0.iter() .zip_eq(v1) @@ -130,6 +136,7 @@ impl, const D: usize> CircuitBuilder { .collect() } + /// Computes `if b { h0 } else { h1 }`. pub(crate) fn select_hash( &mut self, b: BoolTarget, @@ -141,6 +148,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { cap0 } else { cap1 }`. fn select_cap( &mut self, b: BoolTarget, @@ -157,6 +165,7 @@ impl, const D: usize> CircuitBuilder { ) } + /// Computes `if b { v0 } else { v1 }`. fn select_vec_cap( &mut self, b: BoolTarget, @@ -169,6 +178,7 @@ impl, const D: usize> CircuitBuilder { .collect() } + /// Computes `if b { os0 } else { os1 }`. fn select_opening_set( &mut self, b: BoolTarget, @@ -186,6 +196,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { v0 } else { v1 }`. fn select_vec_ext( &mut self, b: BoolTarget, @@ -198,6 +209,7 @@ impl, const D: usize> CircuitBuilder { .collect() } + /// Computes `if b { proof0 } else { proof1 }`. fn select_opening_proof( &mut self, b: BoolTarget, @@ -224,6 +236,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { qr0 } else { qr1 }`. fn select_query_round( &mut self, b: BoolTarget, @@ -240,6 +253,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { v0 } else { v1 }`. fn select_vec_query_round( &mut self, b: BoolTarget, @@ -252,6 +266,7 @@ impl, const D: usize> CircuitBuilder { .collect() } + /// Computes `if b { proof0 } else { proof1 }`. fn select_initial_tree_proof( &mut self, b: BoolTarget, @@ -273,6 +288,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { proof0 } else { proof1 }`. fn select_merkle_proof( &mut self, b: BoolTarget, @@ -289,6 +305,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { qs0 } else { qs01 }`. fn select_query_step( &mut self, b: BoolTarget, @@ -301,6 +318,7 @@ impl, const D: usize> CircuitBuilder { } } + /// Computes `if b { v0 } else { v1 }`. fn select_vec_query_step( &mut self, b: BoolTarget, @@ -322,7 +340,7 @@ mod tests { use super::*; use crate::field::types::Sample; use crate::gates::noop::NoopGate; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use crate::recursion::dummy_circuit::{dummy_circuit, dummy_proof}; diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 497d655b..a12c31d4 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -1,48 +1,17 @@ #![allow(clippy::int_plus_one)] // Makes more sense for some inequalities below. -use alloc::vec; - use anyhow::{ensure, Result}; -use hashbrown::HashMap; -use itertools::Itertools; use crate::field::extension::Extendable; -use crate::gates::noop::NoopGate; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{ - CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, + CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; -use crate::recursion::dummy_circuit::{dummy_circuit, dummy_proof}; - -pub struct CyclicRecursionData< - 'a, - F: RichField + Extendable, - C: GenericConfig, - const D: usize, -> { - proof: &'a Option>, - verifier_data: &'a VerifierOnlyCircuitData, - common_data: &'a CommonCircuitData, -} - -pub struct CyclicRecursionTarget -where - F: RichField + Extendable, - C: GenericConfig, -{ - pub(crate) proof: ProofWithPublicInputsTarget, - pub(crate) verifier_data: VerifierCircuitTarget, - pub(crate) dummy_proof: ProofWithPublicInputsTarget, - pub(crate) dummy_verifier_data: VerifierCircuitTarget, - pub(crate) condition: BoolTarget, - pub(crate) dummy_circuit: CircuitData, -} impl, const D: usize> VerifierOnlyCircuitData { fn from_slice(slice: &[C::F], common_data: &CommonCircuitData) -> Result @@ -98,7 +67,7 @@ impl VerifierCircuitTarget { impl, const D: usize> CircuitBuilder { /// If `condition` is true, recursively verify a proof for the same circuit as the one we're - /// currently building. + /// currently building. Otherwise, verify `other_proof_with_pis`. /// /// For a typical IVC use case, `condition` will be false for the very first proof in a chain, /// i.e. the base case. @@ -110,12 +79,14 @@ impl, const D: usize> CircuitBuilder { /// that the verification key matches. /// /// WARNING: Do not register any public input after calling this! TODO: relax this - pub fn cyclic_recursion>( + pub fn conditionally_verify_cyclic_proof>( &mut self, condition: BoolTarget, - proof_with_pis: &ProofWithPublicInputsTarget, + cyclic_proof_with_pis: &ProofWithPublicInputsTarget, + other_proof_with_pis: &ProofWithPublicInputsTarget, + other_verifier_data: &VerifierCircuitTarget, common_data: &CommonCircuitData, - ) -> Result> + ) -> Result<()> where C::Hasher: AlgebraicHasher, { @@ -123,131 +94,67 @@ impl, const D: usize> CircuitBuilder { .verifier_data_public_input .clone() .expect("Must call add_verifier_data_public_inputs before cyclic recursion"); - self.goal_common_data = Some(common_data.clone()); - let dummy_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), - circuit_digest: self.add_virtual_hash(), - }; + if let Some(existing_common_data) = self.goal_common_data.as_ref() { + assert_eq!(existing_common_data, common_data); + } else { + self.goal_common_data = Some(common_data.clone()); + } - let dummy_proof = self.add_virtual_proof_with_pis::(common_data); - - let pis = VerifierCircuitTarget::from_slice::( - &proof_with_pis.public_inputs, + let inner_cyclic_pis = VerifierCircuitTarget::from_slice::( + &cyclic_proof_with_pis.public_inputs, common_data, )?; // Connect previous verifier data to current one. This guarantees that every proof in the cycle uses the same verifier data. - self.connect_hashes(pis.circuit_digest, verifier_data.circuit_digest); - for (h0, h1) in pis - .constants_sigmas_cap - .0 - .iter() - .zip_eq(&verifier_data.constants_sigmas_cap.0) - { - self.connect_hashes(*h0, *h1); - } + self.connect_hashes( + inner_cyclic_pis.circuit_digest, + verifier_data.circuit_digest, + ); + self.connect_merkle_caps( + &inner_cyclic_pis.constants_sigmas_cap, + &verifier_data.constants_sigmas_cap, + ); - // Verify the real proof if `condition` is set to true, otherwise verify the dummy proof. + // Verify the cyclic proof if `condition` is set to true, otherwise verify the other proof. self.conditionally_verify_proof::( condition, - proof_with_pis, + cyclic_proof_with_pis, &verifier_data, - &dummy_proof, - &dummy_verifier_data, + other_proof_with_pis, + other_verifier_data, common_data, ); - // Make sure we have enough gates to match `common_data`. - while self.num_gates() < (common_data.degree() / 2) { - self.add_gate(NoopGate, vec![]); - } // Make sure we have every gate to match `common_data`. for g in &common_data.gates { self.add_gate_to_gate_set(g.clone()); } - Ok(CyclicRecursionTarget { - proof: proof_with_pis.clone(), - verifier_data, - dummy_proof, - dummy_verifier_data, + Ok(()) + } + + pub fn conditionally_verify_cyclic_proof_or_dummy + 'static>( + &mut self, + condition: BoolTarget, + cyclic_proof_with_pis: &ProofWithPublicInputsTarget, + common_data: &CommonCircuitData, + ) -> Result<()> + where + C::Hasher: AlgebraicHasher, + { + let (dummy_proof_with_pis_target, dummy_verifier_data_target) = + self.dummy_proof_and_vk::(common_data)?; + self.conditionally_verify_cyclic_proof::( condition, - dummy_circuit: dummy_circuit(common_data), - }) + cyclic_proof_with_pis, + &dummy_proof_with_pis_target, + &dummy_verifier_data_target, + common_data, + )?; + Ok(()) } } -/// Set the targets in a `CyclicRecursionTarget` to their corresponding values in a `CyclicRecursionData`. -/// The `public_inputs` parameter let the caller specify certain public inputs (identified by their -/// indices) which should be given specific values. The rest will default to zero. -pub fn set_cyclic_recursion_data_target< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, ->( - pw: &mut PartialWitness, - cyclic_recursion_data_target: &CyclicRecursionTarget, - cyclic_recursion_data: &CyclicRecursionData, - // Public inputs to set in the base case to seed some initial data. - mut public_inputs: HashMap, -) -> Result<()> -where - C::Hasher: AlgebraicHasher, -{ - if let Some(proof) = cyclic_recursion_data.proof { - pw.set_bool_target(cyclic_recursion_data_target.condition, true); - pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, proof); - pw.set_verifier_data_target( - &cyclic_recursion_data_target.verifier_data, - cyclic_recursion_data.verifier_data, - ); - pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, proof); - pw.set_verifier_data_target( - &cyclic_recursion_data_target.dummy_verifier_data, - cyclic_recursion_data.verifier_data, - ); - } else { - pw.set_bool_target(cyclic_recursion_data_target.condition, false); - - let pis_len = cyclic_recursion_data_target - .dummy_circuit - .common - .num_public_inputs; - let cap_elements = cyclic_recursion_data - .common_data - .config - .fri_config - .num_cap_elements(); - let start_vk_pis = pis_len - 4 - 4 * cap_elements; - - // The circuit checks that the verifier data is the same throughout the cycle, so - // we set the verifier data to the "real" verifier data even though it's unused in the base case. - let verifier_data = &cyclic_recursion_data.verifier_data; - public_inputs.extend((start_vk_pis..).zip(verifier_data.circuit_digest.elements)); - - for i in 0..cap_elements { - let start = start_vk_pis + 4 + 4 * i; - public_inputs.extend((start..).zip(verifier_data.constants_sigmas_cap.0[i].elements)); - } - - let proof = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, public_inputs)?; - pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, &proof); - pw.set_verifier_data_target( - &cyclic_recursion_data_target.verifier_data, - cyclic_recursion_data.verifier_data, - ); - - let dummy_p = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, HashMap::new())?; - pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, &dummy_p); - pw.set_verifier_data_target( - &cyclic_recursion_data_target.dummy_verifier_data, - &cyclic_recursion_data_target.dummy_circuit.verifier_only, - ); - } - - Ok(()) -} - /// Additional checks to be performed on a cyclic recursive proof in addition to verifying the proof. /// Checks that the purported verifier data in the public inputs match the real verifier data. pub fn check_cyclic_proof_verifier_data< @@ -272,7 +179,6 @@ where #[cfg(test)] mod tests { use anyhow::Result; - use hashbrown::HashMap; use crate::field::extension::Extendable; use crate::field::types::{Field, PrimeField64}; @@ -280,13 +186,12 @@ mod tests { use crate::hash::hash_types::{HashOutTarget, RichField}; use crate::hash::hashing::hash_n_to_hash_no_pad; use crate::hash::poseidon::{PoseidonHash, PoseidonPermutation}; - use crate::iop::witness::PartialWitness; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig}; - use crate::recursion::cyclic_recursion::{ - check_cyclic_proof_verifier_data, set_cyclic_recursion_data_target, CyclicRecursionData, - }; + use crate::recursion::cyclic_recursion::check_cyclic_proof_verifier_data; + use crate::recursion::dummy_circuit::cyclic_base_proof; // Generates `CommonCircuitData` usable for recursion. fn common_data_for_recursion< @@ -341,8 +246,8 @@ mod tests { let one = builder.one(); // Circuit that computes a repeated hash. - let initial_hash = builder.add_virtual_hash(); - builder.register_public_inputs(&initial_hash.elements); + let initial_hash_target = builder.add_virtual_hash(); + builder.register_public_inputs(&initial_hash_target.elements); let current_hash_in = builder.add_virtual_hash(); let current_hash_out = builder.hash_n_to_hash_no_pad::(current_hash_in.elements.to_vec()); @@ -350,97 +255,84 @@ mod tests { let counter = builder.add_virtual_public_input(); let mut common_data = common_data_for_recursion::(); - builder.add_verifier_data_public_inputs(); + let verifier_data_target = builder.add_verifier_data_public_inputs(); common_data.num_public_inputs = builder.num_public_inputs(); let condition = builder.add_virtual_bool_target_safe(); // Unpack inner proof's public inputs. - let inner_proof_with_pis = builder.add_virtual_proof_with_pis::(&common_data); - let inner_pis = &inner_proof_with_pis.public_inputs; - let inner_initial_hash = HashOutTarget::try_from(&inner_pis[0..4]).unwrap(); - let inner_latest_hash = HashOutTarget::try_from(&inner_pis[4..8]).unwrap(); - let inner_counter = inner_pis[8]; + let inner_cyclic_proof_with_pis = builder.add_virtual_proof_with_pis::(&common_data); + let inner_cyclic_pis = &inner_cyclic_proof_with_pis.public_inputs; + let inner_cyclic_initial_hash = HashOutTarget::try_from(&inner_cyclic_pis[0..4]).unwrap(); + let inner_cyclic_latest_hash = HashOutTarget::try_from(&inner_cyclic_pis[4..8]).unwrap(); + let inner_cyclic_counter = inner_cyclic_pis[8]; // Connect our initial hash to that of our inner proof. (If there is no inner proof, the // initial hash will be unconstrained, which is intentional.) - builder.connect_hashes(initial_hash, inner_initial_hash); + builder.connect_hashes(initial_hash_target, inner_cyclic_initial_hash); // The input hash is the previous hash output if we have an inner proof, or the initial hash // if this is the base case. - let actual_hash_in = builder.select_hash(condition, inner_latest_hash, initial_hash); + let actual_hash_in = + builder.select_hash(condition, inner_cyclic_latest_hash, initial_hash_target); builder.connect_hashes(current_hash_in, actual_hash_in); // Our chain length will be inner_counter + 1 if we have an inner proof, or 1 if not. - let new_counter = builder.mul_add(condition.target, inner_counter, one); + let new_counter = builder.mul_add(condition.target, inner_cyclic_counter, one); builder.connect(counter, new_counter); - let cyclic_data_target = - builder.cyclic_recursion::(condition, &inner_proof_with_pis, &common_data)?; + builder.conditionally_verify_cyclic_proof_or_dummy::( + condition, + &inner_cyclic_proof_with_pis, + &common_data, + )?; let cyclic_circuit_data = builder.build::(); let mut pw = PartialWitness::new(); - let cyclic_recursion_data = CyclicRecursionData { - proof: &None, // Base case: We don't have a proof to put here yet. - verifier_data: &cyclic_circuit_data.verifier_only, - common_data: &cyclic_circuit_data.common, - }; let initial_hash = [F::ZERO, F::ONE, F::TWO, F::from_canonical_usize(3)]; let initial_hash_pis = initial_hash.into_iter().enumerate().collect(); - set_cyclic_recursion_data_target( - &mut pw, - &cyclic_data_target, - &cyclic_recursion_data, - initial_hash_pis, - )?; + pw.set_bool_target(condition, false); + pw.set_proof_with_pis_target::( + &inner_cyclic_proof_with_pis, + &cyclic_base_proof( + &common_data, + &cyclic_circuit_data.verifier_only, + initial_hash_pis, + ), + ); + pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( &proof, - cyclic_recursion_data.verifier_data, - cyclic_recursion_data.common_data, + &cyclic_circuit_data.verifier_only, + &cyclic_circuit_data.common, )?; cyclic_circuit_data.verify(proof.clone())?; // 1st recursive layer. let mut pw = PartialWitness::new(); - let cyclic_recursion_data = CyclicRecursionData { - proof: &Some(proof), // Input previous proof. - verifier_data: &cyclic_circuit_data.verifier_only, - common_data: &cyclic_circuit_data.common, - }; - set_cyclic_recursion_data_target( - &mut pw, - &cyclic_data_target, - &cyclic_recursion_data, - HashMap::new(), - )?; + pw.set_bool_target(condition, true); + pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof); + pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( &proof, - cyclic_recursion_data.verifier_data, - cyclic_recursion_data.common_data, + &cyclic_circuit_data.verifier_only, + &cyclic_circuit_data.common, )?; cyclic_circuit_data.verify(proof.clone())?; // 2nd recursive layer. let mut pw = PartialWitness::new(); - let cyclic_recursion_data = CyclicRecursionData { - proof: &Some(proof), // Input previous proof. - verifier_data: &cyclic_circuit_data.verifier_only, - common_data: &cyclic_circuit_data.common, - }; - set_cyclic_recursion_data_target( - &mut pw, - &cyclic_data_target, - &cyclic_recursion_data, - HashMap::new(), - )?; + pw.set_bool_target(condition, true); + pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof); + pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( &proof, - cyclic_recursion_data.verifier_data, - cyclic_recursion_data.common_data, + &cyclic_circuit_data.verifier_only, + &cyclic_circuit_data.common, )?; // Verify that the proof correctly computes a repeated hash. diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs index 4012b5e6..34b20c71 100644 --- a/plonky2/src/recursion/dummy_circuit.rs +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -6,11 +6,47 @@ use plonky2_util::ceil_div_usize; use crate::gates::noop::NoopGate; use crate::hash::hash_types::RichField; -use crate::iop::witness::{PartialWitness, Witness}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator}; +use crate::iop::target::Target; +use crate::iop::witness::{PartialWitness, PartitionWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::{CircuitData, CommonCircuitData}; -use crate::plonk::config::GenericConfig; -use crate::plonk::proof::ProofWithPublicInputs; +use crate::plonk::circuit_data::{ + CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, +}; +use crate::plonk::config::{AlgebraicHasher, GenericConfig}; +use crate::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; + +/// Creates a dummy proof which is suitable for use as a base proof in a cyclic recursion tree. +/// Such a base proof will not actually be verified, so most of its data is arbitrary. However, its +/// public inputs which encode the cyclic verification key must be set properly, and this method +/// takes care of that. It also allows the user to specify any other public inputs which should be +/// set in this base proof. +pub fn cyclic_base_proof( + common_data: &CommonCircuitData, + verifier_data: &VerifierOnlyCircuitData, + mut nonzero_public_inputs: HashMap, +) -> ProofWithPublicInputs +where + F: RichField + Extendable, + C: GenericConfig, + C::Hasher: AlgebraicHasher, +{ + let pis_len = common_data.num_public_inputs; + let cap_elements = common_data.config.fri_config.num_cap_elements(); + let start_vk_pis = pis_len - 4 - 4 * cap_elements; + + // Add the cyclic verifier data public inputs. + nonzero_public_inputs.extend((start_vk_pis..).zip(verifier_data.circuit_digest.elements)); + for i in 0..cap_elements { + let start = start_vk_pis + 4 + 4 * i; + nonzero_public_inputs + .extend((start..).zip(verifier_data.constants_sigmas_cap.0[i].elements)); + } + + // TODO: A bit wasteful to build a dummy circuit here. We could potentially use a proof that + // just consists of zeros, apart from public inputs. + dummy_proof(&dummy_circuit(common_data), nonzero_public_inputs).unwrap() +} /// Generate a proof for a dummy circuit. The `public_inputs` parameter let the caller specify /// certain public inputs (identified by their indices) which should be given specific values. @@ -65,3 +101,59 @@ pub(crate) fn dummy_circuit< assert_eq!(&circuit.common, common_data); circuit } + +impl, const D: usize> CircuitBuilder { + pub(crate) fn dummy_proof_and_vk + 'static>( + &mut self, + common_data: &CommonCircuitData, + ) -> anyhow::Result<(ProofWithPublicInputsTarget, VerifierCircuitTarget)> + where + C::Hasher: AlgebraicHasher, + { + let dummy_circuit = dummy_circuit::(common_data); + let dummy_proof_with_pis = dummy_proof(&dummy_circuit, HashMap::new())?; + let dummy_proof_with_pis_target = self.add_virtual_proof_with_pis::(common_data); + + let dummy_verifier_data_target = VerifierCircuitTarget { + constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), + circuit_digest: self.add_virtual_hash(), + }; + + self.add_simple_generator(DummyProofGenerator { + proof_with_pis_target: dummy_proof_with_pis_target.clone(), + proof_with_pis: dummy_proof_with_pis, + verifier_data_target: dummy_verifier_data_target.clone(), + verifier_data: dummy_circuit.verifier_only, + }); + + Ok((dummy_proof_with_pis_target, dummy_verifier_data_target)) + } +} + +#[derive(Debug)] +pub(crate) struct DummyProofGenerator +where + F: RichField + Extendable, + C: GenericConfig, +{ + pub(crate) proof_with_pis_target: ProofWithPublicInputsTarget, + pub(crate) proof_with_pis: ProofWithPublicInputs, + pub(crate) verifier_data_target: VerifierCircuitTarget, + pub(crate) verifier_data: VerifierOnlyCircuitData, +} + +impl SimpleGenerator for DummyProofGenerator +where + F: RichField + Extendable, + C: GenericConfig + 'static, + C::Hasher: AlgebraicHasher, +{ + fn dependencies(&self) -> Vec { + vec![] + } + + fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { + out_buffer.set_proof_with_pis_target(&self.proof_with_pis_target, &self.proof_with_pis); + out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data); + } +} diff --git a/plonky2/src/recursion/mod.rs b/plonky2/src/recursion/mod.rs index 3aba4ffd..0e9cd2cc 100644 --- a/plonky2/src/recursion/mod.rs +++ b/plonky2/src/recursion/mod.rs @@ -1,4 +1,4 @@ pub mod conditional_recursive_verifier; pub mod cyclic_recursion; -pub(crate) mod dummy_circuit; +pub mod dummy_circuit; pub mod recursive_verifier; diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index d53095a4..15943a87 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -191,7 +191,7 @@ mod tests { use crate::fri::reduction_strategies::FriReductionStrategy; use crate::fri::FriConfig; use crate::gates::noop::NoopGate; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_data::{CircuitConfig, VerifierOnlyCircuitData}; use crate::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig}; use crate::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}; diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index 0bed0b84..aaf905d5 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -278,7 +278,7 @@ mod tests { use super::*; use crate::field::types::Sample; - use crate::iop::witness::{PartialWitness, Witness}; + use crate::iop::witness::{PartialWitness, WitnessWrite}; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use crate::plonk::verifier::verify; diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index 7adcacc4..02c6bcd0 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -6,7 +6,7 @@ use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use plonky2::field::types::{Field, Sample}; use plonky2::hash::hash_types::RichField; -use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, Hasher}; diff --git a/u32/src/gates/add_many_u32.rs b/u32/src/gates/add_many_u32.rs index a2bd2dac..566a7827 100644 --- a/u32/src/gates/add_many_u32.rs +++ b/u32/src/gates/add_many_u32.rs @@ -14,7 +14,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/u32/src/gates/arithmetic_u32.rs b/u32/src/gates/arithmetic_u32.rs index 3f249d29..c65b32a4 100644 --- a/u32/src/gates/arithmetic_u32.rs +++ b/u32/src/gates/arithmetic_u32.rs @@ -16,7 +16,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::vars::{ diff --git a/u32/src/gates/comparison.rs b/u32/src/gates/comparison.rs index 6cb67106..d10f3b80 100644 --- a/u32/src/gates/comparison.rs +++ b/u32/src/gates/comparison.rs @@ -15,7 +15,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; use plonky2::plonk::vars::{ diff --git a/u32/src/gates/range_check_u32.rs b/u32/src/gates/range_check_u32.rs index 6dd20d48..55faa6ca 100644 --- a/u32/src/gates/range_check_u32.rs +++ b/u32/src/gates/range_check_u32.rs @@ -12,7 +12,7 @@ use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; use plonky2::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; diff --git a/u32/src/gates/subtraction_u32.rs b/u32/src/gates/subtraction_u32.rs index 9a3b1db6..01f55e09 100644 --- a/u32/src/gates/subtraction_u32.rs +++ b/u32/src/gates/subtraction_u32.rs @@ -15,7 +15,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::vars::{ diff --git a/u32/src/witness.rs b/u32/src/witness.rs index 004fedc6..cf308d2a 100644 --- a/u32/src/witness.rs +++ b/u32/src/witness.rs @@ -1,6 +1,6 @@ use plonky2::field::types::{Field, PrimeField64}; use plonky2::iop::generator::GeneratedValues; -use plonky2::iop::witness::Witness; +use plonky2::iop::witness::{Witness, WitnessWrite}; use crate::gadgets::arithmetic_u32::U32Target; diff --git a/waksman/src/gates/assert_le.rs b/waksman/src/gates/assert_le.rs index 745bb62f..0213dd38 100644 --- a/waksman/src/gates/assert_le.rs +++ b/waksman/src/gates/assert_le.rs @@ -8,7 +8,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; use plonky2::plonk::vars::{ diff --git a/waksman/src/gates/switch.rs b/waksman/src/gates/switch.rs index 58fad4c7..b868916e 100644 --- a/waksman/src/gates/switch.rs +++ b/waksman/src/gates/switch.rs @@ -9,7 +9,7 @@ use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::generator::{GeneratedValues, WitnessGenerator}; use plonky2::iop::target::Target; use plonky2::iop::wire::Wire; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::vars::{ diff --git a/waksman/src/permutation.rs b/waksman/src/permutation.rs index b9d69f75..57ede529 100644 --- a/waksman/src/permutation.rs +++ b/waksman/src/permutation.rs @@ -6,7 +6,7 @@ use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use crate::bimap::bimap_from_lists; diff --git a/waksman/src/sorting.rs b/waksman/src/sorting.rs index dbfe8a81..571a066b 100644 --- a/waksman/src/sorting.rs +++ b/waksman/src/sorting.rs @@ -6,7 +6,7 @@ use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; -use plonky2::iop::witness::{PartitionWitness, Witness}; +use plonky2::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2_util::ceil_div_usize;