mirror of
https://github.com/Rate-Limiting-Nullifier/rln_rs_bellman.git
synced 2026-01-09 15:18:10 -05:00
wip, wasm effort
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
/target
|
||||
/pkg
|
||||
node_modules
|
||||
*.key
|
||||
Cargo.lock
|
||||
14
Cargo.toml
14
Cargo.toml
@@ -1,10 +1,22 @@
|
||||
[package]
|
||||
name = "rln"
|
||||
version = "0.1.0"
|
||||
authors = ["Onur Kılıç <onurkilic@itu.edu.tr>"]
|
||||
authors = ["Onur Kılıç <kiliconu@itu.edu.tr>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
rand = "0.4"
|
||||
blake2 = "0.8.1"
|
||||
sapling-crypto = { package = "sapling-crypto_ce", version = "0.1.2" }
|
||||
hex = "0.4.2"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
console_error_panic_hook = { version = "0.1.1" }
|
||||
wasm-bindgen = "0.2"
|
||||
wee_alloc = "0.4.5"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
|
||||
10
example/www/index.html
Normal file
10
example/www/index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rln prover example</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
16
example/www/index.js
Normal file
16
example/www/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// import key from 'binary-loader!./verifier.key';
|
||||
// var hexdata = Buffer.from(key, 'ascii').toString('hex');
|
||||
const js = import('../../pkg/rln.js');
|
||||
js.then((js) => {
|
||||
bufi = Buffer.alloc(64, 1);
|
||||
buf0 = Buffer.alloc(32, 0);
|
||||
// console.log(buf);
|
||||
try {
|
||||
let result = js.RLNWasm.generate_proof(bufi, buf0);
|
||||
console.log(result);
|
||||
console.log(buf0[0]);
|
||||
} catch (err) {
|
||||
console.log('LOGS ERROR');
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
5475
example/www/package-lock.json
generated
Normal file
5475
example/www/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
example/www/package.json
Normal file
13
example/www/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"binary-loader": "0.0.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"raw-loader": "^4.0.1",
|
||||
"webpack": "^4.25.1",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-server": "^3.1.10"
|
||||
}
|
||||
}
|
||||
25
example/www/webpack.config.js
Normal file
25
example/www/webpack.config.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const path = require('path');
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'index.js',
|
||||
},
|
||||
// module: {
|
||||
// rules: [{ test: /\.key$/, use: 'raw-loader' }],
|
||||
// },
|
||||
// module: {
|
||||
// rules: [
|
||||
// {
|
||||
// test: /\.(key)$/i,
|
||||
// use: [
|
||||
// {
|
||||
// loader: 'file-loader',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
|
||||
mode: 'development',
|
||||
};
|
||||
44
src/bin/export_test_keys.rs
Normal file
44
src/bin/export_test_keys.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use hex;
|
||||
use sapling_crypto::bellman::pairing::Engine;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
|
||||
fn main() {
|
||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
let merkle_depth = 32usize;
|
||||
export_test_keys::<Bn256>(merkle_depth);
|
||||
}
|
||||
|
||||
fn export_test_keys<E: Engine>(merkle_depth: usize) {
|
||||
// use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
// use rln::circuit::poseidon::PoseidonCircuit;
|
||||
// use rln::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
// use rln::poseidon::PoseidonParams;
|
||||
use sapling_crypto::bellman::groth16::{generate_random_parameters, Parameters};
|
||||
|
||||
// let poseidon_params = PoseidonParams::<E>::default();
|
||||
// let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
// let hasher = PoseidonCircuit::new(poseidon_params.clone());
|
||||
// let circuit = RLNCircuit::<E> {
|
||||
// inputs: RLNInputs::<E>::empty(merkle_depth),
|
||||
// hasher: hasher.clone(),
|
||||
// };
|
||||
// let parameters = generate_random_parameters(circuit, &mut rng).unwrap();
|
||||
// let mut file_vk = File::create("verifier.key").unwrap();
|
||||
// let vk = parameters.vk.clone();
|
||||
|
||||
// let s = "1122";
|
||||
// let r = hex::decode(s);
|
||||
// println!("{:?}", r);
|
||||
|
||||
let mut s: Vec<u8> = vec![0; 63];
|
||||
// vk.write(&mut s).unwrap();
|
||||
// println!("{:x?}", s);
|
||||
// println!("{}", s.len());
|
||||
// println!("{}", hex::encode(&s));
|
||||
// file_vk.write_all(&s).unwrap();
|
||||
|
||||
let parameters2 = Parameters::<E>::read(&mut s.as_slice(), true).unwrap();
|
||||
println!("{:?}", parameters2.h);
|
||||
println!("xxx");
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
mod polynomial;
|
||||
mod poseidon;
|
||||
mod rln;
|
||||
pub mod poseidon;
|
||||
pub mod rln;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod circuit;
|
||||
mod merkle;
|
||||
mod poseidon;
|
||||
pub mod circuit;
|
||||
pub mod merkle;
|
||||
pub mod poseidon;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod wasm;
|
||||
|
||||
@@ -72,8 +72,7 @@ where
|
||||
}
|
||||
}
|
||||
};
|
||||
let x = self.hasher.hash(vec![new]);
|
||||
self.nodes.insert((d, leaf_index), x);
|
||||
|
||||
self.recalculate_from(leaf_index);
|
||||
}
|
||||
|
||||
|
||||
2
src/wasm/mod.rs
Normal file
2
src/wasm/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
mod utils;
|
||||
mod wasm;
|
||||
10
src/wasm/utils.rs
Normal file
10
src/wasm/utils.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
// #[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
165
src/wasm/wasm.rs
Normal file
165
src/wasm/wasm.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use super::utils::set_panic_hook;
|
||||
use crate::circuit::poseidon::PoseidonCircuit;
|
||||
use crate::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use sapling_crypto::bellman::groth16::{create_proof, prepare_verifying_key, verify_proof};
|
||||
use sapling_crypto::bellman::groth16::{create_random_proof, Parameters, Proof};
|
||||
use sapling_crypto::bellman::pairing::bn256::{Bn256, Fr};
|
||||
use sapling_crypto::bellman::pairing::Engine;
|
||||
use sapling_crypto::bellman::{Circuit, ConstraintSystem, SynthesisError};
|
||||
use std::io::{self, Error, ErrorKind, Read, Write};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
#[wasm_bindgen]
|
||||
struct RLNWasm {
|
||||
circuit_parameters: Parameters<Bn256>,
|
||||
circuit_hasher: PoseidonCircuit<Bn256>,
|
||||
merkle_depth: usize,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl RLNWasm {
|
||||
#[wasm_bindgen]
|
||||
pub fn new(merkle_depth: usize, raw_circuit_parameters: &[u8]) -> RLNWasm {
|
||||
set_panic_hook();
|
||||
let circuit_parameters = Parameters::<Bn256>::read(raw_circuit_parameters, true).unwrap();
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let circuit_hasher = PoseidonCircuit::new(poseidon_params.clone());
|
||||
RLNWasm {
|
||||
circuit_parameters,
|
||||
circuit_hasher,
|
||||
merkle_depth,
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_proof(&self, input: &[u8]) -> Result<Vec<u8>, JsValue> {
|
||||
use rand::chacha::ChaChaRng;
|
||||
use rand::SeedableRng;
|
||||
let mut rng = ChaChaRng::new_unseeded();
|
||||
let inputs = RLNInputs::<Bn256>::read(input).expect("failed to read inputs");
|
||||
assert_eq!(self.merkle_depth, inputs.merkle_depth());
|
||||
let circuit = RLNCircuit {
|
||||
inputs: inputs.clone(),
|
||||
hasher: self.circuit_hasher.clone(),
|
||||
};
|
||||
let proof = create_random_proof(circuit, &self.circuit_parameters, &mut rng).expect("failed to create proof");
|
||||
let mut output: Vec<u8> = Vec::new();
|
||||
proof.write(&mut output).expect("failed to write proof");
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn verify(&self, raw_proof: &[u8], raw_public_inputs: &[u8]) -> bool {
|
||||
let proof = Proof::read(raw_proof).unwrap();
|
||||
let public_inputs =
|
||||
RLNInputs::<Bn256>::read_public_inputs(raw_public_inputs).expect("failed to read public inputs");
|
||||
let verifing_key = prepare_verifying_key(&self.circuit_parameters.vk);
|
||||
let success = verify_proof(&verifing_key, &proof, &public_inputs).expect("failed to verify proof");
|
||||
success
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::circuit::poseidon::PoseidonCircuit;
|
||||
use crate::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
use crate::merkle::MerkleTree;
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
use sapling_crypto::bellman::groth16::{generate_random_parameters, Parameters, Proof};
|
||||
use sapling_crypto::bellman::pairing::bn256::{Bn256, Fr};
|
||||
use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
fn gen_circuit_parameters(merkle_depth: usize) -> Vec<u8> {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let inputs = RLNInputs::<Bn256>::empty(merkle_depth);
|
||||
let circuit = RLNCircuit::<Bn256> {
|
||||
inputs,
|
||||
hasher: PoseidonCircuit::new(poseidon_params.clone()),
|
||||
};
|
||||
let parameters = generate_random_parameters(circuit, &mut rng).unwrap();
|
||||
let mut writer: Vec<u8> = Vec::new();
|
||||
parameters.write(&mut writer);
|
||||
writer
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn test_rln_wasm() {
|
||||
let merkle_depth = 32usize;
|
||||
let circuit_parameters = gen_circuit_parameters(merkle_depth);
|
||||
//
|
||||
// prepare inputs
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let mut hasher = PoseidonHasher::new(poseidon_params.clone());
|
||||
let mut membership_tree = MerkleTree::empty(hasher.clone(), merkle_depth);
|
||||
|
||||
// A. setup an identity
|
||||
|
||||
let id_key = Fr::rand(&mut rng);
|
||||
let id_comm = hasher.hash(vec![id_key.clone()]);
|
||||
|
||||
// B. insert to the membership tree
|
||||
|
||||
let id_index = 6; // any number below 2^depth will work
|
||||
membership_tree.update(id_index, id_comm);
|
||||
|
||||
// C.1 get membership witness
|
||||
|
||||
let auth_path = membership_tree.witness(id_index);
|
||||
assert!(membership_tree.check_inclusion(auth_path.clone(), id_index, id_key.clone()));
|
||||
|
||||
// C.2 prepare sss
|
||||
|
||||
// get current epoch
|
||||
let epoch = Fr::rand(&mut rng);
|
||||
|
||||
let signal_hash = Fr::rand(&mut rng);
|
||||
// evaluation point is the signal_hash
|
||||
let share_x = signal_hash.clone();
|
||||
|
||||
// calculate current line equation
|
||||
let a_0 = id_key.clone();
|
||||
let a_1 = hasher.hash(vec![a_0, epoch]);
|
||||
|
||||
// evaluate line equation
|
||||
let mut share_y = a_1.clone();
|
||||
share_y.mul_assign(&share_x);
|
||||
share_y.add_assign(&a_0);
|
||||
|
||||
// calculate nullfier
|
||||
let nullifier = hasher.hash(vec![a_1]);
|
||||
|
||||
let root = membership_tree.root();
|
||||
|
||||
//
|
||||
// serialize input
|
||||
|
||||
let mut writer: Vec<u8> = Vec::new();
|
||||
share_x.into_repr().write_le(&mut writer).unwrap();
|
||||
share_y.into_repr().write_le(&mut writer).unwrap();
|
||||
epoch.into_repr().write_le(&mut writer).unwrap();
|
||||
nullifier.into_repr().write_le(&mut writer).unwrap();
|
||||
root.into_repr().write_le(&mut writer).unwrap();
|
||||
id_key.into_repr().write_le(&mut writer).unwrap();
|
||||
for (e, _) in auth_path.iter() {
|
||||
e.into_repr().write_le(&mut writer).unwrap();
|
||||
}
|
||||
let raw_circuit_parameters = writer.as_slice();
|
||||
|
||||
//
|
||||
// call wasm
|
||||
|
||||
use super::RLNWasm;
|
||||
// let rlnWasm = RLNWasm::new(merkle_depth, raw_circuit_parameters);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user