Skip to content

Commit

Permalink
add wasm sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
allen-cmyk committed Jun 1, 2024
1 parent 52d8972 commit 61bd5f0
Show file tree
Hide file tree
Showing 9 changed files with 602 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"shuffle/wasm",
"matchmaking",
"c-uzkge",
"wasm",
]
resolver = "2"

Expand Down Expand Up @@ -54,6 +55,7 @@ sha3 = "0.10"
structopt = "0.3"
tera = "1.19"
thiserror = "1.0"
ethabi = "18.0.0"

# wasm
getrandom = { version = "0.2", features = ["js"] }
Expand Down
31 changes: 31 additions & 0 deletions wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "wasm"
description = "WASM SDK for encrypt and shuffle cards"
version.workspace = true
edition.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true
license.workspace = true

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
zshuffle.workspace = true
zmatchmaking.workspace = true
uzkge = { workspace = true, features = ["shuffle"] }

ark-ec.workspace = true
ark-ff.workspace = true
ark-bn254.workspace = true
ark-serialize.workspace = true
ark-ed-on-bn254.workspace = true
bincode.workspace = true
hex.workspace = true
wasm-bindgen.workspace = true
serde-wasm-bindgen.workspace = true
rand_chacha = { workspace = true }
ethabi.workspace = true
getrandom = { version = "0.2", features = ["js"] }
68 changes: 68 additions & 0 deletions wasm/demo.js

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions wasm/src/anemoi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use alloc::{string::String, vec::Vec};
use ark_bn254::Fr;
use ark_ff::{BigInteger, PrimeField};
use uzkge::anemoi::{AnemoiJive, AnemoiJive254};
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
pub fn anemoi_hash(datas: Vec<String>) -> String {
let mut inputs: Vec<Fr> = Vec::new();
for data in datas {
let input =
hex::decode(data.strip_prefix("0x").unwrap_or(&data)).expect("hex decode data error");
let input = Fr::from_be_bytes_mod_order(&input);
inputs.push(input);
}

let res = AnemoiJive254::eval_variable_length_hash(&inputs);

format!("0x{}", hex::encode(res.into_bigint().to_bytes_be()))
}
53 changes: 53 additions & 0 deletions wasm/src/ed_on_bn254.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use alloc::string::String;
use ark_ec::{AffineRepr, CurveGroup};
use ark_ed_on_bn254::{EdwardsAffine, Fq, Fr};
use ark_ff::{BigInteger, PrimeField};
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
pub fn point_add(x1: String, y1: String, x2: String, y2: String) -> String {
let x1 = hex::decode(x1.strip_prefix("0x").unwrap_or(&x1)).expect("hex decode x1 error");
let x_1 = Fq::from_be_bytes_mod_order(&x1);

let y1 = hex::decode(y1.strip_prefix("0x").unwrap_or(&y1)).expect("hex decode y1 error");
let y_1 = Fq::from_be_bytes_mod_order(&y1);

let x2 = hex::decode(x2.strip_prefix("0x").unwrap_or(&x2)).expect("hex decode x2 error");
let x_2 = Fq::from_be_bytes_mod_order(&x2);

let y2 = hex::decode(y2.strip_prefix("0x").unwrap_or(&y2)).expect("hex decode y2 error");
let y_2 = Fq::from_be_bytes_mod_order(&y2);

let mut ret = [0u8; 64];
let p1 = EdwardsAffine::new(x_1, y_1);
let p2 = EdwardsAffine::new(x_2, y_2);
let p3 = p1 + p2;

if let Some((r_x, r_y)) = p3.into_affine().xy() {
ret[0..32].copy_from_slice(&r_x.into_bigint().to_bytes_be());
ret[32..64].copy_from_slice(&r_y.into_bigint().to_bytes_be());
}
format!("0x{}", hex::encode(ret.to_vec()))
}

#[wasm_bindgen]
pub fn scalar_mul(s: String, x: String, y: String) -> String {
let s = hex::decode(s.strip_prefix("0x").unwrap_or(&s)).expect("hex decode s error");
let s = Fr::from_be_bytes_mod_order(&s);

let x = hex::decode(x.strip_prefix("0x").unwrap_or(&x)).expect("hex decode s error");
let x = Fq::from_be_bytes_mod_order(&x);

let y = hex::decode(y.strip_prefix("0x").unwrap_or(&y)).expect("hex decode s error");
let y = Fq::from_be_bytes_mod_order(&y);

let mut ret = [0u8; 64];
let p = EdwardsAffine::new(x, y);
let p2 = p * s;

if let Some((r_x, r_y)) = p2.into_affine().xy() {
ret[0..32].copy_from_slice(&r_x.into_bigint().to_bytes_be());
ret[32..64].copy_from_slice(&r_y.into_bigint().to_bytes_be());
}
format!("0x{}", hex::encode(ret.to_vec()))
}
9 changes: 9 additions & 0 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extern crate alloc;

pub mod ed_on_bn254;

pub mod anemoi;

pub mod shuffle;

