WebAssembly compatibility
This commit is contained in:
parent
9bdbe85480
commit
1fa63c9d3d
@ -8,13 +8,13 @@ homepage = "https://github.com/ebfull/phase2"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/ebfull/phase2"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
|
||||
[dependencies]
|
||||
rand = "0.4"
|
||||
bellman_ce = { path = "../bellman" }
|
||||
byteorder = "1"
|
||||
exitcode = "1.1.2"
|
||||
num_cpus = "1"
|
||||
crossbeam = "0.3"
|
||||
blake2-rfc = "0.2"
|
||||
blake2 = "0.6.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
@ -22,5 +22,20 @@ serde_json = "1.0"
|
||||
num-bigint = "0.2.3"
|
||||
num-traits = "0.2.8"
|
||||
itertools = "0.8.1"
|
||||
rust-crypto = "0.2"
|
||||
hex = "0.4.0"
|
||||
cfg-if = "0.1.10"
|
||||
bellman_ce = { path = "../bellman", default-features = false } # active features depend on build type
|
||||
|
||||
# needed for native only but don't break wasm if present
|
||||
num_cpus = "1"
|
||||
crossbeam = "0.3"
|
||||
|
||||
# needed for wasm only
|
||||
wasm-bindgen = { version = "0.2.58", optional = true }
|
||||
js-sys = { version = "0.3.35", optional = true }
|
||||
web-sys = { version = "0.3.35", features = ["console"], optional = true }
|
||||
console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["bellman_ce/multicore"]
|
||||
wasm = ["wasm-bindgen", "js-sys", "web-sys", "console_error_panic_hook", "bellman_ce/wasm"]
|
||||
|
@ -2,6 +2,28 @@
|
||||
|
||||
This library is still under development.
|
||||
|
||||
## WebAssembly how-to
|
||||
|
||||
Build wasm package using `wasm-pack build --release -- --no-default-features --features wasm`
|
||||
|
||||
this will generate `./pkg` directory with wasm file and js bindings. After that you
|
||||
can use this package in your browser application like so:
|
||||
|
||||
```js
|
||||
async function main() {
|
||||
const phase2 = await import("./pkg/phase2.js")
|
||||
let data = await fetch('params')
|
||||
data = await data.arrayBuffer()
|
||||
data = new Uint8Array(data)
|
||||
console.log('Source params', data)
|
||||
const result = phase2.contribute(data)
|
||||
console.log('Updated params', result)
|
||||
// upload updated params
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
```
|
||||
|
||||
## [Documentation](https://docs.rs/phase2/)
|
||||
|
||||
## Security Warnings
|
||||
|
@ -1,19 +1,61 @@
|
||||
#![allow(unused_imports)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
extern crate bellman_ce;
|
||||
extern crate rand;
|
||||
extern crate byteorder;
|
||||
extern crate blake2_rfc;
|
||||
extern crate num_cpus;
|
||||
extern crate crossbeam;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate cfg_if;
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
pub mod keypair;
|
||||
pub mod keypair_assembly;
|
||||
pub mod hash_writer;
|
||||
pub mod parameters;
|
||||
pub mod utils;
|
||||
pub mod circom_circuit;
|
||||
pub mod circom_circuit;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "wasm")] {
|
||||
extern crate serde_json;
|
||||
extern crate js_sys;
|
||||
extern crate web_sys;
|
||||
extern crate wasm_bindgen;
|
||||
extern crate console_error_panic_hook;
|
||||
extern crate itertools;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use itertools::Itertools;
|
||||
use parameters::MPCParameters;
|
||||
use std::io::{
|
||||
Read,
|
||||
Write,
|
||||
};
|
||||
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn contribute(params: Vec<u8>) -> Result<Vec<u8>, JsValue> {
|
||||
console_error_panic_hook::set_once();
|
||||
let disallow_points_at_infinity = false;
|
||||
|
||||
log!("Initializing phase2");
|
||||
let mut rng = &mut rand::XorShiftRng::new_unseeded(); // TODO: change this unsafe unseeded random (!)
|
||||
let mut params = MPCParameters::read(&*params, disallow_points_at_infinity, true).expect("unable to read params");
|
||||
|
||||
log!("Contributing...");
|
||||
let hash = params.contribute(&mut rng);
|
||||
log!("Contribution hash: 0x{:02x}", hash.iter().format(""));
|
||||
|
||||
let mut output: Vec<u8> = vec![];
|
||||
params.write(&mut output).expect("failed to write updated parameters");
|
||||
log!("Returning parameters");
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ extern crate byteorder;
|
||||
extern crate num_cpus;
|
||||
extern crate crossbeam;
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
use bellman_ce::singlecore::Worker;
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
use bellman_ce::multicore::Worker;
|
||||
|
||||
use byteorder::{
|
||||
BigEndian,
|
||||
ReadBytesExt,
|
||||
@ -46,8 +51,6 @@ use bellman_ce::pairing::{
|
||||
}
|
||||
};
|
||||
|
||||
pub use bellman_ce::multicore::*;
|
||||
|
||||
use bellman_ce::{
|
||||
Circuit,
|
||||
SynthesisError,
|
||||
@ -415,6 +418,7 @@ impl MPCParameters {
|
||||
// Generate a keypair
|
||||
let (pubkey, privkey) = keypair(rng, self);
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
fn batch_exp<C: CurveAffine>(bases: &mut [C], coeff: C::Scalar) {
|
||||
let coeff = coeff.into_repr();
|
||||
|
||||
@ -459,6 +463,27 @@ impl MPCParameters {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
fn batch_exp<C: CurveAffine>(bases: &mut [C], coeff: C::Scalar) {
|
||||
let coeff = coeff.into_repr();
|
||||
|
||||
let mut projective = vec![C::Projective::zero(); bases.len()];
|
||||
|
||||
// Perform wNAF, placing results into `projective`.
|
||||
let mut wnaf = Wnaf::new();
|
||||
for (base, projective) in bases.iter_mut().zip(projective.iter_mut()) {
|
||||
*projective = wnaf.base(base.into_projective(), 1).scalar(coeff);
|
||||
}
|
||||
|
||||
// Perform batch normalization
|
||||
C::Projective::batch_normalization(&mut projective);
|
||||
|
||||
// Turn it all back into affine points
|
||||
for (projective, affine) in projective.iter().zip(bases.iter_mut()) {
|
||||
*affine = projective.into_affine();
|
||||
}
|
||||
}
|
||||
|
||||
let delta_inv = privkey.delta.inverse().expect("nonzero");
|
||||
let mut l = (&self.params.l[..]).to_vec();
|
||||
let mut h = (&self.params.h[..]).to_vec();
|
||||
|
Loading…
Reference in New Issue
Block a user