From 945b23bf706210fdf92fe955b53b8b10593642ab Mon Sep 17 00:00:00 2001 From: kilic Date: Thu, 4 Jun 2020 20:55:45 +0300 Subject: [PATCH] add input serialization --- src/circuit/rln.rs | 123 +++++++++++++++++++++++++++++++++++++++++++-- src/merkle.rs | 15 +++++- 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/src/circuit/rln.rs b/src/circuit/rln.rs index 2babf9f..d864976 100644 --- a/src/circuit/rln.rs +++ b/src/circuit/rln.rs @@ -1,11 +1,14 @@ use crate::circuit::polynomial::allocate_add_with_coeff; use crate::circuit::poseidon::PoseidonCircuit; use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams}; +use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use sapling_crypto::bellman::pairing::Engine; use sapling_crypto::bellman::{Circuit, ConstraintSystem, SynthesisError, Variable}; use sapling_crypto::circuit::{boolean, ecc, num, Assignment}; use sapling_crypto::jubjub::{JubjubEngine, JubjubParams, PrimeOrder}; +use std::io::{self, Read, Write}; + // Rate Limit Nullifier #[derive(Clone)] @@ -46,7 +49,7 @@ impl RLNInputs where E: Engine, { - fn public_inputs(self) -> Vec { + fn public_inputs(&self) -> Vec { vec![ self.root.unwrap(), self.epoch.unwrap(), @@ -55,6 +58,82 @@ where self.nullifier.unwrap(), ] } + + pub fn merkle_depth(&self) -> usize { + self.auth_path.len() + } + + pub fn empty(merkle_depth: usize) -> RLNInputs { + RLNInputs:: { + share_x: None, + share_y: None, + epoch: None, + nullifier: None, + root: None, + id_key: None, + auth_path: vec![None; merkle_depth], + } + } + + pub fn read(mut reader: R) -> io::Result> { + let mut buf = ::Repr::default(); + buf.read_le(&mut reader)?; + let share_x = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let share_y = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let epoch = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let nullifier = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let root = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let id_key = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + let mut byte_buf = vec![0u8; 1]; + let mut auth_path: Vec> = vec![]; + loop { + match reader.read_exact(&mut byte_buf) { + Ok(_) => match byte_buf[0] { + 0u8 => auth_path.push(Some((E::Fr::zero(), false))), + 1u8 => auth_path.push(Some((E::Fr::one(), true))), + _ => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "auth path element should be 1 or 0", + )) + } + }, + Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => { + break; + } + Err(err) => return Err(err), + }; + } + Ok(RLNInputs { + share_x: Some(share_x), + share_y: Some(share_y), + epoch: Some(epoch), + nullifier: Some(nullifier), + root: Some(root), + id_key: Some(id_key), + auth_path, + }) + } + + pub fn read_public_inputs(mut reader: R) -> io::Result> { + let mut buf = ::Repr::default(); + buf.read_le(&mut reader)?; + let root = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let epoch = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let share_x = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let share_y = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + buf.read_le(&mut reader)?; + let nullifier = E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + Ok(vec![root, epoch, share_x, share_y, nullifier]) + } } #[derive(Clone)] @@ -204,9 +283,10 @@ mod test { use crate::merkle::MerkleTree; use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams}; use rand::{Rand, SeedableRng, XorShiftRng}; - use sapling_crypto::bellman::groth16::{ - create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, - }; + // use sapling_crypto::bellman::groth16::{ + // create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, Parameters, + // }; + use sapling_crypto::bellman::groth16::*; use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use sapling_crypto::bellman::pairing::Engine; use sapling_crypto::bellman::Circuit; @@ -349,7 +429,11 @@ mod test { key_size += parameters.b_g1.len() * point_size; key_size += parameters.b_g2.len() * point_size * 2; + let mut v = vec![]; + parameters.write(&mut v).unwrap(); + println!("prover key size in bytes: {}", key_size); + println!("prover key size in bytes2: {}", v.len()); let now = Instant::now(); let proof = create_random_proof(circuit, ¶meters, &mut rng).unwrap(); @@ -376,4 +460,35 @@ mod test { let rln_test = RLNTest::new(poseidon_params, 32); rln_test.run(); } + + #[test] + fn test_input_serialization() { + use sapling_crypto::bellman::pairing::bn256::{Bn256, Fr}; + use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; + let share_x = Fr::from_str("1").unwrap(); + let share_y = Fr::from_str("2").unwrap(); + let epoch = Fr::from_str("3").unwrap(); + let nullifier = Fr::from_str("4").unwrap(); + let root = Fr::from_str("5").unwrap(); + let id_key = Fr::from_str("6").unwrap(); + let mut writer: Vec = Vec::new(); + share_x.into_repr().write_le(&mut writer).unwrap(); + share_y.into_repr().write_le(&mut writer).unwrap(); + epoch.into_repr().write_le(&mut writer).unwrap(); + nullifier.into_repr().write_le(&mut writer).unwrap(); + root.into_repr().write_le(&mut writer).unwrap(); + id_key.into_repr().write_le(&mut writer).unwrap(); + writer.push(1u8); + writer.push(1u8); + writer.push(1u8); + writer.push(1u8); + let inputs = RLNInputs::::read(writer.as_slice()).unwrap(); + assert_eq!(inputs.share_x.unwrap().eq(&share_x), true); + assert_eq!(inputs.share_y.unwrap().eq(&share_y), true); + assert_eq!(inputs.epoch.unwrap().eq(&epoch), true); + assert_eq!(inputs.nullifier.unwrap().eq(&nullifier), true); + assert_eq!(inputs.root.unwrap().eq(&root), true); + assert_eq!(inputs.id_key.unwrap().eq(&id_key), true); + assert_eq!(4, inputs.merkle_depth()); + } } diff --git a/src/merkle.rs b/src/merkle.rs index b7177ca..a51b75c 100644 --- a/src/merkle.rs +++ b/src/merkle.rs @@ -72,7 +72,8 @@ where } } }; - self.nodes.insert((d, leaf_index), self.hasher.hash(vec![new])); + let x = self.hasher.hash(vec![new]); + self.nodes.insert((d, leaf_index), x); self.recalculate_from(leaf_index); } @@ -131,3 +132,15 @@ fn test_merkle_set() { let witness = set.witness(leaf_index); assert!(set.check_inclusion(witness, leaf_index, data[0])); } + +#[test] +fn test_merkle_zeros() { + use sapling_crypto::bellman::pairing::bn256::{Bn256, Fr, FrRepr}; + let params = PoseidonParams::::default(); + let hasher = Hasher::new(params); + let mut set = MerkleTree::empty(hasher, 32); + set.insert(5, Fr::from_str("1").unwrap(), Some(Fr::zero())); + println!("{}", set.root()); + set.insert(6, Fr::from_str("2").unwrap(), Some(Fr::zero())); + println!("{}", set.root()); +}