mirror of https://github.com/status-im/rln.git
add member deletion ffi
This commit is contained in:
parent
1c1fbf402e
commit
c61737e22f
|
@ -91,7 +91,7 @@ where
|
||||||
// B. insert to the membership tree
|
// B. insert to the membership tree
|
||||||
|
|
||||||
let id_index = 6; // any number below 2^depth will work
|
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
|
// C.1 get membership witness
|
||||||
|
|
||||||
|
@ -170,6 +170,7 @@ where
|
||||||
self.rln
|
self.rln
|
||||||
.generate_proof(raw_inputs.as_slice(), &mut proof)
|
.generate_proof(raw_inputs.as_slice(), &mut proof)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let prover_time = now.elapsed().as_millis() as f64 / 1000.0;
|
let prover_time = now.elapsed().as_millis() as f64 / 1000.0;
|
||||||
|
|
||||||
let mut raw_public_inputs: Vec<u8> = Vec::new();
|
let mut raw_public_inputs: Vec<u8> = Vec::new();
|
||||||
|
|
77
src/ffi.rs
77
src/ffi.rs
|
@ -44,14 +44,22 @@ pub extern "C" fn new_circuit_from_params(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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 rln = unsafe { &mut *ctx };
|
||||||
let input_data = <&[u8]>::from(unsafe { &*input_buffer });
|
let input_data = <&[u8]>::from(unsafe { &*input_buffer });
|
||||||
match rln.update_next(input_data) {
|
match rln.update_next_member(input_data) {
|
||||||
Ok(proof_data) => proof_data,
|
Ok(_) => true,
|
||||||
Err(_) => return false,
|
Err(_) => false,
|
||||||
};
|
}
|
||||||
true
|
}
|
||||||
|
|
||||||
|
#[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]
|
#[no_mangle]
|
||||||
|
@ -209,35 +217,46 @@ mod tests {
|
||||||
new_member.into_repr().write_le(&mut input_data).unwrap();
|
new_member.into_repr().write_le(&mut input_data).unwrap();
|
||||||
let input_buffer = &Buffer::from(input_data.as_ref());
|
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");
|
assert!(success, "update with new pubkey failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create signal
|
let mut gen_proof_and_verify = |rln_pointer: *const RLN<Bn256>| {
|
||||||
let epoch = Fr::rand(&mut rng);
|
// create signal
|
||||||
let signal_hash = Fr::rand(&mut rng);
|
let epoch = Fr::rand(&mut rng);
|
||||||
let inputs = RLNSignal::<Bn256> {
|
let signal_hash = Fr::rand(&mut rng);
|
||||||
epoch: epoch,
|
let inputs = RLNSignal::<Bn256> {
|
||||||
hash: signal_hash,
|
epoch: epoch,
|
||||||
id_key: id_key,
|
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
|
gen_proof_and_verify(rln_pointer);
|
||||||
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
|
// delete 0th member
|
||||||
let mut result = 0u32;
|
let success = delete_member(rln_pointer, 0);
|
||||||
let result_ptr = &mut result as *mut u32;
|
assert!(success, "deletion failed");
|
||||||
let success = unsafe { verify(rln_pointer, &mut proof_buffer, result_ptr) };
|
|
||||||
assert!(success, "verification failed");
|
// gen proof & verify once more
|
||||||
assert_eq!(0, result);
|
gen_proof_and_verify(rln_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -43,22 +43,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_next(&mut self, leaf: E::Fr) {
|
pub fn update_next(&mut self, leaf: E::Fr) -> io::Result<()> {
|
||||||
// println!("{}", self.get_root());
|
self.merkle_tree.update(self.current_index, leaf)?;
|
||||||
self.merkle_tree.update(self.current_index, leaf);
|
|
||||||
self.current_index += 1;
|
self.current_index += 1;
|
||||||
// println!("{}", self.get_root());
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self, index: usize) -> io::Result<()> {
|
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();
|
let zero = E::Fr::from_str("0").unwrap();
|
||||||
self.merkle_tree.update(index, zero);
|
self.merkle_tree.update(index, zero)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +125,16 @@ where
|
||||||
1 << self.depth
|
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.nodes.insert((self.depth, index), leaf);
|
||||||
self.recalculate_from(index);
|
self.recalculate_from(index);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_inclusion(&self, witness: Vec<(E::Fr, bool)>, index: usize) -> io::Result<bool> {
|
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 mut set = MerkleTree::empty(hasher.clone(), 3);
|
||||||
let leaf_index = 6;
|
let leaf_index = 6;
|
||||||
let leaf = hasher.hash(vec![data[0]]);
|
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();
|
let witness = set.get_witness(leaf_index).unwrap();
|
||||||
assert!(set.check_inclusion(witness, leaf_index).unwrap());
|
assert!(set.check_inclusion(witness, leaf_index).unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
let mut buf = <E::Fr as PrimeField>::Repr::default();
|
||||||
buf.read_le(input)?;
|
buf.read_le(input)?;
|
||||||
let leaf =
|
let leaf =
|
||||||
E::Fr::from_repr(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,17 +154,18 @@ where
|
||||||
PoseidonHasher::new(self.poseidon_params.clone())
|
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<()> {
|
pub fn hash<R: Read, W: Write>(&self, input: R, n: usize, mut output: W) -> io::Result<()> {
|
||||||
let hasher = self.hasher();
|
let hasher = self.hasher();
|
||||||
let input: Vec<E::Fr> = read_inputs::<R, E>(input, n)?;
|
let input: Vec<E::Fr> = read_inputs::<R, E>(input, n)?;
|
||||||
let result = hasher.hash(input);
|
let result = hasher.hash(input);
|
||||||
// let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
result.into_repr().write_le(&mut output)?;
|
result.into_repr().write_le(&mut output)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// input: |epoch<32>|signal_hash<32>|id_key<32>|
|
/// expect `input` serialized as |epoch<32>|signal_hash<32>|id_key<32>|
|
||||||
/// output: |proof<?>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<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<()> {
|
pub fn generate_proof<R: Read, W: Write>(&self, input: R, mut output: W) -> io::Result<()> {
|
||||||
use rand::chacha::ChaChaRng;
|
use rand::chacha::ChaChaRng;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -208,7 +214,8 @@ where
|
||||||
Ok(())
|
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> {
|
pub fn verify<R: Read>(&self, mut proof_data: R) -> io::Result<bool> {
|
||||||
let proof = read_uncompressed_proof(&mut proof_data)?;
|
let proof = read_uncompressed_proof(&mut proof_data)?;
|
||||||
let public_inputs = RLNInputs::<E>::read_public_inputs(&mut proof_data)?;
|
let public_inputs = RLNInputs::<E>::read_public_inputs(&mut proof_data)?;
|
||||||
|
@ -218,13 +225,14 @@ where
|
||||||
Ok(success)
|
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 mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
let hasher = self.hasher();
|
let hasher = self.hasher();
|
||||||
let secret = E::Fr::rand(&mut rng);
|
let secret = E::Fr::rand(&mut rng);
|
||||||
let public: E::Fr = hasher.hash(vec![secret.clone()]);
|
let public: E::Fr = hasher.hash(vec![secret.clone()]);
|
||||||
secret.into_repr().write_le(&mut w)?;
|
secret.into_repr().write_le(&mut output)?;
|
||||||
public.into_repr().write_le(&mut w)?;
|
public.into_repr().write_le(&mut output)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue