diff --git a/leo/commands/build.rs b/leo/commands/build.rs index 38916d0e63..ba375a3843 100644 --- a/leo/commands/build.rs +++ b/leo/commands/build.rs @@ -13,6 +13,7 @@ use snarkos_models::{ curves::PairingEngine, gadgets::r1cs::{ConstraintSystem, Index}, }; +use snarkos_utilities::serialize::*; use clap::ArgMatches; use std::{convert::TryFrom, env::current_dir}; @@ -101,146 +102,6 @@ impl CLI for BuildCommand { // Generate the program on the constraint system and verify correctness { - use snarkos_utilities::serialize::*; - fn serialize_circuit(assembly: KeypairAssembly, writer: &mut W) { - let fr_size = <::Fr as ConstantSerializedSize>::SERIALIZED_SIZE; - let index_size = ::SERIALIZED_SIZE; - let tuple_size = fr_size + index_size; - println!("tuple size {}", tuple_size); - - let mut total_size_bytes = 0; - - let num_inputs = assembly.num_inputs; - CanonicalSerialize::serialize(&(num_inputs as u8), writer).unwrap(); - total_size_bytes += 1; - - let num_aux = assembly.num_aux; - CanonicalSerialize::serialize(&(num_aux as u8), writer).unwrap(); - total_size_bytes += 1; - - let num_constraints = assembly.num_constraints; - CanonicalSerialize::serialize(&(num_constraints as u8), writer).unwrap(); - total_size_bytes += 1; - - // println!("{}", assembly.num_constraints); - // serialize each constraint - for i in 0..num_constraints { - // Serialize the at[i] vector of tuples Vec<(Fr, Index)> - - let a_len = assembly.at[i].len(); - CanonicalSerialize::serialize(&(a_len as u8), writer).unwrap(); - - total_size_bytes += 1; - total_size_bytes += a_len * tuple_size; - - for &(ref coeff, index) in assembly.at[i].iter() { - // println!("a({:?}, {:?})", coeff, index); - CanonicalSerialize::serialize(coeff, writer).unwrap(); - CanonicalSerialize::serialize(&index, writer).unwrap(); - } - - // Serialize the bt[i] vector of tuples Vec<(Fr, Index)> - - let b_len = assembly.bt[i].len(); - CanonicalSerialize::serialize(&(b_len as u8), writer).unwrap(); - - total_size_bytes += 1; - total_size_bytes += b_len * tuple_size; - - for &(ref coeff, index) in assembly.bt[i].iter() { - // println!("b({:?}, {:?})", coeff, index); - CanonicalSerialize::serialize(coeff, writer).unwrap(); - CanonicalSerialize::serialize(&index, writer).unwrap(); - } - - // Serialize the ct[i] vector of tuples Vec<(Fr, Index)> - - let c_len = assembly.ct[i].len(); - CanonicalSerialize::serialize(&(c_len as u8), writer).unwrap(); - - total_size_bytes += 1; - total_size_bytes += c_len * tuple_size; - - for &(ref coeff, index) in assembly.ct[i].iter() { - // println!("c({:?}, {:?})", coeff, index); - CanonicalSerialize::serialize(coeff, writer).unwrap(); - CanonicalSerialize::serialize(&index, writer).unwrap(); - } - } - - println!("expected size bytes {:?}", total_size_bytes); - // println!("actual size bytes {:?}", writer.len()); - } - - fn deserialize_circuit(reader: &mut R) -> KeypairAssembly { - let fr_size = <::Fr as ConstantSerializedSize>::SERIALIZED_SIZE; - let index_size = ::SERIALIZED_SIZE; - let tuple_size = fr_size + index_size; - println!("tuple size {}", tuple_size); - - let num_inputs = ::deserialize(reader).unwrap() as usize; - let num_aux = ::deserialize(reader).unwrap() as usize; - let num_constraints = ::deserialize(reader).unwrap() as usize; - - let mut assembly = KeypairAssembly:: { - num_inputs, - num_aux, - num_constraints, - at: vec![], - bt: vec![], - ct: vec![], - }; - - for _ in 0..num_constraints { - // deserialize each at[i] vector - - let a_len = ::deserialize(reader).unwrap() as usize; - let mut a_lc = vec![]; - - for _ in 0..a_len { - let fr = <::Fr as CanonicalDeserialize>::deserialize(reader).unwrap(); - let index = ::deserialize(reader).unwrap(); - let tuple = (fr, index); - - a_lc.push(tuple); - } - - assembly.at.push(a_lc); - - // deserialize each bt[i] vector - - let b_len = ::deserialize(reader).unwrap() as usize; - let mut b_lc = vec![]; - - for _ in 0..b_len { - let fr = <::Fr as CanonicalDeserialize>::deserialize(reader).unwrap(); - let index = ::deserialize(reader).unwrap(); - let tuple = (fr, index); - - b_lc.push(tuple); - } - - assembly.at.push(b_lc); - - // deserialize each ct[i] vector - - let c_len = ::deserialize(reader).unwrap() as usize; - let mut c_lc = vec![]; - - for _ in 0..c_len { - let fr = <::Fr as CanonicalDeserialize>::deserialize(reader).unwrap(); - let index = ::deserialize(reader).unwrap(); - let tuple = (fr, index); - - c_lc.push(tuple); - } - - assembly.at.push(c_lc); - } - - assembly - } - let mut cs = KeypairAssembly:: { num_inputs: 0, num_aux: 0, @@ -256,28 +117,21 @@ impl CLI for BuildCommand { // Serialize circuit let mut writer = Vec::new(); - serialize_circuit(cs, &mut writer); + as CanonicalSerialize>::serialize(&cs, &mut writer).unwrap(); + // serialize_circuit(cs, &mut writer); println!("actual size bytes {:?}", writer.len()); // Write serialized circuit to circuit `.bytes` file. let circuit_file = CircuitFile::new(&package_name); circuit_file.write_to(&path, &writer[..])?; - // Read serialized circuit file + // Check that we can read the serialized circuit file let serialized = circuit_file.read_from(&package_path)?; - let same = writer == serialized; - println!("same {}", same); + let _deserialized = + as CanonicalDeserialize>::deserialize(&mut &serialized[..]).unwrap(); + // let _deserialized = deserialize_circuit::(&mut &serialized[..]); - let deserialized = deserialize_circuit::(&mut &serialized[..]); - - println!("deserialized {:?}", deserialized.num_constraints); - - // println!("{}", std::mem::size_of::()); - // println!("{}", std::mem::size_of::()); - // println!("{}", ::SERIALIZED_SIZE); - // println!("{}", ::SERIALIZED_SIZE); - - // println!("{}", std::mem::size_of::()); + // println!("deserialized {:?}", deserialized); } // If a checksum file exists, check if it differs from the new checksum @@ -308,3 +162,78 @@ impl CLI for BuildCommand { Ok(None) } } +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct SerializedKeypairAssembly { + pub num_inputs: usize, + pub num_aux: usize, + pub num_constraints: usize, + pub at: Vec>, + pub bt: Vec>, + pub ct: Vec>, +} + +impl SerializedKeypairAssembly { + pub fn to_json_string(&self) -> Result { + Ok(serde_json::to_string_pretty(&self)?) + } + + pub fn from_json_string(json: &str) -> Result { + serde_json::from_str(json) + } +} + +impl From> for SerializedKeypairAssembly { + fn from(assembly: KeypairAssembly) -> Self { + let mut result = Self { + num_inputs: assembly.num_inputs, + num_aux: assembly.num_aux, + num_constraints: assembly.num_constraints, + at: vec![], + bt: vec![], + ct: vec![], + }; + + for i in 0..assembly.num_constraints { + let mut a_vec = vec![]; + for &(ref coeff, index) in assembly.at[i].iter() { + let field = SerializedField::from(coeff); + let index = SerializedIndex::from(index); + + a_vec.push((field, index)) + } + result.at.push(a_vec); + } + + result + } +} + +#[derive(Serialize, Deserialize)] +pub struct SerializedField(pub Vec); + +impl From<&::Fr> for SerializedField { + fn from(field: &::Fr) -> Self { + let mut writer = Vec::new(); + + <::Fr as CanonicalSerialize>::serialize(field, &mut writer).unwrap(); + + Self(writer) + } +} + +#[derive(Serialize, Deserialize)] +pub enum SerializedIndex { + Input(usize), + Aux(usize), +} + +impl From for SerializedIndex { + fn from(index: Index) -> Self { + match index { + Index::Input(idx) => Self::Input(idx), + Index::Aux(idx) => Self::Aux(idx), + } + } +}