diff --git a/evm/src/fixed_recursive_verifier.rs b/evm/src/fixed_recursive_verifier.rs index ba63c0f8..19a026d7 100644 --- a/evm/src/fixed_recursive_verifier.rs +++ b/evm/src/fixed_recursive_verifier.rs @@ -837,6 +837,7 @@ where buffer.write_prover_only_circuit_data( &wrapper.circuit.prover_only, generator_serializer, + &wrapper.circuit.common, )?; buffer.write_verifier_only_circuit_data(&wrapper.circuit.verifier_only)?; buffer.write_target_proof_with_public_inputs(&wrapper.proof_with_pis_target)?; diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index ce94fca7..d0c273d1 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -248,18 +248,18 @@ where fn test_serialization, C: GenericConfig, const D: usize>( proof: &ProofWithPublicInputs, vd: &VerifierOnlyCircuitData, - cd: &CommonCircuitData, + common_data: &CommonCircuitData, ) -> Result<()> { let proof_bytes = proof.to_bytes(); info!("Proof length: {} bytes", proof_bytes.len()); - let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; + let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, common_data)?; assert_eq!(proof, &proof_from_bytes); let now = std::time::Instant::now(); - let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?; + let compressed_proof = proof.clone().compress(&vd.circuit_digest, common_data)?; let decompressed_compressed_proof = compressed_proof .clone() - .decompress(&vd.circuit_digest, cd)?; + .decompress(&vd.circuit_digest, common_data)?; info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); @@ -269,11 +269,11 @@ fn test_serialization, C: GenericConfig, compressed_proof_bytes.len() ); let compressed_proof_from_bytes = - CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, cd)?; + CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, common_data)?; assert_eq!(compressed_proof, compressed_proof_from_bytes); let gate_serializer = DefaultGateSerializer; - let common_data_bytes = cd + let common_data_bytes = common_data .to_bytes(&gate_serializer) .map_err(|_| anyhow::Error::msg("CommonCircuitData serialization failed."))?; info!( @@ -283,7 +283,7 @@ fn test_serialization, C: GenericConfig, let common_data_from_bytes = CommonCircuitData::::from_bytes(common_data_bytes, &gate_serializer) .map_err(|_| anyhow::Error::msg("CommonCircuitData deserialization failed."))?; - assert_eq!(cd, &common_data_from_bytes); + assert_eq!(common_data, &common_data_from_bytes); Ok(()) } @@ -312,35 +312,35 @@ pub fn benchmark_function( }; // Start with a dummy proof of specified size let inner = dummy_proof_function(config, log2_inner_size)?; - let (_, _, cd) = &inner; + let (_, _, common_data) = &inner; info!( "Initial {} degree {} = 2^{}", name, - cd.degree(), - cd.degree_bits() + common_data.degree(), + common_data.degree_bits() ); // Recursively verify the proof let middle = recursive_proof::(&inner, config, None)?; - let (_, _, cd) = &middle; + let (_, _, common_data) = &middle; info!( "Single recursion {} degree {} = 2^{}", name, - cd.degree(), - cd.degree_bits() + common_data.degree(), + common_data.degree_bits() ); // Add a second layer of recursion to shrink the proof size further let outer = recursive_proof::(&middle, config, None)?; - let (proof, vd, cd) = &outer; + let (proof, vd, common_data) = &outer; info!( "Double recursion {} degree {} = 2^{}", name, - cd.degree(), - cd.degree_bits() + common_data.degree(), + common_data.degree_bits() ); - test_serialization(proof, vd, cd)?; + test_serialization(proof, vd, common_data)?; Ok(()) } diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 019d2c14..40c2e1fc 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -14,7 +14,7 @@ use plonky2::iop::generator::{ use plonky2::iop::target::Target; use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; +use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData}; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig}; use plonky2::recursion::dummy_circuit::DummyProofGenerator; use plonky2::util::serialization::{ @@ -32,7 +32,7 @@ struct SquareRootGenerator, const D: usize> { _phantom: PhantomData, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for SquareRootGenerator { fn id(&self) -> String { @@ -52,12 +52,12 @@ impl, const D: usize> SimpleGenerator out_buffer.set_target(self.x, x); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.x)?; dst.write_target(self.x_squared) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let x = src.read_target()?; let x_squared = src.read_target()?; Ok(Self { diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index ed9e7c4a..858a4eaf 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -11,6 +11,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::serialization::{Buffer, IoResult, Read, Write}; impl, const D: usize> CircuitBuilder { @@ -379,7 +380,7 @@ pub struct EqualityGenerator { inv: Target, } -impl SimpleGenerator for EqualityGenerator { +impl, const D: usize> SimpleGenerator for EqualityGenerator { fn id(&self) -> String { "EqualityGenerator".to_string() } @@ -398,14 +399,14 @@ impl SimpleGenerator for EqualityGenerator { out_buffer.set_target(self.inv, inv); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.x)?; dst.write_target(self.y)?; dst.write_target_bool(self.equal)?; dst.write_target(self.inv) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let x = src.read_target()?; let y = src.read_target()?; let equal = src.read_target_bool()?; diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index ccb84a40..0fe8083a 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::bits_u64; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -501,7 +502,7 @@ pub struct QuotientGeneratorExtension { quotient: ExtensionTarget, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for QuotientGeneratorExtension { fn id(&self) -> String { @@ -521,13 +522,13 @@ impl, const D: usize> SimpleGenerator out_buffer.set_extension_target(self.quotient, quotient) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target_ext(self.numerator)?; dst.write_target_ext(self.denominator)?; dst.write_target_ext(self.quotient) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let numerator = src.read_target_ext()?; let denominator = src.read_target_ext()?; let quotient = src.read_target_ext()?; diff --git a/plonky2/src/gadgets/range_check.rs b/plonky2/src/gadgets/range_check.rs index bdd1942c..bdb35f9e 100644 --- a/plonky2/src/gadgets/range_check.rs +++ b/plonky2/src/gadgets/range_check.rs @@ -7,6 +7,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::serialization::{Buffer, IoResult, Read, Write}; impl, const D: usize> CircuitBuilder { @@ -60,7 +61,7 @@ pub struct LowHighGenerator { high: Target, } -impl SimpleGenerator for LowHighGenerator { +impl, const D: usize> SimpleGenerator for LowHighGenerator { fn id(&self) -> String { "LowHighGenerator".to_string() } @@ -78,14 +79,14 @@ impl SimpleGenerator for LowHighGenerator { out_buffer.set_target(self.high, F::from_canonical_u64(high)); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.integer)?; dst.write_usize(self.n_log)?; dst.write_target(self.low)?; dst.write_target(self.high) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let integer = src.read_target()?; let n_log = src.read_usize()?; let low = src.read_target()?; diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index c2919315..0a39b8f0 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -5,13 +5,13 @@ use core::borrow::Borrow; use itertools::Itertools; use crate::field::extension::Extendable; -use crate::field::types::Field; 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, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::log_floor; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -86,7 +86,9 @@ pub struct BaseSumGenerator { limbs: Vec, } -impl SimpleGenerator for BaseSumGenerator { +impl, const B: usize, const D: usize> SimpleGenerator + for BaseSumGenerator +{ fn id(&self) -> String { "BaseSumGenerator".to_string() } @@ -108,12 +110,12 @@ impl SimpleGenerator for BaseSumGenerator { out_buffer.set_target(Target::wire(self.row, BaseSumGate::::WIRE_SUM), sum); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_target_bool_vec(&self.limbs) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let limbs = src.read_target_bool_vec()?; Ok(Self { row, limbs }) @@ -123,6 +125,7 @@ impl SimpleGenerator for BaseSumGenerator { #[cfg(test)] mod tests { use anyhow::Result; + use plonky2_field::types::Field; use rand::rngs::OsRng; use rand::Rng; diff --git a/plonky2/src/gadgets/split_join.rs b/plonky2/src/gadgets/split_join.rs index e3eda241..fb83c3a6 100644 --- a/plonky2/src/gadgets/split_join.rs +++ b/plonky2/src/gadgets/split_join.rs @@ -8,6 +8,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::ceil_div_usize; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -62,7 +63,7 @@ pub struct SplitGenerator { bits: Vec, } -impl SimpleGenerator for SplitGenerator { +impl, const D: usize> SimpleGenerator for SplitGenerator { fn id(&self) -> String { "SplitGenerator".to_string() } @@ -86,12 +87,12 @@ impl SimpleGenerator for SplitGenerator { ); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.integer)?; dst.write_target_vec(&self.bits) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let integer = src.read_target()?; let bits = src.read_target_vec()?; Ok(Self { integer, bits }) @@ -105,7 +106,7 @@ pub struct WireSplitGenerator { num_limbs: usize, } -impl SimpleGenerator for WireSplitGenerator { +impl, const D: usize> SimpleGenerator for WireSplitGenerator { fn id(&self) -> String { "WireSplitGenerator".to_string() } @@ -141,13 +142,13 @@ impl SimpleGenerator for WireSplitGenerator { ); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.integer)?; dst.write_usize_vec(&self.gates)?; dst.write_usize(self.num_limbs) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let integer = src.read_target()?; let gates = src.read_usize_vec()?; let num_limbs = src.read_usize()?; diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 7ed25328..cf111a71 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -13,7 +13,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -60,11 +60,11 @@ impl, const D: usize> Gate for ArithmeticGate format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } @@ -126,7 +126,7 @@ impl, const D: usize> Gate for ArithmeticGate constraints } - fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { (0..self.num_ops) .map(|i| { WitnessGeneratorRef::new( @@ -188,7 +188,7 @@ pub struct ArithmeticBaseGenerator, const D: usize> i: usize, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for ArithmeticBaseGenerator { fn id(&self) -> String { @@ -221,14 +221,14 @@ impl, const D: usize> SimpleGenerator out_buffer.set_target(output_target, computed_output) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_field(self.const_0)?; dst.write_field(self.const_1)?; dst.write_usize(self.i) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let const_0 = src.read_field()?; let const_1 = src.read_field()?; diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index ebe7a650..82ca8a56 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -12,7 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -56,11 +56,11 @@ impl, const D: usize> Gate for ArithmeticExte format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } @@ -131,7 +131,7 @@ impl, const D: usize> Gate for ArithmeticExte constraints } - fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { (0..self.num_ops) .map(|i| { WitnessGeneratorRef::new( @@ -172,7 +172,7 @@ pub struct ArithmeticExtensionGenerator, const D: u i: usize, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for ArithmeticExtensionGenerator { fn id(&self) -> String { @@ -214,14 +214,14 @@ impl, const D: usize> SimpleGenerator out_buffer.set_extension_target(output_target, computed_output) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_field(self.const_0)?; dst.write_field(self.const_1)?; dst.write_usize(self.i) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let const_0 = src.read_field()?; let const_1 = src.read_field()?; diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index fee50c66..181252a2 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -15,7 +15,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, @@ -55,11 +55,11 @@ impl, const D: usize, const B: usize> Gate fo format!("{self:?} + Base: {B}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_limbs) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_limbs = src.read_usize()?; Ok(Self { num_limbs }) } @@ -118,7 +118,7 @@ impl, const D: usize, const B: usize> Gate fo constraints } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { let gen = BaseSplitGenerator:: { row, num_limbs: self.num_limbs, @@ -175,7 +175,9 @@ pub struct BaseSplitGenerator { num_limbs: usize, } -impl SimpleGenerator for BaseSplitGenerator { +impl, const B: usize, const D: usize> SimpleGenerator + for BaseSplitGenerator +{ fn id(&self) -> String { "BaseSplitGenerator".to_string() } @@ -209,12 +211,12 @@ impl SimpleGenerator for BaseSplitGenerator } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_usize(self.num_limbs) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let num_limbs = src.read_usize()?; Ok(Self { row, num_limbs }) diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index dba65258..965b30b6 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -13,6 +13,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGeneratorRef; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -46,11 +47,11 @@ impl, const D: usize> Gate for ConstantGate { format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_consts) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_consts = src.read_usize()?; Ok(Self { num_consts }) } @@ -90,7 +91,7 @@ impl, const D: usize> Gate for ConstantGate { .collect() } - fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { vec![] } diff --git a/plonky2/src/gates/coset_interpolation.rs b/plonky2/src/gates/coset_interpolation.rs index ff6d9918..c701b8cf 100644 --- a/plonky2/src/gates/coset_interpolation.rs +++ b/plonky2/src/gates/coset_interpolation.rs @@ -17,6 +17,7 @@ use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -168,14 +169,14 @@ impl, const D: usize> Gate for CosetInterpola format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.subgroup_bits)?; dst.write_usize(self.degree)?; dst.write_usize(self.barycentric_weights.len())?; dst.write_field_vec(&self.barycentric_weights) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let subgroup_bits = src.read_usize()?; let degree = src.read_usize()?; let length = src.read_usize()?; @@ -362,7 +363,7 @@ impl, const D: usize> Gate for CosetInterpola constraints } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { let gen = InterpolationGenerator::::new(row, self.clone()); vec![WitnessGeneratorRef::new(gen.adapter())] } @@ -406,7 +407,7 @@ impl, const D: usize> InterpolationGenerator } } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for InterpolationGenerator { fn id(&self) -> String { @@ -496,14 +497,14 @@ impl, const D: usize> SimpleGenerator out_buffer.set_ext_wires(evaluation_value_wires, computed_eval); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - self.gate.serialize(dst) + self.gate.serialize(dst, _common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = CosetInterpolationGate::deserialize(src)?; + let gate = CosetInterpolationGate::deserialize(src, _common_data)?; Ok(Self::new(row, gate)) } } diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index eefc7ba7..a8629a84 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -17,7 +17,7 @@ use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -76,11 +76,11 @@ impl, const D: usize> Gate for Exponentiation format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_power_bits) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_power_bits = src.read_usize()?; Ok(Self::new(num_power_bits)) } @@ -173,7 +173,7 @@ impl, const D: usize> Gate for Exponentiation constraints } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { let gen = ExponentiationGenerator:: { row, gate: self.clone(), @@ -243,7 +243,7 @@ pub struct ExponentiationGenerator, const D: usize> gate: ExponentiationGate, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for ExponentiationGenerator { fn id(&self) -> String { @@ -295,14 +295,14 @@ impl, const D: usize> SimpleGenerator out_buffer.set_wire(output_wire, intermediate_values[num_power_bits - 1]); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - self.gate.serialize(dst) + self.gate.serialize(dst, _common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = ExponentiationGate::deserialize(src)?; + let gate = ExponentiationGate::deserialize(src, _common_data)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index dd0779de..2c52076b 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -19,6 +19,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGeneratorRef; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, }; @@ -28,9 +29,9 @@ use crate::util::serialization::{Buffer, IoResult}; pub trait Gate, const D: usize>: 'static + Send + Sync { fn id(&self) -> String; - fn serialize(&self, dst: &mut Vec) -> IoResult<()>; + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()>; - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult where Self: Sized; @@ -175,7 +176,7 @@ pub trait Gate, const D: usize>: 'static + Send + S /// The generators used to populate the witness. /// Note: This should return exactly 1 generator per operation in the gate. - fn generators(&self, row: usize, local_constants: &[F]) -> Vec>; + fn generators(&self, row: usize, local_constants: &[F]) -> Vec>; /// The number of wires used by this gate. fn num_wires(&self) -> usize; diff --git a/plonky2/src/gates/lookup.rs b/plonky2/src/gates/lookup.rs index 0ecac501..f682be23 100644 --- a/plonky2/src/gates/lookup.rs +++ b/plonky2/src/gates/lookup.rs @@ -1,9 +1,11 @@ use alloc::format; use alloc::string::String; -use alloc::sync::Arc; use alloc::vec::Vec; use core::usize; +use itertools::Itertools; +use keccak_hash::keccak; + use super::lookup_table::LookupTable; use crate::field::extension::Extendable; use crate::field::packed::PackedField; @@ -16,7 +18,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -32,13 +34,21 @@ pub struct LookupGate { pub num_slots: usize, /// LUT associated to the gate. lut: LookupTable, + /// The Keccak hash of the lookup table. + lut_hash: [u8; 32], } impl LookupGate { pub fn new_from_table(config: &CircuitConfig, lut: LookupTable) -> Self { + let table_bytes = lut + .iter() + .flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat()) + .collect_vec(); + Self { num_slots: Self::num_slots(config), lut, + lut_hash: keccak(table_bytes).0, } } pub(crate) fn num_slots(config: &CircuitConfig) -> usize { @@ -57,21 +67,35 @@ impl LookupGate { impl, const D: usize> Gate for LookupGate { fn id(&self) -> String { - format!("{self:?}") + // Custom implementation to not have the entire lookup table + format!( + "LookupGate {{num_slots: {}, lut_hash: {:?}}}", + self.num_slots, self.lut_hash + ) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_slots)?; - dst.write_lut(&self.lut) + for (i, lut) in common_data.luts.iter().enumerate() { + if lut == &self.lut { + dst.write_usize(i)?; + return dst.write_all(&self.lut_hash); + } + } + + panic!("The associated lookup table couldn't be found.") } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { let num_slots = src.read_usize()?; - let lut = src.read_lut()?; + let lut_index = src.read_usize()?; + let mut lut_hash = [0u8; 32]; + src.read_exact(&mut lut_hash)?; Ok(Self { num_slots, - lut: Arc::new(lut), + lut: common_data.luts[lut_index].clone(), + lut_hash, }) } @@ -101,7 +125,7 @@ impl, const D: usize> Gate for LookupGate { vec![] } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { (0..self.num_slots) .map(|i| { WitnessGeneratorRef::new( @@ -149,7 +173,7 @@ pub struct LookupGenerator { slot_nb: usize, } -impl SimpleGenerator for LookupGenerator { +impl, const D: usize> SimpleGenerator for LookupGenerator { fn id(&self) -> String { "LookupGenerator".to_string() } @@ -165,39 +189,47 @@ impl SimpleGenerator for LookupGenerator { let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) }; let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb)); - let output_val = if input_val - == F::from_canonical_u16(self.lut[input_val.to_canonical_u64() as usize].0) - { - F::from_canonical_u16(self.lut[input_val.to_canonical_u64() as usize].1) + let (input, output) = self.lut[input_val.to_canonical_u64() as usize]; + if input_val == F::from_canonical_u16(input) { + let output_val = F::from_canonical_u16(output); + + let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb)); + out_buffer.set_target(out_wire, output_val); } else { - let mut cur_idx = 0; - while input_val != F::from_canonical_u16(self.lut[cur_idx].0) - && cur_idx < self.lut.len() - { - cur_idx += 1; + for (input, output) in self.lut.iter() { + if input_val == F::from_canonical_u16(*input) { + let output_val = F::from_canonical_u16(*output); + + let out_wire = + Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb)); + out_buffer.set_target(out_wire, output_val); + return; + } } - assert!(cur_idx < self.lut.len(), "Incorrect input value provided"); - F::from_canonical_u16(self.lut[cur_idx].1) + panic!("Incorrect input value provided"); }; - - let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb)); - out_buffer.set_target(out_wire, output_val); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - dst.write_lut(&self.lut)?; - dst.write_usize(self.slot_nb) + dst.write_usize(self.slot_nb)?; + for (i, lut) in common_data.luts.iter().enumerate() { + if lut == &self.lut { + return dst.write_usize(i); + } + } + + panic!("The associated lookup table couldn't be found.") } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let lut = src.read_lut()?; let slot_nb = src.read_usize()?; + let lut_index = src.read_usize()?; Ok(Self { row, - lut: Arc::new(lut), + lut: common_data.luts[lut_index].clone(), slot_nb, }) } diff --git a/plonky2/src/gates/lookup_table.rs b/plonky2/src/gates/lookup_table.rs index b4ad902a..f3ed842d 100644 --- a/plonky2/src/gates/lookup_table.rs +++ b/plonky2/src/gates/lookup_table.rs @@ -4,6 +4,8 @@ use alloc::sync::Arc; use alloc::vec::Vec; use core::usize; +use itertools::Itertools; +use keccak_hash::keccak; use plonky2_util::ceil_div_usize; use crate::field::extension::Extendable; @@ -17,7 +19,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -33,15 +35,23 @@ pub struct LookupTableGate { pub num_slots: usize, /// Lookup table associated to the gate. pub lut: LookupTable, + /// The Keccak hash of the lookup table. + lut_hash: [u8; 32], /// First row of the lookup table. last_lut_row: usize, } impl LookupTableGate { pub fn new_from_table(config: &CircuitConfig, lut: LookupTable, last_lut_row: usize) -> Self { + let table_bytes = lut + .iter() + .flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat()) + .collect_vec(); + Self { num_slots: Self::num_slots(config), lut, + lut_hash: keccak(table_bytes).0, last_lut_row, } } @@ -69,23 +79,37 @@ impl LookupTableGate { impl, const D: usize> Gate for LookupTableGate { fn id(&self) -> String { - format!("{self:?}") + // Custom implementation to not have the entire lookup table + format!( + "LookupGate {{num_slots: {}, lut_hash: {:?}, last_lut_row: {}}}", + self.num_slots, self.lut_hash, self.last_lut_row + ) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_slots)?; - dst.write_lut(&self.lut)?; - dst.write_usize(self.last_lut_row) + dst.write_usize(self.last_lut_row)?; + for (i, lut) in common_data.luts.iter().enumerate() { + if lut == &self.lut { + dst.write_usize(i)?; + return dst.write_all(&self.lut_hash); + } + } + + panic!("The associated lookup table couldn't be found.") } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { let num_slots = src.read_usize()?; - let lut = src.read_lut()?; let last_lut_row = src.read_usize()?; + let lut_index = src.read_usize()?; + let mut lut_hash = [0u8; 32]; + src.read_exact(&mut lut_hash)?; Ok(Self { num_slots, - lut: Arc::new(lut), + lut: common_data.luts[lut_index].clone(), + lut_hash, last_lut_row, }) } @@ -116,7 +140,7 @@ impl, const D: usize> Gate for LookupTableGat vec![] } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { (0..self.num_slots) .map(|i| { WitnessGeneratorRef::new( @@ -168,7 +192,7 @@ pub struct LookupTableGenerator { last_lut_row: usize, } -impl SimpleGenerator for LookupTableGenerator { +impl, const D: usize> SimpleGenerator for LookupTableGenerator { fn id(&self) -> String { "LookupTableGenerator".to_string() } @@ -187,14 +211,9 @@ impl SimpleGenerator for LookupTableGenerator { Target::wire(self.row, LookupTableGate::wire_ith_looked_out(self.slot_nb)); if slot < self.lut.len() { - out_buffer.set_target( - slot_input_target, - F::from_canonical_usize(self.lut[slot].0 as usize), - ); - out_buffer.set_target( - slot_output_target, - F::from_canonical_usize(self.lut[slot].1.into()), - ); + let (input, output) = self.lut[slot]; + out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize)); + out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize)); } else { // Pad with zeros. out_buffer.set_target(slot_input_target, F::ZERO); @@ -202,24 +221,30 @@ impl SimpleGenerator for LookupTableGenerator { } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - dst.write_lut(&self.lut)?; dst.write_usize(self.slot_nb)?; dst.write_usize(self.num_slots)?; - dst.write_usize(self.last_lut_row) + dst.write_usize(self.last_lut_row)?; + for (i, lut) in common_data.luts.iter().enumerate() { + if lut == &self.lut { + return dst.write_usize(i); + } + } + + panic!("The associated lookup table couldn't be found.") } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let lut = src.read_lut()?; let slot_nb = src.read_usize()?; let num_slots = src.read_usize()?; let last_lut_row = src.read_usize()?; + let lut_index = src.read_usize()?; Ok(Self { row, - lut: Arc::new(lut), + lut: common_data.luts[lut_index].clone(), slot_nb, num_slots, last_lut_row, diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 7e1c1924..6799bd37 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -12,7 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -53,11 +53,11 @@ impl, const D: usize> Gate for MulExtensionGa format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } @@ -119,7 +119,7 @@ impl, const D: usize> Gate for MulExtensionGa constraints } - fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, local_constants: &[F]) -> Vec> { (0..self.num_ops) .map(|i| { WitnessGeneratorRef::new( @@ -158,7 +158,7 @@ pub struct MulExtensionGenerator, const D: usize> { i: usize, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for MulExtensionGenerator { fn id(&self) -> String { @@ -191,13 +191,13 @@ impl, const D: usize> SimpleGenerator out_buffer.set_extension_target(output_target, computed_output) } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_field(self.const_0)?; dst.write_usize(self.i) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let const_0 = src.read_field()?; let i = src.read_usize()?; diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index cfcfb912..8752f380 100644 --- a/plonky2/src/gates/noop.rs +++ b/plonky2/src/gates/noop.rs @@ -7,6 +7,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGeneratorRef; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch}; use crate::util::serialization::{Buffer, IoResult}; @@ -18,11 +19,15 @@ impl, const D: usize> Gate for NoopGate { "NoopGate".into() } - fn serialize(&self, _dst: &mut Vec) -> IoResult<()> { + fn serialize( + &self, + _dst: &mut Vec, + _common_data: &CommonCircuitData, + ) -> IoResult<()> { Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { Ok(Self) } @@ -42,7 +47,7 @@ impl, const D: usize> Gate for NoopGate { Vec::new() } - fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { Vec::new() } diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index caab7faf..f6d06572 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -17,6 +17,7 @@ use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -99,11 +100,15 @@ impl, const D: usize> Gate for PoseidonGate") } - fn serialize(&self, _dst: &mut Vec) -> IoResult<()> { + fn serialize( + &self, + _dst: &mut Vec, + _common_data: &CommonCircuitData, + ) -> IoResult<()> { Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { Ok(PoseidonGate::new()) } @@ -380,7 +385,7 @@ impl, const D: usize> Gate for PoseidonGate Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { let gen = PoseidonGenerator:: { row, _phantom: PhantomData, @@ -415,7 +420,7 @@ pub struct PoseidonGenerator + Poseidon, const D: u _phantom: PhantomData, } -impl + Poseidon, const D: usize> SimpleGenerator +impl + Poseidon, const D: usize> SimpleGenerator for PoseidonGenerator { fn id(&self) -> String { @@ -512,11 +517,11 @@ impl + Poseidon, const D: usize> SimpleGenerator } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; Ok(Self { row, diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index a3b4c927..8e2f4a76 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -16,6 +16,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -118,11 +119,15 @@ impl + Poseidon, const D: usize> Gate for Pos format!("{self:?}") } - fn serialize(&self, _dst: &mut Vec) -> IoResult<()> { + fn serialize( + &self, + _dst: &mut Vec, + _common_data: &CommonCircuitData, + ) -> IoResult<()> { Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { Ok(PoseidonMdsGate::new()) } @@ -187,7 +192,7 @@ impl + Poseidon, const D: usize> Gate for Pos .collect() } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { let gen = PoseidonMdsGenerator:: { row }; vec![WitnessGeneratorRef::new(gen.adapter())] } @@ -214,7 +219,7 @@ pub struct PoseidonMdsGenerator { row: usize, } -impl + Poseidon, const D: usize> SimpleGenerator +impl + Poseidon, const D: usize> SimpleGenerator for PoseidonMdsGenerator { fn id(&self) -> String { @@ -250,11 +255,11 @@ impl + Poseidon, const D: usize> SimpleGenerator } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; Ok(Self { row }) } diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index 2c3e2428..f770e2e6 100644 --- a/plonky2/src/gates/public_input.rs +++ b/plonky2/src/gates/public_input.rs @@ -11,6 +11,7 @@ use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGeneratorRef; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -31,11 +32,15 @@ impl, const D: usize> Gate for PublicInputGat "PublicInputGate".into() } - fn serialize(&self, _dst: &mut Vec) -> IoResult<()> { + fn serialize( + &self, + _dst: &mut Vec, + _common_data: &CommonCircuitData, + ) -> IoResult<()> { Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { Ok(Self) } @@ -72,7 +77,7 @@ impl, const D: usize> Gate for PublicInputGat .collect() } - fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, _row: usize, _local_constants: &[F]) -> Vec> { Vec::new() } diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 7f651bab..9110a59b 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -18,7 +18,7 @@ use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::CircuitConfig; +use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, @@ -122,14 +122,14 @@ impl, const D: usize> Gate for RandomAccessGa format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.bits)?; dst.write_usize(self.num_copies)?; dst.write_usize(self.num_extra_constants)?; Ok(()) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let bits = src.read_usize()?; let num_copies = src.read_usize()?; let num_extra_constants = src.read_usize()?; @@ -252,7 +252,7 @@ impl, const D: usize> Gate for RandomAccessGa constraints } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { (0..self.num_copies) .map(|copy| { WitnessGeneratorRef::new( @@ -345,7 +345,7 @@ pub struct RandomAccessGenerator, const D: usize> { copy: usize, } -impl, const D: usize> SimpleGenerator +impl, const D: usize> SimpleGenerator for RandomAccessGenerator { fn id(&self) -> String { @@ -394,16 +394,16 @@ impl, const D: usize> SimpleGenerator } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_usize(self.copy)?; - self.gate.serialize(dst) + self.gate.serialize(dst, _common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let copy = src.read_usize()?; - let gate = RandomAccessGate::::deserialize(src)?; + let gate = RandomAccessGate::::deserialize(src, _common_data)?; Ok(Self { row, gate, copy }) } } diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index b9bd025a..b313efe6 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -60,12 +61,12 @@ impl, const D: usize> Gate for ReducingGate) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_coeffs)?; Ok(()) } - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult where Self: Sized, { @@ -150,7 +151,7 @@ impl, const D: usize> Gate for ReducingGate Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { vec![WitnessGeneratorRef::new( ReducingGenerator { row, @@ -183,7 +184,7 @@ pub struct ReducingGenerator { gate: ReducingGate, } -impl, const D: usize> SimpleGenerator for ReducingGenerator { +impl, const D: usize> SimpleGenerator for ReducingGenerator { fn id(&self) -> String { "ReducingGenerator".to_string() } @@ -225,14 +226,14 @@ impl, const D: usize> SimpleGenerator for Reduci out_buffer.set_extension_target(output, acc); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - as Gate>::serialize(&self.gate, dst) + as Gate>::serialize(&self.gate, dst, _common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = as Gate>::deserialize(src)?; + let gate = as Gate>::deserialize(src, _common_data)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 11541ec2..5492c506 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -12,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGeneratorRe use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; @@ -63,12 +64,12 @@ impl, const D: usize> Gate for ReducingExtens format!("{self:?}") } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.num_coeffs)?; Ok(()) } - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult where Self: Sized, { @@ -150,7 +151,7 @@ impl, const D: usize> Gate for ReducingExtens .collect() } - fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { + fn generators(&self, row: usize, _local_constants: &[F]) -> Vec> { vec![WitnessGeneratorRef::new( ReducingGenerator { row, @@ -183,7 +184,7 @@ pub struct ReducingGenerator { gate: ReducingExtensionGate, } -impl, const D: usize> SimpleGenerator for ReducingGenerator { +impl, const D: usize> SimpleGenerator for ReducingGenerator { fn id(&self) -> String { "ReducingExtensionGenerator".to_string() } @@ -219,14 +220,14 @@ impl, const D: usize> SimpleGenerator for Reduci } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; - as Gate>::serialize(&self.gate, dst) + as Gate>::serialize(&self.gate, dst, _common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = as Gate>::deserialize(src)?; + let gate = as Gate>::deserialize(src, _common_data)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 16a23e26..478c5ff5 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -98,7 +98,9 @@ pub(crate) fn generate_partial_witness< } /// A generator participates in the generation of the witness. -pub trait WitnessGenerator: 'static + Send + Sync + Debug { +pub trait WitnessGenerator, const D: usize>: + 'static + Send + Sync + Debug +{ fn id(&self) -> String; /// Targets to be "watched" by this generator. Whenever a target in the watch list is populated, @@ -110,32 +112,34 @@ pub trait WitnessGenerator: 'static + Send + Sync + Debug { /// run next time a target in its watch list is populated. fn run(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) -> bool; - fn serialize(&self, dst: &mut Vec) -> IoResult<()>; + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()>; - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult where Self: Sized; } /// A wrapper around an `Box` which implements `PartialEq` /// and `Eq` based on generator IDs. -pub struct WitnessGeneratorRef(pub Box>); +pub struct WitnessGeneratorRef, const D: usize>( + pub Box>, +); -impl WitnessGeneratorRef { - pub fn new>(generator: G) -> WitnessGeneratorRef { +impl, const D: usize> WitnessGeneratorRef { + pub fn new>(generator: G) -> WitnessGeneratorRef { WitnessGeneratorRef(Box::new(generator)) } } -impl PartialEq for WitnessGeneratorRef { +impl, const D: usize> PartialEq for WitnessGeneratorRef { fn eq(&self, other: &Self) -> bool { self.0.id() == other.0.id() } } -impl Eq for WitnessGeneratorRef {} +impl, const D: usize> Eq for WitnessGeneratorRef {} -impl Debug for WitnessGeneratorRef { +impl, const D: usize> Debug for WitnessGeneratorRef { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.0.id()) } @@ -190,14 +194,16 @@ impl GeneratedValues { } /// A generator which runs once after a list of dependencies is present in the witness. -pub trait SimpleGenerator: 'static + Send + Sync + Debug { +pub trait SimpleGenerator, const D: usize>: + 'static + Send + Sync + Debug +{ fn id(&self) -> String; fn dependencies(&self) -> Vec; fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues); - fn adapter(self) -> SimpleGeneratorAdapter + fn adapter(self) -> SimpleGeneratorAdapter where Self: Sized, { @@ -207,20 +213,26 @@ pub trait SimpleGenerator: 'static + Send + Sync + Debug { } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()>; + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()>; - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult where Self: Sized; } #[derive(Debug)] -pub struct SimpleGeneratorAdapter + ?Sized> { +pub struct SimpleGeneratorAdapter< + F: RichField + Extendable, + SG: SimpleGenerator + ?Sized, + const D: usize, +> { _phantom: PhantomData, inner: SG, } -impl> WitnessGenerator for SimpleGeneratorAdapter { +impl, SG: SimpleGenerator, const D: usize> WitnessGenerator + for SimpleGeneratorAdapter +{ fn id(&self) -> String { self.inner.id() } @@ -238,13 +250,13 @@ impl> WitnessGenerator for SimpleGeneratorAd } } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { - self.inner.serialize(dst) + fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()> { + self.inner.serialize(dst, common_data) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { Ok(Self { - inner: SG::deserialize(src)?, + inner: SG::deserialize(src, common_data)?, _phantom: PhantomData, }) } @@ -257,7 +269,7 @@ pub struct CopyGenerator { pub(crate) dst: Target, } -impl SimpleGenerator for CopyGenerator { +impl, const D: usize> SimpleGenerator for CopyGenerator { fn id(&self) -> String { "CopyGenerator".to_string() } @@ -271,12 +283,12 @@ impl SimpleGenerator for CopyGenerator { out_buffer.set_target(self.dst, value); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.src)?; dst.write_target(self.dst) } - fn deserialize(source: &mut Buffer) -> IoResult { + fn deserialize(source: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let src = source.read_target()?; let dst = source.read_target()?; Ok(Self { src, dst }) @@ -289,7 +301,7 @@ pub struct RandomValueGenerator { pub(crate) target: Target, } -impl SimpleGenerator for RandomValueGenerator { +impl, const D: usize> SimpleGenerator for RandomValueGenerator { fn id(&self) -> String { "RandomValueGenerator".to_string() } @@ -303,11 +315,11 @@ impl SimpleGenerator for RandomValueGenerator { out_buffer.set_target(self.target, random_value); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.target) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let target = src.read_target()?; Ok(Self { target }) } @@ -320,7 +332,7 @@ pub struct NonzeroTestGenerator { pub(crate) dummy: Target, } -impl SimpleGenerator for NonzeroTestGenerator { +impl, const D: usize> SimpleGenerator for NonzeroTestGenerator { fn id(&self) -> String { "NonzeroTestGenerator".to_string() } @@ -341,12 +353,12 @@ impl SimpleGenerator for NonzeroTestGenerator { out_buffer.set_target(self.dummy, dummy_value); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target(self.to_test)?; dst.write_target(self.dummy) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let to_test = src.read_target()?; let dummy = src.read_target()?; Ok(Self { to_test, dummy }) @@ -368,7 +380,7 @@ impl ConstantGenerator { } } -impl SimpleGenerator for ConstantGenerator { +impl, const D: usize> SimpleGenerator for ConstantGenerator { fn id(&self) -> String { "ConstantGenerator".to_string() } @@ -381,14 +393,14 @@ impl SimpleGenerator for ConstantGenerator { out_buffer.set_target(Target::wire(self.row, self.wire_index), self.constant); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_usize(self.row)?; dst.write_usize(self.constant_index)?; dst.write_usize(self.wire_index)?; dst.write_field(self.constant) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _common_data: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let constant_index = src.read_usize()?; let wire_index = src.read_usize()?; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 8955a2bd..d8f9e32c 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -109,7 +109,7 @@ pub struct CircuitBuilder, const D: usize> { context_log: ContextTree, /// Generators used to generate the witness. - generators: Vec>, + generators: Vec>, constants_to_targets: HashMap, targets_to_constants: HashMap, @@ -444,11 +444,11 @@ impl, const D: usize> CircuitBuilder { self.connect(x, one); } - pub fn add_generators(&mut self, generators: Vec>) { + pub fn add_generators(&mut self, generators: Vec>) { self.generators.extend(generators); } - pub fn add_simple_generator>(&mut self, generator: G) { + pub fn add_simple_generator>(&mut self, generator: G) { self.generators .push(WitnessGeneratorRef::new(generator.adapter())); } diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index a2fd48df..6e4e0638 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -295,7 +295,7 @@ pub struct ProverOnlyCircuitData< C: GenericConfig, const D: usize, > { - pub generators: Vec>, + pub generators: Vec>, /// Generator indices (within the `Vec` above), indexed by the representative of each target /// they watch. pub generator_indices_by_watches: BTreeMap>, @@ -321,6 +321,29 @@ pub struct ProverOnlyCircuitData< pub lut_to_lookups: Vec, } +impl, C: GenericConfig, const D: usize> + ProverOnlyCircuitData +{ + pub fn to_bytes( + &self, + generator_serializer: &dyn WitnessGeneratorSerializer, + common_data: &CommonCircuitData, + ) -> IoResult> { + let mut buffer = Vec::new(); + buffer.write_prover_only_circuit_data(self, generator_serializer, common_data)?; + Ok(buffer) + } + + pub fn from_bytes( + bytes: &[u8], + generator_serializer: &dyn WitnessGeneratorSerializer, + common_data: &CommonCircuitData, + ) -> IoResult { + let mut buffer = Buffer::new(bytes); + buffer.read_prover_only_circuit_data(generator_serializer, common_data) + } +} + /// Circuit data required by the verifier, but not the prover. #[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct VerifierOnlyCircuitData, const D: usize> { diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 27ddf14d..21f22b47 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -80,15 +80,14 @@ pub fn set_lookup_wires< let remaining_slots = (num_entries - (prover_data.lut_to_lookups[lut_index].len() % num_entries)) % num_entries; - let first_inp_value = F::from_canonical_u16(common_data.luts[lut_index][0].0); - let first_out_value = F::from_canonical_u16(common_data.luts[lut_index][0].1); + let (first_inp_value, first_out_value) = common_data.luts[lut_index][0]; for slot in (num_entries - remaining_slots)..num_entries { let inp_target = Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_inp(slot)); let out_target = Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_out(slot)); - pw.set_target(inp_target, first_inp_value); - pw.set_target(out_target, first_out_value); + pw.set_target(inp_target, F::from_canonical_u16(first_inp_value)); + pw.set_target(out_target, F::from_canonical_u16(first_out_value)); multiplicities[0] += 1; } diff --git a/plonky2/src/plonk/vanishing_poly.rs b/plonky2/src/plonk/vanishing_poly.rs index 4708cddd..bf99aa54 100644 --- a/plonky2/src/plonk/vanishing_poly.rs +++ b/plonky2/src/plonk/vanishing_poly.rs @@ -37,11 +37,8 @@ pub(crate) fn get_lut_poly, const D: usize>( let b = deltas[LookupChallenges::ChallengeB as usize]; let mut coeffs = Vec::new(); let n = common_data.luts[lut_index].len(); - for i in 0..n { - coeffs.push( - F::from_canonical_u16(common_data.luts[lut_index][i].0) - + b * F::from_canonical_u16(common_data.luts[lut_index][i].1), - ); + for (input, output) in common_data.luts[lut_index].iter() { + coeffs.push(F::from_canonical_u16(*input) + b * F::from_canonical_u16(*output)); } coeffs.append(&mut vec![F::ZERO; degree - n]); coeffs.reverse(); @@ -760,14 +757,11 @@ pub(crate) fn get_lut_poly_circuit, const D: usize> let b = deltas[LookupChallenges::ChallengeB as usize]; let delta = deltas[LookupChallenges::ChallengeDelta as usize]; let n = common_data.luts[lut_index].len(); - let mut coeffs: Vec = (0..n) - .map(|i| { - let temp = - builder.mul_const(F::from_canonical_u16(common_data.luts[lut_index][i].1), b); - builder.add_const( - temp, - F::from_canonical_u16(common_data.luts[lut_index][i].0), - ) + let mut coeffs: Vec = common_data.luts[lut_index] + .iter() + .map(|(input, output)| { + let temp = builder.mul_const(F::from_canonical_u16(*output), b); + builder.add_const(temp, F::from_canonical_u16(*input)) }) .collect(); for _ in n..degree { diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs index daf9319a..620c979f 100644 --- a/plonky2/src/recursion/dummy_circuit.rs +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -215,30 +215,7 @@ where } } -impl DummyProofGenerator -where - F: RichField + Extendable, - C: GenericConfig + 'static, - C::Hasher: AlgebraicHasher, -{ - pub fn deserialize_with_circuit_data( - src: &mut Buffer, - cd: &CommonCircuitData, - ) -> IoResult { - let proof_with_pis_target = src.read_target_proof_with_public_inputs()?; - let proof_with_pis = src.read_proof_with_public_inputs(cd)?; - let verifier_data_target = src.read_target_verifier_circuit()?; - let verifier_data = src.read_verifier_only_circuit_data()?; - Ok(Self { - proof_with_pis_target, - proof_with_pis, - verifier_data_target, - verifier_data, - }) - } -} - -impl SimpleGenerator for DummyProofGenerator +impl SimpleGenerator for DummyProofGenerator where F: RichField + Extendable, C: GenericConfig + 'static, @@ -257,14 +234,23 @@ where out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data); } - fn serialize(&self, dst: &mut Vec) -> IoResult<()> { + fn serialize(&self, dst: &mut Vec, _common_data: &CommonCircuitData) -> IoResult<()> { dst.write_target_proof_with_public_inputs(&self.proof_with_pis_target)?; dst.write_proof_with_public_inputs(&self.proof_with_pis)?; dst.write_target_verifier_circuit(&self.verifier_data_target)?; dst.write_verifier_only_circuit_data(&self.verifier_data) } - fn deserialize(_src: &mut Buffer) -> IoResult { - panic!() + fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult { + let proof_with_pis_target = src.read_target_proof_with_public_inputs()?; + let proof_with_pis = src.read_proof_with_public_inputs(common_data)?; + let verifier_data_target = src.read_target_verifier_circuit()?; + let verifier_data = src.read_verifier_only_circuit_data()?; + Ok(Self { + proof_with_pis_target, + proof_with_pis, + verifier_data_target, + verifier_data, + }) } } diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index 613766e4..ada2b002 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -218,10 +218,10 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_zk_config(); - let (proof, vd, cd) = dummy_proof::(&config, 4_000)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, true, true)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = dummy_proof::(&config, 4_000)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, true, true)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -234,10 +234,10 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_zk_config(); - let (proof, vd, cd) = dummy_lookup_proof::(&config, 10)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, true, true)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = dummy_lookup_proof::(&config, 10)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, true, true)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -250,10 +250,10 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let (proof, vd, cd) = dummy_two_luts_proof::(&config)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, true, true)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = dummy_two_luts_proof::(&config)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, true, true)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -266,10 +266,10 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let (proof, vd, cd) = dummy_too_many_rows_proof::(&config)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, true, true)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = dummy_too_many_rows_proof::(&config)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, true, true)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -284,20 +284,20 @@ mod tests { let config = CircuitConfig::standard_recursion_config(); // Start with a degree 2^14 proof - let (proof, vd, cd) = dummy_proof::(&config, 16_000)?; - assert_eq!(cd.degree_bits(), 14); + let (proof, vd, common_data) = dummy_proof::(&config, 16_000)?; + assert_eq!(common_data.degree_bits(), 14); // Shrink it to 2^13. - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, Some(13), false, false)?; - assert_eq!(cd.degree_bits(), 13); + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, Some(13), false, false)?; + assert_eq!(common_data.degree_bits(), 13); // Shrink it to 2^12. - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, true, true)?; - assert_eq!(cd.degree_bits(), 12); + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, true, true)?; + assert_eq!(common_data.degree_bits(), 12); - test_serialization(&proof, &vd, &cd)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -316,13 +316,20 @@ mod tests { let standard_config = CircuitConfig::standard_recursion_config(); // An initial dummy proof. - let (proof, vd, cd) = dummy_proof::(&standard_config, 4_000)?; - assert_eq!(cd.degree_bits(), 12); + let (proof, vd, common_data) = dummy_proof::(&standard_config, 4_000)?; + assert_eq!(common_data.degree_bits(), 12); // A standard recursive proof. - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &standard_config, None, false, false)?; - assert_eq!(cd.degree_bits(), 12); + let (proof, vd, common_data) = recursive_proof::( + proof, + vd, + common_data, + &standard_config, + None, + false, + false, + )?; + assert_eq!(common_data.degree_bits(), 12); // A high-rate recursive proof, designed to be verifiable with fewer routed wires. let high_rate_config = CircuitConfig { @@ -334,9 +341,16 @@ mod tests { }, ..standard_config }; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &high_rate_config, None, true, true)?; - assert_eq!(cd.degree_bits(), 12); + let (proof, vd, common_data) = recursive_proof::( + proof, + vd, + common_data, + &high_rate_config, + None, + true, + true, + )?; + assert_eq!(common_data.degree_bits(), 12); // A final proof, optimized for size. let final_config = CircuitConfig { @@ -350,11 +364,18 @@ mod tests { }, ..high_rate_config }; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &final_config, None, true, true)?; - assert_eq!(cd.degree_bits(), 12, "final proof too large"); + let (proof, vd, common_data) = recursive_proof::( + proof, + vd, + common_data, + &final_config, + None, + true, + true, + )?; + assert_eq!(common_data.degree_bits(), 12, "final proof too large"); - test_serialization(&proof, &vd, &cd)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -368,15 +389,15 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let (proof, vd, cd) = dummy_proof::(&config, 4_000)?; + let (proof, vd, common_data) = dummy_proof::(&config, 4_000)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, false, false)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, false, false)?; + test_serialization(&proof, &vd, &common_data)?; - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, false, false)?; - test_serialization(&proof, &vd, &cd)?; + let (proof, vd, common_data) = + recursive_proof::(proof, vd, common_data, &config, None, false, false)?; + test_serialization(&proof, &vd, &common_data)?; Ok(()) } @@ -662,18 +683,18 @@ mod tests { >( proof: &ProofWithPublicInputs, vd: &VerifierOnlyCircuitData, - cd: &CommonCircuitData, + common_data: &CommonCircuitData, ) -> Result<()> { let proof_bytes = proof.to_bytes(); info!("Proof length: {} bytes", proof_bytes.len()); - let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; + let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, common_data)?; assert_eq!(proof, &proof_from_bytes); let now = std::time::Instant::now(); - let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?; + let compressed_proof = proof.clone().compress(&vd.circuit_digest, common_data)?; let decompressed_compressed_proof = compressed_proof .clone() - .decompress(&vd.circuit_digest, cd)?; + .decompress(&vd.circuit_digest, common_data)?; info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); @@ -683,7 +704,7 @@ mod tests { compressed_proof_bytes.len() ); let compressed_proof_from_bytes = - CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, cd)?; + CompressedProofWithPublicInputs::from_bytes(compressed_proof_bytes, common_data)?; assert_eq!(compressed_proof, compressed_proof_from_bytes); Ok(()) diff --git a/plonky2/src/util/serialization/gate_serialization.rs b/plonky2/src/util/serialization/gate_serialization.rs index 2d9e3e30..008e29c0 100644 --- a/plonky2/src/util/serialization/gate_serialization.rs +++ b/plonky2/src/util/serialization/gate_serialization.rs @@ -2,21 +2,31 @@ use plonky2_field::extension::Extendable; use crate::gates::gate::GateRef; use crate::hash::hash_types::RichField; +use crate::plonk::circuit_data::CommonCircuitData; use crate::util::serialization::{Buffer, IoResult}; pub trait GateSerializer, const D: usize> { - fn read_gate(&self, buf: &mut Buffer) -> IoResult>; - fn write_gate(&self, buf: &mut Vec, gate: &GateRef) -> IoResult<()>; + fn read_gate( + &self, + buf: &mut Buffer, + common_data: &CommonCircuitData, + ) -> IoResult>; + fn write_gate( + &self, + buf: &mut Vec, + gate: &GateRef, + common_data: &CommonCircuitData, + ) -> IoResult<()>; } #[macro_export] macro_rules! read_gate_impl { - ($buf:expr, $tag:expr, $($gate_types:ty),+) => {{ + ($buf:expr, $tag:expr, $common:expr, $($gate_types:ty),+) => {{ let tag = $tag; let buf = $buf; let mut i = 0..; $(if tag == i.next().unwrap() { - let gate = <$gate_types as $crate::gates::gate::Gate>::deserialize(buf)?; + let gate = <$gate_types as $crate::gates::gate::Gate>::deserialize(buf, $common)?; Ok($crate::gates::gate::GateRef::::new(gate)) } else)* { @@ -47,16 +57,25 @@ macro_rules! get_gate_tag_impl { /// this as first argument, followed by all the targeted gates. macro_rules! impl_gate_serializer { ($target:ty, $($gate_types:ty),+) => { - fn read_gate(&self, buf: &mut $crate::util::serialization::Buffer) -> $crate::util::serialization::IoResult<$crate::gates::gate::GateRef> { + fn read_gate( + &self, + buf: &mut $crate::util::serialization::Buffer, + common: &$crate::plonk::circuit_data::CommonCircuitData, + ) -> $crate::util::serialization::IoResult<$crate::gates::gate::GateRef> { let tag = $crate::util::serialization::Read::read_u32(buf)?; - read_gate_impl!(buf, tag, $($gate_types),+) + read_gate_impl!(buf, tag, common, $($gate_types),+) } - fn write_gate(&self, buf: &mut Vec, gate: &$crate::gates::gate::GateRef) -> $crate::util::serialization::IoResult<()> { + fn write_gate( + &self, + buf: &mut Vec, + gate: &$crate::gates::gate::GateRef, + common: &$crate::plonk::circuit_data::CommonCircuitData, + ) -> $crate::util::serialization::IoResult<()> { let tag = get_gate_tag_impl!(gate, $($gate_types),+)?; $crate::util::serialization::Write::write_u32(buf, tag)?; - gate.0.serialize(buf)?; + gate.0.serialize(buf, common)?; Ok(()) } }; diff --git a/plonky2/src/util/serialization/generator_serialization.rs b/plonky2/src/util/serialization/generator_serialization.rs index cbc6d6ba..6e003400 100644 --- a/plonky2/src/util/serialization/generator_serialization.rs +++ b/plonky2/src/util/serialization/generator_serialization.rs @@ -11,12 +11,14 @@ pub trait WitnessGeneratorSerializer, const D: usiz fn read_generator( &self, buf: &mut Buffer, - common: &CommonCircuitData, - ) -> IoResult>; + common_data: &CommonCircuitData, + ) -> IoResult>; + fn write_generator( &self, buf: &mut Vec, - generator: &WitnessGeneratorRef, + generator: &WitnessGeneratorRef, + common_data: &CommonCircuitData, ) -> IoResult<()>; } @@ -27,19 +29,11 @@ macro_rules! read_generator_impl { let buf = $buf; let mut i = 0..; - if tag == 0 { - let generator: $crate::recursion::dummy_circuit::DummyProofGenerator = - $crate::recursion::dummy_circuit::DummyProofGenerator::deserialize_with_circuit_data(buf, $common)?; - return Ok($crate::iop::generator::WitnessGeneratorRef::::new( - $crate::iop::generator::SimpleGenerator::::adapter(generator), - )); - } - $(if tag == i.next().unwrap() { let generator = - <$generator_types as $crate::iop::generator::SimpleGenerator>::deserialize(buf)?; - Ok($crate::iop::generator::WitnessGeneratorRef::::new( - $crate::iop::generator::SimpleGenerator::::adapter(generator), + <$generator_types as $crate::iop::generator::SimpleGenerator>::deserialize(buf, $common)?; + Ok($crate::iop::generator::WitnessGeneratorRef::::new( + $crate::iop::generator::SimpleGenerator::::adapter(generator), )) } else)* { @@ -52,7 +46,7 @@ macro_rules! read_generator_impl { macro_rules! get_generator_tag_impl { ($generator:expr, $($generator_types:ty),+) => {{ let mut i = 0..; - $(if let (tag, true) = (i.next().unwrap(), $generator.0.id() == $crate::iop::generator::SimpleGenerator::::id(&<$generator_types>::default())) { + $(if let (tag, true) = (i.next().unwrap(), $generator.0.id() == $crate::iop::generator::SimpleGenerator::::id(&<$generator_types>::default())) { Ok(tag) } else)* { @@ -67,17 +61,13 @@ macro_rules! get_generator_tag_impl { /// To serialize a list of generators used for a circuit, /// this macro should be called with a struct on which to implement /// this as first argument, followed by all the targeted generators. -/// -/// ***NOTE:*** If you need to include `DummyProofGenerator`, you **MUST** -/// place it at the *beginning* of the generators list, right after -/// the serializer struct. macro_rules! impl_generator_serializer { ($target:ty, $($generator_types:ty),+) => { fn read_generator( &self, buf: &mut $crate::util::serialization::Buffer, common: &$crate::plonk::circuit_data::CommonCircuitData, - ) -> $crate::util::serialization::IoResult<$crate::iop::generator::WitnessGeneratorRef> { + ) -> $crate::util::serialization::IoResult<$crate::iop::generator::WitnessGeneratorRef> { let tag = $crate::util::serialization::Read::read_u32(buf)?; read_generator_impl!(buf, tag, common, $($generator_types),+) } @@ -85,12 +75,13 @@ macro_rules! impl_generator_serializer { fn write_generator( &self, buf: &mut Vec, - generator: &$crate::iop::generator::WitnessGeneratorRef, + generator: &$crate::iop::generator::WitnessGeneratorRef, + common: &$crate::plonk::circuit_data::CommonCircuitData, ) -> $crate::util::serialization::IoResult<()> { let tag = get_generator_tag_impl!(generator, $($generator_types),+)?; $crate::util::serialization::Write::write_u32(buf, tag)?; - generator.0.serialize(buf)?; + generator.0.serialize(buf, common)?; Ok(()) } }; @@ -139,13 +130,13 @@ pub mod default { { impl_generator_serializer! { DefaultGeneratorSerializer, - DummyProofGenerator, ArithmeticBaseGenerator, ArithmeticExtensionGenerator, BaseSplitGenerator<2>, BaseSumGenerator<2>, ConstantGenerator, CopyGenerator, + DummyProofGenerator, EqualityGenerator, ExponentiationGenerator, InterpolationGenerator, diff --git a/plonky2/src/util/serialization/mod.rs b/plonky2/src/util/serialization/mod.rs index 4324d715..2751ec69 100644 --- a/plonky2/src/util/serialization/mod.rs +++ b/plonky2/src/util/serialization/mod.rs @@ -684,13 +684,14 @@ pub trait Read { fn read_gate, const D: usize>( &mut self, gate_serializer: &dyn GateSerializer, + common_data: &CommonCircuitData, ) -> IoResult>; fn read_generator, const D: usize>( &mut self, generator_serializer: &dyn WitnessGeneratorSerializer, common_data: &CommonCircuitData, - ) -> IoResult>; + ) -> IoResult>; fn read_selectors_info(&mut self) -> IoResult { let selector_indices = self.read_usize_vec()?; @@ -743,13 +744,6 @@ pub trait Read { let config = self.read_circuit_config()?; let fri_params = self.read_fri_params()?; - let gates_len = self.read_usize()?; - let mut gates = Vec::with_capacity(gates_len); - for _ in 0..gates_len { - let gate = self.read_gate::(gate_serializer)?; - gates.push(gate); - } - let selectors_info = self.read_selectors_info()?; let quotient_degree_factor = self.read_usize()?; let num_gate_constraints = self.read_usize()?; @@ -770,10 +764,15 @@ pub trait Read { luts.push(Arc::new(self.read_lut()?)); } - Ok(CommonCircuitData { + let gates_len = self.read_usize()?; + let mut gates = Vec::with_capacity(gates_len); + + // We construct the common data without gates first, + // to pass it as argument when reading the gates. + let mut common_data = CommonCircuitData { config, fri_params, - gates, + gates: vec![], selectors_info, quotient_degree_factor, num_gate_constraints, @@ -784,7 +783,16 @@ pub trait Read { num_lookup_polys, num_lookup_selectors, luts, - }) + }; + + for _ in 0..gates_len { + let gate = self.read_gate::(gate_serializer, &common_data)?; + gates.push(gate); + } + + common_data.gates = gates; + + Ok(common_data) } fn read_circuit_data< @@ -813,12 +821,12 @@ pub trait Read { >( &mut self, generator_serializer: &dyn WitnessGeneratorSerializer, - cd: &CommonCircuitData, + common_data: &CommonCircuitData, ) -> IoResult> { let gen_len = self.read_usize()?; let mut generators = Vec::with_capacity(gen_len); for _ in 0..gen_len { - generators.push(self.read_generator(generator_serializer, cd)?); + generators.push(self.read_generator(generator_serializer, common_data)?); } let map_len = self.read_usize()?; let mut generator_indices_by_watches = BTreeMap::new(); @@ -1689,12 +1697,14 @@ pub trait Write { &mut self, gate: &GateRef, gate_serializer: &dyn GateSerializer, + common_data: &CommonCircuitData, ) -> IoResult<()>; fn write_generator, const D: usize>( &mut self, - generator: &WitnessGeneratorRef, + generator: &WitnessGeneratorRef, generator_serializer: &dyn WitnessGeneratorSerializer, + common_data: &CommonCircuitData, ) -> IoResult<()>; fn write_selectors_info(&mut self, selectors_info: &SelectorsInfo) -> IoResult<()> { @@ -1757,11 +1767,6 @@ pub trait Write { self.write_circuit_config(config)?; self.write_fri_params(fri_params)?; - self.write_usize(gates.len())?; - for gate in gates.iter() { - self.write_gate::(gate, gate_serializer)?; - } - self.write_selectors_info(selectors_info)?; self.write_usize(*quotient_degree_factor)?; self.write_usize(*num_gate_constraints)?; @@ -1780,6 +1785,11 @@ pub trait Write { self.write_lut(lut)?; } + self.write_usize(gates.len())?; + for gate in gates.iter() { + self.write_gate::(gate, gate_serializer, common_data)?; + } + Ok(()) } @@ -1794,7 +1804,11 @@ pub trait Write { generator_serializer: &dyn WitnessGeneratorSerializer, ) -> IoResult<()> { self.write_common_circuit_data(&circuit_data.common, gate_serializer)?; - self.write_prover_only_circuit_data(&circuit_data.prover_only, generator_serializer)?; + self.write_prover_only_circuit_data( + &circuit_data.prover_only, + generator_serializer, + &circuit_data.common, + )?; self.write_verifier_only_circuit_data(&circuit_data.verifier_only) } @@ -1806,6 +1820,7 @@ pub trait Write { &mut self, prover_only_circuit_data: &ProverOnlyCircuitData, generator_serializer: &dyn WitnessGeneratorSerializer, + common_data: &CommonCircuitData, ) -> IoResult<()> { let ProverOnlyCircuitData { generators, @@ -1823,7 +1838,7 @@ pub trait Write { self.write_usize(generators.len())?; for generator in generators.iter() { - self.write_generator::(generator, generator_serializer)?; + self.write_generator::(generator, generator_serializer, common_data)?; } self.write_usize(generator_indices_by_watches.len())?; @@ -1883,7 +1898,11 @@ pub trait Write { generator_serializer: &dyn WitnessGeneratorSerializer, ) -> IoResult<()> { self.write_common_circuit_data(&prover_circuit_data.common, gate_serializer)?; - self.write_prover_only_circuit_data(&prover_circuit_data.prover_only, generator_serializer) + self.write_prover_only_circuit_data( + &prover_circuit_data.prover_only, + generator_serializer, + &prover_circuit_data.common, + ) } fn write_verifier_only_circuit_data< @@ -2110,16 +2129,18 @@ impl Write for Vec { &mut self, gate: &GateRef, gate_serializer: &dyn GateSerializer, + common_data: &CommonCircuitData, ) -> IoResult<()> { - gate_serializer.write_gate(self, gate) + gate_serializer.write_gate(self, gate, common_data) } fn write_generator, const D: usize>( &mut self, - generator: &WitnessGeneratorRef, + generator: &WitnessGeneratorRef, generator_serializer: &dyn WitnessGeneratorSerializer, + common_data: &CommonCircuitData, ) -> IoResult<()> { - generator_serializer.write_generator(self, generator) + generator_serializer.write_generator(self, generator, common_data) } } @@ -2178,15 +2199,16 @@ impl<'a> Read for Buffer<'a> { fn read_gate, const D: usize>( &mut self, gate_serializer: &dyn GateSerializer, + common_data: &CommonCircuitData, ) -> IoResult> { - gate_serializer.read_gate(self) + gate_serializer.read_gate(self, common_data) } fn read_generator, const D: usize>( &mut self, generator_serializer: &dyn WitnessGeneratorSerializer, common_data: &CommonCircuitData, - ) -> IoResult> { + ) -> IoResult> { generator_serializer.read_generator(self, common_data) } }