mirror of
https://github.com/vacp2p/zerokit.git
synced 2026-01-09 13:47:58 -05:00
Compare commits
7 Commits
v0.3.3
...
v0.3.6-rel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dd019b0a5 | ||
|
|
78bec51fba | ||
|
|
b0be32943e | ||
|
|
09da5304c1 | ||
|
|
d5e09524d7 | ||
|
|
b903d8d740 | ||
|
|
f73c83b571 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -134,4 +134,4 @@ jobs:
|
||||
- uses: boa-dev/criterion-compare-action@v3
|
||||
with:
|
||||
branchName: ${{ github.base_ref }}
|
||||
cwd: ${{ matrix.crate }}
|
||||
cwd: ${{ matrix.crate }}
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2695,7 +2695,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rln"
|
||||
version = "0.3.3"
|
||||
version = "0.3.6"
|
||||
dependencies = [
|
||||
"ark-bn254 0.4.0",
|
||||
"ark-circom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -29,4 +29,7 @@ image = "ghcr.io/cross-rs/mips64-unknown-linux-gnuabi64:latest"
|
||||
image = "ghcr.io/cross-rs/mips64el-unknown-linux-gnuabi64:latest"
|
||||
|
||||
[target.mipsel-unknown-linux-gnu]
|
||||
image = "ghcr.io/cross-rs/mipsel-unknown-linux-gnu:latest"
|
||||
image = "ghcr.io/cross-rs/mipsel-unknown-linux-gnu:latest"
|
||||
|
||||
[target.aarch64-linux-android]
|
||||
image = "ghcr.io/cross-rs/aarch64-linux-android:edge"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rln"
|
||||
version = "0.3.3"
|
||||
version = "0.3.6"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "APIs to manage, compute and verify zkSNARK proofs and RLN primitives"
|
||||
|
||||
@@ -361,6 +361,21 @@ pub extern "C" fn generate_rln_proof(
|
||||
call_with_output_arg!(ctx, generate_rln_proof, output_buffer, input_buffer)
|
||||
}
|
||||
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn generate_rln_proof_with_witness(
|
||||
ctx: *mut RLN,
|
||||
input_buffer: *const Buffer,
|
||||
output_buffer: *mut Buffer,
|
||||
) -> bool {
|
||||
call_with_output_arg!(
|
||||
ctx,
|
||||
generate_rln_proof_with_witness,
|
||||
output_buffer,
|
||||
input_buffer
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn verify_rln_proof(
|
||||
|
||||
@@ -197,11 +197,13 @@ impl ZerokitMerkleTree for PmTree {
|
||||
let mut indices = indices.into_iter().collect::<Vec<_>>();
|
||||
indices.sort();
|
||||
|
||||
match (leaves.is_empty(), indices.is_empty()) {
|
||||
(true, true) => Err(Report::msg("no leaves or indices to be removed")),
|
||||
(false, true) => self.set_range_with_leaves(start, leaves),
|
||||
(true, false) => self.remove_indices(indices),
|
||||
(false, false) => self.remove_indices_and_set_leaves(start, leaves, indices),
|
||||
match (leaves.len(), indices.len()) {
|
||||
(0, 0) => Err(Report::msg("no leaves or indices to be removed")),
|
||||
(1, 0) => self.set(start, leaves[0]),
|
||||
(0, 1) => self.delete(indices[0]),
|
||||
(_, 0) => self.set_range_with_leaves(start, leaves),
|
||||
(0, _) => self.remove_indices(&indices),
|
||||
(_, _) => self.remove_indices_and_set_leaves(start, leaves, &indices),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +246,8 @@ impl ZerokitMerkleTree for PmTree {
|
||||
let data = self.tree.db.get(METADATA_KEY)?;
|
||||
|
||||
if data.is_none() {
|
||||
return Err(Report::msg("metadata does not exist"));
|
||||
// send empty Metadata
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
Ok(data.unwrap())
|
||||
}
|
||||
@@ -264,18 +267,11 @@ impl PmTree {
|
||||
.map_err(|e| Report::msg(e.to_string()))
|
||||
}
|
||||
|
||||
fn remove_indices(&mut self, indices: Vec<usize>) -> Result<()> {
|
||||
fn remove_indices(&mut self, indices: &[usize]) -> Result<()> {
|
||||
let start = indices[0];
|
||||
let end = indices.last().unwrap() + 1;
|
||||
|
||||
let mut new_leaves: Vec<_> = (start..end)
|
||||
.map(|i| self.tree.get(i))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
new_leaves
|
||||
.iter_mut()
|
||||
.take(indices.len())
|
||||
.for_each(|leaf| *leaf = PmTreeHasher::default_leaf());
|
||||
let new_leaves = (start..end).map(|_| PmTreeHasher::default_leaf());
|
||||
|
||||
self.tree
|
||||
.set_range(start, new_leaves)
|
||||
@@ -286,16 +282,13 @@ impl PmTree {
|
||||
&mut self,
|
||||
start: usize,
|
||||
leaves: Vec<FrOfPmTreeHasher>,
|
||||
indices: Vec<usize>,
|
||||
indices: &[usize],
|
||||
) -> Result<()> {
|
||||
let min_index = *indices.first().unwrap();
|
||||
let max_index = start + leaves.len();
|
||||
|
||||
// Generated a placeholder with the exact size needed,
|
||||
// Initiated with default values to be overridden throughout the method
|
||||
let mut set_values = vec![PmTreeHasher::default_leaf(); max_index - min_index];
|
||||
|
||||
// If the index is not in indices list, keep the original value
|
||||
for i in min_index..start {
|
||||
if !indices.contains(&i) {
|
||||
let value = self.tree.get(i)?;
|
||||
@@ -303,7 +296,6 @@ impl PmTree {
|
||||
}
|
||||
}
|
||||
|
||||
// Insert new leaves after 'start' position
|
||||
for (i, &leaf) in leaves.iter().enumerate() {
|
||||
set_values[start - min_index + i] = leaf;
|
||||
}
|
||||
|
||||
@@ -720,9 +720,9 @@ impl RLN<'_> {
|
||||
mut output_data: W,
|
||||
) -> Result<()> {
|
||||
// We read input RLN witness and we serialize_compressed it
|
||||
let mut witness_byte: Vec<u8> = Vec::new();
|
||||
input_data.read_to_end(&mut witness_byte)?;
|
||||
let (rln_witness, _) = proof_inputs_to_rln_witness(&mut self.tree, &witness_byte)?;
|
||||
let mut input_byte: Vec<u8> = Vec::new();
|
||||
input_data.read_to_end(&mut input_byte)?;
|
||||
let (rln_witness, _) = proof_inputs_to_rln_witness(&mut self.tree, &input_byte)?;
|
||||
let proof_values = proof_values_from_witness(&rln_witness);
|
||||
|
||||
let proof = generate_proof(self.witness_calculator, &self.proving_key, &rln_witness)?;
|
||||
@@ -735,12 +735,33 @@ impl RLN<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: this function seems to use redundant witness (as bigint and serialized) and should be refactored
|
||||
// Generate RLN Proof using a witness calculated from outside zerokit
|
||||
//
|
||||
// output_data is [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]
|
||||
// we skip it from documentation for now
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn generate_rln_proof_with_witness<R: Read, W: Write>(
|
||||
&mut self,
|
||||
mut input_data: R,
|
||||
mut output_data: W,
|
||||
) -> Result<()> {
|
||||
let mut witness_byte: Vec<u8> = Vec::new();
|
||||
input_data.read_to_end(&mut witness_byte)?;
|
||||
let (rln_witness, _) = deserialize_witness(&witness_byte)?;
|
||||
let proof_values = proof_values_from_witness(&rln_witness);
|
||||
|
||||
let proof = generate_proof(self.witness_calculator, &self.proving_key, &rln_witness)?;
|
||||
|
||||
// Note: we export a serialization of ark-groth16::Proof not semaphore::Proof
|
||||
// This proof is compressed, i.e. 128 bytes long
|
||||
proof.serialize_compressed(&mut output_data)?;
|
||||
output_data.write_all(&serialize_proof_values(&proof_values))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Different in wasm since witness_calculator is not available
|
||||
// See: https://github.com/vacp2p/zerokit/blob/b903d8d740e0b8b82057bcc5377ddce05ae5676b/rln/src/public.rs#L47-L49
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn generate_rln_proof_with_witness<W: Write>(
|
||||
&mut self,
|
||||
calculated_witness: Vec<BigInt>,
|
||||
@@ -1800,13 +1821,10 @@ mod test {
|
||||
.collect();
|
||||
|
||||
// Generating the proof
|
||||
let mut input_buffer = Cursor::new(serialized_witness);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof_with_witness(
|
||||
calculated_witness_vec,
|
||||
serialized_witness,
|
||||
&mut output_buffer,
|
||||
)
|
||||
.unwrap();
|
||||
rln.generate_rln_proof_with_witness(&mut input_buffer, &mut output_buffer)
|
||||
.unwrap();
|
||||
|
||||
// output_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ]
|
||||
let mut proof_data = output_buffer.into_inner();
|
||||
@@ -2090,4 +2108,19 @@ mod test {
|
||||
|
||||
assert_eq!(arbitrary_metadata, received_metadata);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_metadata() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_metadata(&mut buffer).unwrap();
|
||||
let received_metadata = buffer.into_inner();
|
||||
|
||||
assert_eq!(received_metadata.len(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,7 +1209,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_metadata() {
|
||||
fn test_valid_metadata() {
|
||||
// We create a RLN instance
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
@@ -1235,4 +1235,25 @@ mod test {
|
||||
|
||||
assert_eq!(result_data, seed_bytes.to_vec());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_metadata() {
|
||||
// We create a RLN instance
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
let mut rln_pointer = MaybeUninit::<*mut RLN>::uninit();
|
||||
let input_config = json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string();
|
||||
let input_buffer = &Buffer::from(input_config.as_bytes());
|
||||
let success = new(tree_height, input_buffer, rln_pointer.as_mut_ptr());
|
||||
assert!(success, "RLN object creation failed");
|
||||
let rln_pointer = unsafe { &mut *rln_pointer.assume_init() };
|
||||
|
||||
let mut output_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
let success = get_metadata(rln_pointer, output_buffer.as_mut_ptr());
|
||||
assert!(success, "get_metadata call failed");
|
||||
|
||||
let output_buffer = unsafe { output_buffer.assume_init() };
|
||||
|
||||
assert_eq!(output_buffer.len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user