From 1045e056d1978045fd622732a993ed8e886a7e89 Mon Sep 17 00:00:00 2001 From: rymnc <43716372+rymnc@users.noreply.github.com> Date: Sat, 9 Dec 2023 14:56:13 +0530 Subject: [PATCH] feat: push reverted wasm circom --- Cargo.lock | 1 - rln-wasm/Cargo.toml | 2 -- rln-wasm/src/lib.rs | 61 +++++++++++++++++++++----------------- rln-wasm/tests/rln-wasm.rs | 39 ++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb6c9a1..5904cf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2828,7 +2828,6 @@ dependencies = [ name = "rln-wasm" version = "0.0.13" dependencies = [ - "ark-circom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "console_error_panic_hook", "getrandom", "js-sys", diff --git a/rln-wasm/Cargo.toml b/rln-wasm/Cargo.toml index 9effed0..1591e52 100644 --- a/rln-wasm/Cargo.toml +++ b/rln-wasm/Cargo.toml @@ -20,8 +20,6 @@ wasm-bindgen = "0.2.63" serde-wasm-bindgen = "0.4" js-sys = "0.3.59" serde_json = "1.0.85" -ark-circom = { version = "=0.1.0", default-features = false, features = ["circom-2"] } - # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires diff --git a/rln-wasm/src/lib.rs b/rln-wasm/src/lib.rs index 528dfc4..ad70d12 100644 --- a/rln-wasm/src/lib.rs +++ b/rln-wasm/src/lib.rs @@ -5,9 +5,9 @@ extern crate web_sys; use std::vec::Vec; -use ark_circom::WitnessCalculator; -use js_sys::{Object, Uint8Array}; -use rln::circuit::{default_circom, default_vk, default_zkey}; +use js_sys::{BigInt as JsBigInt, Object, Uint8Array}; +use num_bigint::BigInt; +use rln::circuit::{default_vk, default_zkey}; use rln::public::{hash, poseidon_hash, RLN}; use wasm_bindgen::prelude::*; @@ -21,7 +21,6 @@ pub struct RLNWrapper { // The purpose of this wrapper is to hold a RLN instance with the 'static lifetime // because wasm_bindgen does not allow returning elements with lifetimes instance: RLN<'static>, - witness_calculator: WitnessCalculator, } // Macro to call methods with arbitrary amount of arguments, @@ -186,12 +185,8 @@ impl<'a> ProcessArg for &'a [u8] { pub fn wasm_new() -> Result<*mut RLNWrapper, String> { let zkey = default_zkey().map_err(|err| format!("{:#?}", err))?; let vk = default_vk().map_err(|err| format!("{:#?}", err))?; - let witness_calculator = default_circom().map_err(|err| format!("{:#?}", err))?; let instance = RLN::new_with_params(zkey, vk).map_err(|err| format!("{:#?}", err))?; - let wrapper = RLNWrapper { - instance, - witness_calculator, - }; + let wrapper = RLNWrapper { instance }; Ok(Box::into_raw(Box::new(wrapper))) } @@ -279,31 +274,41 @@ pub fn rln_witness_to_json( Object::from_entries(&js_value).map_err(|err| format!("{:#?}", err)) } -#[allow(clippy::not_unsafe_ptr_arg_deref)] -#[wasm_bindgen] -pub fn generate_rln_proof(ctx: *mut RLNWrapper, input: Uint8Array) -> Result { - let mut output_data: Vec = Vec::new(); - let new_instance = ctx.process(); - if let Err(err) = new_instance.instance.generate_rln_proof( - &mut new_instance.witness_calculator, - &input.to_vec()[..], - &mut output_data, - ) { - std::mem::forget(output_data); - Err(format!("Error: {:#?}", err)) - } else { - let result = Uint8Array::from(&output_data[..]); - std::mem::forget(output_data); - Ok(result) - } -} - #[allow(clippy::not_unsafe_ptr_arg_deref)] #[wasm_bindgen(js_name = generateMembershipKey)] pub fn wasm_key_gen(ctx: *const RLNWrapper) -> Result { call_with_output_and_error_msg!(ctx, key_gen, "could not generate membership keys") } +#[allow(clippy::not_unsafe_ptr_arg_deref)] +#[wasm_bindgen] +pub fn generate_rln_proof_with_witness( + ctx: *mut RLNWrapper, + calculated_witness: Vec, + serialized_witness: Uint8Array, +) -> Result { + let mut witness_vec: Vec = vec![]; + + for v in calculated_witness { + witness_vec.push( + v.to_string(10) + .map_err(|err| format!("{:#?}", err))? + .as_string() + .ok_or("not a string error")? + .parse::() + .map_err(|err| format!("{:#?}", err))?, + ); + } + + call_with_output_and_error_msg!( + ctx, + generate_rln_proof_with_witness, + "could not generate proof", + witness_vec, + serialized_witness.to_vec() + ) +} + #[allow(clippy::not_unsafe_ptr_arg_deref)] #[wasm_bindgen(js_name = generateExtendedMembershipKey)] pub fn wasm_extended_key_gen(ctx: *const RLNWrapper) -> Result { diff --git a/rln-wasm/tests/rln-wasm.rs b/rln-wasm/tests/rln-wasm.rs index f5e0879..4ce15e6 100644 --- a/rln-wasm/tests/rln-wasm.rs +++ b/rln-wasm/tests/rln-wasm.rs @@ -2,17 +2,27 @@ #[cfg(test)] mod tests { - use js_sys::Uint8Array; + use js_sys::{BigInt as JsBigInt, Object, Uint8Array}; use rln::circuit::Fr; 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::JsValue; + use wasm_bindgen::{prelude::*, JsValue}; use wasm_bindgen_test::wasm_bindgen_test; + #[wasm_bindgen(module = "src/utils.js")] + extern "C" { + #[wasm_bindgen(catch)] + fn read_file(path: &str) -> Result; + + #[wasm_bindgen(catch)] + async fn calculateWitness(circom_path: &str, input: Object) -> Result; + } + #[wasm_bindgen_test] pub async fn test_basic_flow() { // Creating an instance of RLN + let circom_path = format!("../rln/resources/tree_height_20/rln.wasm"); let rln_instance = wasm_new().unwrap(); // Creating membership key @@ -58,8 +68,31 @@ mod tests { let serialized_rln_witness = wasm_get_serialized_rln_witness(rln_instance, serialized_message).unwrap(); + // Obtaining inputs that should be sent to circom witness calculator + let json_inputs = + rln_witness_to_json(rln_instance, serialized_rln_witness.clone()).unwrap(); + + // Calculating witness with JS + // (Using a JSON since wasm_bindgen does not like Result,JsValue>) + let calculated_witness_json = calculateWitness(&circom_path, json_inputs) + .await + .unwrap() + .as_string() + .unwrap(); + let calculated_witness_vec_str: Vec = + serde_json::from_str(&calculated_witness_json).unwrap(); + let calculated_witness: Vec = calculated_witness_vec_str + .iter() + .map(|x| JsBigInt::new(&x.into()).unwrap()) + .collect(); + // Generating proof - let proof = generate_rln_proof(rln_instance, serialized_rln_witness).unwrap(); + let proof = generate_rln_proof_with_witness( + rln_instance, + calculated_witness.into(), + serialized_rln_witness, + ) + .unwrap(); // Add signal_len | signal let mut proof_bytes = proof.to_vec();