Impl wasm prover in wasm.rs.

This commit is contained in:
SoraSuegami
2023-12-10 18:19:06 +09:00
parent 3ce89fe88f
commit b107e28760
4 changed files with 191 additions and 4 deletions

2
.cargo/config Normal file
View File

@@ -0,0 +1,2 @@
[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C", "link-arg=--max-memory=4294967296"]

62
Cargo.lock generated
View File

@@ -426,7 +426,7 @@ dependencies = [
[[package]]
name = "cfdkim"
version = "0.3.0"
source = "git+https://github.com/SoraSuegami/dkim.git#d5635de989f1bb54741bc8a7a63837550e23ae93"
source = "git+https://github.com/SoraSuegami/dkim.git#1e61b0a703b8d7cdb730624373adf971398311f7"
dependencies = [
"base64 0.21.5",
"chrono",
@@ -439,11 +439,15 @@ dependencies = [
"mailparse",
"nom",
"quick-error 2.0.1",
"regex",
"reqwasm",
"rsa",
"serde_json",
"sha-1",
"sha2",
"slog",
"trust-dns-resolver",
"wasm-bindgen",
]
[[package]]
@@ -1896,6 +1900,26 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gloo-net"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2899cb1a13be9020b010967adc6b2a8a343b6f1428b90238c9d53ca24decc6db"
dependencies = [
"futures-channel",
"futures-core",
"futures-sink",
"gloo-utils",
"js-sys",
"pin-project",
"serde",
"serde_json",
"thiserror",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "gloo-timers"
version = "0.2.6"
@@ -1908,6 +1932,19 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gloo-utils"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e"
dependencies = [
"js-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "graph-cycles"
version = "0.1.0"
@@ -2109,7 +2146,7 @@ dependencies = [
"rayon",
"rsa",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.4.5",
"sha2",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -2151,6 +2188,7 @@ dependencies = [
"regex",
"rsa",
"serde",
"serde-wasm-bindgen 0.6.2",
"serde_json",
"serde_regex",
"sha2",
@@ -3659,6 +3697,15 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reqwasm"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b89870d729c501fa7a68c43bf4d938bbb3a8c156d333d90faa0e8b3e3212fb"
dependencies = [
"gloo-net",
]
[[package]]
name = "reqwest"
version = "0.11.22"
@@ -4017,6 +4064,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "serde-wasm-bindgen"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67d27afff48127b3edfe6ad379a2bd0795d2cfa56730ca2745e5b89386126404"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "serde_bytes"
version = "0.11.12"

View File

@@ -93,6 +93,8 @@ snark-verifier-sdk = { git = "https://github.com/zkemail/snark-verifier.git", ve
] }
quad-storage = "0.1.3"
stringreader = "0.1.1"
serde-wasm-bindgen = "0.6.2"
[dev-dependencies]
criterion = { version = "0.3" }

View File

@@ -1,8 +1,23 @@
use crate::*;
use halo2_base::halo2_proofs::circuit;
use halo2_base::halo2_proofs::circuit::Layouter;
use halo2_base::halo2_proofs::circuit::{SimpleFloorPlanner, Value};
use halo2_base::halo2_proofs::plonk::{Circuit, Column, ConstraintSystem, Instance};
use halo2_base::halo2_proofs::{circuit::Layouter, plonk::Error};
use halo2_base::halo2_proofs::halo2curves::bn256::{Bn256, Fq, Fr, G1Affine};
use halo2_base::halo2_proofs::halo2curves::FieldExt;
use halo2_base::halo2_proofs::plonk::{create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, Column, ConstraintSystem, Instance, ProvingKey, VerifyingKey};
use halo2_base::halo2_proofs::poly::kzg::multiopen::VerifierSHPLONK;
use halo2_base::halo2_proofs::poly::kzg::strategy::AccumulatorStrategy;
use halo2_base::halo2_proofs::poly::{
commitment::{Params, ParamsProver},
kzg::{
commitment::{KZGCommitmentScheme, ParamsKZG},
multiopen::{ProverGWC, VerifierGWC},
strategy::SingleStrategy,
},
Rotation, VerificationStrategy,
};
use halo2_base::halo2_proofs::transcript::{Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer};
use halo2_base::halo2_proofs::SerdeFormat;
use halo2_base::utils::fe_to_biguint;
use halo2_base::utils::{decompose_fe_to_u64_limbs, value_to_option};
use halo2_base::QuantumCell;
@@ -11,10 +26,109 @@ use halo2_base::{
gates::{flex_gate::FlexGateConfig, range::RangeConfig, GateInstructions, RangeInstructions},
utils::PrimeField,
};
use js_sys::Uint8Array;
use quad_storage;
use serde_json;
use std::io::BufReader;
use stringreader::StringReader;
use wasm_bindgen::prelude::*;
pub use wasm_bindgen_rayon::init_thread_pool;
extern crate console_error_panic_hook;
use cfdkim::resolve_rsa_public_key;
use js_sys::Promise;
use num_bigint::BigUint;
use rsa::rand_core::OsRng;
use serde_wasm_bindgen::*;
use wasm_bindgen_futures::future_to_promise;
#[wasm_bindgen]
pub fn init_panic_hook() {
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
pub fn prove_email(params: JsValue, proving_key: JsValue, email_str: String) -> Promise {
console_error_panic_hook::set_once();
future_to_promise(async move {
let params = Uint8Array::new(&params).to_vec();
let params = match ParamsKZG::<Bn256>::read(&mut BufReader::new(&params[..])) {
Ok(params) => params,
Err(_) => {
return Err(JsValue::from_str("fail to read params"));
}
};
let pk: Vec<u8> = Uint8Array::new(&proving_key).to_vec();
let pk = match ProvingKey::<G1Affine>::read::<_, DefaultEmailVerifyCircuit<Fr>>(&mut BufReader::new(&pk[..]), SerdeFormat::RawBytes) {
Ok(pk) => pk,
Err(_) => {
return Err(JsValue::from_str("fail to read proving key"));
}
};
let circuit = build_circuit::<Fr>(&email_str).await;
let mut transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]);
let instances = circuit.instances();
match create_proof::<KZGCommitmentScheme<_>, ProverGWC<_>, _, _, _, _>(&params, &pk, &[circuit], &[&[instances[0].as_slice()]], OsRng, &mut transcript) {
Ok(_) => (),
Err(_) => {
return Err(JsValue::from_str("fail to create proof"));
}
};
let proof = transcript.finalize();
{
let strategy = SingleStrategy::new(&params);
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
verify_proof::<_, VerifierGWC<_>, _, _, _>(&params, pk.get_vk(), strategy, &[&[instances[0].as_slice()]], &mut transcript).expect("proof invalid");
}
Ok(serde_wasm_bindgen::to_value(&proof).unwrap())
})
}
// #[wasm_bindgen]
// pub fn verify_email_proof(params: JsValue, verifying_key: JsValue, proof: JsValue, public_input: JsValue) -> Promise {
// console_error_panic_hook::set_once();
// future_to_promise(async move {
// let params = Uint8Array::new(&params).to_vec();
// let params = match ParamsKZG::<Bn256>::read(&mut BufReader::new(&params[..])) {
// Ok(params) => params,
// Err(_) => {
// return Err(JsValue::from_str("fail to read params"));
// }
// };
// let vk: Vec<u8> = Uint8Array::new(&verifying_key).to_vec();
// let vk = match VerifyingKey::<G1Affine>::read::<_, DefaultEmailVerifyCircuit<Fr>>(&mut BufReader::new(&vk[..]), SerdeFormat::RawBytes) {
// Ok(vk) => vk,
// Err(_) => {
// return Err(JsValue::from_str("fail to read verifying key"));
// }
// };
// let proof: Vec<u8> = Uint8Array::new(&proof).to_vec();
// let proof = match <KZGCommitmentScheme<_> as VerificationStrategy<DefaultEmailVerifyCircuit<Fr>, _>>::Proof::read(&mut BufReader::new(&proof[..])) {
// Ok(proof) => proof,
// Err(_) => {
// return Err(JsValue::from_str("fail to read proof"));
// }
// };
// let public_input: Vec<u8> = Uint8Array::new(&public_input).to_vec();
// let public_input = match <KZGCommitmentScheme<_> as VerificationStrategy<DefaultEmailVerifyCircuit<Fr>, _>>::PublicInput::read(&mut BufReader::new(&public_input[..])) {
// Ok(public_input) => public_input,
// Err(_) => {
// return Err(JsValue::from_str("fail to read public input"));
// }
// };
// let mut transcript = Blake2bRead::<_, G1Affine, Challenge255<_>>::init(&proof);
// match proof.verify(&params, &vk, &[public_input], &mut transcript) {
// Ok(_) => Ok(JsValue::from_bool(true)),
// Err(_) => Ok(JsValue::from_bool(false)),
// }
// })
// }
pub(crate) fn configure_wasm<F: PrimeField>(meta: &mut ConstraintSystem<F>) -> DefaultEmailVerifyConfig<F> {
let storage = &mut quad_storage::STORAGE.lock().unwrap();
@@ -142,3 +256,14 @@ pub(crate) fn get_config_params_wasm() -> EmailVerifyConfigParams {
let config_params: EmailVerifyConfigParams = serde_json::from_str(&config_params_str).expect("failed to parse config params");
config_params
}
pub(crate) async fn build_circuit<F: PrimeField>(email_str: &str) -> DefaultEmailVerifyCircuit<F> {
let email_bytes = email_str.as_bytes().to_vec();
let public_key = resolve_rsa_public_key(&email_bytes).await.expect("failed to resolve public key");
let public_key_n = BigUint::from_radix_le(&public_key.n().clone().to_radix_le(16), 16).unwrap();
DefaultEmailVerifyCircuit {
email_bytes,
public_key_n,
_f: PhantomData,
}
}