mirror of
https://github.com/vacp2p/zerokit.git
synced 2026-01-08 21:28:11 -05:00
Compare commits
8 Commits
v0.3.7
...
refactorin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4e5df549e | ||
|
|
7e27e87139 | ||
|
|
a0f9945fce | ||
|
|
09b74f9267 | ||
|
|
7ab4e367ff | ||
|
|
41aad0fae2 | ||
|
|
0997d15d33 | ||
|
|
8614b2a33a |
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,7 +1,3 @@
|
||||
[submodule "rln/vendor/rln"]
|
||||
path = rln/vendor/rln
|
||||
ignore = dirty
|
||||
url = https://github.com/Rate-Limiting-Nullifier/rln_circuits.git
|
||||
[submodule "semaphore/vendor/semaphore"]
|
||||
path = semaphore/vendor/semaphore
|
||||
ignore = dirty
|
||||
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2695,7 +2695,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rln"
|
||||
version = "0.3.4"
|
||||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"ark-bn254 0.4.0",
|
||||
"ark-circom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -4260,7 +4260,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerokit_utils"
|
||||
version = "0.3.2"
|
||||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"ark-bn254 0.4.0",
|
||||
"ark-ff 0.4.1",
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use js_sys::{BigInt as JsBigInt, Object, Uint8Array};
|
||||
use rln::circuit::TEST_TREE_HEIGHT;
|
||||
use rln::utils::normalize_usize;
|
||||
use rln::circuit::{Fr, TEST_TREE_HEIGHT};
|
||||
use rln::hashers::{hash_to_field, poseidon_hash};
|
||||
use rln::utils::{bytes_le_to_fr, fr_to_bytes_le, normalize_usize};
|
||||
use rln_wasm::*;
|
||||
use wasm_bindgen::{prelude::*, JsValue};
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
@@ -33,26 +34,40 @@ mod tests {
|
||||
|
||||
// Creating membership key
|
||||
let mem_keys = wasm_key_gen(rln_instance).unwrap();
|
||||
let idkey = mem_keys.subarray(0, 32);
|
||||
let idcommitment = mem_keys.subarray(32, 64);
|
||||
|
||||
// Insert PK
|
||||
wasm_set_next_leaf(rln_instance, idcommitment).unwrap();
|
||||
let id_key = mem_keys.subarray(0, 32);
|
||||
let id_commitment = mem_keys.subarray(32, 64);
|
||||
|
||||
// Prepare the message
|
||||
let signal = "Hello World".as_bytes();
|
||||
|
||||
// Setting up the epoch (With 0s for the test)
|
||||
let epoch = Uint8Array::new_with_length(32);
|
||||
epoch.fill(0, 0, 32);
|
||||
let signal = b"Hello World";
|
||||
|
||||
let identity_index: usize = 0;
|
||||
// Setting up the epoch and rln_identifier
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
|
||||
let external_nullifier = poseidon_hash(&[epoch, rln_identifier]);
|
||||
let external_nullifier = fr_to_bytes_le(&external_nullifier);
|
||||
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = fr_to_bytes_le(&Fr::from(0));
|
||||
|
||||
let (id_commitment_fr, _) = bytes_le_to_fr(&id_commitment.to_vec()[..]);
|
||||
let rate_commitment = poseidon_hash(&[id_commitment_fr, user_message_limit]);
|
||||
|
||||
// Insert PK
|
||||
wasm_set_next_leaf(
|
||||
rln_instance,
|
||||
Uint8Array::from(fr_to_bytes_le(&rate_commitment).as_slice()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Serializing the message
|
||||
let mut serialized_vec: Vec<u8> = Vec::new();
|
||||
serialized_vec.append(&mut idkey.to_vec());
|
||||
serialized_vec.append(&mut id_key.to_vec());
|
||||
serialized_vec.append(&mut normalize_usize(identity_index));
|
||||
serialized_vec.append(&mut epoch.to_vec());
|
||||
serialized_vec.append(&mut fr_to_bytes_le(&user_message_limit).to_vec());
|
||||
serialized_vec.append(&mut message_id.to_vec());
|
||||
serialized_vec.append(&mut external_nullifier.to_vec());
|
||||
serialized_vec.append(&mut normalize_usize(signal.len()));
|
||||
serialized_vec.append(&mut signal.to_vec());
|
||||
let serialized_message = Uint8Array::from(&serialized_vec[..]);
|
||||
@@ -112,7 +127,6 @@ mod tests {
|
||||
#[wasm_bindgen_test]
|
||||
fn test_metadata() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let circom_path = format!("../rln/resources/tree_height_{TEST_TREE_HEIGHT}/rln.wasm");
|
||||
let zkey_path = format!("../rln/resources/tree_height_{TEST_TREE_HEIGHT}/rln_final.zkey");
|
||||
let vk_path =
|
||||
format!("../rln/resources/tree_height_{TEST_TREE_HEIGHT}/verification_key.json");
|
||||
@@ -122,7 +136,6 @@ mod tests {
|
||||
// Creating an instance of RLN
|
||||
let rln_instance = wasm_new(tree_height, zkey, vk).unwrap();
|
||||
|
||||
|
||||
let test_metadata = Uint8Array::new(&JsValue::from_str("test"));
|
||||
// Inserting random metadata
|
||||
wasm_set_metadata(rln_instance, test_metadata.clone()).unwrap();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rln"
|
||||
version = "0.3.4"
|
||||
version = "0.4.1"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "APIs to manage, compute and verify zkSNARK proofs and RLN primitives"
|
||||
@@ -42,7 +42,8 @@ once_cell = "=1.17.1"
|
||||
rand = "=0.8.5"
|
||||
rand_chacha = "=0.3.1"
|
||||
tiny-keccak = { version = "=2.0.2", features = ["keccak"] }
|
||||
utils = { package = "zerokit_utils", version = "=0.3.2", path = "../utils/", default-features = false }
|
||||
utils = { package = "zerokit_utils", version = "=0.4.1", path = "../utils/", default-features = false }
|
||||
|
||||
|
||||
# serialization
|
||||
serde_json = "=1.0.96"
|
||||
|
||||
@@ -56,7 +56,7 @@ However, if `N` is too big, this might require a bigger Powers of Tau ceremony t
|
||||
In such case we refer to the official [Circom documentation](https://docs.circom.io/getting-started/proving-circuits/#powers-of-tau) for instructions on how to run an appropriate Powers of Tau ceremony and Phase 2 in order to compile the desired circuit.
|
||||
|
||||
|
||||
Currently, the `rln` module comes with three [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) RLN circuits having Merkle tree of height `15`, `19` and `20`, respectively.
|
||||
Currently, the `rln` module comes with 2 [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) RLN circuits having Merkle tree of height `20` and `32`, respectively.
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -102,18 +102,20 @@ let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.key_gen(&mut buffer).unwrap();
|
||||
|
||||
// We deserialize the keygen output to obtain
|
||||
// the identiy_secret and id_commitment
|
||||
// the identity_secret and id_commitment
|
||||
let (identity_secret_hash, id_commitment) = deserialize_identity_pair(buffer.into_inner());
|
||||
```
|
||||
|
||||
### Add ID commitment to the RLN Merkle tree
|
||||
### Add Rate commitment to the RLN Merkle tree
|
||||
|
||||
```rust
|
||||
// We define the tree index where id_commitment will be added
|
||||
let id_index = 10;
|
||||
let user_message_limit = 10;
|
||||
|
||||
// We serialize id_commitment and pass it to set_leaf
|
||||
let mut buffer = Cursor::new(serialize_field_element(id_commitment));
|
||||
let rate_commitment = poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
let mut buffer = Cursor::new(serialize_field_element(rate_commitment));
|
||||
rln.set_leaf(id_index, &mut buffer).unwrap();
|
||||
```
|
||||
|
||||
@@ -141,11 +143,11 @@ let signal = b"RLN is awesome";
|
||||
|
||||
We prepare the input to the proof generation routine.
|
||||
|
||||
Input buffer is serialized as `[ identity_key | id_index | epoch | signal_len | signal ]`.
|
||||
Input buffer is serialized as `[ identity_key | id_index | epoch | rln_identifier | user_message_limit | message_id | signal_len | signal ]`.
|
||||
|
||||
```rust
|
||||
// We prepare input to the proof generation routine
|
||||
let proof_input = prepare_prove_input(identity_secret_hash, id_index, epoch, signal);
|
||||
let proof_input = prepare_prove_input(identity_secret_hash, id_index, epoch, rln_identifier, user_message_limit, message_id, signal);
|
||||
```
|
||||
|
||||
We are now ready to generate a RLN ZK proof along with the _public outputs_ of the ZK circuit evaluation.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 6,
|
||||
"vk_alpha_1": [
|
||||
"20124996762962216725442980738609010303800849578410091356605067053491763969391",
|
||||
"9118593021526896828671519912099489027245924097793322973632351264852174143923",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"4693952934005375501364248788849686435240706020501681709396105298107971354382",
|
||||
"14346958885444710485362620645446987998958218205939139994511461437152241966681"
|
||||
],
|
||||
[
|
||||
"16851772916911573982706166384196538392731905827088356034885868448550849804972",
|
||||
"823612331030938060799959717749043047845343400798220427319188951998582076532"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"1361919643088555407518565462732544232965454074504004321739078395285189557133",
|
||||
"20823246840633598579879223919854294301857184404415306521912631074982696570306"
|
||||
],
|
||||
[
|
||||
"7088590198103342249937795923142619828109070290720888704402714617857746884833",
|
||||
"8191367139632195506244169264298620546181137131063303219908889318280111188437"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"12608968655665301215455851857466367636344427685631271961542642719683786103711",
|
||||
"9849575605876329747382930567422916152871921500826003490242628251047652318086"
|
||||
],
|
||||
[
|
||||
"6322029441245076030714726551623552073612922718416871603535535085523083939021",
|
||||
"8700115492541474338049149013125102281865518624059015445617546140629435818912"
|
||||
],
|
||||
[
|
||||
"10674973475340072635573101639867487770811074181475255667220644196793546640210",
|
||||
"2926286967251299230490668407790788696102889214647256022788211245826267484824"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"9660441540778523475944706619139394922744328902833875392144658911530830074820",
|
||||
"19548113127774514328631808547691096362144426239827206966690021428110281506546"
|
||||
],
|
||||
[
|
||||
"1870837942477655969123169532603615788122896469891695773961478956740992497097",
|
||||
"12536105729661705698805725105036536744930776470051238187456307227425796690780"
|
||||
],
|
||||
[
|
||||
"21811903352654147452884857281720047789720483752548991551595462057142824037334",
|
||||
"19021616763967199151052893283384285352200445499680068407023236283004353578353"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"17643142412395322664866141827318671249236739056291610144830020671604112279111",
|
||||
"13273439661778801509295280274403992505521239023074387826870538372514206268318",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"12325966053136615826793633393742326952102053533176311103856731330114882211366",
|
||||
"6439956820140153832120005353467272867287237423425778281905068783317736451260",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"20405310272367450124741832665322768131899487413829191383721623069139009993137",
|
||||
"21336772016824870564600007750206596010566056069977718959140462128560786193566",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4007669092231576644992949839487535590075070172447826102934640178940614212519",
|
||||
"7597503385395289202372182678960254605827199004598882158153019657732525465207",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4545695279389338758267531646940033299700127241196839077811942492841603458462",
|
||||
"6635771967009274882904456432128877995932122611166121203658485990305433499873",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"7876954805169515500747828488548350352651069599547377092970620945851311591012",
|
||||
"7571431725691513008054581132582771105743462534789373657638701712901679323321",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"5563973122249220346301217166900152021860462617567141574881706390202619333219",
|
||||
"5147729144109676590873823097632042430451708874867871369293332620382492068692",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 6,
|
||||
"vk_alpha_1": [
|
||||
"20124996762962216725442980738609010303800849578410091356605067053491763969391",
|
||||
"9118593021526896828671519912099489027245924097793322973632351264852174143923",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"4693952934005375501364248788849686435240706020501681709396105298107971354382",
|
||||
"14346958885444710485362620645446987998958218205939139994511461437152241966681"
|
||||
],
|
||||
[
|
||||
"16851772916911573982706166384196538392731905827088356034885868448550849804972",
|
||||
"823612331030938060799959717749043047845343400798220427319188951998582076532"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"16125279975606773676640811113051624654121459921695914044301154938920321009721",
|
||||
"14844345250267029614093295465313288254479124604567709177260777529651293576873"
|
||||
],
|
||||
[
|
||||
"20349277326920398483890518242229158117668855310237215044647746783223259766294",
|
||||
"19338776107510040969200058390413661029003750817172740054990168933780935479540"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"12608968655665301215455851857466367636344427685631271961542642719683786103711",
|
||||
"9849575605876329747382930567422916152871921500826003490242628251047652318086"
|
||||
],
|
||||
[
|
||||
"6322029441245076030714726551623552073612922718416871603535535085523083939021",
|
||||
"8700115492541474338049149013125102281865518624059015445617546140629435818912"
|
||||
],
|
||||
[
|
||||
"10674973475340072635573101639867487770811074181475255667220644196793546640210",
|
||||
"2926286967251299230490668407790788696102889214647256022788211245826267484824"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"9660441540778523475944706619139394922744328902833875392144658911530830074820",
|
||||
"19548113127774514328631808547691096362144426239827206966690021428110281506546"
|
||||
],
|
||||
[
|
||||
"1870837942477655969123169532603615788122896469891695773961478956740992497097",
|
||||
"12536105729661705698805725105036536744930776470051238187456307227425796690780"
|
||||
],
|
||||
[
|
||||
"21811903352654147452884857281720047789720483752548991551595462057142824037334",
|
||||
"19021616763967199151052893283384285352200445499680068407023236283004353578353"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"5645604624116784480262312750033349186912223090668673154853165165224747369512",
|
||||
"5656337658385597582701340925622307146226708710361427687425735166776477641124",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"8216930132302312821663833393171053651364962198587857550991047765311607638330",
|
||||
"19934865864074163318938688021560358348660709566570123384268356491416384822148",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"11046959016591768534564223076484566731774575511709349452804727872479525392631",
|
||||
"9401797690410912638766111919371607085248054251975419812613989999345815833269",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"13216594148914395028254776738842380005944817065680915990743659996725367876414",
|
||||
"11541283802841111343960351782994043892623551381569479006737253908665900144087",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"6957074593219251760608960101283708711892008557897337713430173510328411964571",
|
||||
"21673833055087220750009279957462375662312260098732685145862504142183400549467",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"20795071270535109448604057031148356571036039566776607847840379441839742201050",
|
||||
"21654952744643117202636583766828639581880877547772465264383291983528268115687",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"19143058772755719660075704757531991493801758701561469885274062297246796623789",
|
||||
"3996020163280925980543600106196205910576345230982361007978823537163123181007",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 6,
|
||||
"nPublic": 5,
|
||||
"vk_alpha_1": [
|
||||
"20124996762962216725442980738609010303800849578410091356605067053491763969391",
|
||||
"9118593021526896828671519912099489027245924097793322973632351264852174143923",
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"4693952934005375501364248788849686435240706020501681709396105298107971354382",
|
||||
"14346958885444710485362620645446987998958218205939139994511461437152241966681"
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"16851772916911573982706166384196538392731905827088356034885868448550849804972",
|
||||
"823612331030938060799959717749043047845343400798220427319188951998582076532"
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
@@ -37,12 +37,12 @@
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"8353516066399360694538747105302262515182301251524941126222712285088022964076",
|
||||
"9329524012539638256356482961742014315122377605267454801030953882967973561832"
|
||||
"17077735495685170943380938230836408503627170115414840315502244846025577589191",
|
||||
"14030085636943255545683322474441991939484590437387381169642530788494152024614"
|
||||
],
|
||||
[
|
||||
"16805391589556134376869247619848130874761233086443465978238468412168162326401",
|
||||
"10111259694977636294287802909665108497237922060047080343914303287629927847739"
|
||||
"11568745146423307387256571230823432454624378106569286849514884592874522611163",
|
||||
"1838524899938769516485895655063198583192139511330418290063560641219523306282"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
@@ -52,67 +52,62 @@
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"12608968655665301215455851857466367636344427685631271961542642719683786103711",
|
||||
"9849575605876329747382930567422916152871921500826003490242628251047652318086"
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"6322029441245076030714726551623552073612922718416871603535535085523083939021",
|
||||
"8700115492541474338049149013125102281865518624059015445617546140629435818912"
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"10674973475340072635573101639867487770811074181475255667220644196793546640210",
|
||||
"2926286967251299230490668407790788696102889214647256022788211245826267484824"
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"9660441540778523475944706619139394922744328902833875392144658911530830074820",
|
||||
"19548113127774514328631808547691096362144426239827206966690021428110281506546"
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"1870837942477655969123169532603615788122896469891695773961478956740992497097",
|
||||
"12536105729661705698805725105036536744930776470051238187456307227425796690780"
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"21811903352654147452884857281720047789720483752548991551595462057142824037334",
|
||||
"19021616763967199151052893283384285352200445499680068407023236283004353578353"
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"11992897507809711711025355300535923222599547639134311050809253678876341466909",
|
||||
"17181525095924075896332561978747020491074338784673526378866503154966799128110",
|
||||
"4920513730204767532050733107749276406754520419375654722016092399980613788208",
|
||||
"10950491564509418434657706642388934308456795265036074733953533582377584967294",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"17018665030246167677911144513385572506766200776123272044534328594850561667818",
|
||||
"18601114175490465275436712413925513066546725461375425769709566180981674884464",
|
||||
"6815064660695497986531118446154820702646540722664044216580897159556261271171",
|
||||
"17838140936832571103329556013529166877877534025488014783346458943575275015438",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"18799470100699658367834559797874857804183288553462108031963980039244731716542",
|
||||
"13064227487174191981628537974951887429496059857753101852163607049188825592007",
|
||||
"16364982450206976302246609763791333525052810246590359380676749324389440643932",
|
||||
"17092624338100676284548565502349491320314889021833923882585524649862570629227",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"17432501889058124609368103715904104425610382063762621017593209214189134571156",
|
||||
"13406815149699834788256141097399354592751313348962590382887503595131085938635",
|
||||
"3679639231485547795420532910726924727560917141402837495597760107842698404034",
|
||||
"16213191511474848247596810551723578773353083440353745908057321946068926848382",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"10320964835612716439094703312987075811498239445882526576970512041988148264481",
|
||||
"9024164961646353611176283204118089412001502110138072989569118393359029324867",
|
||||
"9215428431027260354679105025212521481930206886203677270216204485256690813172",
|
||||
"934602510541226149881779979217731465262250233587980565969044391353665291792",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"718355081067365548229685160476620267257521491773976402837645005858953849298",
|
||||
"14635482993933988261008156660773180150752190597753512086153001683711587601974",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"11777720285956632126519898515392071627539405001940313098390150593689568177535",
|
||||
"8483603647274280691250972408211651407952870456587066148445913156086740744515",
|
||||
"8935861545794299876685457331391349387048184820319250771243971382360441890897",
|
||||
"4993459033694759724715904486381952906869986989682015547152342336961693234616",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
|
||||
BIN
rln/resources/tree_height_32/rln.wasm
Normal file
BIN
rln/resources/tree_height_32/rln.wasm
Normal file
Binary file not shown.
BIN
rln/resources/tree_height_32/rln_final.zkey
Normal file
BIN
rln/resources/tree_height_32/rln_final.zkey
Normal file
Binary file not shown.
114
rln/resources/tree_height_32/verification_key.json
Normal file
114
rln/resources/tree_height_32/verification_key.json
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128",
|
||||
"nPublic": 5,
|
||||
"vk_alpha_1": [
|
||||
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
||||
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
||||
"1"
|
||||
],
|
||||
"vk_beta_2": [
|
||||
[
|
||||
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
||||
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
||||
],
|
||||
[
|
||||
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
||||
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_gamma_2": [
|
||||
[
|
||||
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
||||
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
||||
],
|
||||
[
|
||||
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
||||
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_delta_2": [
|
||||
[
|
||||
"3689226096868373144622340732612563195789744807442014147637039988348252818659",
|
||||
"18947459102520510468597269280688700807407684209892273827108603062925288762423"
|
||||
],
|
||||
[
|
||||
"5816405977664254142436796931495067997250259145480168934320978750042633353708",
|
||||
"14555486789839131710516067578112557185806110684461247253491378577062852578892"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"vk_alphabeta_12": [
|
||||
[
|
||||
[
|
||||
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
||||
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
||||
],
|
||||
[
|
||||
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
||||
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
||||
],
|
||||
[
|
||||
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
||||
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
||||
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
||||
],
|
||||
[
|
||||
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
||||
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
||||
],
|
||||
[
|
||||
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
||||
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
||||
]
|
||||
]
|
||||
],
|
||||
"IC": [
|
||||
[
|
||||
"5412646265162057015134786739992128493053406364679846617542694915593022919217",
|
||||
"9665511386935901867415947590751330959748921059696950821222365265700369811120",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"4294362651275803035824711662252687124584574009834787359330648404293309808795",
|
||||
"1861758671717754835450145961645465880215655915164196594175485865489885224285",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"1911114017568107170522785254288953144010421698038439931935418407428234018676",
|
||||
"13761363892532562822351086117281964648116890138564516558345965908415019790129",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"16312980235585837964428386585067529342038135099260965575497230302984635878053",
|
||||
"20286500347141875536561618770383759234192052027362539966911091298688849002783",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"21038649368092225315431823433752123495654049075935052064397443455654061176031",
|
||||
"6976971039866104284556300526186000690370678593992968176463280189048347216392",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"971745799362951123575710699973701411260115357326598060711339429906895409324",
|
||||
"12959821343398475313407440786226277845673045139874184400082186049649123071798",
|
||||
"1"
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -30,12 +30,11 @@ const VK_FILENAME: &str = "verification_key.json";
|
||||
const WASM_FILENAME: &str = "rln.wasm";
|
||||
|
||||
// These parameters are used for tests
|
||||
// Note that the circuit and keys in TEST_RESOURCES_FOLDER are compiled for Merkle trees of height 15, 19 and 20
|
||||
// Note that the circuit and keys in TEST_RESOURCES_FOLDER are compiled for Merkle trees of height 20 & 32
|
||||
// Changing these parameters to other values than these defaults will cause zkSNARK proof verification to fail
|
||||
pub const TEST_PARAMETERS_INDEX: usize = 2;
|
||||
pub const TEST_TREE_HEIGHT: usize = [15, 19, 20][TEST_PARAMETERS_INDEX];
|
||||
pub const TEST_RESOURCES_FOLDER: &str =
|
||||
["tree_height_15", "tree_height_19", "tree_height_20"][TEST_PARAMETERS_INDEX];
|
||||
pub const TEST_PARAMETERS_INDEX: usize = 0;
|
||||
pub const TEST_TREE_HEIGHT: usize = [20, 32][TEST_PARAMETERS_INDEX];
|
||||
pub const TEST_RESOURCES_FOLDER: &str = ["tree_height_20", "tree_height_32"][TEST_PARAMETERS_INDEX];
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
static RESOURCES_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/resources");
|
||||
|
||||
@@ -7,6 +7,8 @@ pub mod pm_tree_adapter;
|
||||
pub mod poseidon_tree;
|
||||
pub mod protocol;
|
||||
pub mod public;
|
||||
#[cfg(test)]
|
||||
pub mod public_api_tests;
|
||||
pub mod utils;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
@@ -32,11 +32,12 @@ use utils::{ZerokitMerkleProof, ZerokitMerkleTree};
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct RLNWitnessInput {
|
||||
identity_secret: Fr,
|
||||
user_message_limit: Fr,
|
||||
message_id: Fr,
|
||||
path_elements: Vec<Fr>,
|
||||
identity_path_index: Vec<u8>,
|
||||
x: Fr,
|
||||
epoch: Fr,
|
||||
rln_identifier: Fr,
|
||||
external_nullifier: Fr,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -47,8 +48,7 @@ pub struct RLNProofValues {
|
||||
pub root: Fr,
|
||||
// Public Inputs:
|
||||
pub x: Fr,
|
||||
pub epoch: Fr,
|
||||
pub rln_identifier: Fr,
|
||||
pub external_nullifier: Fr,
|
||||
}
|
||||
|
||||
pub fn serialize_field_element(element: Fr) -> Vec<u8> {
|
||||
@@ -90,25 +90,46 @@ pub fn deserialize_identity_tuple(serialized: Vec<u8>) -> (Fr, Fr, Fr, Fr) {
|
||||
)
|
||||
}
|
||||
|
||||
/// Serializes witness
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `rln_witness.message_id` is not within `rln_witness.user_message_limit`.
|
||||
pub fn serialize_witness(rln_witness: &RLNWitnessInput) -> Result<Vec<u8>> {
|
||||
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
|
||||
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.identity_secret));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.message_id));
|
||||
serialized.append(&mut vec_fr_to_bytes_le(&rln_witness.path_elements)?);
|
||||
serialized.append(&mut vec_u8_to_bytes_le(&rln_witness.identity_path_index)?);
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.x));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.rln_identifier));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_witness.external_nullifier));
|
||||
|
||||
Ok(serialized)
|
||||
}
|
||||
|
||||
/// Deserializes witness
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `message_id` is not within `user_message_limit`.
|
||||
pub fn deserialize_witness(serialized: &[u8]) -> Result<(RLNWitnessInput, usize)> {
|
||||
let mut all_read: usize = 0;
|
||||
|
||||
let (identity_secret, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (user_message_limit, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (message_id, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
message_id_range_check(&message_id, &user_message_limit)?;
|
||||
|
||||
let (path_elements, read) = bytes_le_to_vec_fr(&serialized[all_read..])?;
|
||||
all_read += read;
|
||||
|
||||
@@ -118,13 +139,9 @@ pub fn deserialize_witness(serialized: &[u8]) -> Result<(RLNWitnessInput, usize)
|
||||
let (x, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (epoch, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
let (external_nullifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (rln_identifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
// TODO: check rln_identifier against public::RLN_IDENTIFIER
|
||||
if serialized.len() != all_read {
|
||||
return Err(Report::msg("serialized length is not equal to all_read"));
|
||||
}
|
||||
@@ -135,8 +152,9 @@ pub fn deserialize_witness(serialized: &[u8]) -> Result<(RLNWitnessInput, usize)
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
external_nullifier,
|
||||
user_message_limit,
|
||||
message_id,
|
||||
},
|
||||
all_read,
|
||||
))
|
||||
@@ -144,7 +162,7 @@ pub fn deserialize_witness(serialized: &[u8]) -> Result<(RLNWitnessInput, usize)
|
||||
|
||||
// This function deserializes input for kilic's rln generate_proof public API
|
||||
// https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L148
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | signal_len<8> | signal<var> ]
|
||||
// return value is a rln witness populated according to this information
|
||||
pub fn proof_inputs_to_rln_witness(
|
||||
tree: &mut PoseidonTree,
|
||||
@@ -160,7 +178,13 @@ pub fn proof_inputs_to_rln_witness(
|
||||
))?;
|
||||
all_read += 8;
|
||||
|
||||
let (epoch, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
let (user_message_limit, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (message_id, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (external_nullifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let signal_len = usize::try_from(u64::from_le_bytes(
|
||||
@@ -176,37 +200,47 @@ pub fn proof_inputs_to_rln_witness(
|
||||
|
||||
let x = hash_to_field(&signal);
|
||||
|
||||
let rln_identifier = hash_to_field(RLN_IDENTIFIER);
|
||||
|
||||
Ok((
|
||||
RLNWitnessInput {
|
||||
identity_secret,
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
user_message_limit,
|
||||
message_id,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
external_nullifier,
|
||||
},
|
||||
all_read,
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns `RLNWitnessInput` given a file with JSON serialized values.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `message_id` is not within `user_message_limit`.
|
||||
pub fn rln_witness_from_json(input_json_str: &str) -> Result<RLNWitnessInput> {
|
||||
let input_json: serde_json::Value =
|
||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
||||
|
||||
let identity_secret = str_to_fr(&input_json["identity_secret"].to_string(), 10)?;
|
||||
let user_message_limit = str_to_fr(&input_json["userMessageLimit"].to_string(), 10)?;
|
||||
|
||||
let path_elements = input_json["path_elements"]
|
||||
let message_id = str_to_fr(&input_json["messageId"].to_string(), 10)?;
|
||||
|
||||
message_id_range_check(&message_id, &user_message_limit)?;
|
||||
|
||||
let identity_secret = str_to_fr(&input_json["identitySecret"].to_string(), 10)?;
|
||||
|
||||
let path_elements = input_json["pathElements"]
|
||||
.as_array()
|
||||
.ok_or(Report::msg("not an array"))?
|
||||
.iter()
|
||||
.map(|v| str_to_fr(&v.to_string(), 10))
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
let identity_path_index_array = input_json["identity_path_index"]
|
||||
let identity_path_index_array = input_json["identityPathIndex"]
|
||||
.as_array()
|
||||
.ok_or(Report::msg("not an arrray"))?;
|
||||
.ok_or(Report::msg("not an array"))?;
|
||||
|
||||
let mut identity_path_index: Vec<u8> = vec![];
|
||||
|
||||
@@ -216,41 +250,46 @@ pub fn rln_witness_from_json(input_json_str: &str) -> Result<RLNWitnessInput> {
|
||||
|
||||
let x = str_to_fr(&input_json["x"].to_string(), 10)?;
|
||||
|
||||
let epoch = str_to_fr(&input_json["epoch"].to_string(), 16)?;
|
||||
|
||||
let rln_identifier = str_to_fr(&input_json["rln_identifier"].to_string(), 10)?;
|
||||
|
||||
// TODO: check rln_identifier against public::RLN_IDENTIFIER
|
||||
let external_nullifier = str_to_fr(&input_json["externalNullifier"].to_string(), 10)?;
|
||||
|
||||
Ok(RLNWitnessInput {
|
||||
identity_secret,
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
external_nullifier,
|
||||
user_message_limit,
|
||||
message_id,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates `RLNWitnessInput` from it's fields.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `message_id` is not within `user_message_limit`.
|
||||
pub fn rln_witness_from_values(
|
||||
identity_secret: Fr,
|
||||
merkle_proof: &MerkleProof,
|
||||
x: Fr,
|
||||
epoch: Fr,
|
||||
//rln_identifier: Fr,
|
||||
) -> RLNWitnessInput {
|
||||
external_nullifier: Fr,
|
||||
user_message_limit: Fr,
|
||||
message_id: Fr,
|
||||
) -> Result<RLNWitnessInput> {
|
||||
message_id_range_check(&message_id, &user_message_limit)?;
|
||||
|
||||
let path_elements = merkle_proof.get_path_elements();
|
||||
let identity_path_index = merkle_proof.get_path_index();
|
||||
let rln_identifier = hash_to_field(RLN_IDENTIFIER);
|
||||
|
||||
RLNWitnessInput {
|
||||
Ok(RLNWitnessInput {
|
||||
identity_secret,
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
}
|
||||
external_nullifier,
|
||||
user_message_limit,
|
||||
message_id,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn random_rln_witness(tree_height: usize) -> RLNWitnessInput {
|
||||
@@ -269,21 +308,26 @@ pub fn random_rln_witness(tree_height: usize) -> RLNWitnessInput {
|
||||
identity_path_index.push(rng.gen_range(0..2) as u8);
|
||||
}
|
||||
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = Fr::from(1);
|
||||
|
||||
RLNWitnessInput {
|
||||
identity_secret,
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
external_nullifier: poseidon_hash(&[epoch, rln_identifier]),
|
||||
user_message_limit,
|
||||
message_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn proof_values_from_witness(rln_witness: &RLNWitnessInput) -> RLNProofValues {
|
||||
pub fn proof_values_from_witness(rln_witness: &RLNWitnessInput) -> Result<RLNProofValues> {
|
||||
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
|
||||
|
||||
// y share
|
||||
let external_nullifier = poseidon_hash(&[rln_witness.epoch, rln_witness.rln_identifier]);
|
||||
let a_0 = rln_witness.identity_secret;
|
||||
let a_1 = poseidon_hash(&[a_0, external_nullifier]);
|
||||
let a_1 = poseidon_hash(&[a_0, rln_witness.external_nullifier, rln_witness.message_id]);
|
||||
let y = a_0 + rln_witness.x * a_1;
|
||||
|
||||
// Nullifier
|
||||
@@ -292,30 +336,28 @@ pub fn proof_values_from_witness(rln_witness: &RLNWitnessInput) -> RLNProofValue
|
||||
// Merkle tree root computations
|
||||
let root = compute_tree_root(
|
||||
&rln_witness.identity_secret,
|
||||
&rln_witness.user_message_limit,
|
||||
&rln_witness.path_elements,
|
||||
&rln_witness.identity_path_index,
|
||||
true,
|
||||
);
|
||||
|
||||
RLNProofValues {
|
||||
Ok(RLNProofValues {
|
||||
y,
|
||||
nullifier,
|
||||
root,
|
||||
x: rln_witness.x,
|
||||
epoch: rln_witness.epoch,
|
||||
rln_identifier: rln_witness.rln_identifier,
|
||||
}
|
||||
external_nullifier: rln_witness.external_nullifier,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn serialize_proof_values(rln_proof_values: &RLNProofValues) -> Vec<u8> {
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.root));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.external_nullifier));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.x));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.y));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.nullifier));
|
||||
serialized.append(&mut fr_to_bytes_le(&rln_proof_values.rln_identifier));
|
||||
|
||||
serialized
|
||||
}
|
||||
@@ -328,7 +370,7 @@ pub fn deserialize_proof_values(serialized: &[u8]) -> (RLNProofValues, usize) {
|
||||
let (root, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (epoch, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
let (external_nullifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (x, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
@@ -340,17 +382,13 @@ pub fn deserialize_proof_values(serialized: &[u8]) -> (RLNProofValues, usize) {
|
||||
let (nullifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
let (rln_identifier, read) = bytes_le_to_fr(&serialized[all_read..]);
|
||||
all_read += read;
|
||||
|
||||
(
|
||||
RLNProofValues {
|
||||
y,
|
||||
nullifier,
|
||||
root,
|
||||
x,
|
||||
epoch,
|
||||
rln_identifier,
|
||||
external_nullifier,
|
||||
},
|
||||
all_read,
|
||||
)
|
||||
@@ -359,14 +397,14 @@ pub fn deserialize_proof_values(serialized: &[u8]) -> (RLNProofValues, usize) {
|
||||
pub fn prepare_prove_input(
|
||||
identity_secret: Fr,
|
||||
id_index: usize,
|
||||
epoch: Fr,
|
||||
external_nullifier: Fr,
|
||||
signal: &[u8],
|
||||
) -> Vec<u8> {
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret));
|
||||
serialized.append(&mut normalize_usize(id_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
@@ -389,15 +427,13 @@ pub fn prepare_verify_input(proof_data: Vec<u8>, signal: &[u8]) -> Vec<u8> {
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
pub fn compute_tree_root(
|
||||
leaf: &Fr,
|
||||
identity_secret: &Fr,
|
||||
user_message_limit: &Fr,
|
||||
path_elements: &[Fr],
|
||||
identity_path_index: &[u8],
|
||||
hash_leaf: bool,
|
||||
) -> Fr {
|
||||
let mut root = *leaf;
|
||||
if hash_leaf {
|
||||
root = poseidon_hash(&[root]);
|
||||
}
|
||||
let id_commitment = poseidon_hash(&[*identity_secret]);
|
||||
let mut root = poseidon_hash(&[id_commitment, *user_message_limit]);
|
||||
|
||||
for i in 0..identity_path_index.len() {
|
||||
if identity_path_index[i] == 0 {
|
||||
@@ -488,11 +524,7 @@ pub fn extended_seeded_keygen(signal: &[u8]) -> (Fr, Fr, Fr, Fr) {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn compute_id_secret(
|
||||
share1: (Fr, Fr),
|
||||
share2: (Fr, Fr),
|
||||
external_nullifier: Fr,
|
||||
) -> Result<Fr, String> {
|
||||
pub fn compute_id_secret(share1: (Fr, Fr), share2: (Fr, Fr)) -> Result<Fr, String> {
|
||||
// Assuming a0 is the identity secret and a1 = poseidonHash([a0, external_nullifier]),
|
||||
// a (x,y) share satisfies the following relation
|
||||
// y = a_0 + x * a_1
|
||||
@@ -506,14 +538,7 @@ pub fn compute_id_secret(
|
||||
let a_0 = y1 - x1 * a_1;
|
||||
|
||||
// If shares come from the same polynomial, a0 is correctly recovered and a1 = poseidonHash([a0, external_nullifier])
|
||||
let computed_a_1 = poseidon_hash(&[a_0, external_nullifier]);
|
||||
|
||||
if a_1 == computed_a_1 {
|
||||
// We successfully recovered the identity secret
|
||||
Ok(a_0)
|
||||
} else {
|
||||
Err("Cannot recover identity_secret_hash from provided shares".into())
|
||||
}
|
||||
Ok(a_0)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
@@ -594,10 +619,17 @@ pub fn generate_proof_with_witness(
|
||||
Ok(proof)
|
||||
}
|
||||
|
||||
/// Formats inputs for witness calculation
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `rln_witness.message_id` is not within `rln_witness.user_message_limit`.
|
||||
pub fn inputs_for_witness_calculation(
|
||||
rln_witness: &RLNWitnessInput,
|
||||
) -> Result<[(&str, Vec<BigInt>); 6]> {
|
||||
// We confert the path indexes to field elements
|
||||
) -> Result<[(&str, Vec<BigInt>); 7]> {
|
||||
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
|
||||
|
||||
// We convert the path indexes to field elements
|
||||
// TODO: check if necessary
|
||||
let mut path_elements = Vec::new();
|
||||
|
||||
@@ -613,16 +645,20 @@ pub fn inputs_for_witness_calculation(
|
||||
|
||||
Ok([
|
||||
(
|
||||
"identity_secret",
|
||||
"identitySecret",
|
||||
vec![to_bigint(&rln_witness.identity_secret)?],
|
||||
),
|
||||
("path_elements", path_elements),
|
||||
("identity_path_index", identity_path_index),
|
||||
("x", vec![to_bigint(&rln_witness.x)?]),
|
||||
("epoch", vec![to_bigint(&rln_witness.epoch)?]),
|
||||
(
|
||||
"rln_identifier",
|
||||
vec![to_bigint(&rln_witness.rln_identifier)?],
|
||||
"userMessageLimit",
|
||||
vec![to_bigint(&rln_witness.user_message_limit)?],
|
||||
),
|
||||
("messageId", vec![to_bigint(&rln_witness.message_id)?]),
|
||||
("pathElements", path_elements),
|
||||
("identityPathIndex", identity_path_index),
|
||||
("x", vec![to_bigint(&rln_witness.x)?]),
|
||||
(
|
||||
"externalNullifier",
|
||||
vec![to_bigint(&rln_witness.external_nullifier)?],
|
||||
),
|
||||
])
|
||||
}
|
||||
@@ -671,7 +707,6 @@ pub fn generate_proof(
|
||||
// If in debug mode, we measure and later print time take to compute proof
|
||||
#[cfg(debug_assertions)]
|
||||
let now = Instant::now();
|
||||
|
||||
let proof = Groth16::<_, CircomReduction>::create_proof_with_reduction_and_matrices(
|
||||
&proving_key.0,
|
||||
r,
|
||||
@@ -705,8 +740,7 @@ pub fn verify_proof(
|
||||
proof_values.root,
|
||||
proof_values.nullifier,
|
||||
proof_values.x,
|
||||
proof_values.epoch,
|
||||
proof_values.rln_identifier,
|
||||
proof_values.external_nullifier,
|
||||
];
|
||||
|
||||
// Check that the proof is valid
|
||||
@@ -729,7 +763,13 @@ pub fn verify_proof(
|
||||
///
|
||||
/// Returns a JSON object containing the inputs necessary to calculate
|
||||
/// the witness with CIRCOM on javascript
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if `rln_witness.message_id` is not within `rln_witness.user_message_limit`.
|
||||
pub fn get_json_inputs(rln_witness: &RLNWitnessInput) -> Result<serde_json::Value> {
|
||||
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
|
||||
|
||||
let mut path_elements = Vec::new();
|
||||
|
||||
for v in rln_witness.path_elements.iter() {
|
||||
@@ -743,13 +783,23 @@ pub fn get_json_inputs(rln_witness: &RLNWitnessInput) -> Result<serde_json::Valu
|
||||
.for_each(|v| identity_path_index.push(BigInt::from(*v).to_str_radix(10)));
|
||||
|
||||
let inputs = serde_json::json!({
|
||||
"identity_secret": to_bigint(&rln_witness.identity_secret)?.to_str_radix(10),
|
||||
"path_elements": path_elements,
|
||||
"identity_path_index": identity_path_index,
|
||||
"identitySecret": to_bigint(&rln_witness.identity_secret)?.to_str_radix(10),
|
||||
"userMessageLimit": to_bigint(&rln_witness.user_message_limit)?.to_str_radix(10),
|
||||
"messageId": to_bigint(&rln_witness.message_id)?.to_str_radix(10),
|
||||
"pathElements": path_elements,
|
||||
"identityPathIndex": identity_path_index,
|
||||
"x": to_bigint(&rln_witness.x)?.to_str_radix(10),
|
||||
"epoch": format!("0x{:064x}", to_bigint(&rln_witness.epoch)?),
|
||||
"rln_identifier": to_bigint(&rln_witness.rln_identifier)?.to_str_radix(10),
|
||||
"externalNullifier": to_bigint(&rln_witness.external_nullifier)?.to_str_radix(10),
|
||||
});
|
||||
|
||||
Ok(inputs)
|
||||
}
|
||||
|
||||
pub fn message_id_range_check(message_id: &Fr, user_message_limit: &Fr) -> Result<()> {
|
||||
if message_id > user_message_limit {
|
||||
return Err(color_eyre::Report::msg(
|
||||
"message_id is not within user_message_limit",
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
995
rln/src/public_api_tests.rs
Normal file
995
rln/src/public_api_tests.rs
Normal file
@@ -0,0 +1,995 @@
|
||||
use crate::circuit::{Curve, Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT};
|
||||
use crate::hashers::{hash_to_field, poseidon_hash as utils_poseidon_hash};
|
||||
use crate::protocol::*;
|
||||
use crate::public::RLN;
|
||||
use crate::utils::*;
|
||||
use ark_groth16::Proof as ArkProof;
|
||||
use ark_serialize::{CanonicalDeserialize, Read};
|
||||
use num_bigint::BigInt;
|
||||
use std::io::Cursor;
|
||||
use std::str::FromStr;
|
||||
use utils::ZerokitMerkleTree;
|
||||
|
||||
use ark_std::{rand::thread_rng, UniformRand};
|
||||
use rand::Rng;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
#[test]
|
||||
// We test merkle batch Merkle tree additions
|
||||
fn test_merkle_operations() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We first add leaves one by one specifying the index
|
||||
for (i, leaf) in leaves.iter().enumerate() {
|
||||
// We check if the number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), i);
|
||||
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&leaf));
|
||||
rln.set_leaf(i, &mut buffer).unwrap();
|
||||
}
|
||||
|
||||
// We get the root of the tree obtained adding one leaf per time
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_single, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// We reset the tree to default
|
||||
rln.set_tree(tree_height).unwrap();
|
||||
|
||||
// We add leaves one by one using the internal index (new leaves goes in next available position)
|
||||
for leaf in &leaves {
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&leaf));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
}
|
||||
|
||||
// We check if numbers of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves using the internal index
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_next, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_single, root_next);
|
||||
|
||||
// We reset the tree to default
|
||||
rln.set_tree(tree_height).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_batch, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_single, root_batch);
|
||||
|
||||
// We now delete all leaves set and check if the root corresponds to the empty tree root
|
||||
// delete calls over indexes higher than no_of_leaves are ignored and will not increase self.tree.next_index
|
||||
for i in 0..no_of_leaves {
|
||||
rln.delete_leaf(i).unwrap();
|
||||
}
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_delete, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// We reset the tree to default
|
||||
rln.set_tree(tree_height).unwrap();
|
||||
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_empty, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_delete, root_empty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// We test leaf setting with a custom index, to enable batch updates to the root
|
||||
// Uses `set_leaves_from` to set leaves in a batch, from index `start_index`
|
||||
fn test_leaf_setting_with_index() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// set_index is the index from which we start setting leaves
|
||||
// random number between 0..no_of_leaves
|
||||
let set_index = rng.gen_range(0..no_of_leaves) as usize;
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_batch_with_init, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// `init_tree_with_leaves` resets the tree to the height it was initialized with, using `set_tree`
|
||||
|
||||
// We add leaves in a batch starting from index 0..set_index
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves[0..set_index]).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We add the remaining n leaves in a batch starting from index m
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves[set_index..]).unwrap());
|
||||
rln.set_leaves_from(set_index, &mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_batch_with_custom_index, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_batch_with_init, root_batch_with_custom_index);
|
||||
|
||||
// We reset the tree to default
|
||||
rln.set_tree(tree_height).unwrap();
|
||||
|
||||
// We add leaves one by one using the internal index (new leaves goes in next available position)
|
||||
for leaf in &leaves {
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&leaf));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
}
|
||||
|
||||
// We check if numbers of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves using the internal index
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_single_additions, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_batch_with_init, root_single_additions);
|
||||
|
||||
rln.flush().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Tests the atomic_operation fn, which set_leaves_from uses internally
|
||||
fn test_atomic_operation() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_insertion, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
let last_leaf = leaves.last().unwrap();
|
||||
let last_leaf_index = no_of_leaves - 1;
|
||||
let indices = vec![last_leaf_index as u8];
|
||||
let last_leaf = vec![*last_leaf];
|
||||
let indices_buffer = Cursor::new(vec_u8_to_bytes_le(&indices).unwrap());
|
||||
let leaves_buffer = Cursor::new(vec_fr_to_bytes_le(&last_leaf).unwrap());
|
||||
|
||||
rln.atomic_operation(last_leaf_index, leaves_buffer, indices_buffer)
|
||||
.unwrap();
|
||||
|
||||
// We get the root of the tree obtained after a no-op
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_noop, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_after_insertion, root_after_noop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_operation_zero_indexed() {
|
||||
// Test duplicated from https://github.com/waku-org/go-zerokit-rln/pull/12/files
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_insertion, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
let zero_index = 0;
|
||||
let indices = vec![zero_index as u8];
|
||||
let zero_leaf: Vec<Fr> = vec![];
|
||||
let indices_buffer = Cursor::new(vec_u8_to_bytes_le(&indices).unwrap());
|
||||
let leaves_buffer = Cursor::new(vec_fr_to_bytes_le(&zero_leaf).unwrap());
|
||||
rln.atomic_operation(0, leaves_buffer, indices_buffer)
|
||||
.unwrap();
|
||||
|
||||
// We get the root of the tree obtained after a deletion
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_deletion, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_ne!(root_after_insertion, root_after_deletion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_operation_consistency() {
|
||||
// Test duplicated from https://github.com/waku-org/go-zerokit-rln/pull/12/files
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), no_of_leaves);
|
||||
|
||||
// We get the root of the tree obtained adding leaves in batch
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_insertion, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
let set_index = rng.gen_range(0..no_of_leaves) as usize;
|
||||
let indices = vec![set_index as u8];
|
||||
let zero_leaf: Vec<Fr> = vec![];
|
||||
let indices_buffer = Cursor::new(vec_u8_to_bytes_le(&indices).unwrap());
|
||||
let leaves_buffer = Cursor::new(vec_fr_to_bytes_le(&zero_leaf).unwrap());
|
||||
rln.atomic_operation(0, leaves_buffer, indices_buffer)
|
||||
.unwrap();
|
||||
|
||||
// We get the root of the tree obtained after a deletion
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_deletion, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_ne!(root_after_insertion, root_after_deletion);
|
||||
|
||||
// We get the leaf
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_leaf(set_index, &mut output_buffer).unwrap();
|
||||
let (received_leaf, _) = bytes_le_to_fr(output_buffer.into_inner().as_ref());
|
||||
|
||||
assert_eq!(received_leaf, Fr::from(0));
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
#[test]
|
||||
// This test checks if `set_leaves_from` throws an error when the index is out of bounds
|
||||
fn test_set_leaves_bad_index() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
let bad_index = (1 << tree_height) - rng.gen_range(0..no_of_leaves) as usize;
|
||||
|
||||
// We create a new tree
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// Get root of empty tree
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_empty, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.set_leaves_from(bad_index, &mut buffer)
|
||||
.expect_err("Should throw an error");
|
||||
|
||||
// We check if number of leaves set is consistent
|
||||
assert_eq!(rln.tree.leaves_set(), 0);
|
||||
|
||||
// Get the root of the tree
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root_after_bad_set, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
assert_eq!(root_empty, root_after_bad_set);
|
||||
}
|
||||
|
||||
fn fq_from_str(s: String) -> ark_bn254::Fq {
|
||||
ark_bn254::Fq::from_str(&s).unwrap()
|
||||
}
|
||||
|
||||
fn g1_from_str(g1: &[String]) -> ark_bn254::G1Affine {
|
||||
let x = fq_from_str(g1[0].clone());
|
||||
let y = fq_from_str(g1[1].clone());
|
||||
let z = fq_from_str(g1[2].clone());
|
||||
ark_bn254::G1Affine::from(ark_bn254::G1Projective::new(x, y, z))
|
||||
}
|
||||
|
||||
fn g2_from_str(g2: &[Vec<String>]) -> ark_bn254::G2Affine {
|
||||
let c0 = fq_from_str(g2[0][0].clone());
|
||||
let c1 = fq_from_str(g2[0][1].clone());
|
||||
let x = ark_bn254::Fq2::new(c0, c1);
|
||||
|
||||
let c0 = fq_from_str(g2[1][0].clone());
|
||||
let c1 = fq_from_str(g2[1][1].clone());
|
||||
let y = ark_bn254::Fq2::new(c0, c1);
|
||||
|
||||
let c0 = fq_from_str(g2[2][0].clone());
|
||||
let c1 = fq_from_str(g2[2][1].clone());
|
||||
let z = ark_bn254::Fq2::new(c0, c1);
|
||||
|
||||
ark_bn254::G2Affine::from(ark_bn254::G2Projective::new(x, y, z))
|
||||
}
|
||||
|
||||
fn value_to_string_vec(value: &Value) -> Vec<String> {
|
||||
value
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|val| val.as_str().unwrap().to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groth16_proof_hardcoded() {
|
||||
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 valid_snarkjs_proof = json!({
|
||||
"pi_a": [
|
||||
"606446415626469993821291758185575230335423926365686267140465300918089871829",
|
||||
"14881534001609371078663128199084130129622943308489025453376548677995646280161",
|
||||
"1"
|
||||
],
|
||||
"pi_b": [
|
||||
[
|
||||
"18053812507994813734583839134426913715767914942522332114506614735770984570178",
|
||||
"11219916332635123001710279198522635266707985651975761715977705052386984005181"
|
||||
],
|
||||
[
|
||||
"17371289494006920912949790045699521359436706797224428511776122168520286372970",
|
||||
"14038575727257298083893642903204723310279435927688342924358714639926373603890"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"0"
|
||||
]
|
||||
],
|
||||
"pi_c": [
|
||||
"17701377127561410274754535747274973758826089226897242202671882899370780845888",
|
||||
"12608543716397255084418384146504333522628400182843246910626782513289789807030",
|
||||
"1"
|
||||
],
|
||||
"protocol": "groth16",
|
||||
"curve": "bn128"
|
||||
});
|
||||
let valid_ark_proof = ArkProof {
|
||||
a: g1_from_str(&value_to_string_vec(&valid_snarkjs_proof["pi_a"])),
|
||||
b: g2_from_str(
|
||||
&valid_snarkjs_proof["pi_b"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|item| value_to_string_vec(item))
|
||||
.collect::<Vec<Vec<String>>>(),
|
||||
),
|
||||
c: g1_from_str(&value_to_string_vec(&valid_snarkjs_proof["pi_c"])),
|
||||
};
|
||||
|
||||
let valid_proof_values = RLNProofValues {
|
||||
x: str_to_fr(
|
||||
"20645213238265527935869146898028115621427162613172918400241870500502509785943",
|
||||
10,
|
||||
)
|
||||
.unwrap(),
|
||||
external_nullifier: str_to_fr(
|
||||
"21074405743803627666274838159589343934394162804826017440941339048886754734203",
|
||||
10,
|
||||
)
|
||||
.unwrap(),
|
||||
y: str_to_fr(
|
||||
"16401008481486069296141645075505218976370369489687327284155463920202585288271",
|
||||
10,
|
||||
)
|
||||
.unwrap(),
|
||||
root: str_to_fr(
|
||||
"8502402278351299594663821509741133196466235670407051417832304486953898514733",
|
||||
10,
|
||||
)
|
||||
.unwrap(),
|
||||
nullifier: str_to_fr(
|
||||
"9102791780887227194595604713537772536258726662792598131262022534710887343694",
|
||||
10,
|
||||
)
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let verified = verify_proof(&rln.verification_key, &valid_ark_proof, &valid_proof_values);
|
||||
assert!(verified.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
// This test is similar to the one in lib, but uses only public API
|
||||
fn test_groth16_proof() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// Note: we only test Groth16 proof generation, so we ignore setting the tree in the RLN object
|
||||
let rln_witness = random_rln_witness(tree_height);
|
||||
let proof_values = proof_values_from_witness(&rln_witness).unwrap();
|
||||
|
||||
// We compute a Groth16 proof
|
||||
let mut input_buffer = Cursor::new(serialize_witness(&rln_witness).unwrap());
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.prove(&mut input_buffer, &mut output_buffer).unwrap();
|
||||
let serialized_proof = output_buffer.into_inner();
|
||||
|
||||
// Before checking public verify API, we check that the (deserialized) proof generated by prove is actually valid
|
||||
let proof = ArkProof::deserialize_compressed(&mut Cursor::new(&serialized_proof)).unwrap();
|
||||
let verified = verify_proof(&rln.verification_key, &proof, &proof_values);
|
||||
// dbg!(verified.unwrap());
|
||||
assert!(verified.unwrap());
|
||||
|
||||
// We prepare the input to prove API, consisting of serialized_proof (compressed, 4*32 bytes) || serialized_proof_values (6*32 bytes)
|
||||
let serialized_proof_values = serialize_proof_values(&proof_values);
|
||||
let mut verify_data = Vec::<u8>::new();
|
||||
verify_data.extend(&serialized_proof);
|
||||
verify_data.extend(&serialized_proof_values);
|
||||
let mut input_buffer = Cursor::new(verify_data);
|
||||
|
||||
// We verify the Groth16 proof against the provided proof values
|
||||
let verified = rln.verify(&mut input_buffer).unwrap();
|
||||
|
||||
assert!(verified);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rln_proof() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
let id_commitment = Fr::rand(&mut rng);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, Fr::from(100)]);
|
||||
leaves.push(rate_commitment);
|
||||
}
|
||||
|
||||
// We create a new RLN instance
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// Generate identity pair
|
||||
let (identity_secret_hash, id_commitment) = keygen();
|
||||
|
||||
// We set as leaf rate_commitment after storing its index
|
||||
let identity_index = rln.tree.leaves_set();
|
||||
let user_message_limit = Fr::from(65535);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
|
||||
// We generate a random signal
|
||||
let mut rng = rand::thread_rng();
|
||||
let signal: [u8; 32] = rng.gen();
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
// We generate a random rln_identifier
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized.append(&mut normalize_usize(identity_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&Fr::from(1)));
|
||||
serialized.append(&mut fr_to_bytes_le(&utils_poseidon_hash(&[
|
||||
epoch,
|
||||
rln_identifier,
|
||||
])));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
let mut input_buffer = Cursor::new(serialized);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof(&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();
|
||||
|
||||
// We prepare input for verify_rln_proof API
|
||||
// input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
||||
// that is [ proof_data || signal_len<8> | signal<var> ]
|
||||
proof_data.append(&mut normalize_usize(signal.len()));
|
||||
proof_data.append(&mut signal.to_vec());
|
||||
|
||||
let mut input_buffer = Cursor::new(proof_data);
|
||||
let verified = rln.verify_rln_proof(&mut input_buffer).unwrap();
|
||||
|
||||
assert!(verified);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rln_with_witness() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new RLN instance
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// Generate identity pair
|
||||
let (identity_secret_hash, id_commitment) = keygen();
|
||||
|
||||
// We set as leaf rate_commitment after storing its index
|
||||
let identity_index = rln.tree.leaves_set();
|
||||
let user_message_limit = Fr::from(100);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
|
||||
// We generate a random signal
|
||||
let mut rng = rand::thread_rng();
|
||||
let signal: [u8; 32] = rng.gen();
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
// We generate a random rln_identifier
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized.append(&mut normalize_usize(identity_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&Fr::from(1)));
|
||||
serialized.append(&mut fr_to_bytes_le(&utils_poseidon_hash(&[
|
||||
epoch,
|
||||
rln_identifier,
|
||||
])));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
let mut input_buffer = Cursor::new(serialized);
|
||||
|
||||
// We read input RLN witness and we serialize_compressed it
|
||||
let mut witness_byte: Vec<u8> = Vec::new();
|
||||
input_buffer.read_to_end(&mut witness_byte).unwrap();
|
||||
let (rln_witness, _) = proof_inputs_to_rln_witness(&mut rln.tree, &witness_byte).unwrap();
|
||||
|
||||
let serialized_witness = serialize_witness(&rln_witness).unwrap();
|
||||
|
||||
// Calculate witness outside zerokit (simulating what JS is doing)
|
||||
let inputs = inputs_for_witness_calculation(&rln_witness)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|(name, values)| (name.to_string(), values));
|
||||
let calculated_witness = rln
|
||||
.witness_calculator
|
||||
.lock()
|
||||
.expect("witness_calculator mutex should not get poisoned")
|
||||
.calculate_witness_element::<Curve, _>(inputs, false)
|
||||
.map_err(ProofError::WitnessError)
|
||||
.unwrap();
|
||||
|
||||
let calculated_witness_vec: Vec<BigInt> = calculated_witness
|
||||
.into_iter()
|
||||
.map(|v| to_bigint(&v).unwrap())
|
||||
.collect();
|
||||
|
||||
// Generating the proof
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof_with_witness(
|
||||
calculated_witness_vec,
|
||||
serialized_witness,
|
||||
&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();
|
||||
|
||||
// We prepare input for verify_rln_proof API
|
||||
// input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
||||
// that is [ proof_data || signal_len<8> | signal<var> ]
|
||||
proof_data.append(&mut normalize_usize(signal.len()));
|
||||
proof_data.append(&mut signal.to_vec());
|
||||
|
||||
let mut input_buffer = Cursor::new(proof_data);
|
||||
let verified = rln.verify_rln_proof(&mut input_buffer).unwrap();
|
||||
|
||||
assert!(verified);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proof_verification_with_roots() {
|
||||
// The first part is similar to test_rln_with_witness
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
}
|
||||
|
||||
// We create a new RLN instance
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We add leaves in a batch into the tree
|
||||
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap());
|
||||
rln.init_tree_with_leaves(&mut buffer).unwrap();
|
||||
|
||||
// Generate identity pair
|
||||
let (identity_secret_hash, id_commitment) = keygen();
|
||||
|
||||
// We set as leaf id_commitment after storing its index
|
||||
let identity_index = rln.tree.leaves_set();
|
||||
let user_message_limit = Fr::from(100);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
|
||||
// We generate a random signal
|
||||
let mut rng = thread_rng();
|
||||
let signal: [u8; 32] = rng.gen();
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
// We generate a random rln_identifier
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | rln_identifier<32> | user_message_limit<32> | message_id<32> | signal_len<8> | signal<var> ]
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized.append(&mut normalize_usize(identity_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&Fr::from(1)));
|
||||
serialized.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
let mut input_buffer = Cursor::new(serialized);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof(&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();
|
||||
|
||||
// We prepare input for verify_rln_proof API
|
||||
// input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
||||
// that is [ proof_data || signal_len<8> | signal<var> ]
|
||||
proof_data.append(&mut normalize_usize(signal.len()));
|
||||
proof_data.append(&mut signal.to_vec());
|
||||
let input_buffer = Cursor::new(proof_data);
|
||||
|
||||
// If no roots is provided, proof validation is skipped and if the remaining proof values are valid, the proof will be correctly verified
|
||||
let mut roots_serialized: Vec<u8> = Vec::new();
|
||||
let mut roots_buffer = Cursor::new(roots_serialized.clone());
|
||||
let verified = rln
|
||||
.verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
|
||||
.unwrap();
|
||||
|
||||
assert!(verified);
|
||||
|
||||
// We serialize in the roots buffer some random values and we check that the proof is not verified since doesn't contain the correct root the proof refers to
|
||||
for _ in 0..5 {
|
||||
roots_serialized.append(&mut fr_to_bytes_le(&Fr::rand(&mut rng)));
|
||||
}
|
||||
roots_buffer = Cursor::new(roots_serialized.clone());
|
||||
let verified = rln
|
||||
.verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(verified, false);
|
||||
|
||||
// We get the root of the tree obtained adding one leaf per time
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
// We add the real root and we check if now the proof is verified
|
||||
roots_serialized.append(&mut fr_to_bytes_le(&root));
|
||||
roots_buffer = Cursor::new(roots_serialized.clone());
|
||||
let verified = rln
|
||||
.verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
|
||||
.unwrap();
|
||||
|
||||
assert!(verified);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recover_id_secret() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
// We create a new RLN instance
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// Generate identity pair
|
||||
let (identity_secret_hash, id_commitment) = keygen();
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = Fr::from(0);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
// We set as leaf id_commitment after storing its index
|
||||
let identity_index = rln.tree.leaves_set();
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
|
||||
// We generate two random signals
|
||||
let mut rng = rand::thread_rng();
|
||||
let signal1: [u8; 32] = rng.gen();
|
||||
|
||||
let signal2: [u8; 32] = rng.gen();
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
// We generate a random rln_identifier
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
// We generate two proofs using same epoch but different signals.
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
let mut serialized1: Vec<u8> = Vec::new();
|
||||
serialized1.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized1.append(&mut normalize_usize(identity_index));
|
||||
serialized1.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized1.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized1.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
|
||||
// The first part is the same for both proof input, so we clone
|
||||
let mut serialized2 = serialized1.clone();
|
||||
|
||||
// We attach the first signal to the first proof input
|
||||
serialized1.append(&mut normalize_usize(signal1.len()));
|
||||
serialized1.append(&mut signal1.to_vec());
|
||||
|
||||
// We attach the second signal to the first proof input
|
||||
serialized2.append(&mut normalize_usize(signal2.len()));
|
||||
serialized2.append(&mut signal2.to_vec());
|
||||
|
||||
// We generate the first proof
|
||||
let mut input_buffer = Cursor::new(serialized1);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof(&mut input_buffer, &mut output_buffer)
|
||||
.unwrap();
|
||||
let proof_data_1 = output_buffer.into_inner();
|
||||
|
||||
// We generate the second proof
|
||||
let mut input_buffer = Cursor::new(serialized2);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof(&mut input_buffer, &mut output_buffer)
|
||||
.unwrap();
|
||||
let proof_data_2 = output_buffer.into_inner();
|
||||
|
||||
let mut input_proof_data_1 = Cursor::new(proof_data_1.clone());
|
||||
let mut input_proof_data_2 = Cursor::new(proof_data_2);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.recover_id_secret(
|
||||
&mut input_proof_data_1,
|
||||
&mut input_proof_data_2,
|
||||
&mut output_buffer,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let serialized_identity_secret_hash = output_buffer.into_inner();
|
||||
|
||||
// We ensure that a non-empty value is written to output_buffer
|
||||
assert!(!serialized_identity_secret_hash.is_empty());
|
||||
|
||||
// We check if the recovered identity secret hash corresponds to the original one
|
||||
let (recovered_identity_secret_hash, _) = bytes_le_to_fr(&serialized_identity_secret_hash);
|
||||
assert_eq!(recovered_identity_secret_hash, identity_secret_hash);
|
||||
|
||||
// We now test that computing identity_secret_hash is unsuccessful if shares computed from two different identity secret hashes but within same epoch are passed
|
||||
|
||||
// We generate a new identity pair
|
||||
let (identity_secret_hash_new, id_commitment_new) = keygen();
|
||||
let rate_commitment_new = utils_poseidon_hash(&[id_commitment_new, user_message_limit]);
|
||||
|
||||
// We add it to the tree
|
||||
let identity_index_new = rln.tree.leaves_set();
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment_new));
|
||||
rln.set_next_leaf(&mut buffer).unwrap();
|
||||
|
||||
// We generate a random signals
|
||||
let signal3: [u8; 32] = rng.gen();
|
||||
|
||||
// We prepare proof input. Note that epoch is the same as before
|
||||
let mut serialized3: Vec<u8> = Vec::new();
|
||||
serialized3.append(&mut fr_to_bytes_le(&identity_secret_hash_new));
|
||||
serialized3.append(&mut normalize_usize(identity_index_new));
|
||||
serialized3.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized3.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized3.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized3.append(&mut normalize_usize(signal3.len()));
|
||||
serialized3.append(&mut signal3.to_vec());
|
||||
|
||||
// We generate the proof
|
||||
let mut input_buffer = Cursor::new(serialized3);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.generate_rln_proof(&mut input_buffer, &mut output_buffer)
|
||||
.unwrap();
|
||||
let proof_data_3 = output_buffer.into_inner();
|
||||
|
||||
// We attempt to recover the secret using share1 (coming from identity_secret_hash) and share3 (coming from identity_secret_hash_new)
|
||||
|
||||
let mut input_proof_data_1 = Cursor::new(proof_data_1.clone());
|
||||
let mut input_proof_data_3 = Cursor::new(proof_data_3);
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.recover_id_secret(
|
||||
&mut input_proof_data_1,
|
||||
&mut input_proof_data_3,
|
||||
&mut output_buffer,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let serialized_identity_secret_hash = output_buffer.into_inner();
|
||||
let (recovered_identity_secret_hash_new, _) = bytes_le_to_fr(&serialized_identity_secret_hash);
|
||||
|
||||
// ensure that the recovered secret does not match with either of the
|
||||
// used secrets in proof generation
|
||||
assert_ne!(recovered_identity_secret_hash_new, identity_secret_hash_new);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_leaf() {
|
||||
// We generate a random tree
|
||||
let tree_height = 10;
|
||||
let mut rng = thread_rng();
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
// We generate a random leaf
|
||||
let leaf = Fr::rand(&mut rng);
|
||||
|
||||
// We generate a random index
|
||||
let index = rng.gen_range(0..rln.tree.capacity());
|
||||
|
||||
// We add the leaf to the tree
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&leaf));
|
||||
rln.set_leaf(index, &mut buffer).unwrap();
|
||||
|
||||
// We get the leaf
|
||||
let mut output_buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_leaf(index, &mut output_buffer).unwrap();
|
||||
|
||||
// We ensure that the leaf is the same as the one we added
|
||||
let (received_leaf, _) = bytes_le_to_fr(output_buffer.into_inner().as_ref());
|
||||
assert_eq!(received_leaf, leaf);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_metadata() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
let mut rln = RLN::new(tree_height, input_buffer).unwrap();
|
||||
|
||||
let arbitrary_metadata: &[u8] = b"block_number:200000";
|
||||
rln.set_metadata(arbitrary_metadata).unwrap();
|
||||
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
rln.get_metadata(&mut buffer).unwrap();
|
||||
let received_metadata = buffer.into_inner();
|
||||
|
||||
assert_eq!(arbitrary_metadata, received_metadata);
|
||||
}
|
||||
125
rln/tests/ffi.rs
125
rln/tests/ffi.rs
@@ -37,7 +37,7 @@ mod test {
|
||||
|
||||
// We first add leaves one by one specifying the index
|
||||
for (i, leaf) in leaves.iter().enumerate() {
|
||||
// We prepare id_commitment and we set the leaf at provided index
|
||||
// We prepare the rate_commitment and we set the leaf at provided index
|
||||
let leaf_ser = fr_to_bytes_le(&leaf);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_leaf(rln_pointer, i, input_buffer);
|
||||
@@ -341,6 +341,7 @@ mod test {
|
||||
fn test_merkle_proof_ffi() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let leaf_index = 3;
|
||||
let user_message_limit = 1;
|
||||
|
||||
// We create a RLN instance
|
||||
let mut rln_pointer = MaybeUninit::<*mut RLN>::uninit();
|
||||
@@ -352,10 +353,12 @@ mod test {
|
||||
|
||||
// generate identity
|
||||
let identity_secret_hash = hash_to_field(b"test-merkle-proof");
|
||||
let id_commitment = utils_poseidon_hash(&vec![identity_secret_hash]);
|
||||
let id_commitment = utils_poseidon_hash(&[identity_secret_hash]);
|
||||
let user_message_limit = Fr::from(100);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
// We prepare id_commitment and we set the leaf at provided index
|
||||
let leaf_ser = fr_to_bytes_le(&id_commitment);
|
||||
let leaf_ser = fr_to_bytes_le(&rate_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_leaf(rln_pointer, leaf_index, input_buffer);
|
||||
assert!(success, "set leaf call failed");
|
||||
@@ -368,6 +371,21 @@ mod test {
|
||||
let result_data = <&[u8]>::from(&output_buffer).to_vec();
|
||||
let (root, _) = bytes_le_to_fr(&result_data);
|
||||
|
||||
use ark_ff::BigInt;
|
||||
|
||||
if TEST_TREE_HEIGHT == 20 || TEST_TREE_HEIGHT == 32 {
|
||||
assert_eq!(
|
||||
root,
|
||||
BigInt([
|
||||
4939322235247991215,
|
||||
5110804094006647505,
|
||||
4427606543677101242,
|
||||
910933464535675827
|
||||
])
|
||||
.into()
|
||||
);
|
||||
}
|
||||
|
||||
// We obtain the Merkle tree root
|
||||
let mut output_buffer = MaybeUninit::<Buffer>::uninit();
|
||||
let success = get_proof(rln_pointer, leaf_index, output_buffer.as_mut_ptr());
|
||||
@@ -460,8 +478,7 @@ mod test {
|
||||
let mut expected_identity_path_index: Vec<u8> =
|
||||
vec![1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
// We add the remaining elements for the case TEST_TREE_HEIGHT = 19
|
||||
if TEST_TREE_HEIGHT == 19 || TEST_TREE_HEIGHT == 20 {
|
||||
if TEST_TREE_HEIGHT == 20 {
|
||||
expected_path_elements.append(&mut vec![
|
||||
str_to_fr(
|
||||
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92",
|
||||
@@ -500,8 +517,12 @@ mod test {
|
||||
assert_eq!(identity_path_index, expected_identity_path_index);
|
||||
|
||||
// We double check that the proof computed from public API is correct
|
||||
let root_from_proof =
|
||||
compute_tree_root(&id_commitment, &path_elements, &identity_path_index, false);
|
||||
let root_from_proof = compute_tree_root(
|
||||
&identity_secret_hash,
|
||||
&user_message_limit,
|
||||
&path_elements,
|
||||
&identity_path_index,
|
||||
);
|
||||
|
||||
assert_eq!(root, root_from_proof);
|
||||
}
|
||||
@@ -529,7 +550,7 @@ mod test {
|
||||
for _ in 0..sample_size {
|
||||
// We generate random witness instances and relative proof values
|
||||
let rln_witness = random_rln_witness(tree_height);
|
||||
let proof_values = proof_values_from_witness(&rln_witness);
|
||||
let proof_values = proof_values_from_witness(&rln_witness).unwrap();
|
||||
|
||||
// We prepare id_commitment and we set the leaf at provided index
|
||||
let rln_witness_ser = serialize_witness(&rln_witness).unwrap();
|
||||
@@ -650,12 +671,15 @@ mod test {
|
||||
fn test_rln_proof_ffi() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
let user_message_limit = Fr::from(65535);
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..no_of_leaves {
|
||||
leaves.push(Fr::rand(&mut rng));
|
||||
let id_commitment = Fr::rand(&mut rng);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, Fr::from(100)]);
|
||||
leaves.push(rate_commitment);
|
||||
}
|
||||
|
||||
// We create a RLN instance
|
||||
@@ -680,12 +704,7 @@ mod test {
|
||||
let result_data = <&[u8]>::from(&output_buffer).to_vec();
|
||||
let (identity_secret_hash, read) = bytes_le_to_fr(&result_data);
|
||||
let (id_commitment, _) = bytes_le_to_fr(&result_data[read..].to_vec());
|
||||
|
||||
// We set as leaf id_commitment, its index would be equal to no_of_leaves
|
||||
let leaf_ser = fr_to_bytes_le(&id_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
let identity_index: usize = no_of_leaves;
|
||||
|
||||
@@ -695,13 +714,30 @@ mod test {
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = Fr::from(0);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
// We set as leaf rate_commitment, its index would be equal to no_of_leaves
|
||||
let leaf_ser = fr_to_bytes_le(&rate_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
|
||||
// We generate a random rln_identifier
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | external_nullifier<32> | signal_len<8> | signal<var> ]
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized.append(&mut normalize_usize(identity_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
@@ -735,6 +771,7 @@ mod test {
|
||||
// First part similar to test_rln_proof_ffi
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let no_of_leaves = 256;
|
||||
let user_message_limit = Fr::from(100);
|
||||
|
||||
// We generate a vector of random leaves
|
||||
let mut leaves: Vec<Fr> = Vec::new();
|
||||
@@ -765,12 +802,7 @@ mod test {
|
||||
let result_data = <&[u8]>::from(&output_buffer).to_vec();
|
||||
let (identity_secret_hash, read) = bytes_le_to_fr(&result_data);
|
||||
let (id_commitment, _) = bytes_le_to_fr(&result_data[read..].to_vec());
|
||||
|
||||
// We set as leaf id_commitment, its index would be equal to no_of_leaves
|
||||
let leaf_ser = fr_to_bytes_le(&id_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
let identity_index: usize = no_of_leaves;
|
||||
|
||||
@@ -780,13 +812,27 @@ mod test {
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = Fr::from(0);
|
||||
|
||||
// We set as leaf rate_commitment, its index would be equal to no_of_leaves
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
let leaf_ser = fr_to_bytes_le(&rate_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | external_nullifier<32> | signal_len<8> | signal<var> ]
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized.append(&mut normalize_usize(identity_index));
|
||||
serialized.append(&mut fr_to_bytes_le(&epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized.append(&mut normalize_usize(signal.len()));
|
||||
serialized.append(&mut signal.to_vec());
|
||||
|
||||
@@ -879,8 +925,12 @@ mod test {
|
||||
let (identity_secret_hash, read) = bytes_le_to_fr(&result_data);
|
||||
let (id_commitment, _) = bytes_le_to_fr(&result_data[read..].to_vec());
|
||||
|
||||
// We set as leaf id_commitment, its index would be equal to 0 since tree is empty
|
||||
let leaf_ser = fr_to_bytes_le(&id_commitment);
|
||||
let user_message_limit = Fr::from(100);
|
||||
let message_id = Fr::from(0);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
// We set as leaf rate_commitment, its index would be equal to 0 since tree is empty
|
||||
let leaf_ser = fr_to_bytes_le(&rate_commitment);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
@@ -898,13 +948,17 @@ mod test {
|
||||
|
||||
// We generate a random epoch
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
// We prepare input for generate_rln_proof API
|
||||
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
let mut serialized1: Vec<u8> = Vec::new();
|
||||
serialized1.append(&mut fr_to_bytes_le(&identity_secret_hash));
|
||||
serialized1.append(&mut normalize_usize(identity_index));
|
||||
serialized1.append(&mut fr_to_bytes_le(&epoch));
|
||||
serialized1.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized1.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized1.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
|
||||
// The first part is the same for both proof input, so we clone
|
||||
let mut serialized2 = serialized1.clone();
|
||||
@@ -966,9 +1020,10 @@ mod test {
|
||||
let result_data = <&[u8]>::from(&output_buffer).to_vec();
|
||||
let (identity_secret_hash_new, read) = bytes_le_to_fr(&result_data);
|
||||
let (id_commitment_new, _) = bytes_le_to_fr(&result_data[read..].to_vec());
|
||||
let rate_commitment_new = utils_poseidon_hash(&[id_commitment_new, user_message_limit]);
|
||||
|
||||
// We set as leaf id_commitment, its index would be equal to 1 since at 0 there is id_commitment
|
||||
let leaf_ser = fr_to_bytes_le(&id_commitment_new);
|
||||
let leaf_ser = fr_to_bytes_le(&rate_commitment_new);
|
||||
let input_buffer = &Buffer::from(leaf_ser.as_ref());
|
||||
let success = set_next_leaf(rln_pointer, input_buffer);
|
||||
assert!(success, "set next leaf call failed");
|
||||
@@ -984,7 +1039,9 @@ mod test {
|
||||
let mut serialized: Vec<u8> = Vec::new();
|
||||
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash_new));
|
||||
serialized.append(&mut normalize_usize(identity_index_new));
|
||||
serialized.append(&mut fr_to_bytes_le(&epoch));
|
||||
serialized.append(&mut fr_to_bytes_le(&user_message_limit));
|
||||
serialized.append(&mut fr_to_bytes_le(&message_id));
|
||||
serialized.append(&mut fr_to_bytes_le(&external_nullifier));
|
||||
serialized.append(&mut normalize_usize(signal3.len()));
|
||||
serialized.append(&mut signal3.to_vec());
|
||||
|
||||
@@ -1011,10 +1068,12 @@ mod test {
|
||||
assert!(success, "recover id secret call failed");
|
||||
let output_buffer = unsafe { output_buffer.assume_init() };
|
||||
let serialized_identity_secret_hash = <&[u8]>::from(&output_buffer).to_vec();
|
||||
let (recovered_identity_secret_hash_new, _) =
|
||||
bytes_le_to_fr(&serialized_identity_secret_hash);
|
||||
|
||||
// We passed two shares for different secrets, so recovery should be not successful
|
||||
// To check it, we ensure that recovered identity secret hash is empty
|
||||
assert!(serialized_identity_secret_hash.is_empty());
|
||||
// ensure that the recovered secret does not match with either of the
|
||||
// used secrets in proof generation
|
||||
assert_ne!(recovered_identity_secret_hash_new, identity_secret_hash_new);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use ark_ff::BigInt;
|
||||
use rln::circuit::{
|
||||
circom_from_folder, vk_from_folder, zkey_from_folder, Fr, TEST_RESOURCES_FOLDER,
|
||||
TEST_TREE_HEIGHT,
|
||||
@@ -13,152 +14,57 @@ mod test {
|
||||
type ConfigOf<T> = <T as ZerokitMerkleTree>::Config;
|
||||
|
||||
// Input generated with https://github.com/oskarth/zk-kit/commit/b6a872f7160c7c14e10a0ea40acab99cbb23c9a8
|
||||
const WITNESS_JSON_15: &str = r#"
|
||||
{
|
||||
"identity_secret": "12825549237505733615964533204745049909430608936689388901883576945030025938736",
|
||||
"path_elements": [
|
||||
"18622655742232062119094611065896226799484910997537830749762961454045300666333",
|
||||
"20590447254980891299813706518821659736846425329007960381537122689749540452732",
|
||||
"7423237065226347324353380772367382631490014989348495481811164164159255474657",
|
||||
"11286972368698509976183087595462810875513684078608517520839298933882497716792",
|
||||
"3607627140608796879659380071776844901612302623152076817094415224584923813162",
|
||||
"19712377064642672829441595136074946683621277828620209496774504837737984048981",
|
||||
"20775607673010627194014556968476266066927294572720319469184847051418138353016",
|
||||
"3396914609616007258851405644437304192397291162432396347162513310381425243293",
|
||||
"21551820661461729022865262380882070649935529853313286572328683688269863701601",
|
||||
"6573136701248752079028194407151022595060682063033565181951145966236778420039",
|
||||
"12413880268183407374852357075976609371175688755676981206018884971008854919922",
|
||||
"14271763308400718165336499097156975241954733520325982997864342600795471836726",
|
||||
"20066985985293572387227381049700832219069292839614107140851619262827735677018",
|
||||
"9394776414966240069580838672673694685292165040808226440647796406499139370960",
|
||||
"11331146992410411304059858900317123658895005918277453009197229807340014528524"
|
||||
],
|
||||
"identity_path_index": [
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"x": "8143228284048792769012135629627737459844825626241842423967352803501040982",
|
||||
"epoch": "0x0000005b612540fc986b42322f8cb91c2273afad58ed006fdba0c97b4b16b12f",
|
||||
"rln_identifier": "11412926387081627876309792396682864042420635853496105400039841573530884328439"
|
||||
}
|
||||
"#;
|
||||
|
||||
// Input generated with protocol::random_rln_witness
|
||||
const WITNESS_JSON_19: &str = r#"
|
||||
{
|
||||
"identity_secret": "922538810348594125658702672067738675294669207539999802857585668079702330450",
|
||||
"path_elements": [
|
||||
"16059714054680148404543504061485737353203416489071538960876865983954285286166",
|
||||
"3041470753871943901334053763207316028823782848445723460227667780327106380356",
|
||||
"2557297527793326315072058421057853700096944625924483912548759909801348042183",
|
||||
"6677578602456189582427063963562590713054668181987223110955234085327917303436",
|
||||
"2250827150965576973906150764756422151438812678308727218463995574869267980301",
|
||||
"1895457427602709606993445561553433669787657053834360973759981803464906070980",
|
||||
"11033689991077061346803816826729204895841441316315304395980565540264104346466",
|
||||
"18588752216879570844240300406954267039026327526134910835334500497981810174976",
|
||||
"19346480964028499661277403659363466542857230928032088490855656809181891953123",
|
||||
"21460193770370072688835316363068413651465631481105148051902686770759127189327",
|
||||
"20906347653364838502964722817589315918082261023317339146393355650507243340078",
|
||||
"13466599592974387800162739317046838825289754472645703919149409009404541432954",
|
||||
"9617165663598957201253074168824246164494443748556931540348223968573884172285",
|
||||
"6936463137584425684797785981770877165377386163416057257854261010817156666898",
|
||||
"369902028235468424790098825415813437044876310542601948037281422841675126849",
|
||||
"13510969869821080499683463562609720931680005714401083864659516045615497273644",
|
||||
"2567921390740781421487331055530491683313154421589525170472201828596388395736",
|
||||
"14360870889466292805403568662660511177232987619663547772298178013674025998478",
|
||||
"4735344599616284973799984501493858013178071155960162022656706545116168334293"
|
||||
],
|
||||
"identity_path_index": [
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"x": "6427050788896290028100534859169645070970780055911091444144195464808120686416",
|
||||
"epoch": "0x2bd155d9f85c741044da6909d144f9cc5ce8e0d545a9ed4921b156e8b8569bab",
|
||||
"rln_identifier": "2193983000213424579594329476781986065965849144986973472766961413131458022566"
|
||||
}
|
||||
"#;
|
||||
|
||||
const WITNESS_JSON_20: &str = r#"
|
||||
{
|
||||
"identity_secret": "13732353453861280511150022598793312186188599006979552959297495195757997428306",
|
||||
"path_elements": [
|
||||
"20463525608687844300981085488128968694844212760055234622292326942405619575964",
|
||||
"8040856403709217901175408904825741112286158901303127670929462145501210871313",
|
||||
"3776499751255585163563840252112871568402966629435152937692711318702338789837",
|
||||
"19415813252626942110541463414404411443562242499365750694284604341271149125679",
|
||||
"19414720788761208006634240390286942738242262010168559813148115573784354129237",
|
||||
"17680594732844291740094158892269696200077963275550625226493856898849422516043",
|
||||
"16009199741350632715210088346611798597033333293348807000623441780059543674510",
|
||||
"18743496911007535170857676824393811326863602477260615792503039058813338644738",
|
||||
"1029572792321380246989475723806770724699749375691788486434716005338938722216",
|
||||
"21713138150151063186050010182615713685603650963220209951496401043119768920892",
|
||||
"6713732504049401389983008178456811894856018247924860823028704114266363984580",
|
||||
"2746686888799473963221285145390361693256731812094259845879519459924507786594",
|
||||
"18620748467731297359505500266677881218553438497271819903304075323783392031715",
|
||||
"2446201221122671119406471414204229600430018713181038717206670749886932158104",
|
||||
"12037171942017611311954851302868199608036334625783560875426350283156617524597",
|
||||
"21798743392351780927808323348278035105395367759688979232116905142049921734349",
|
||||
"17450230289417496971557215666910229260621413088991137405744457922069827319039",
|
||||
"20936854099128086256353520300046664152516566958630447858438908748907198510485",
|
||||
"13513344965831154386658059617477268600255664386844920822248038939666265737046",
|
||||
"15546319496880899251450021422131511560001766832580480193115646510655765306630"
|
||||
|
||||
],
|
||||
"identity_path_index": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"x": "18073935665561339809445069958310044423750771681863480888589546877024349720547",
|
||||
"epoch": "0x147e4c23a43a1ddca78d94bcd28147f62ca74b3dc7e56bb0a314a954b9f0e567",
|
||||
"rln_identifier": "2193983000213424579594329476781986065965849144986973472766961413131458022566"
|
||||
"externalNullifier": "21074405743803627666274838159589343934394162804826017440941339048886754734203",
|
||||
"identityPathIndex": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"identitySecret": "2301650865650889795878889082892690584512243988708213561328369865554257051708",
|
||||
"messageId": "1",
|
||||
"pathElements": [
|
||||
"14082964758224722211945379872337797638951236517417253447686770846170014042825",
|
||||
"6628418579821163687428454604867534487917867918886059133241840211975892987309",
|
||||
"12745863228198753394445659605634840709296716381893463421165313830643281758511",
|
||||
"56118267389743063830320351452083247040583061493621478539311100137113963555",
|
||||
"3648731943306935051357703221473866306053186513730785325303257057776816073765",
|
||||
"10548621390442503192989374711060717107954536293658152583621924810330521179016",
|
||||
"11741160669079729961275351458682156164905457324981803454515784688429276743441",
|
||||
"17165464309215350864730477596846156251863702878546777829650812432906796008534",
|
||||
"18947162586829418653666557598416458949428989734998924978331450666032720066913",
|
||||
"8809427088917589399897132358419395928548406347152047718919154153577297139202",
|
||||
"6261460226929242970747566981077801929281729646713842579109271945192964422300",
|
||||
"13871468675790284383809887052382100311103716176061564908030808887079542722597",
|
||||
"10413964486611723004584705484327518190402370933255450052832412709168190985805",
|
||||
"3978387560092078849178760154060822400741873818692524912249877867958842934383",
|
||||
"14014915591348694328771517896715085647041518432952027841088176673715002508448",
|
||||
"17680675606519345547327984724173632294904524423937145835611954334756161077843",
|
||||
"17107175244885276119916848057745382329169223109661217238296871427531065458152",
|
||||
"18326186549441826262593357123467931475982067066825042001499291800252145875109",
|
||||
"7043961192177345916232559778383741091053414803377017307095275172896944935996",
|
||||
"2807630271073553218355393059254209097448243975722083008310815929736065268921"
|
||||
],
|
||||
"userMessageLimit": "100",
|
||||
"x": "20645213238265527935869146898028115621427162613172918400241870500502509785943"
|
||||
}
|
||||
"#;
|
||||
|
||||
@@ -170,7 +76,8 @@ mod test {
|
||||
|
||||
// generate identity
|
||||
let identity_secret_hash = hash_to_field(b"test-merkle-proof");
|
||||
let id_commitment = poseidon_hash(&vec![identity_secret_hash]);
|
||||
let id_commitment = poseidon_hash(&[identity_secret_hash]);
|
||||
let rate_commitment = poseidon_hash(&[id_commitment, 100.into()]);
|
||||
|
||||
// generate merkle tree
|
||||
let default_leaf = Fr::from(0);
|
||||
@@ -180,37 +87,21 @@ mod test {
|
||||
ConfigOf::<PoseidonTree>::default(),
|
||||
)
|
||||
.unwrap();
|
||||
tree.set(leaf_index, id_commitment.into()).unwrap();
|
||||
tree.set(leaf_index, rate_commitment.into()).unwrap();
|
||||
|
||||
// We check correct computation of the root
|
||||
let root = tree.root();
|
||||
|
||||
if TEST_TREE_HEIGHT == 15 {
|
||||
if TEST_TREE_HEIGHT == 20 || TEST_TREE_HEIGHT == 32 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
"0x1984f2e01184aef5cb974640898a5f5c25556554e2b06d99d4841badb8b198cd",
|
||||
16
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
} else if TEST_TREE_HEIGHT == 19 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
"0x219ceb53f2b1b7a6cf74e80d50d44d68ecb4a53c6cc65b25593c8d56343fb1fe",
|
||||
16
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
} else if TEST_TREE_HEIGHT == 20 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
"0x21947ffd0bce0c385f876e7c97d6a42eec5b1fe935aab2f01c1f8a8cbcc356d2",
|
||||
16
|
||||
)
|
||||
.unwrap()
|
||||
BigInt([
|
||||
4939322235247991215,
|
||||
5110804094006647505,
|
||||
4427606543677101242,
|
||||
910933464535675827
|
||||
])
|
||||
.into()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -302,7 +193,7 @@ mod test {
|
||||
vec![1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
// We add the remaining elements for the case TEST_TREE_HEIGHT = 20
|
||||
if TEST_TREE_HEIGHT == 19 || TEST_TREE_HEIGHT == 20 {
|
||||
if TEST_TREE_HEIGHT == 20 {
|
||||
expected_path_elements.append(&mut vec![
|
||||
str_to_fr(
|
||||
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92",
|
||||
@@ -341,7 +232,7 @@ mod test {
|
||||
assert_eq!(identity_path_index, expected_identity_path_index);
|
||||
|
||||
// We check correct verification of the proof
|
||||
assert!(tree.verify(&id_commitment, &merkle_proof).unwrap());
|
||||
assert!(tree.verify(&rate_commitment, &merkle_proof).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -353,24 +244,12 @@ mod test {
|
||||
let builder = circom_from_folder(TEST_RESOURCES_FOLDER).unwrap();
|
||||
|
||||
// We compute witness from the json input example
|
||||
let mut witness_json: &str = "";
|
||||
|
||||
if TEST_TREE_HEIGHT == 15 {
|
||||
witness_json = WITNESS_JSON_15;
|
||||
} else if TEST_TREE_HEIGHT == 19 {
|
||||
witness_json = WITNESS_JSON_19;
|
||||
} else if TEST_TREE_HEIGHT == 20 {
|
||||
witness_json = WITNESS_JSON_20;
|
||||
}
|
||||
|
||||
let rln_witness = rln_witness_from_json(witness_json);
|
||||
|
||||
let rln_witness_unwrapped = rln_witness.unwrap();
|
||||
let witness_json = WITNESS_JSON_20;
|
||||
let rln_witness = rln_witness_from_json(witness_json).unwrap();
|
||||
|
||||
// Let's generate a zkSNARK proof
|
||||
let proof = generate_proof(builder, &proving_key, &rln_witness_unwrapped).unwrap();
|
||||
|
||||
let proof_values = proof_values_from_witness(&rln_witness_unwrapped);
|
||||
let proof = generate_proof(builder, &proving_key, &rln_witness).unwrap();
|
||||
let proof_values = proof_values_from_witness(&rln_witness).unwrap();
|
||||
|
||||
// Let's verify the proof
|
||||
let verified = verify_proof(&verification_key, &proof, &proof_values);
|
||||
@@ -386,6 +265,8 @@ mod test {
|
||||
|
||||
// Generate identity pair
|
||||
let (identity_secret_hash, id_commitment) = keygen();
|
||||
let user_message_limit = Fr::from(100);
|
||||
let rate_commitment = poseidon_hash(&[id_commitment, user_message_limit]);
|
||||
|
||||
//// generate merkle tree
|
||||
let default_leaf = Fr::from(0);
|
||||
@@ -395,7 +276,7 @@ mod test {
|
||||
ConfigOf::<PoseidonTree>::default(),
|
||||
)
|
||||
.unwrap();
|
||||
tree.set(leaf_index, id_commitment.into()).unwrap();
|
||||
tree.set(leaf_index, rate_commitment.into()).unwrap();
|
||||
|
||||
let merkle_proof = tree.proof(leaf_index).expect("proof should exist");
|
||||
|
||||
@@ -404,14 +285,18 @@ mod test {
|
||||
|
||||
// We set the remaining values to random ones
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
//let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
let external_nullifier = poseidon_hash(&[epoch, rln_identifier]);
|
||||
|
||||
let rln_witness: RLNWitnessInput = rln_witness_from_values(
|
||||
identity_secret_hash,
|
||||
&merkle_proof,
|
||||
x,
|
||||
epoch, /*, rln_identifier*/
|
||||
);
|
||||
external_nullifier,
|
||||
user_message_limit,
|
||||
Fr::from(1),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// We generate all relevant keys
|
||||
let proving_key = zkey_from_folder(TEST_RESOURCES_FOLDER).unwrap();
|
||||
@@ -421,7 +306,7 @@ mod test {
|
||||
// Let's generate a zkSNARK proof
|
||||
let proof = generate_proof(builder, &proving_key, &rln_witness).unwrap();
|
||||
|
||||
let proof_values = proof_values_from_witness(&rln_witness);
|
||||
let proof_values = proof_values_from_witness(&rln_witness).unwrap();
|
||||
|
||||
// Let's verify the proof
|
||||
let success = verify_proof(&verification_key, &proof, &proof_values).unwrap();
|
||||
@@ -432,15 +317,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_witness_serialization() {
|
||||
// We test witness serialization
|
||||
let mut witness_json: &str = "";
|
||||
|
||||
if TEST_TREE_HEIGHT == 15 {
|
||||
witness_json = WITNESS_JSON_15;
|
||||
} else if TEST_TREE_HEIGHT == 19 {
|
||||
witness_json = WITNESS_JSON_19;
|
||||
} else if TEST_TREE_HEIGHT == 20 {
|
||||
witness_json = WITNESS_JSON_20;
|
||||
}
|
||||
let witness_json: &str = WITNESS_JSON_20;
|
||||
|
||||
let rln_witness = rln_witness_from_json(witness_json).unwrap();
|
||||
|
||||
@@ -449,7 +326,7 @@ mod test {
|
||||
assert_eq!(rln_witness, deser);
|
||||
|
||||
// We test Proof values serialization
|
||||
let proof_values = proof_values_from_witness(&rln_witness);
|
||||
let proof_values = proof_values_from_witness(&rln_witness).unwrap();
|
||||
let ser = serialize_proof_values(&proof_values);
|
||||
let (deser, _) = deserialize_proof_values(&ser);
|
||||
assert_eq!(proof_values, deser);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use ark_ff::BigInt;
|
||||
use ark_std::{rand::thread_rng, UniformRand};
|
||||
use rand::Rng;
|
||||
use rln::circuit::{Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT};
|
||||
@@ -15,6 +16,7 @@ mod test {
|
||||
fn test_merkle_proof() {
|
||||
let tree_height = TEST_TREE_HEIGHT;
|
||||
let leaf_index = 3;
|
||||
let user_message_limit = 1;
|
||||
|
||||
let input_buffer =
|
||||
Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());
|
||||
@@ -23,9 +25,10 @@ mod test {
|
||||
// generate identity
|
||||
let identity_secret_hash = hash_to_field(b"test-merkle-proof");
|
||||
let id_commitment = utils_poseidon_hash(&vec![identity_secret_hash]);
|
||||
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit.into()]);
|
||||
|
||||
// We pass id_commitment as Read buffer to RLN's set_leaf
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&id_commitment));
|
||||
// We pass rate_commitment as Read buffer to RLN's set_leaf
|
||||
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
|
||||
rln.set_leaf(leaf_index, &mut buffer).unwrap();
|
||||
|
||||
// We check correct computation of the root
|
||||
@@ -33,25 +36,17 @@ mod test {
|
||||
rln.get_root(&mut buffer).unwrap();
|
||||
let (root, _) = bytes_le_to_fr(&buffer.into_inner());
|
||||
|
||||
if TEST_TREE_HEIGHT == 15 {
|
||||
if TEST_TREE_HEIGHT == 20 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
"0x1984f2e01184aef5cb974640898a5f5c25556554e2b06d99d4841badb8b198cd",
|
||||
16
|
||||
)
|
||||
.unwrap()
|
||||
Fr::from(BigInt([
|
||||
17110646155607829651,
|
||||
5040045984242729823,
|
||||
6965416728592533086,
|
||||
2328960363755461975
|
||||
]))
|
||||
);
|
||||
} else if TEST_TREE_HEIGHT == 19 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
"0x219ceb53f2b1b7a6cf74e80d50d44d68ecb4a53c6cc65b25593c8d56343fb1fe",
|
||||
16
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
} else if TEST_TREE_HEIGHT == 20 {
|
||||
} else if TEST_TREE_HEIGHT == 32 {
|
||||
assert_eq!(
|
||||
root,
|
||||
str_to_fr(
|
||||
@@ -153,7 +148,7 @@ mod test {
|
||||
vec![1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
// We add the remaining elements for the case TEST_TREE_HEIGHT = 20
|
||||
if TEST_TREE_HEIGHT == 19 || TEST_TREE_HEIGHT == 20 {
|
||||
if TEST_TREE_HEIGHT == 20 || TEST_TREE_HEIGHT == 32 {
|
||||
expected_path_elements.append(&mut vec![
|
||||
str_to_fr(
|
||||
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92",
|
||||
@@ -192,8 +187,12 @@ mod test {
|
||||
assert_eq!(identity_path_index, expected_identity_path_index);
|
||||
|
||||
// We double check that the proof computed from public API is correct
|
||||
let root_from_proof =
|
||||
compute_tree_root(&id_commitment, &path_elements, &identity_path_index, false);
|
||||
let root_from_proof = compute_tree_root(
|
||||
&identity_secret_hash,
|
||||
&user_message_limit.into(),
|
||||
&path_elements,
|
||||
&identity_path_index,
|
||||
);
|
||||
|
||||
assert_eq!(root, root_from_proof);
|
||||
}
|
||||
|
||||
1
rln/vendor/rln
vendored
1
rln/vendor/rln
vendored
Submodule rln/vendor/rln deleted from fc86ad156a
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "zerokit_utils"
|
||||
version = "0.3.2"
|
||||
version = "0.4.1"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Various utilities for Zerokit"
|
||||
|
||||
Reference in New Issue
Block a user