add member deletion ffi

This commit is contained in:
kilic 2021-02-08 18:56:53 +03:00
parent 1c1fbf402e
commit c61737e22f
4 changed files with 80 additions and 52 deletions

View File

@ -91,7 +91,7 @@ where
// B. insert to the membership tree
let id_index = 6; // any number below 2^depth will work
membership_tree.update(id_index, id_comm);
membership_tree.update(id_index, id_comm).unwrap();
// C.1 get membership witness
@ -170,6 +170,7 @@ where
self.rln
.generate_proof(raw_inputs.as_slice(), &mut proof)
.unwrap();
let prover_time = now.elapsed().as_millis() as f64 / 1000.0;
let mut raw_public_inputs: Vec<u8> = Vec::new();

View File

@ -44,14 +44,22 @@ pub extern "C" fn new_circuit_from_params(
}
#[no_mangle]
pub extern "C" fn update_next(ctx: *mut RLN<Bn256>, input_buffer: *const Buffer) -> bool {
pub extern "C" fn update_next_member(ctx: *mut RLN<Bn256>, input_buffer: *const Buffer) -> bool {
let rln = unsafe { &mut *ctx };
let input_data = <&[u8]>::from(unsafe { &*input_buffer });
match rln.update_next(input_data) {
Ok(proof_data) => proof_data,
Err(_) => return false,
};
true
match rln.update_next_member(input_data) {
Ok(_) => true,
Err(_) => false,
}
}
#[no_mangle]
pub extern "C" fn delete_member(ctx: *mut RLN<Bn256>, index: usize) -> bool {
let rln = unsafe { &mut *ctx };
match rln.delete_member(index) {
Ok(_) => true,
Err(_) => false,
}
}
#[no_mangle]
@ -209,35 +217,46 @@ mod tests {
new_member.into_repr().write_le(&mut input_data).unwrap();
let input_buffer = &Buffer::from(input_data.as_ref());
let success = update_next(rln_pointer, input_buffer);
let success = update_next_member(rln_pointer, input_buffer);
assert!(success, "update with new pubkey failed");
}
// create signal
let epoch = Fr::rand(&mut rng);
let signal_hash = Fr::rand(&mut rng);
let inputs = RLNSignal::<Bn256> {
epoch: epoch,
hash: signal_hash,
id_key: id_key,
let mut gen_proof_and_verify = |rln_pointer: *const RLN<Bn256>| {
// create signal
let epoch = Fr::rand(&mut rng);
let signal_hash = Fr::rand(&mut rng);
let inputs = RLNSignal::<Bn256> {
epoch: epoch,
hash: signal_hash,
id_key: id_key,
};
// generate proof
let mut inputs_data: Vec<u8> = Vec::new();
inputs.write(&mut inputs_data).unwrap();
let inputs_buffer = &Buffer::from(inputs_data.as_ref());
let mut proof_buffer = MaybeUninit::<Buffer>::uninit();
let success =
unsafe { generate_proof(rln_pointer, inputs_buffer, 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) };
assert!(success, "verification failed");
assert_eq!(0, result);
};
// generate proof
let mut inputs_data: Vec<u8> = Vec::new();
inputs.write(&mut inputs_data).unwrap();
let inputs_buffer = &Buffer::from(inputs_data.as_ref());
let mut proof_buffer = MaybeUninit::<Buffer>::uninit();
let success =
unsafe { generate_proof(rln_pointer, inputs_buffer, proof_buffer.as_mut_ptr()) };
assert!(success, "proof generation failed");
let mut proof_buffer = unsafe { proof_buffer.assume_init() };
gen_proof_and_verify(rln_pointer);
// 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) };
assert!(success, "verification failed");
assert_eq!(0, result);
// delete 0th member
let success = delete_member(rln_pointer, 0);
assert!(success, "deletion failed");
// gen proof & verify once more
gen_proof_and_verify(rln_pointer);
}
#[test]

View File

@ -43,22 +43,15 @@ where
}
}
pub fn update_next(&mut self, leaf: E::Fr) {
// println!("{}", self.get_root());
self.merkle_tree.update(self.current_index, leaf);
pub fn update_next(&mut self, leaf: E::Fr) -> io::Result<()> {
self.merkle_tree.update(self.current_index, leaf)?;
self.current_index += 1;
// println!("{}", self.get_root());
Ok(())
}
pub fn delete(&mut self, index: usize) -> io::Result<()> {
if index >= self.current_index {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"index exceeds incremental index",
));
}
let zero = E::Fr::from_str("0").unwrap();
self.merkle_tree.update(index, zero);
self.merkle_tree.update(index, zero)?;
Ok(())
}
@ -132,9 +125,16 @@ where
1 << self.depth
}
pub fn update(&mut self, index: usize, leaf: E::Fr) {
pub fn update(&mut self, index: usize, leaf: E::Fr) -> io::Result<()> {
if index >= self.set_size() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"index exceeds set size",
));
}
self.nodes.insert((self.depth, index), leaf);
self.recalculate_from(index);
Ok(())
}
pub fn check_inclusion(&self, witness: Vec<(E::Fr, bool)>, index: usize) -> io::Result<bool> {
@ -229,7 +229,7 @@ fn test_merkle_set() {
let mut set = MerkleTree::empty(hasher.clone(), 3);
let leaf_index = 6;
let leaf = hasher.hash(vec![data[0]]);
set.update(leaf_index, leaf);
set.update(leaf_index, leaf).unwrap();
let witness = set.get_witness(leaf_index).unwrap();
assert!(set.check_inclusion(witness, leaf_index).unwrap());
}

View File

@ -132,12 +132,17 @@ where
))
}
pub fn update_next<R: Read>(&mut self, input: R) -> io::Result<()> {
pub fn update_next_member<R: Read>(&mut self, input: R) -> io::Result<()> {
let mut buf = <E::Fr as PrimeField>::Repr::default();
buf.read_le(input)?;
let leaf =
E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
self.tree.update_next(leaf);
self.tree.update_next(leaf)?;
Ok(())
}
pub fn delete_member(&mut self, index: usize) -> io::Result<()> {
self.tree.delete(index)?;
Ok(())
}
@ -149,17 +154,18 @@ where
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<()> {
let hasher = self.hasher();
let input: Vec<E::Fr> = read_inputs::<R, E>(input, n)?;
let result = hasher.hash(input);
// let mut output_data: Vec<u8> = Vec::new();
result.into_repr().write_le(&mut output)?;
Ok(())
}
/// input: |epoch<32>|signal_hash<32>|id_key<32>|
/// output: |proof<?>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
/// 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<()> {
use rand::chacha::ChaChaRng;
use rand::SeedableRng;
@ -208,7 +214,8 @@ where
Ok(())
}
/// proof: |proof<?>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
/// `proof_data` is the proof along with public inputs 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)?;
let public_inputs = RLNInputs::<E>::read_public_inputs(&mut proof_data)?;
@ -218,13 +225,14 @@ where
Ok(success)
}
pub fn key_gen<W: Write>(&self, mut w: W) -> io::Result<()> {
/// `output` is seralized as |secret<32>|public<32>|
pub fn key_gen<W: Write>(&self, mut output: 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 w)?;
public.into_repr().write_le(&mut w)?;
secret.into_repr().write_le(&mut output)?;
public.into_repr().write_le(&mut output)?;
Ok(())
}