add to and from json string methods for serialized circuit in build command

This commit is contained in:
collin 2020-08-08 22:11:36 -07:00
parent e7851d98d0
commit 0a35babdf6

View File

@ -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<E: PairingEngine, W: Write>(assembly: KeypairAssembly<E>, writer: &mut W) {
let fr_size = <<E as PairingEngine>::Fr as ConstantSerializedSize>::SERIALIZED_SIZE;
let index_size = <Index as ConstantSerializedSize>::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<E: PairingEngine, R: Read>(reader: &mut R) -> KeypairAssembly<E> {
let fr_size = <<E as PairingEngine>::Fr as ConstantSerializedSize>::SERIALIZED_SIZE;
let index_size = <Index as ConstantSerializedSize>::SERIALIZED_SIZE;
let tuple_size = fr_size + index_size;
println!("tuple size {}", tuple_size);
let num_inputs = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let num_aux = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let num_constraints = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let mut assembly = KeypairAssembly::<E> {
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 = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let mut a_lc = vec![];
for _ in 0..a_len {
let fr = <<E as PairingEngine>::Fr as CanonicalDeserialize>::deserialize(reader).unwrap();
let index = <Index as CanonicalDeserialize>::deserialize(reader).unwrap();
let tuple = (fr, index);
a_lc.push(tuple);
}
assembly.at.push(a_lc);
// deserialize each bt[i] vector
let b_len = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let mut b_lc = vec![];
for _ in 0..b_len {
let fr = <<E as PairingEngine>::Fr as CanonicalDeserialize>::deserialize(reader).unwrap();
let index = <Index as CanonicalDeserialize>::deserialize(reader).unwrap();
let tuple = (fr, index);
b_lc.push(tuple);
}
assembly.at.push(b_lc);
// deserialize each ct[i] vector
let c_len = <u8 as CanonicalDeserialize>::deserialize(reader).unwrap() as usize;
let mut c_lc = vec![];
for _ in 0..c_len {
let fr = <<E as PairingEngine>::Fr as CanonicalDeserialize>::deserialize(reader).unwrap();
let index = <Index as CanonicalDeserialize>::deserialize(reader).unwrap();
let tuple = (fr, index);
c_lc.push(tuple);
}
assembly.at.push(c_lc);
}
assembly
}
let mut cs = KeypairAssembly::<Bls12_377> {
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);
<KeypairAssembly<Bls12_377> 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 =
<KeypairAssembly<Bls12_377> as CanonicalDeserialize>::deserialize(&mut &serialized[..]).unwrap();
// let _deserialized = deserialize_circuit::<Bls12_377, _>(&mut &serialized[..]);
let deserialized = deserialize_circuit::<Bls12_377, _>(&mut &serialized[..]);
println!("deserialized {:?}", deserialized.num_constraints);
// println!("{}", std::mem::size_of::<snarkos_curves::bls12_377::Fq>());
// println!("{}", std::mem::size_of::<snarkos_curves::edwards_bls12::Fq>());
// println!("{}", <snarkos_models::gadgets::r1cs::Index as ConstantSerializedSize>::SERIALIZED_SIZE);
// println!("{}", <snarkos_curves::edwards_bls12::Fq as ConstantSerializedSize>::SERIALIZED_SIZE);
// println!("{}", std::mem::size_of::<snarkos_models::gadgets::r1cs::Index>());
// 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<Vec<(SerializedField, SerializedIndex)>>,
pub bt: Vec<Vec<(SerializedField, SerializedIndex)>>,
pub ct: Vec<Vec<(SerializedField, SerializedIndex)>>,
}
impl SerializedKeypairAssembly {
pub fn to_json_string(&self) -> Result<String, serde_json::Error> {
Ok(serde_json::to_string_pretty(&self)?)
}
pub fn from_json_string(json: &str) -> Result<Self, serde_json::Error> {
serde_json::from_str(json)
}
}
impl<E: PairingEngine> From<KeypairAssembly<E>> for SerializedKeypairAssembly {
fn from(assembly: KeypairAssembly<E>) -> 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<u8>);
impl<E: PairingEngine> From<&<E as PairingEngine>::Fr> for SerializedField {
fn from(field: &<E as PairingEngine>::Fr) -> Self {
let mut writer = Vec::new();
<<E as PairingEngine>::Fr as CanonicalSerialize>::serialize(field, &mut writer).unwrap();
Self(writer)
}
}
#[derive(Serialize, Deserialize)]
pub enum SerializedIndex {
Input(usize),
Aux(usize),
}
impl From<Index> for SerializedIndex {
fn from(index: Index) -> Self {
match index {
Index::Input(idx) => Self::Input(idx),
Index::Aux(idx) => Self::Aux(idx),
}
}
}