From addca1fefa32e3ef1a85b1e52e0253b94ccc0e3f Mon Sep 17 00:00:00 2001 From: "Augusto F. Hack" Date: Thu, 30 Nov 2023 21:01:59 +0100 Subject: [PATCH] StarkProof impl Serializable/Deserializable --- air/src/options.rs | 8 ++++ air/src/proof/commitments.rs | 8 ++++ air/src/proof/context.rs | 3 ++ air/src/proof/mod.rs | 89 +++++++++++++++++++----------------- air/src/proof/ood_frame.rs | 8 ++++ air/src/proof/queries.rs | 8 ++++ utils/core/src/serde/mod.rs | 48 +++++++++++++++++++ 7 files changed, 129 insertions(+), 43 deletions(-) diff --git a/air/src/options.rs b/air/src/options.rs index 75f4674d0..a34f8939b 100644 --- a/air/src/options.rs +++ b/air/src/options.rs @@ -272,11 +272,19 @@ impl FieldExtension { } } +// SERIALIZATION +// ================================================================================================ + impl Serializable for FieldExtension { /// Serializes `self` and writes the resulting bytes into the `target`. fn write_into(&self, target: &mut W) { target.write_u8(*self as u8); } + + /// Returns an estimate of how many bytes are needed to represent self. + fn get_size_hint(&self) -> usize { + 1 + } } impl Deserializable for FieldExtension { diff --git a/air/src/proof/commitments.rs b/air/src/proof/commitments.rs index 94122bd6f..780389e68 100644 --- a/air/src/proof/commitments.rs +++ b/air/src/proof/commitments.rs @@ -86,6 +86,9 @@ impl Commitments { } } +// SERIALIZATION +// ================================================================================================ + impl Serializable for Commitments { /// Serializes `self` and writes the resulting bytes into the `target`. fn write_into(&self, target: &mut W) { @@ -93,6 +96,11 @@ impl Serializable for Commitments { target.write_u16(self.0.len() as u16); target.write_bytes(&self.0); } + + /// Returns an estimate of how many bytes are needed to represent self. + fn get_size_hint(&self) -> usize { + self.0.len() + 2 + } } impl Deserializable for Commitments { diff --git a/air/src/proof/context.rs b/air/src/proof/context.rs index 3098e4957..549e3b2a9 100644 --- a/air/src/proof/context.rs +++ b/air/src/proof/context.rs @@ -132,6 +132,9 @@ impl ToElements for Context { } } +// SERIALIZATION +// ================================================================================================ + impl Serializable for Context { /// Serializes `self` and writes the resulting bytes into the `target`. fn write_into(&self, target: &mut W) { diff --git a/air/src/proof/mod.rs b/air/src/proof/mod.rs index 2c8d97e1f..01c4d2f09 100644 --- a/air/src/proof/mod.rs +++ b/air/src/proof/mod.rs @@ -129,16 +129,7 @@ impl StarkProof { /// Serializes this proof into a vector of bytes. pub fn to_bytes(&self) -> Vec { - let mut result = Vec::new(); - self.context.write_into(&mut result); - result.push(self.num_unique_queries); - self.commitments.write_into(&mut result); - self.trace_queries.write_into(&mut result); - self.constraint_queries.write_into(&mut result); - self.ood_frame.write_into(&mut result); - self.fri_proof.write_into(&mut result); - result.extend_from_slice(&self.pow_nonce.to_le_bytes()); - result + Serializable::to_bytes(self) } /// Returns a STARK proof read from the specified `source`. @@ -146,39 +137,7 @@ impl StarkProof { /// # Errors /// Returns an error of a valid STARK proof could not be read from the specified `source`. pub fn from_bytes(source: &[u8]) -> Result { - let mut source = SliceReader::new(source); - - // parse the context - let context = Context::read_from(&mut source)?; - - // parse the number of unique queries made by the verifier - let num_unique_queries = source.read_u8()?; - - // parse the commitments - let commitments = Commitments::read_from(&mut source)?; - - // parse trace queries - let num_trace_segments = context.trace_layout().num_segments(); - let mut trace_queries = Vec::with_capacity(num_trace_segments); - for _ in 0..num_trace_segments { - trace_queries.push(Queries::read_from(&mut source)?); - } - - // parse the rest of the proof - let proof = StarkProof { - context, - num_unique_queries, - commitments, - trace_queries, - constraint_queries: Queries::read_from(&mut source)?, - ood_frame: OodFrame::read_from(&mut source)?, - fri_proof: FriProof::read_from(&mut source)?, - pow_nonce: source.read_u64()?, - }; - if source.has_more_bytes() { - return Err(DeserializationError::UnconsumedBytes); - } - Ok(proof) + Deserializable::read_from_bytes(source) } /// Creates a dummy `StarkProof` for use in tests. @@ -211,6 +170,50 @@ impl StarkProof { } } +// SERIALIZATION +// ================================================================================================ + +impl Serializable for StarkProof { + fn write_into(&self, target: &mut W) { + self.context.write_into(target); + target.write_u8(self.num_unique_queries); + self.commitments.write_into(target); + self.trace_queries.write_into(target); + self.constraint_queries.write_into(target); + self.ood_frame.write_into(target); + self.fri_proof.write_into(target); + self.pow_nonce.write_into(target) + } +} + +impl Deserializable for StarkProof { + fn read_from(source: &mut R) -> Result { + let context = Context::read_from(source)?; + let num_unique_queries = source.read_u8()?; + let commitments = Commitments::read_from(source)?; + let num_trace_segments = context.trace_layout().num_segments(); + let mut trace_queries = Vec::with_capacity(num_trace_segments); + for _ in 0..num_trace_segments { + trace_queries.push(Queries::read_from(source)?); + } + + let proof = StarkProof { + context, + num_unique_queries, + commitments, + trace_queries, + constraint_queries: Queries::read_from(source)?, + ood_frame: OodFrame::read_from(source)?, + fri_proof: FriProof::read_from(source)?, + pow_nonce: source.read_u64()?, + }; + if source.has_more_bytes() { + return Err(DeserializationError::UnconsumedBytes); + } + Ok(proof) + } +} + // HELPER FUNCTIONS // ================================================================================================ diff --git a/air/src/proof/ood_frame.rs b/air/src/proof/ood_frame.rs index 2bd7fa034..24629bbd5 100644 --- a/air/src/proof/ood_frame.rs +++ b/air/src/proof/ood_frame.rs @@ -119,6 +119,9 @@ impl OodFrame { } } +// SERIALIZATION +// ================================================================================================ + impl Serializable for OodFrame { /// Serializes `self` and writes the resulting bytes into the `target`. fn write_into(&self, target: &mut W) { @@ -130,6 +133,11 @@ impl Serializable for OodFrame { target.write_u16(self.evaluations.len() as u16); target.write_bytes(&self.evaluations) } + + /// Returns an estimate of how many bytes are needed to represent self. + fn get_size_hint(&self) -> usize { + self.trace_states.len() + self.evaluations.len() + 4 + } } impl Deserializable for OodFrame { diff --git a/air/src/proof/queries.rs b/air/src/proof/queries.rs index 4d76ad193..57acd88c1 100644 --- a/air/src/proof/queries.rs +++ b/air/src/proof/queries.rs @@ -128,6 +128,9 @@ impl Queries { } } +// SERIALIZATION +// ================================================================================================ + impl Serializable for Queries { /// Serializes `self` and writes the resulting bytes into the `target`. fn write_into(&self, target: &mut W) { @@ -139,6 +142,11 @@ impl Serializable for Queries { target.write_u32(self.paths.len() as u32); target.write_bytes(&self.paths); } + + /// Returns an estimate of how many bytes are needed to represent self. + fn get_size_hint(&self) -> usize { + self.paths.len() + self.values.len() + 8 + } } impl Deserializable for Queries { diff --git a/utils/core/src/serde/mod.rs b/utils/core/src/serde/mod.rs index ac912709a..de5a39672 100644 --- a/utils/core/src/serde/mod.rs +++ b/utils/core/src/serde/mod.rs @@ -53,6 +53,54 @@ impl Serializable for () { fn write_into(&self, _target: &mut W) {} } +impl Serializable for u8 { + fn write_into(&self, target: &mut W) { + target.write_u8(*self); + } +} + +impl Serializable for u16 { + fn write_into(&self, target: &mut W) { + target.write_u16(*self); + } +} + +impl Serializable for u32 { + fn write_into(&self, target: &mut W) { + target.write_u32(*self); + } +} + +impl Serializable for u64 { + fn write_into(&self, target: &mut W) { + target.write_u64(*self); + } +} + +impl Serializable for Option { + fn write_into(&self, target: &mut W) { + match self { + Some(v) => { + target.write_bool(true); + v.write_into(target); + } + None => target.write_bool(false), + } + } +} + +impl Serializable for &Option { + fn write_into(&self, target: &mut W) { + match self { + Some(v) => { + target.write_bool(true); + v.write_into(target); + } + None => target.write_bool(false), + } + } +} + impl Serializable for Vec { fn write_into(&self, target: &mut W) { T::write_batch_into(self, target);