pub mod matchmaking;
164 changes: 164 additions & 0 deletions wasm/src/matchmaking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
use alloc::{format, string::String, vec::Vec};
use ark_bn254::Fr;
use ark_ff::{BigInteger, PrimeField};
use ethabi::Token;
use rand_chacha::{rand_core::SeedableRng, ChaChaRng};
use uzkge::{
anemoi::{AnemoiJive, AnemoiJive254},
gen_params::VerifierParams,
};
use wasm_bindgen::prelude::wasm_bindgen;
use zmatchmaking::{
build_cs::{prove_matchmaking, verify_matchmaking, Proof},
gen_params::{gen_prover_params, get_verifier_params},
};

#[wasm_bindgen]
pub fn verifier_matchmaking_params() -> String {
let param = get_verifier_params().unwrap();

format!("0x{}", hex::encode(bincode::serialize(&param).unwrap()))
}

#[wasm_bindgen]
pub fn generate_matchmaking_proof(
verifier_params: String,
rng_seed: String,
inputs: Vec<String>,
committed_seed: String,
random_number: String,
) -> String {
let verifier_params = {
hex::decode(
verifier_params
.strip_prefix("0x")
.unwrap_or(&verifier_params),
)
.expect("hex decode verifier_params error")
};

let rng_seed = {
hex::decode(rng_seed.strip_prefix("0x").unwrap_or(&rng_seed))
.expect("hex decode rng_seed error")
.try_into()
.unwrap()
};
let mut rng = ChaChaRng::from_seed(rng_seed);

let mut input_param = Vec::new();
for (index, input) in inputs.iter().enumerate() {
let data = hex::decode(input.strip_prefix("0x").unwrap_or(&input))
.expect(&format!("hex decode {} input error", index));
let input = Fr::from_be_bytes_mod_order(&data);
input_param.push(input)
}

let committed_seed = {
let data = hex::decode(committed_seed.strip_prefix("0x").unwrap_or(&committed_seed))
.expect("hex decode committed_seed error");
Fr::from_be_bytes_mod_order(&data)
};

let committment = AnemoiJive254::eval_variable_length_hash(&[committed_seed]);

let random_number = {
let data = hex::decode(random_number.strip_prefix("0x").unwrap_or(&random_number))
.expect("hex decode random_number error");
Fr::from_be_bytes_mod_order(&data)
};

let (proof, outputs) = prove_matchmaking(
&mut rng,
&input_param,
&committed_seed,
&random_number,
&gen_prover_params().unwrap(),
)
.unwrap();

let proof = bincode::serialize(&proof).unwrap();

let data = ethabi::encode(&[
Token::Bytes(verifier_params),
Token::Array(
input_param
.iter()
.map(|v| Token::Bytes(v.into_bigint().to_bytes_be()))
.collect::<Vec<_>>(),
),
Token::Array(
outputs
.iter()
.map(|v| Token::Bytes(v.into_bigint().to_bytes_be()))
.collect::<Vec<_>>(),
),
Token::Bytes(committment.into_bigint().to_bytes_be()),
Token::Bytes(random_number.into_bigint().to_bytes_be()),
Token::Bytes(proof),
]);
format!("0x{}", hex::encode(data))
}

#[wasm_bindgen]
pub fn plonk_verify_matchmaking(
verifier_params: String,
inputs: Vec<String>,
outputs: Vec<String>,
commitment: String,
random_number: String,
proof: String,
) -> bool {
let verifier_params: VerifierParams = {
let data = hex::decode(
verifier_params
.strip_prefix("0x")
.unwrap_or(&verifier_params),
)
.expect("hex decode verifier_params error");
bincode::deserialize(&data).expect("bincode deserialize verifier_params error")
};

let mut input_param = Vec::new();
for (index, input) in inputs.iter().enumerate() {
let data = hex::decode(input.strip_prefix("0x").unwrap_or(&input))
.expect(&format!("hex decode {} input error", index));
let input = Fr::from_be_bytes_mod_order(&data);
input_param.push(input)
}

let mut output_param = Vec::new();
for (index, output) in outputs.iter().enumerate() {
let data = hex::decode(output.strip_prefix("0x").unwrap_or(&output))
.expect(&format!("hex decode {} output error", index));
let output = Fr::from_be_bytes_mod_order(&data);
output_param.push(output)
}

let commitment = {
let data = hex::decode(commitment.strip_prefix("0x").unwrap_or(&commitment))
.expect("hex decode commitment error");
Fr::from_be_bytes_mod_order(&data)
};

let random_number = {
let data = hex::decode(random_number.strip_prefix("0x").unwrap_or(&random_number))
.expect("hex decode random_number error");
Fr::from_be_bytes_mod_order(&data)
};

let proof: Proof = {
let data = hex::decode(proof.strip_prefix("0x").unwrap_or(&proof))
.expect("hex decode proof error");
bincode::deserialize(&data).expect("bincode deserialize proof error")
};

verify_matchmaking(
&verifier_params,
&input_param,
&output_param,
&commitment,
&random_number,
&proof,
)
.is_ok()
}
Loading

0 comments on commit 61bd5f0

Please sign in to comment.