diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 0156e9ec..3e238dd4 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -64,7 +64,7 @@ impl, const D: usize> Gate for ArithmeticGate dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index c42a72e4..352aeadf 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -60,7 +60,7 @@ impl, const D: usize> Gate for ArithmeticExte dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index 15cf4995..3e00940a 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -59,7 +59,7 @@ impl, const D: usize, const B: usize> Gate fo dst.write_usize(self.num_limbs) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_limbs = src.read_usize()?; Ok(Self { num_limbs }) } diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index d6be45a9..c759ee91 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,7 +47,7 @@ impl, const D: usize> Gate for ConstantGate { dst.write_usize(self.num_consts) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_consts = src.read_usize()?; Ok(Self { num_consts }) } diff --git a/plonky2/src/gates/coset_interpolation.rs b/plonky2/src/gates/coset_interpolation.rs index 8351834c..c5d6bfbf 100644 --- a/plonky2/src/gates/coset_interpolation.rs +++ b/plonky2/src/gates/coset_interpolation.rs @@ -176,7 +176,7 @@ impl, const D: usize> Gate for CosetInterpola dst.write_field_vec(&self.barycentric_weights) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let subgroup_bits = src.read_usize()?; let degree = src.read_usize()?; let length = src.read_usize()?; @@ -504,7 +504,7 @@ impl, const D: usize> SimpleGenerator fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = CosetInterpolationGate::deserialize(src)?; + let gate = CosetInterpolationGate::deserialize(src, _cd)?; Ok(Self::new(row, gate)) } } diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index a39a14df..7cb18f59 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -80,7 +80,7 @@ impl, const D: usize> Gate for Exponentiation dst.write_usize(self.num_power_bits) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_power_bits = src.read_usize()?; Ok(Self::new(num_power_bits)) } @@ -302,7 +302,7 @@ impl, const D: usize> SimpleGenerator fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = ExponentiationGate::deserialize(src)?; + let gate = ExponentiationGate::deserialize(src, _cd)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 78552588..71b1b64c 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, }; @@ -30,7 +31,7 @@ pub trait Gate, const D: usize>: 'static + Send + S fn serialize(&self, dst: &mut Vec) -> IoResult<()>; - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, cd: &CommonCircuitData) -> IoResult where Self: Sized; diff --git a/plonky2/src/gates/lookup.rs b/plonky2/src/gates/lookup.rs index 37b7087e..e7d24057 100644 --- a/plonky2/src/gates/lookup.rs +++ b/plonky2/src/gates/lookup.rs @@ -65,7 +65,7 @@ impl, const D: usize> Gate for LookupGate { dst.write_lut(&self.lut) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_slots = src.read_usize()?; let lut = src.read_lut()?; diff --git a/plonky2/src/gates/lookup_table.rs b/plonky2/src/gates/lookup_table.rs index b53d805c..706ce3e6 100644 --- a/plonky2/src/gates/lookup_table.rs +++ b/plonky2/src/gates/lookup_table.rs @@ -78,7 +78,7 @@ impl, const D: usize> Gate for LookupTableGat dst.write_usize(self.last_lut_row) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_slots = src.read_usize()?; let lut = src.read_lut()?; let last_lut_row = src.read_usize()?; diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 1a598cbe..ffed12f8 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -57,7 +57,7 @@ impl, const D: usize> Gate for MulExtensionGa dst.write_usize(self.num_ops) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let num_ops = src.read_usize()?; Ok(Self { num_ops }) } diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index 332dd3a8..7ce5e92f 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}; @@ -22,7 +23,7 @@ impl, const D: usize> Gate for NoopGate { Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { Ok(Self) } diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index 7b5fb6a3..4eba0eb9 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -104,7 +104,7 @@ impl, const D: usize> Gate for PoseidonGate IoResult { + fn deserialize(_src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { Ok(PoseidonGate::new()) } diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index 927b10fc..ae796e67 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -123,7 +123,7 @@ impl + Poseidon, const D: usize> Gate for Pos Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { Ok(PoseidonMdsGate::new()) } diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index 4d3f6982..0009d4ac 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, @@ -35,7 +36,7 @@ impl, const D: usize> Gate for PublicInputGat Ok(()) } - fn deserialize(_src: &mut Buffer) -> IoResult { + fn deserialize(_src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { Ok(Self) } diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 114ae5f4..e0aae2a7 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -129,7 +129,7 @@ impl, const D: usize> Gate for RandomAccessGa Ok(()) } - fn deserialize(src: &mut Buffer) -> IoResult { + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let bits = src.read_usize()?; let num_copies = src.read_usize()?; let num_extra_constants = src.read_usize()?; @@ -403,7 +403,7 @@ impl, const D: usize> SimpleGenerator fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; let copy = src.read_usize()?; - let gate = RandomAccessGate::::deserialize(src)?; + let gate = RandomAccessGate::::deserialize(src, _cd)?; Ok(Self { row, gate, copy }) } } diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index 1c196ede..b72bcc42 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -66,7 +66,7 @@ impl, const D: usize> Gate for ReducingGate IoResult + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult where Self: Sized, { @@ -233,7 +233,7 @@ impl, const D: usize> SimpleGenerator for Red fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = as Gate>::deserialize(src)?; + let gate = as Gate>::deserialize(src, _cd)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 2e35d54f..021188ea 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -69,7 +69,7 @@ impl, const D: usize> Gate for ReducingExtens Ok(()) } - fn deserialize(src: &mut Buffer) -> IoResult + fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult where Self: Sized, { @@ -227,7 +227,7 @@ impl, const D: usize> SimpleGenerator for Red fn deserialize(src: &mut Buffer, _cd: &CommonCircuitData) -> IoResult { let row = src.read_usize()?; - let gate = as Gate>::deserialize(src)?; + let gate = as Gate>::deserialize(src, _cd)?; Ok(Self { row, gate }) } } diff --git a/plonky2/src/util/serialization/gate_serialization.rs b/plonky2/src/util/serialization/gate_serialization.rs index 2d9e3e30..3313937f 100644 --- a/plonky2/src/util/serialization/gate_serialization.rs +++ b/plonky2/src/util/serialization/gate_serialization.rs @@ -2,21 +2,26 @@ 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 read_gate( + &self, + buf: &mut Buffer, + common: &CommonCircuitData, + ) -> IoResult>; fn write_gate(&self, buf: &mut Vec, gate: &GateRef) -> 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,9 +52,13 @@ 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<()> { diff --git a/plonky2/src/util/serialization/mod.rs b/plonky2/src/util/serialization/mod.rs index 88038da8..875929fa 100644 --- a/plonky2/src/util/serialization/mod.rs +++ b/plonky2/src/util/serialization/mod.rs @@ -684,6 +684,7 @@ 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>( @@ -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 cd = 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, &cd)?; + gates.push(gate); + } + + cd.gates = gates; + + Ok(cd) } fn read_circuit_data< @@ -1757,11 +1765,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 +1783,11 @@ pub trait Write { self.write_lut(lut)?; } + self.write_usize(gates.len())?; + for gate in gates.iter() { + self.write_gate::(gate, gate_serializer)?; + } + Ok(()) } @@ -2178,8 +2186,9 @@ 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>(