mirror of https://github.com/status-im/rln.git
move member index to auth object
This commit is contained in:
parent
c61737e22f
commit
a80f5d013e
|
@ -1,17 +1,17 @@
|
|||
use crate::circuit::poseidon::PoseidonCircuit;
|
||||
use crate::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
use crate::merkle::MerkleTree;
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use crate::{circuit::poseidon::PoseidonCircuit, public::RLNSignal};
|
||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
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;
|
||||
use sapling_crypto::circuit::test::TestConstraintSystem;
|
||||
use std::error::Error;
|
||||
use std::io::{self, ErrorKind, Read, Write};
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{error::Error, hash::Hash};
|
||||
|
||||
use crate::public::RLN;
|
||||
|
||||
|
@ -52,23 +52,29 @@ where
|
|||
XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654])
|
||||
}
|
||||
|
||||
fn empty_inputs(merkle_depth: usize) -> RLNInputs<E> {
|
||||
RLNInputs::<E> {
|
||||
share_x: None,
|
||||
share_y: None,
|
||||
epoch: None,
|
||||
nullifier: None,
|
||||
root: None,
|
||||
id_key: None,
|
||||
auth_path: vec![None; merkle_depth],
|
||||
}
|
||||
fn secret_key() -> E::Fr {
|
||||
E::Fr::from_str("1001").unwrap()
|
||||
}
|
||||
|
||||
fn insert_public_key(&mut self) {
|
||||
let hasher = self.hasher();
|
||||
let public_key = hasher.hash(vec![Self::secret_key()]);
|
||||
let mut pubkey_data: Vec<u8> = Vec::new();
|
||||
public_key.into_repr().write_le(&mut pubkey_data).unwrap();
|
||||
self.rln.update_next_member(pubkey_data.as_slice()).unwrap();
|
||||
}
|
||||
|
||||
fn id_index() -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn new(merkle_depth: usize, poseidon_params: Option<PoseidonParams<E>>) -> RLNTest<E> {
|
||||
RLNTest {
|
||||
rln: RLN::new(merkle_depth, 0, poseidon_params),
|
||||
let mut rln_test = RLNTest {
|
||||
rln: RLN::new(merkle_depth, poseidon_params),
|
||||
merkle_depth,
|
||||
}
|
||||
};
|
||||
rln_test.insert_public_key();
|
||||
rln_test
|
||||
}
|
||||
|
||||
pub fn hasher(&self) -> PoseidonHasher<E> {
|
||||
|
@ -85,8 +91,8 @@ where
|
|||
|
||||
// A. setup an identity
|
||||
|
||||
let id_key = E::Fr::rand(&mut rng);
|
||||
let id_comm: E::Fr = hasher.hash(vec![id_key.clone()]);
|
||||
let secret_key = E::Fr::rand(&mut rng);
|
||||
let id_comm: E::Fr = hasher.hash(vec![secret_key.clone()]);
|
||||
|
||||
// B. insert to the membership tree
|
||||
|
||||
|
@ -110,7 +116,7 @@ where
|
|||
let share_x = signal_hash.clone();
|
||||
|
||||
// calculate current line equation
|
||||
let a_0 = id_key.clone();
|
||||
let a_0 = secret_key.clone();
|
||||
let a_1: E::Fr = hasher.hash(vec![a_0, epoch]);
|
||||
|
||||
// evaluate line equation
|
||||
|
@ -129,15 +135,27 @@ where
|
|||
epoch: Some(epoch),
|
||||
nullifier: Some(nullifier),
|
||||
root: Some(membership_tree.get_root()),
|
||||
id_key: Some(id_key),
|
||||
id_key: Some(secret_key),
|
||||
auth_path: auth_path.into_iter().map(|w| Some(w)).collect(),
|
||||
};
|
||||
|
||||
inputs
|
||||
}
|
||||
|
||||
pub fn signal(&self) -> RLNSignal<E> {
|
||||
let mut rng = Self::rng();
|
||||
let epoch = E::Fr::rand(&mut rng);
|
||||
let signal_hash = E::Fr::rand(&mut rng);
|
||||
|
||||
RLNSignal {
|
||||
epoch,
|
||||
hash: signal_hash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn synthesize(&self) -> usize {
|
||||
let hasher = PoseidonCircuit::new(self.rln.poseidon_params());
|
||||
println!("{}", self.merkle_depth);
|
||||
let inputs = self.valid_inputs();
|
||||
let circuit = RLNCircuit::<E> {
|
||||
inputs: inputs.clone(),
|
||||
|
@ -147,7 +165,12 @@ where
|
|||
let mut cs = TestConstraintSystem::<E>::new();
|
||||
|
||||
let circuit = circuit.clone();
|
||||
circuit.synthesize(&mut cs).unwrap();
|
||||
match circuit.synthesize(&mut cs) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
println!("err\n{}", e);
|
||||
}
|
||||
}
|
||||
let unsatisfied = cs.which_is_unsatisfied();
|
||||
if unsatisfied.is_some() {
|
||||
panic!("unsatisfied\n{}", unsatisfied.unwrap());
|
||||
|
@ -161,27 +184,33 @@ where
|
|||
}
|
||||
|
||||
pub fn run_prover_bench(&self) -> ProverBenchResult {
|
||||
let mut raw_inputs: Vec<u8> = Vec::new();
|
||||
let inputs = self.valid_inputs();
|
||||
inputs.write(&mut raw_inputs).unwrap();
|
||||
let mut signal_data: Vec<u8> = Vec::new();
|
||||
let signal = self.signal();
|
||||
signal.write(&mut signal_data).unwrap();
|
||||
|
||||
let mut proof: Vec<u8> = Vec::new();
|
||||
let now = Instant::now();
|
||||
|
||||
let mut secret_key_data: Vec<u8> = Vec::new();
|
||||
let secret_key = Self::secret_key();
|
||||
secret_key
|
||||
.into_repr()
|
||||
.write_le(&mut secret_key_data)
|
||||
.unwrap();
|
||||
let id_index = Self::id_index();
|
||||
|
||||
self.rln
|
||||
.generate_proof(raw_inputs.as_slice(), &mut proof)
|
||||
.generate_proof(
|
||||
signal_data.as_slice(),
|
||||
secret_key_data.as_slice(),
|
||||
id_index,
|
||||
&mut proof,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let prover_time = now.elapsed().as_millis() as f64 / 1000.0;
|
||||
|
||||
let mut raw_public_inputs: Vec<u8> = Vec::new();
|
||||
inputs.write_public_inputs(&mut raw_public_inputs).unwrap();
|
||||
|
||||
// assert!(
|
||||
// self.rln
|
||||
// .verify(proof.as_slice(), raw_public_inputs.as_slice())
|
||||
// .unwrap(),
|
||||
// true
|
||||
// );
|
||||
assert!(self.rln.verify(proof.as_slice()).unwrap(), true);
|
||||
|
||||
let mut circuit_parameters: Vec<u8> = Vec::new();
|
||||
self.rln
|
||||
|
|
98
src/ffi.rs
98
src/ffi.rs
|
@ -26,16 +26,28 @@ impl<'a> From<&Buffer> for &'a [u8] {
|
|||
unsafe { slice::from_raw_parts(src.ptr, src.len) }
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Auth {
|
||||
secret_buffer: *const Buffer,
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
impl Auth {
|
||||
fn get_secret(&self) -> &[u8] {
|
||||
let secret_data = <&[u8]>::from(unsafe { &*self.secret_buffer });
|
||||
secret_data
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn new_circuit_from_params(
|
||||
merkle_depth: usize,
|
||||
index: usize,
|
||||
parameters_buffer: *const Buffer,
|
||||
ctx: *mut *mut RLN<Bn256>,
|
||||
) -> bool {
|
||||
let buffer = <&[u8]>::from(unsafe { &*parameters_buffer });
|
||||
let rln = match RLN::<Bn256>::new_with_raw_params(merkle_depth, index, buffer, None) {
|
||||
let rln = match RLN::<Bn256>::new_with_raw_params(merkle_depth, buffer, None) {
|
||||
Ok(rln) => rln,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
@ -66,12 +78,15 @@ pub extern "C" fn delete_member(ctx: *mut RLN<Bn256>, index: usize) -> bool {
|
|||
pub extern "C" fn generate_proof(
|
||||
ctx: *const RLN<Bn256>,
|
||||
input_buffer: *const Buffer,
|
||||
auth: *const Auth,
|
||||
output_buffer: *mut Buffer,
|
||||
) -> bool {
|
||||
let rln = unsafe { &*ctx };
|
||||
let auth = unsafe { &*auth };
|
||||
let input_data = <&[u8]>::from(unsafe { &*input_buffer });
|
||||
let mut output_data: Vec<u8> = Vec::new();
|
||||
match rln.generate_proof(input_data, &mut output_data) {
|
||||
|
||||
match rln.generate_proof(input_data, auth.get_secret(), auth.index, &mut output_data) {
|
||||
Ok(proof_data) => proof_data,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
@ -103,14 +118,13 @@ pub extern "C" fn verify(
|
|||
pub extern "C" fn hash(
|
||||
ctx: *const RLN<Bn256>,
|
||||
inputs_buffer: *const Buffer,
|
||||
input_len: *const usize,
|
||||
input_len: usize,
|
||||
output_buffer: *mut Buffer,
|
||||
) -> bool {
|
||||
let rln = unsafe { &*ctx };
|
||||
let input_data = <&[u8]>::from(unsafe { &*inputs_buffer });
|
||||
let n: usize = unsafe { *input_len };
|
||||
let mut output_data: Vec<u8> = Vec::new();
|
||||
match rln.hash(input_data, n, &mut output_data) {
|
||||
match rln.hash(input_data, input_len, &mut output_data) {
|
||||
Ok(output_data) => output_data,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
@ -164,17 +178,14 @@ mod tests {
|
|||
fn rln_pointer(circuit_parameters: Vec<u8>) -> MaybeUninit<*mut RLN<Bn256>> {
|
||||
// restore this new curcuit with bindings
|
||||
let merkle_depth = merkle_depth();
|
||||
let index = index();
|
||||
let circuit_parameters_buffer = &Buffer::from(circuit_parameters.as_ref());
|
||||
let mut rln_pointer = MaybeUninit::<*mut RLN<Bn256>>::uninit();
|
||||
unsafe {
|
||||
new_circuit_from_params(
|
||||
merkle_depth,
|
||||
index,
|
||||
circuit_parameters_buffer,
|
||||
rln_pointer.as_mut_ptr(),
|
||||
)
|
||||
};
|
||||
let success = new_circuit_from_params(
|
||||
merkle_depth,
|
||||
circuit_parameters_buffer,
|
||||
rln_pointer.as_mut_ptr(),
|
||||
);
|
||||
assert!(success, "cannot init rln instance");
|
||||
|
||||
rln_pointer
|
||||
}
|
||||
|
@ -195,10 +206,12 @@ mod tests {
|
|||
|
||||
// generate new key pair
|
||||
let mut keypair_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
let success = unsafe { key_gen(rln_pointer, keypair_buffer.as_mut_ptr()) };
|
||||
let success = key_gen(rln_pointer, keypair_buffer.as_mut_ptr());
|
||||
assert!(success, "key generation failed");
|
||||
let keypair_buffer = unsafe { keypair_buffer.assume_init() };
|
||||
let mut keypair_data = <&[u8]>::from(&keypair_buffer);
|
||||
|
||||
// read keypair
|
||||
let mut buf = <Fr as PrimeField>::Repr::default();
|
||||
buf.read_le(&mut keypair_data).unwrap();
|
||||
let id_key = Fr::from_repr(buf).unwrap();
|
||||
|
@ -228,23 +241,33 @@ mod tests {
|
|||
let inputs = RLNSignal::<Bn256> {
|
||||
epoch: epoch,
|
||||
hash: signal_hash,
|
||||
id_key: id_key,
|
||||
};
|
||||
|
||||
// generate proof
|
||||
// serialize signal
|
||||
let mut inputs_data: Vec<u8> = Vec::new();
|
||||
inputs.write(&mut inputs_data).unwrap();
|
||||
let inputs_buffer = &Buffer::from(inputs_data.as_ref());
|
||||
|
||||
// construct auth object
|
||||
let mut secret_data: Vec<u8> = Vec::new();
|
||||
id_key.into_repr().write_le(&mut secret_data).unwrap();
|
||||
let secret_buffer = &Buffer::from(secret_data.as_ref());
|
||||
let auth = &Auth {
|
||||
secret_buffer,
|
||||
index,
|
||||
} as *const Auth;
|
||||
|
||||
// generate proof
|
||||
let mut proof_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
let success =
|
||||
unsafe { generate_proof(rln_pointer, inputs_buffer, proof_buffer.as_mut_ptr()) };
|
||||
generate_proof(rln_pointer, inputs_buffer, auth, proof_buffer.as_mut_ptr());
|
||||
assert!(success, "proof generation failed");
|
||||
let mut proof_buffer = unsafe { proof_buffer.assume_init() };
|
||||
|
||||
// verify proof
|
||||
let mut result = 0u32;
|
||||
let result_ptr = &mut result as *mut u32;
|
||||
let success = unsafe { verify(rln_pointer, &mut proof_buffer, result_ptr) };
|
||||
let success = verify(rln_pointer, &mut proof_buffer, result_ptr);
|
||||
assert!(success, "verification failed");
|
||||
assert_eq!(0, result);
|
||||
};
|
||||
|
@ -281,7 +304,6 @@ mod tests {
|
|||
let input_buffer = &Buffer::from(input_data.as_ref());
|
||||
|
||||
let input_len: usize = 2;
|
||||
let input_len_pointer = &input_len as *const usize;
|
||||
|
||||
let expected = hasher.hash(inputs);
|
||||
let mut expected_data: Vec<u8> = Vec::new();
|
||||
|
@ -289,14 +311,13 @@ mod tests {
|
|||
|
||||
let mut result_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
|
||||
let success = unsafe {
|
||||
hash(
|
||||
rln_pointer,
|
||||
input_buffer,
|
||||
input_len_pointer,
|
||||
result_buffer.as_mut_ptr(),
|
||||
)
|
||||
};
|
||||
let success = hash(
|
||||
rln_pointer,
|
||||
input_buffer,
|
||||
input_len,
|
||||
result_buffer.as_mut_ptr(),
|
||||
);
|
||||
|
||||
assert!(success, "hash ffi call failed");
|
||||
|
||||
let result_buffer = unsafe { result_buffer.assume_init() };
|
||||
|
@ -319,7 +340,7 @@ mod tests {
|
|||
|
||||
let mut keypair_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
|
||||
let success = unsafe { key_gen(rln_pointer, keypair_buffer.as_mut_ptr()) };
|
||||
let success = key_gen(rln_pointer, keypair_buffer.as_mut_ptr());
|
||||
assert!(success, "proof generation failed");
|
||||
|
||||
let keypair_buffer = unsafe { keypair_buffer.assume_init() };
|
||||
|
@ -334,4 +355,21 @@ mod tests {
|
|||
|
||||
assert_eq!(public, expected_public);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_parameters_from_file() {
|
||||
use hex;
|
||||
use std::fs;
|
||||
let data = fs::read("./parameters.key").expect("Unable to read file");
|
||||
let merkle_depth = merkle_depth();
|
||||
let circuit_parameters_buffer = &Buffer::from(data.as_ref());
|
||||
let mut rln_pointer = MaybeUninit::<*mut RLN<Bn256>>::uninit();
|
||||
let success = new_circuit_from_params(
|
||||
merkle_depth,
|
||||
circuit_parameters_buffer,
|
||||
rln_pointer.as_mut_ptr(),
|
||||
);
|
||||
assert!(success, "creating failed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ pub struct IncrementalMerkleTree<E>
|
|||
where
|
||||
E: Engine,
|
||||
{
|
||||
pub self_index: usize,
|
||||
pub current_index: usize,
|
||||
merkle_tree: MerkleTree<E>,
|
||||
}
|
||||
|
@ -22,7 +21,7 @@ impl<E> IncrementalMerkleTree<E>
|
|||
where
|
||||
E: Engine,
|
||||
{
|
||||
pub fn empty(hasher: Hasher<E>, depth: usize, self_index: usize) -> Self {
|
||||
pub fn empty(hasher: Hasher<E>, depth: usize) -> Self {
|
||||
let mut zero: Vec<E::Fr> = Vec::with_capacity(depth + 1);
|
||||
zero.push(E::Fr::from_str("0").unwrap());
|
||||
for i in 0..depth {
|
||||
|
@ -37,7 +36,6 @@ where
|
|||
};
|
||||
let current_index: usize = 0;
|
||||
IncrementalMerkleTree {
|
||||
self_index,
|
||||
current_index,
|
||||
merkle_tree,
|
||||
}
|
||||
|
@ -65,10 +63,6 @@ where
|
|||
self.merkle_tree.get_witness(index)
|
||||
}
|
||||
|
||||
pub fn get_auth_path(&self) -> Vec<(E::Fr, bool)> {
|
||||
self.merkle_tree.get_witness(self.self_index).unwrap()
|
||||
}
|
||||
|
||||
pub fn hash(&self, inputs: Vec<E::Fr>) -> E::Fr {
|
||||
self.merkle_tree.hasher.hash(inputs)
|
||||
}
|
||||
|
|
116
src/public.rs
116
src/public.rs
|
@ -1,7 +1,7 @@
|
|||
use crate::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
use crate::merkle::MerkleTree;
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use crate::utils::{read_inputs, read_uncompressed_proof, write_uncompressed_proof};
|
||||
use crate::utils::{read_fr, read_uncompressed_proof, write_uncompressed_proof};
|
||||
use crate::{circuit::poseidon::PoseidonCircuit, merkle::IncrementalMerkleTree};
|
||||
use bellman::groth16::generate_random_parameters;
|
||||
use bellman::groth16::{create_proof, prepare_verifying_key, verify_proof};
|
||||
|
@ -23,7 +23,6 @@ where
|
|||
{
|
||||
pub epoch: E::Fr,
|
||||
pub hash: E::Fr,
|
||||
pub id_key: E::Fr,
|
||||
}
|
||||
|
||||
impl<E> RLNSignal<E>
|
||||
|
@ -39,21 +38,13 @@ where
|
|||
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 id_key =
|
||||
E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
|
||||
Ok(RLNSignal {
|
||||
epoch,
|
||||
hash,
|
||||
id_key,
|
||||
})
|
||||
Ok(RLNSignal { epoch, hash })
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
self.epoch.into_repr().write_le(&mut writer).unwrap();
|
||||
self.hash.into_repr().write_le(&mut writer).unwrap();
|
||||
self.id_key.into_repr().write_le(&mut writer).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -87,12 +78,11 @@ where
|
|||
|
||||
fn new_with_params(
|
||||
merkle_depth: usize,
|
||||
index: usize,
|
||||
circuit_parameters: Parameters<E>,
|
||||
poseidon_params: PoseidonParams<E>,
|
||||
) -> RLN<E> {
|
||||
let hasher = PoseidonHasher::new(poseidon_params.clone());
|
||||
let tree = IncrementalMerkleTree::empty(hasher, merkle_depth, index);
|
||||
let tree = IncrementalMerkleTree::empty(hasher, merkle_depth);
|
||||
RLN {
|
||||
circuit_parameters,
|
||||
poseidon_params,
|
||||
|
@ -100,22 +90,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
merkle_depth: usize,
|
||||
index: usize,
|
||||
poseidon_params: Option<PoseidonParams<E>>,
|
||||
) -> RLN<E> {
|
||||
pub fn new(merkle_depth: usize, poseidon_params: Option<PoseidonParams<E>>) -> RLN<E> {
|
||||
let poseidon_params = match poseidon_params {
|
||||
Some(params) => params,
|
||||
None => Self::default_poseidon_params(),
|
||||
};
|
||||
let circuit_parameters = Self::new_circuit(merkle_depth, poseidon_params.clone());
|
||||
Self::new_with_params(merkle_depth, index, circuit_parameters, poseidon_params)
|
||||
Self::new_with_params(merkle_depth, circuit_parameters, poseidon_params)
|
||||
}
|
||||
|
||||
pub fn new_with_raw_params<R: Read>(
|
||||
merkle_depth: usize,
|
||||
index: usize,
|
||||
raw_circuit_parameters: R,
|
||||
poseidon_params: Option<PoseidonParams<E>>,
|
||||
) -> io::Result<RLN<E>> {
|
||||
|
@ -126,58 +111,69 @@ where
|
|||
};
|
||||
Ok(Self::new_with_params(
|
||||
merkle_depth,
|
||||
index,
|
||||
circuit_parameters,
|
||||
poseidon_params,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn update_next_member<R: Read>(&mut self, input: R) -> io::Result<()> {
|
||||
//// inserts new member with given public key
|
||||
/// * `public_key_data` is a 32 scalar field element in 32 bytes
|
||||
pub fn update_next_member<R: Read>(&mut self, public_key_data: R) -> io::Result<()> {
|
||||
let mut buf = <E::Fr as PrimeField>::Repr::default();
|
||||
buf.read_le(input)?;
|
||||
buf.read_le(public_key_data)?;
|
||||
let leaf =
|
||||
E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
self.tree.update_next(leaf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
//// deletes member with given index
|
||||
pub fn delete_member(&mut self, index: usize) -> io::Result<()> {
|
||||
self.tree.delete(index)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn poseidon_params(&self) -> PoseidonParams<E> {
|
||||
self.poseidon_params.clone()
|
||||
}
|
||||
|
||||
pub fn hasher(&self) -> PoseidonHasher<E> {
|
||||
PoseidonHasher::new(self.poseidon_params.clone())
|
||||
}
|
||||
|
||||
/// expect one or two scalar field element in 32 bytes in `input`
|
||||
/// `output` is a 32 scalar field element in 32 bytes
|
||||
pub fn hash<R: Read, W: Write>(&self, input: R, n: usize, mut output: W) -> io::Result<()> {
|
||||
/// hashes scalar field elements
|
||||
/// * expect numbers of scalar field element in 32 bytes in `input_data`
|
||||
/// * expect `result_data` is a scalar field element in 32 bytes
|
||||
/// * `n` is number of scalar field elemends stored in `input`
|
||||
pub fn hash<R: Read, W: Write>(
|
||||
&self,
|
||||
input_data: R,
|
||||
n: usize,
|
||||
mut result_data: W,
|
||||
) -> io::Result<()> {
|
||||
let hasher = self.hasher();
|
||||
let input: Vec<E::Fr> = read_inputs::<R, E>(input, n)?;
|
||||
let input: Vec<E::Fr> = read_fr::<R, E>(input_data, n)?;
|
||||
let result = hasher.hash(input);
|
||||
result.into_repr().write_le(&mut output)?;
|
||||
result.into_repr().write_le(&mut result_data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// expect `input` serialized as |epoch<32>|signal_hash<32>|id_key<32>|
|
||||
/// `output` is proof data serialized as |proof<416>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
|
||||
pub fn generate_proof<R: Read, W: Write>(&self, input: R, mut output: W) -> io::Result<()> {
|
||||
/// given public inputs and autharization data generates public inputs and proof
|
||||
/// * expect `input` serialized as |epoch<32>|signal_hash<32>|
|
||||
/// * expect `id_key_data` is a scalar field element in 32 bytes
|
||||
/// * `output_data` is proof data serialized as |proof<416>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
|
||||
pub fn generate_proof<R: Read, W: Write>(
|
||||
&self,
|
||||
input_data: R,
|
||||
id_key_data: R,
|
||||
member_index: usize,
|
||||
mut output_data: W,
|
||||
) -> io::Result<()> {
|
||||
use rand::chacha::ChaChaRng;
|
||||
use rand::SeedableRng;
|
||||
let mut rng = ChaChaRng::new_unseeded();
|
||||
let signal = RLNSignal::<E>::read(input)?;
|
||||
let signal = RLNSignal::<E>::read(input_data)?;
|
||||
// prepare inputs
|
||||
|
||||
let hasher = self.hasher();
|
||||
let share_x = signal.hash.clone();
|
||||
|
||||
let id_key: E::Fr = read_fr::<R, E>(id_key_data, 1)?[0];
|
||||
|
||||
// line equation
|
||||
let a_0 = signal.id_key.clone();
|
||||
let a_0 = id_key.clone();
|
||||
let a_1: E::Fr = hasher.hash(vec![a_0, signal.epoch]);
|
||||
// evaluate line equation
|
||||
let mut share_y = a_1.clone();
|
||||
|
@ -186,7 +182,8 @@ where
|
|||
let nullifier = hasher.hash(vec![a_1]);
|
||||
|
||||
let root = self.tree.get_root();
|
||||
let auth_path = self.tree.get_auth_path();
|
||||
// TODO: check id key here
|
||||
let auth_path = self.tree.get_witness(member_index)?;
|
||||
|
||||
let inputs = RLNInputs::<E> {
|
||||
share_x: Some(share_x),
|
||||
|
@ -194,7 +191,7 @@ where
|
|||
epoch: Some(signal.epoch),
|
||||
nullifier: Some(nullifier),
|
||||
root: Some(root),
|
||||
id_key: Some(signal.id_key),
|
||||
id_key: Some(id_key),
|
||||
auth_path: auth_path.into_iter().map(|w| Some(w)).collect(),
|
||||
};
|
||||
|
||||
|
@ -203,18 +200,20 @@ where
|
|||
hasher: PoseidonCircuit::new(self.poseidon_params.clone()),
|
||||
};
|
||||
|
||||
// TOOD: handle create proof error
|
||||
let proof = create_random_proof(circuit, &self.circuit_parameters, &mut rng).unwrap();
|
||||
write_uncompressed_proof(proof.clone(), &mut output)?;
|
||||
root.into_repr().write_le(&mut output)?;
|
||||
signal.epoch.into_repr().write_le(&mut output)?;
|
||||
share_x.into_repr().write_le(&mut output)?;
|
||||
share_y.into_repr().write_le(&mut output)?;
|
||||
nullifier.into_repr().write_le(&mut output)?;
|
||||
write_uncompressed_proof(proof.clone(), &mut output_data)?;
|
||||
root.into_repr().write_le(&mut output_data)?;
|
||||
signal.epoch.into_repr().write_le(&mut output_data)?;
|
||||
share_x.into_repr().write_le(&mut output_data)?;
|
||||
share_y.into_repr().write_le(&mut output_data)?;
|
||||
nullifier.into_repr().write_le(&mut output_data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `proof_data` is the proof along with public inputs serialized as:
|
||||
/// given proof and public data verifies the signal
|
||||
/// * expect `proof_data` is serialized as:
|
||||
/// |proof<416>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
|
||||
pub fn verify<R: Read>(&self, mut proof_data: R) -> io::Result<bool> {
|
||||
let proof = read_uncompressed_proof(&mut proof_data)?;
|
||||
|
@ -225,14 +224,15 @@ where
|
|||
Ok(success)
|
||||
}
|
||||
|
||||
/// `output` is seralized as |secret<32>|public<32>|
|
||||
pub fn key_gen<W: Write>(&self, mut output: W) -> io::Result<()> {
|
||||
/// generates public private key pair
|
||||
/// * `key_pair_data` is seralized as |secret<32>|public<32>|
|
||||
pub fn key_gen<W: Write>(&self, mut key_pair_data: W) -> io::Result<()> {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let hasher = self.hasher();
|
||||
let secret = E::Fr::rand(&mut rng);
|
||||
let public: E::Fr = hasher.hash(vec![secret.clone()]);
|
||||
secret.into_repr().write_le(&mut output)?;
|
||||
public.into_repr().write_le(&mut output)?;
|
||||
secret.into_repr().write_le(&mut key_pair_data)?;
|
||||
public.into_repr().write_le(&mut key_pair_data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -243,4 +243,12 @@ where
|
|||
pub fn export_circuit_parameters<W: Write>(&self, w: W) -> io::Result<()> {
|
||||
self.circuit_parameters.write(w)
|
||||
}
|
||||
|
||||
pub fn hasher(&self) -> PoseidonHasher<E> {
|
||||
PoseidonHasher::new(self.poseidon_params.clone())
|
||||
}
|
||||
|
||||
pub fn poseidon_params(&self) -> PoseidonParams<E> {
|
||||
self.poseidon_params.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use bellman::pairing::{CurveAffine, EncodedPoint, Engine};
|
|||
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
use std::io::{self, Error, ErrorKind, Read, Write};
|
||||
|
||||
pub fn read_inputs<R: Read, E: Engine>(mut reader: R, n: usize) -> io::Result<Vec<E::Fr>> {
|
||||
pub fn read_fr<R: Read, E: Engine>(mut reader: R, n: usize) -> io::Result<Vec<E::Fr>> {
|
||||
let mut out: Vec<E::Fr> = Vec::new();
|
||||
let mut buf = <E::Fr as PrimeField>::Repr::default();
|
||||
for _ in 0..n {
|
||||
|
|
Loading…
Reference in New Issue