diff --git a/air/src/lib.rs b/air/src/lib.rs index d954eef7fa..c561f5251d 100644 --- a/air/src/lib.rs +++ b/air/src/lib.rs @@ -5,7 +5,9 @@ extern crate alloc; use vm_core::{ - utils::{collections::Vec, string::String, ByteWriter, Serializable}, + utils::{ + collections::Vec, string::String, ByteReader, ByteWriter, Deserializable, Serializable, + }, ExtensionOf, ProgramInfo, StackInputs, StackOutputs, ONE, ZERO, }; use winter_air::{ @@ -271,6 +273,18 @@ impl PublicInputs { } } +impl vm_core::ToElements for PublicInputs { + fn to_elements(&self) -> Vec { + let mut result = self.program_info.to_elements(); + result.append(&mut self.stack_inputs.to_elements()); + result.append(&mut self.stack_outputs.to_elements()); + result + } +} + +// SERIALIZATION +// ================================================================================================ + impl Serializable for PublicInputs { fn write_into(&self, target: &mut W) { self.program_info.write_into(target); @@ -279,11 +293,16 @@ impl Serializable for PublicInputs { } } -impl vm_core::ToElements for PublicInputs { - fn to_elements(&self) -> Vec { - let mut result = self.program_info.to_elements(); - result.append(&mut self.stack_inputs.to_elements()); - result.append(&mut self.stack_outputs.to_elements()); - result +impl Deserializable for PublicInputs { + fn read_from(source: &mut R) -> Result { + let program_info = ProgramInfo::read_from(source)?; + let stack_inputs = StackInputs::read_from(source)?; + let stack_outputs = StackOutputs::read_from(source)?; + + Ok(PublicInputs { + program_info, + stack_inputs, + stack_outputs, + }) } } diff --git a/air/src/proof.rs b/air/src/proof.rs index 7f83908a51..4fd4fc5a30 100644 --- a/air/src/proof.rs +++ b/air/src/proof.rs @@ -1,7 +1,7 @@ use super::DeserializationError; use vm_core::{ crypto::hash::{Blake3_192, Blake3_256, Hasher, Rpo256}, - utils::collections::Vec, + utils::{collections::Vec, ByteReader, ByteWriter, Deserializable, Serializable}, }; use winter_air::proof::StarkProof; @@ -127,3 +127,34 @@ impl TryFrom for HashFunction { } } } + +// SERIALIZATION +// ================================================================================================ + +impl Serializable for HashFunction { + fn write_into(&self, target: &mut W) { + target.write_u8(*self as u8); + } +} + +impl Deserializable for HashFunction { + fn read_from(source: &mut R) -> Result { + source.read_u8()?.try_into() + } +} + +impl Serializable for ExecutionProof { + fn write_into(&self, target: &mut W) { + self.proof.write_into(target); + self.hash_fn.write_into(target); + } +} + +impl Deserializable for ExecutionProof { + fn read_from(source: &mut R) -> Result { + let proof = StarkProof::read_from(source)?; + let hash_fn = HashFunction::read_from(source)?; + + Ok(ExecutionProof { proof, hash_fn }) + } +} diff --git a/core/src/stack/inputs.rs b/core/src/stack/inputs.rs index 4e8c6520e7..84ac9a5895 100644 --- a/core/src/stack/inputs.rs +++ b/core/src/stack/inputs.rs @@ -1,3 +1,5 @@ +use winter_utils::{ByteReader, Deserializable, DeserializationError}; + use super::{vec, ByteWriter, Felt, InputError, Serializable, ToElements, Vec}; use core::slice; @@ -60,6 +62,15 @@ impl IntoIterator for StackInputs { } } +impl ToElements for StackInputs { + fn to_elements(&self) -> Vec { + self.values.to_vec() + } +} + +// SERIALIZATION +// ================================================================================================ + impl Serializable for StackInputs { fn write_into(&self, target: &mut W) { // TODO the length of the stack, by design, will not be greater than `u32::MAX`. however, @@ -68,12 +79,18 @@ impl Serializable for StackInputs { debug_assert!(self.values.len() <= u32::MAX as usize); target.write_u32(self.values.len() as u32); - self.values.iter().copied().for_each(|v| target.write(v)); + self.values.write_into(target); } } -impl ToElements for StackInputs { - fn to_elements(&self) -> Vec { - self.values.to_vec() +impl Deserializable for StackInputs { + fn read_from(source: &mut R) -> Result { + let count = source.read_u32()?; + + let mut values = Vec::with_capacity(count as usize); + for _ in 0..count { + values.push(Felt::read_from(source)?); + } + Ok(StackInputs { values }) } } diff --git a/core/src/stack/outputs.rs b/core/src/stack/outputs.rs index 1e391dec41..70625eb332 100644 --- a/core/src/stack/outputs.rs +++ b/core/src/stack/outputs.rs @@ -1,4 +1,5 @@ use miden_crypto::Word; +use winter_utils::{ByteReader, Deserializable, DeserializationError}; use crate::utils::range; @@ -192,6 +193,23 @@ fn find_invalid_elements(outputs: &[u64]) -> Option { None } +impl ToElements for StackOutputs { + fn to_elements(&self) -> Vec { + // infallible conversion from u64 to Felt is OK here because we check validity of u64 + // values in the constructor + // TODO: change internal data types of self.stack and self.overflow_addrs to Felt? + self.stack + .iter() + .chain(self.overflow_addrs.iter()) + .cloned() + .map(Felt::new) + .collect() + } +} + +// SERIALIZATION +// ================================================================================================ + impl Serializable for StackOutputs { fn write_into(&self, target: &mut W) { // TODO the length of the stack, by design, will not be greater than `u32::MAX`. however, @@ -201,25 +219,32 @@ impl Serializable for StackOutputs { // stack debug_assert!(self.stack.len() <= u32::MAX as usize); target.write_u32(self.stack.len() as u32); - self.stack.iter().copied().for_each(|v| target.write_u64(v)); + self.stack.write_into(target); // overflow addrs debug_assert!(self.overflow_addrs.len() <= u32::MAX as usize); target.write_u32(self.overflow_addrs.len() as u32); - self.overflow_addrs.iter().copied().for_each(|v| target.write_u64(v)); + self.overflow_addrs.write_into(target); } } -impl ToElements for StackOutputs { - fn to_elements(&self) -> Vec { - // infallible conversion from u64 to Felt is OK here because we check validity of u64 - // values in the constructor - // TODO: change internal data types of self.stack and self.overflow_addrs to Felt? - self.stack - .iter() - .chain(self.overflow_addrs.iter()) - .cloned() - .map(Felt::new) - .collect() +impl Deserializable for StackOutputs { + fn read_from(source: &mut R) -> Result { + let count = source.read_u32()?; + let mut stack = Vec::with_capacity(count as usize); + for _ in 0..count { + stack.push(source.read_u64()?); + } + + let count = source.read_u32()?; + let mut overflow_addrs = Vec::with_capacity(count as usize); + for _ in 0..count { + overflow_addrs.push(source.read_u64()?); + } + + Ok(Self { + stack, + overflow_addrs, + }) } }