Merge branch 'develop' into ark-parallel
This commit is contained in:
commit
a76e14c00b
41 changed files with 8834 additions and 594 deletions
|
@ -119,11 +119,13 @@ jobs:
|
|||
- setup-sccache
|
||||
- restore-sccache-cache
|
||||
- run:
|
||||
name: Check format
|
||||
command: cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Run clippy
|
||||
command: cargo clippy -- -D warnings
|
||||
name: Install headless chrome dependencies
|
||||
command: |
|
||||
apt-get update && apt-get install -yq \
|
||||
ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 \
|
||||
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 \
|
||||
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
|
||||
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils
|
||||
- run:
|
||||
name: Run tests
|
||||
no_output_timeout: "30m"
|
||||
|
|
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -1325,9 +1325,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -3180,6 +3180,7 @@ dependencies = [
|
|||
"pairing_ce",
|
||||
"phase2",
|
||||
"rand 0.4.6",
|
||||
"rand 0.8.5",
|
||||
"zokrates_ast",
|
||||
"zokrates_field",
|
||||
"zokrates_interpreter",
|
||||
|
@ -3364,10 +3365,12 @@ name = "zokrates_js"
|
|||
version = "1.1.4"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"getrandom",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"json",
|
||||
"lazy_static",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
|
@ -3412,12 +3415,13 @@ dependencies = [
|
|||
name = "zokrates_proof_systems"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blake2 0.8.1",
|
||||
"byteorder",
|
||||
"cfg-if 0.1.10",
|
||||
"ethabi",
|
||||
"getrandom",
|
||||
"hex 0.4.3",
|
||||
"primitive-types",
|
||||
"rand 0.4.6",
|
||||
"rand 0.8.5",
|
||||
"regex 0.2.11",
|
||||
"serde",
|
||||
"zokrates_ast",
|
||||
|
@ -3451,6 +3455,8 @@ dependencies = [
|
|||
name = "zokrates_test"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
|
|
1
changelogs/unreleased/1254-dark64
Normal file
1
changelogs/unreleased/1254-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Allow user-provided randomness in setup and proof generation
|
1
changelogs/unreleased/1264-dark64
Normal file
1
changelogs/unreleased/1264-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Optimize `zokrates-js` library size
|
|
@ -9,19 +9,18 @@ use zokrates_field::{ArkFieldExtensions, Field};
|
|||
use crate::Computation;
|
||||
use crate::{parse_fr, parse_g1, parse_g2};
|
||||
use crate::{serialization, Ark};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::gm17::{ProofPoints, VerificationKey, GM17};
|
||||
use zokrates_proof_systems::Scheme;
|
||||
use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, GM17> for Ark {
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
rng: &mut R,
|
||||
) -> SetupKeypair<T, GM17> {
|
||||
let computation = Computation::without_witness(program);
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let (pk, vk) = ArkGM17::<T::ArkEngine>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
|
@ -41,10 +40,11 @@ impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, GM17> for Ark {
|
|||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> Backend<T, GM17> for Ark {
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
witness: Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T, GM17> {
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
|
@ -59,9 +59,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, GM17> for Ark {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let proof = ArkGM17::<T::ArkEngine>::prove(&pk, computation, rng).unwrap();
|
||||
|
||||
let proof_points = ProofPoints {
|
||||
a: parse_g1::<T>(&proof.a),
|
||||
b: parse_g2::<T>(&proof.b),
|
||||
|
@ -110,6 +108,8 @@ impl<T: Field + ArkFieldExtensions> Backend<T, GM17> for Ark {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
@ -125,15 +125,18 @@ mod tests {
|
|||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bls12_377Field, GM17>>::setup(program.clone());
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair =
|
||||
<Ark as NonUniversalBackend<Bls12_377Field, GM17>>::setup(program.clone(), rng);
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bls12_377Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bls12_377Field, GM17>>::generate_proof(program, witness, keypair.pk);
|
||||
let proof = <Ark as Backend<Bls12_377Field, GM17>>::generate_proof(
|
||||
program, witness, keypair.pk, rng,
|
||||
);
|
||||
let ans = <Ark as Backend<Bls12_377Field, GM17>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
@ -147,7 +150,8 @@ mod tests {
|
|||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, GM17>>::setup(program.clone());
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, GM17>>::setup(program.clone(), rng);
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
|
@ -155,7 +159,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bw6_761Field, GM17>>::generate_proof(program, witness, keypair.pk);
|
||||
<Ark as Backend<Bw6_761Field, GM17>>::generate_proof(program, witness, keypair.pk, rng);
|
||||
let ans = <Ark as Backend<Bw6_761Field, GM17>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
|
|
@ -11,21 +11,18 @@ use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair};
|
|||
use crate::Computation;
|
||||
use crate::{parse_fr, serialization, Ark};
|
||||
use crate::{parse_g1, parse_g2};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16};
|
||||
use zokrates_proof_systems::Scheme;
|
||||
|
||||
const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications.";
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> Backend<T, G16> for Ark {
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
witness: Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let inputs = computation
|
||||
|
@ -39,9 +36,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, G16> for Ark {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let proof = Groth16::<T::ArkEngine>::prove(&pk, computation, rng).unwrap();
|
||||
|
||||
let proof_points = ProofPoints {
|
||||
a: parse_g1::<T>(&proof.a),
|
||||
b: parse_g2::<T>(&proof.b),
|
||||
|
@ -86,14 +81,11 @@ impl<T: Field + ArkFieldExtensions> Backend<T, G16> for Ark {
|
|||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, G16> for Ark {
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
rng: &mut R,
|
||||
) -> SetupKeypair<T, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let computation = Computation::without_witness(program);
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let (pk, vk) = Groth16::<T::ArkEngine>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
|
@ -113,6 +105,8 @@ impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, G16> for Ark {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
@ -128,15 +122,18 @@ mod tests {
|
|||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bls12_377Field, G16>>::setup(program.clone());
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair =
|
||||
<Ark as NonUniversalBackend<Bls12_377Field, G16>>::setup(program.clone(), rng);
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bls12_377Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bls12_377Field, G16>>::generate_proof(program, witness, keypair.pk);
|
||||
let proof = <Ark as Backend<Bls12_377Field, G16>>::generate_proof(
|
||||
program, witness, keypair.pk, rng,
|
||||
);
|
||||
let ans = <Ark as Backend<Bls12_377Field, G16>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
@ -150,7 +147,8 @@ mod tests {
|
|||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, G16>>::setup(program.clone());
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, G16>>::setup(program.clone(), rng);
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
|
@ -158,7 +156,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bw6_761Field, G16>>::generate_proof(program, witness, keypair.pk);
|
||||
<Ark as Backend<Bw6_761Field, G16>>::generate_proof(program, witness, keypair.pk, rng);
|
||||
let ans = <Ark as Backend<Bw6_761Field, G16>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
|
|
@ -17,7 +17,7 @@ use ark_poly_commit::{
|
|||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use digest::Digest;
|
||||
use rand_0_8::{Error, RngCore, SeedableRng};
|
||||
use rand_0_8::{CryptoRng, Error, RngCore, SeedableRng};
|
||||
use sha3::Keccak256;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -116,9 +116,7 @@ type MarlinInst<T> = ArkMarlin<
|
|||
>;
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark {
|
||||
fn universal_setup(size: u32) -> Vec<u8> {
|
||||
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
|
||||
|
||||
fn universal_setup<R: RngCore + CryptoRng>(size: u32, rng: &mut R) -> Vec<u8> {
|
||||
let srs = MarlinInst::<T>::universal_setup(
|
||||
2usize.pow(size),
|
||||
2usize.pow(size),
|
||||
|
@ -128,9 +126,7 @@ impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark
|
|||
.unwrap();
|
||||
|
||||
let mut res = vec![];
|
||||
|
||||
srs.serialize(&mut res).unwrap();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
@ -210,15 +206,14 @@ impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark
|
|||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
witness: Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T, marlin::Marlin> {
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
|
||||
|
||||
let pk = IndexProverKey::<
|
||||
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr,
|
||||
MarlinKZG10<
|
||||
|
@ -229,7 +224,6 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
.unwrap();
|
||||
|
||||
let public_inputs = computation.public_inputs_values();
|
||||
|
||||
let inputs = public_inputs.iter().map(parse_fr::<T>).collect::<Vec<_>>();
|
||||
|
||||
let proof = MarlinInst::<T>::prove(&pk, computation, rng).unwrap();
|
||||
|
@ -386,6 +380,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, QuadComb, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
@ -411,7 +406,8 @@ mod tests {
|
|||
],
|
||||
};
|
||||
|
||||
let srs = <Ark as UniversalBackend<Bls12_377Field, Marlin>>::universal_setup(5);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let srs = <Ark as UniversalBackend<Bls12_377Field, Marlin>>::universal_setup(5, rng);
|
||||
let keypair =
|
||||
<Ark as UniversalBackend<Bls12_377Field, Marlin>>::setup(srs, program.clone()).unwrap();
|
||||
let interpreter = Interpreter::default();
|
||||
|
@ -420,8 +416,9 @@ mod tests {
|
|||
.execute(program.clone(), &[Bls12_377Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bls12_377Field, Marlin>>::generate_proof(program, witness, keypair.pk);
|
||||
let proof = <Ark as Backend<Bls12_377Field, Marlin>>::generate_proof(
|
||||
program, witness, keypair.pk, rng,
|
||||
);
|
||||
let ans = <Ark as Backend<Bls12_377Field, Marlin>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
@ -444,7 +441,8 @@ mod tests {
|
|||
],
|
||||
};
|
||||
|
||||
let srs = <Ark as UniversalBackend<Bw6_761Field, Marlin>>::universal_setup(5);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let srs = <Ark as UniversalBackend<Bw6_761Field, Marlin>>::universal_setup(5, rng);
|
||||
let keypair =
|
||||
<Ark as UniversalBackend<Bw6_761Field, Marlin>>::setup(srs, program.clone()).unwrap();
|
||||
let interpreter = Interpreter::default();
|
||||
|
@ -453,8 +451,9 @@ mod tests {
|
|||
.execute(program.clone(), &[Bw6_761Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bw6_761Field, Marlin>>::generate_proof(program, witness, keypair.pk);
|
||||
let proof = <Ark as Backend<Bw6_761Field, Marlin>>::generate_proof(
|
||||
program, witness, keypair.pk, rng,
|
||||
);
|
||||
let ans = <Ark as Backend<Bw6_761Field, Marlin>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
|
|
@ -16,8 +16,9 @@ zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems",
|
|||
bellman = { package = "bellman_ce", version = "^0.3", default-features = false }
|
||||
pairing = { package = "pairing_ce", version = "^0.21" }
|
||||
phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }#
|
||||
getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
getrandom = { version = "0.2.8" }
|
||||
hex = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -8,26 +8,24 @@ use zokrates_field::BellmanFieldExtensions;
|
|||
use zokrates_field::Field;
|
||||
use zokrates_proof_systems::{Backend, MpcBackend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
|
||||
use crate::Bellman;
|
||||
use crate::Computation;
|
||||
use crate::{get_random_seed, Bellman};
|
||||
use crate::{parse_g1, parse_g2};
|
||||
use phase2::MPCParameters;
|
||||
use rand_0_4::Rng;
|
||||
use rand_0_4::{ChaChaRng, SeedableRng};
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
use std::io::{Read, Write};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16};
|
||||
use zokrates_proof_systems::Scheme;
|
||||
|
||||
const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications.";
|
||||
|
||||
impl<T: Field + BellmanFieldExtensions> Backend<T, G16> for Bellman {
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn generate_proof<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
witness: Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
let params = Parameters::read(proving_key.as_slice(), true).unwrap();
|
||||
|
||||
|
@ -37,7 +35,7 @@ impl<T: Field + BellmanFieldExtensions> Backend<T, G16> for Bellman {
|
|||
.map(|e| format!("0x{}", to_hex(e)))
|
||||
.collect();
|
||||
|
||||
let proof = computation.prove(¶ms);
|
||||
let proof = computation.prove(¶ms, rng);
|
||||
let proof_points = ProofPoints {
|
||||
a: parse_g1::<T>(&proof.a),
|
||||
b: parse_g2::<T>(&proof.b),
|
||||
|
@ -84,12 +82,11 @@ impl<T: Field + BellmanFieldExtensions> Backend<T, G16> for Bellman {
|
|||
}
|
||||
|
||||
impl<T: Field + BellmanFieldExtensions> NonUniversalBackend<T, G16> for Bellman {
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>>(
|
||||
fn setup<'a, I: IntoIterator<Item = Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ProgIterator<'a, T, I>,
|
||||
rng: &mut R,
|
||||
) -> SetupKeypair<T, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let parameters = Computation::without_witness(program).setup();
|
||||
let parameters = Computation::without_witness(program).setup(rng);
|
||||
let mut pk: Vec<u8> = Vec::new();
|
||||
parameters.write(&mut pk).unwrap();
|
||||
|
||||
|
@ -110,7 +107,7 @@ impl<T: Field + BellmanFieldExtensions> MpcBackend<T, G16> for Bellman {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn contribute<R: Read, W: Write, G: Rng>(
|
||||
fn contribute<R: Read, W: Write, G: RngCore + CryptoRng>(
|
||||
params: &mut R,
|
||||
rng: &mut G,
|
||||
output: &mut W,
|
||||
|
@ -118,6 +115,9 @@ impl<T: Field + BellmanFieldExtensions> MpcBackend<T, G16> for Bellman {
|
|||
let mut params =
|
||||
MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;
|
||||
|
||||
let seed = get_random_seed(rng);
|
||||
let rng = &mut ChaChaRng::from_seed(seed.as_ref());
|
||||
|
||||
let hash = params.contribute(rng);
|
||||
params.write(output).map_err(|e| e.to_string())?;
|
||||
|
||||
|
@ -199,6 +199,8 @@ pub mod serialization {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
|
@ -214,15 +216,18 @@ mod tests {
|
|||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Bellman as NonUniversalBackend<Bn128Field, G16>>::setup(program.clone());
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair =
|
||||
<Bellman as NonUniversalBackend<Bn128Field, G16>>::setup(program.clone(), rng);
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bn128Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Bellman as Backend<Bn128Field, G16>>::generate_proof(program, witness, keypair.pk);
|
||||
let proof = <Bellman as Backend<Bn128Field, G16>>::generate_proof(
|
||||
program, witness, keypair.pk, rng,
|
||||
);
|
||||
let ans = <Bellman as Backend<Bn128Field, G16>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
|
|
|
@ -16,6 +16,7 @@ use zokrates_field::BellmanFieldExtensions;
|
|||
use zokrates_field::Field;
|
||||
|
||||
use rand_0_4::ChaChaRng;
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
|
||||
pub use self::parse::*;
|
||||
|
||||
|
@ -148,24 +149,28 @@ impl<'a, T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<'a,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_random_seed<R: RngCore + CryptoRng>(rng: &mut R) -> [u32; 8] {
|
||||
let mut seed = [0u8; 32];
|
||||
rng.fill_bytes(&mut seed);
|
||||
|
||||
use std::mem::transmute;
|
||||
// This is safe because we are just reinterpreting the bytes (u8[32] -> u32[8]),
|
||||
// byte order or the actual content does not matter here as this is used
|
||||
// as a random seed for the rng (rand 0.4)
|
||||
let seed: [u32; 8] = unsafe { transmute(seed) };
|
||||
seed
|
||||
}
|
||||
|
||||
impl<'a, T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<'a, T>>>
|
||||
Computation<'a, T, I>
|
||||
{
|
||||
fn get_random_seed(&self) -> Result<[u32; 8], getrandom::Error> {
|
||||
let mut seed = [0u8; 32];
|
||||
getrandom::getrandom(&mut seed)?;
|
||||
|
||||
use std::mem::transmute;
|
||||
// This is safe because we are just reinterpreting the bytes (u8[32] -> u32[8]),
|
||||
// byte order or the actual content does not matter here as this is used
|
||||
// as a random seed for the rng.
|
||||
let seed: [u32; 8] = unsafe { transmute(seed) };
|
||||
Ok(seed)
|
||||
}
|
||||
|
||||
pub fn prove(self, params: &Parameters<T::BellmanEngine>) -> Proof<T::BellmanEngine> {
|
||||
pub fn prove<R: RngCore + CryptoRng>(
|
||||
self,
|
||||
params: &Parameters<T::BellmanEngine>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T::BellmanEngine> {
|
||||
use rand_0_4::SeedableRng;
|
||||
let seed = self.get_random_seed().unwrap();
|
||||
let seed = get_random_seed(rng);
|
||||
let rng = &mut ChaChaRng::from_seed(seed.as_ref());
|
||||
|
||||
// extract public inputs
|
||||
|
@ -188,9 +193,9 @@ impl<'a, T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<'a,
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn setup(self) -> Parameters<T::BellmanEngine> {
|
||||
pub fn setup<R: RngCore + CryptoRng>(self, rng: &mut R) -> Parameters<T::BellmanEngine> {
|
||||
use rand_0_4::SeedableRng;
|
||||
let seed = self.get_random_seed().unwrap();
|
||||
let seed = get_random_seed(rng);
|
||||
let rng = &mut ChaChaRng::from_seed(seed.as_ref());
|
||||
// run setup phase
|
||||
generate_random_parameters(self, rng).unwrap()
|
||||
|
@ -246,6 +251,8 @@ mod tests {
|
|||
|
||||
mod prove {
|
||||
use super::*;
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use zokrates_ast::flat::Parameter;
|
||||
use zokrates_ast::ir::Prog;
|
||||
|
||||
|
@ -258,8 +265,9 @@ mod tests {
|
|||
let witness = interpreter.execute(program.clone(), &[]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -278,8 +286,9 @@ mod tests {
|
|||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -298,8 +307,9 @@ mod tests {
|
|||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -315,8 +325,9 @@ mod tests {
|
|||
let witness = interpreter.execute(program.clone(), &[]).unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -348,8 +359,9 @@ mod tests {
|
|||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -371,8 +383,9 @@ mod tests {
|
|||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -396,8 +409,9 @@ mod tests {
|
|||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let params = computation.clone().setup();
|
||||
let _proof = computation.prove(¶ms);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let params = computation.clone().setup(rng);
|
||||
let _proof = computation.prove(¶ms, rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ We will start this tutorial by using ZoKrates to compile a basic program.
|
|||
First, we create a new file named `program.zok` with the following content:
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/mpc_tutorial/circuit.zok}}
|
||||
{{#include ../../../zokrates_cli/examples/book/mpc_tutorial/program.zok}}
|
||||
```
|
||||
|
||||
We compile the program using the `compile` command.
|
||||
|
|
|
@ -8,118 +8,140 @@ npm install zokrates-js
|
|||
|
||||
## Importing
|
||||
|
||||
##### Bundlers
|
||||
**Note:** As this library uses a model where the wasm module itself is natively an ES module, you will need a bundler of some form.
|
||||
Currently the only known bundler known to be fully compatible with `zokrates-js` is [Webpack](https://webpack.js.org/) (`experiments.syncWebAssembly` must be enabled).
|
||||
The choice of this default was done to reflect the trends of the JS ecosystem.
|
||||
#### ES modules
|
||||
|
||||
```js
|
||||
import { initialize } from 'zokrates-js';
|
||||
import { initialize } from "zokrates-js";
|
||||
```
|
||||
|
||||
##### Node
|
||||
#### CommonJS
|
||||
|
||||
```js
|
||||
const { initialize } = require('zokrates-js')
|
||||
let { initialize } = await import("zokrates-js");
|
||||
```
|
||||
|
||||
#### CDN
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/zokrates-js@latest/umd.min.js"></script>
|
||||
<script>
|
||||
zokrates.initialize().then((zokratesProvider) => {
|
||||
/* ... */
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
initialize().then((zokratesProvider) => {
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
|
||||
// compilation
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
// compilation
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
|
||||
// computation
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
// computation
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
|
||||
// run setup
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
// run setup
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
|
||||
// generate proof
|
||||
const proof = zokratesProvider.generateProof(artifacts.program, witness, keypair.pk);
|
||||
// generate proof
|
||||
const proof = zokratesProvider.generateProof(
|
||||
artifacts.program,
|
||||
witness,
|
||||
keypair.pk
|
||||
);
|
||||
|
||||
// export solidity verifier
|
||||
const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk);
|
||||
|
||||
// or verify off-chain
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
// export solidity verifier
|
||||
const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk);
|
||||
|
||||
// or verify off-chain
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
##### initialize()
|
||||
|
||||
Returns an initialized `ZoKratesProvider` as a promise.
|
||||
|
||||
```js
|
||||
initialize().then((zokratesProvider) => {
|
||||
// call api functions here
|
||||
initialize().then((zokratesProvider) => {
|
||||
// call api functions here
|
||||
});
|
||||
```
|
||||
|
||||
Returns: `Promise<ZoKratesProvider>`
|
||||
|
||||
##### withOptions(options)
|
||||
|
||||
Returns a `ZoKratesProvider` configured with given options.
|
||||
|
||||
```js
|
||||
initialize().then((defaultProvider) => {
|
||||
let zokratesProvider = defaultProvider.withOptions({
|
||||
backend: "ark",
|
||||
curve: "bls12_381",
|
||||
scheme: "g16"
|
||||
});
|
||||
// ...
|
||||
initialize().then((defaultProvider) => {
|
||||
let zokratesProvider = defaultProvider.withOptions({
|
||||
backend: "ark",
|
||||
curve: "bls12_381",
|
||||
scheme: "g16",
|
||||
});
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Options:
|
||||
* `backend` - Backend (options: `ark` | `bellman`, default: `ark`)
|
||||
* `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`)
|
||||
* `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`)
|
||||
|
||||
- `backend` - Backend (options: `ark` | `bellman`, default: `ark`)
|
||||
- `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`)
|
||||
- `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`)
|
||||
|
||||
Returns: `ZoKratesProvider`
|
||||
|
||||
##### compile(source[, options])
|
||||
|
||||
Compiles source code into ZoKrates internal representation of arithmetic circuits.
|
||||
|
||||
Parameters:
|
||||
* `source` - Source code to compile
|
||||
* `options` - Compilation options
|
||||
|
||||
- `source` - Source code to compile
|
||||
- `options` - Compilation options
|
||||
|
||||
Returns: `CompilationArtifacts`
|
||||
|
||||
**Examples:**
|
||||
|
||||
Compilation:
|
||||
|
||||
```js
|
||||
const artifacts = zokratesProvider.compile("def main() { return; }");
|
||||
```
|
||||
|
||||
Compilation with custom options:
|
||||
|
||||
```js
|
||||
const source = "...";
|
||||
const options = {
|
||||
location: "main.zok", // location of the root module
|
||||
resolveCallback: (currentLocation, importLocation) => {
|
||||
console.log(currentLocation + ' is importing ' + importLocation);
|
||||
return {
|
||||
source: "def main() { return; }",
|
||||
location: importLocation
|
||||
};
|
||||
}
|
||||
location: "main.zok", // location of the root module
|
||||
resolveCallback: (currentLocation, importLocation) => {
|
||||
console.log(currentLocation + " is importing " + importLocation);
|
||||
return {
|
||||
source: "def main() { return; }",
|
||||
location: importLocation,
|
||||
};
|
||||
},
|
||||
};
|
||||
const artifacts = zokratesProvider.compile(source, options);
|
||||
```
|
||||
|
||||
**Note:** The `resolveCallback` function is used to resolve dependencies.
|
||||
This callback receives the current module location and the import location of the module which is being imported.
|
||||
The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above.
|
||||
A simple file system resolver for a node environment can be implemented as follows:
|
||||
**Note:** The `resolveCallback` function is used to resolve dependencies.
|
||||
This callback receives the current module location and the import location of the module which is being imported.
|
||||
The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above.
|
||||
A simple file system resolver in a node environment can be implemented as follows:
|
||||
|
||||
```js
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
const fileSystemResolver = (from, to) => {
|
||||
const location = path.resolve(path.dirname(path.resolve(from)), to);
|
||||
|
@ -129,19 +151,21 @@ const fileSystemResolver = (from, to) => {
|
|||
```
|
||||
|
||||
##### computeWitness(artifacts, args[, options])
|
||||
|
||||
Computes a valid assignment of the variables, which include the results of the computation.
|
||||
|
||||
Parameters:
|
||||
* `artifacts` - Compilation artifacts
|
||||
* `args` - Array of arguments (eg. `["1", "2", true]`)
|
||||
* `options` - Computation options
|
||||
|
||||
- `artifacts` - Compilation artifacts
|
||||
- `args` - Array of arguments (eg. `["1", "2", true]`)
|
||||
- `options` - Computation options
|
||||
|
||||
Returns: `ComputationResult`
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
const code = 'def main(private field a) -> field { return a * a; }';
|
||||
const code = "def main(private field a) -> field { return a * a; }";
|
||||
const artifacts = zokratesProvider.compile(code);
|
||||
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
|
@ -150,54 +174,79 @@ console.log(witness); // Resulting witness which can be used to generate a proof
|
|||
console.log(output); // Computation output: "4"
|
||||
```
|
||||
|
||||
##### setup(program)
|
||||
##### setup(program[, entropy])
|
||||
|
||||
Generates a trusted setup for the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `program` - Compiled program
|
||||
|
||||
- `program` - Compiled program
|
||||
- `entropy` - User provided randomness (optional)
|
||||
|
||||
Returns: `SetupKeypair`
|
||||
|
||||
##### universalSetup(size)
|
||||
##### universalSetup(size[, entropy])
|
||||
|
||||
Performs the universal phase of a trusted setup. Only available for the `marlin` scheme.
|
||||
|
||||
Parameters:
|
||||
* `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`.
|
||||
|
||||
- `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`.
|
||||
- `entropy` - User provided randomness (optional)
|
||||
|
||||
Returns: `Uint8Array`
|
||||
|
||||
##### setupWithSrs(srs, program)
|
||||
|
||||
Generates a trusted setup with universal public parameters for the compiled program. Only available for `marlin` scheme.
|
||||
|
||||
Parameters:
|
||||
* `srs` - Universal public parameters from the universal setup phase
|
||||
* `program` - Compiled program
|
||||
|
||||
- `srs` - Universal public parameters from the universal setup phase
|
||||
- `program` - Compiled program
|
||||
|
||||
Returns: `SetupKeypair`
|
||||
|
||||
##### generateProof(program, witness, provingKey)
|
||||
##### generateProof(program, witness, provingKey[, entropy])
|
||||
|
||||
Generates a proof for a computation of the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `program` - Compiled program
|
||||
* `witness` - Witness (valid assignment of the variables) from the computation result
|
||||
* `provingKey` - Proving key from the setup keypair
|
||||
|
||||
- `program` - Compiled program
|
||||
- `witness` - Witness (valid assignment of the variables) from the computation result
|
||||
- `provingKey` - Proving key from the setup keypair
|
||||
- `entropy` - User provided randomness (optional)
|
||||
|
||||
Returns: `Proof`
|
||||
|
||||
##### verify(verificationKey, proof)
|
||||
|
||||
Verifies the generated proof.
|
||||
|
||||
Parameters:
|
||||
* `verificationKey` - Verification key from the setup keypair
|
||||
* `proof` - Generated proof
|
||||
|
||||
- `verificationKey` - Verification key from the setup keypair
|
||||
- `proof` - Generated proof
|
||||
|
||||
Returns: `boolean`
|
||||
|
||||
##### exportSolidityVerifier(verificationKey)
|
||||
|
||||
Generates a Solidity contract which contains the generated verification key and a public function to verify proofs of computation of the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `verificationKey` - Verification key from the setup keypair
|
||||
|
||||
- `verificationKey` - Verification key from the setup keypair
|
||||
|
||||
Returns: `string`
|
||||
|
||||
##### utils.formatProof(proof)
|
||||
|
||||
Formats the proof into an array of field elements that are compatible as input to the generated solidity contract
|
||||
|
||||
Parameters:
|
||||
|
||||
- `proof` - Generated proof
|
||||
|
||||
Returns: `array`
|
||||
|
|
|
@ -7,8 +7,8 @@ function zokrates() {
|
|||
ZOKRATES_STDLIB=$stdlib $bin "$@"
|
||||
}
|
||||
|
||||
# compile the circuit
|
||||
zokrates compile -i circuit.zok -o circuit
|
||||
# compile the program
|
||||
zokrates compile -i program.zok -o circuit
|
||||
|
||||
# initialize the ceremony
|
||||
# this step requires phase1 files eg. phase1radix2m2 for circuits of 2^2 constraints
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::cli_constants;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write};
|
||||
|
@ -12,6 +14,7 @@ use zokrates_bellman::Bellman;
|
|||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
use zokrates_field::Field;
|
||||
use zokrates_proof_systems::rng::get_rng_from_entropy;
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
|
@ -79,6 +82,14 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
.possible_values(cli_constants::SCHEMES)
|
||||
.default_value(constants::G16),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("entropy")
|
||||
.short("e")
|
||||
.long("entropy")
|
||||
.help("User provided randomness")
|
||||
.takes_value(true)
|
||||
.required(false),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
||||
|
@ -167,7 +178,12 @@ fn cli_generate_proof<
|
|||
.read_to_end(&mut pk)
|
||||
.map_err(|why| format!("Could not read {}: {}", pk_path.display(), why))?;
|
||||
|
||||
let proof = B::generate_proof(program, witness, pk);
|
||||
let mut rng = sub_matches
|
||||
.value_of("entropy")
|
||||
.map(get_rng_from_entropy)
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
let proof = B::generate_proof(program, witness, pk, &mut rng);
|
||||
let mut proof_file = File::create(proof_path).unwrap();
|
||||
|
||||
let proof =
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::cli_constants::MPC_DEFAULT_PATH;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::path::Path;
|
||||
|
@ -87,9 +88,7 @@ fn cli_mpc_beacon<T: Field + BellmanFieldExtensions, S: MpcScheme<T>, B: MpcBack
|
|||
|
||||
// Create an RNG based on the outcome of the random beacon
|
||||
let mut rng = {
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use rand_0_4::chacha::ChaChaRng;
|
||||
use rand_0_4::SeedableRng;
|
||||
use byteorder::ReadBytesExt;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
// The hash used for the beacon
|
||||
|
@ -126,12 +125,12 @@ fn cli_mpc_beacon<T: Field + BellmanFieldExtensions, S: MpcScheme<T>, B: MpcBack
|
|||
|
||||
let mut digest = &cur_hash[..];
|
||||
|
||||
let mut seed = [0u32; 8];
|
||||
let mut seed = [0u8; 32];
|
||||
for e in &mut seed {
|
||||
*e = digest.read_u32::<BigEndian>().unwrap();
|
||||
*e = digest.read_u8().unwrap();
|
||||
}
|
||||
|
||||
ChaChaRng::from_seed(&seed)
|
||||
StdRng::from_seed(seed)
|
||||
};
|
||||
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use crate::cli_constants::MPC_DEFAULT_PATH;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::path::Path;
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants::{BLS12_381, BN128};
|
||||
use zokrates_field::{BellmanFieldExtensions, Bls12_381Field, Bn128Field, Field};
|
||||
use zokrates_proof_systems::rng::get_rng_from_entropy;
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
|
@ -71,40 +73,6 @@ pub fn cli_mpc_contribute<
|
|||
File::open(&path).map_err(|why| format!("Could not open `{}`: {}", path.display(), why))?;
|
||||
|
||||
let mut reader = BufReader::new(file);
|
||||
let entropy = sub_matches.value_of("entropy").unwrap();
|
||||
|
||||
// Create an RNG based on a mixture of system randomness and user provided randomness
|
||||
let mut rng = {
|
||||
use blake2::{Blake2b, Digest};
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use rand_0_4::chacha::ChaChaRng;
|
||||
use rand_0_4::{OsRng, Rng, SeedableRng};
|
||||
|
||||
let h = {
|
||||
let mut system_rng = OsRng::new().unwrap();
|
||||
let mut h = Blake2b::default();
|
||||
|
||||
// Gather 1024 bytes of entropy from the system
|
||||
for _ in 0..1024 {
|
||||
let r: u8 = system_rng.gen();
|
||||
h.input(&[r]);
|
||||
}
|
||||
|
||||
// Hash it all up to make a seed
|
||||
h.input(&entropy.as_bytes());
|
||||
h.result()
|
||||
};
|
||||
|
||||
let mut digest = &h[..];
|
||||
|
||||
// Interpret the first 32 bytes of the digest as 8 32-bit words
|
||||
let mut seed = [0u32; 8];
|
||||
for e in &mut seed {
|
||||
*e = digest.read_u32::<BigEndian>().unwrap();
|
||||
}
|
||||
|
||||
ChaChaRng::from_seed(&seed)
|
||||
};
|
||||
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
let output_file = File::create(&output_path)
|
||||
|
@ -114,6 +82,11 @@ pub fn cli_mpc_contribute<
|
|||
|
||||
println!("Contributing to `{}`...", path.display());
|
||||
|
||||
let mut rng = sub_matches
|
||||
.value_of("entropy")
|
||||
.map(get_rng_from_entropy)
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
let hash = B::contribute(&mut reader, &mut rng, &mut writer)
|
||||
.map_err(|e| format!("Failed to contribute: {}", e))?;
|
||||
println!("The BLAKE2b hash of your contribution is:\n");
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::cli_constants;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Write};
|
||||
|
@ -12,6 +14,7 @@ use zokrates_bellman::Bellman;
|
|||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
use zokrates_field::Field;
|
||||
use zokrates_proof_systems::rng::get_rng_from_entropy;
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
|
@ -78,6 +81,14 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
.required(false)
|
||||
.default_value(cli_constants::UNIVERSAL_SETUP_DEFAULT_PATH),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("entropy")
|
||||
.short("e")
|
||||
.long("entropy")
|
||||
.help("User provided randomness")
|
||||
.takes_value(true)
|
||||
.required(false),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
||||
|
@ -182,8 +193,13 @@ fn cli_setup_non_universal<
|
|||
let pk_path = Path::new(sub_matches.value_of("proving-key-path").unwrap());
|
||||
let vk_path = Path::new(sub_matches.value_of("verification-key-path").unwrap());
|
||||
|
||||
let mut rng = sub_matches
|
||||
.value_of("entropy")
|
||||
.map(get_rng_from_entropy)
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
// run setup phase
|
||||
let keypair = B::setup(program);
|
||||
let keypair = B::setup(program, &mut rng);
|
||||
|
||||
// write verification key
|
||||
let mut vk_file = File::create(vk_path)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::cli_constants;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rand_0_8::rngs::StdRng;
|
||||
use rand_0_8::SeedableRng;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
@ -9,6 +11,7 @@ use zokrates_ark::Ark;
|
|||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field};
|
||||
use zokrates_proof_systems::rng::get_rng_from_entropy;
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
|
@ -54,6 +57,14 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
.required(false)
|
||||
.default_value(cli_constants::UNIVERSAL_SETUP_DEFAULT_SIZE),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("entropy")
|
||||
.short("e")
|
||||
.long("entropy")
|
||||
.help("User provided randomness")
|
||||
.takes_value(true)
|
||||
.required(false),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
||||
|
@ -98,8 +109,13 @@ fn cli_universal_setup<T: Field, S: UniversalScheme<T>, B: UniversalBackend<T, S
|
|||
.parse::<u32>()
|
||||
.map_err(|_| format!("Universal setup size {} is invalid", size))?;
|
||||
|
||||
let mut rng = sub_matches
|
||||
.value_of("entropy")
|
||||
.map(get_rng_from_entropy)
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
// run universal setup phase
|
||||
let setup = B::universal_setup(size);
|
||||
let setup = B::universal_setup(size, &mut rng);
|
||||
|
||||
// write proving key
|
||||
let mut u_file = File::create(u_path)
|
||||
|
|
|
@ -14,14 +14,9 @@ zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = f
|
|||
zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false }
|
||||
zokrates_abi = { version = "0.1", path = "../zokrates_abi", default-features = false }
|
||||
zokrates_analysis = { version = "0.1", path = "../zokrates_analysis", default-features = false }
|
||||
|
||||
num = { version = "0.1.36", default-features = false }
|
||||
num-bigint = { version = "0.2", default-features = false }
|
||||
|
||||
ark-bls12-377 = { version = "^0.3.0", features = ["curve"], default-features = false, optional = true }
|
||||
|
||||
pairing_ce = { version = "^0.21", optional = true }
|
||||
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
|
|
6
zokrates_js/.gitignore
vendored
6
zokrates_js/.gitignore
vendored
|
@ -3,6 +3,6 @@ dist
|
|||
target
|
||||
pkg
|
||||
wasm-pack.log
|
||||
stdlib
|
||||
stdlib.js
|
||||
metadata.js
|
||||
metadata.js
|
||||
wasm.js
|
||||
umd.min.js
|
|
@ -15,6 +15,8 @@ wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] }
|
|||
typed-arena = "1.4.1"
|
||||
lazy_static = "1.4.0"
|
||||
zokrates_field = { path = "../zokrates_field" }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
getrandom = { version = "0.2.8", features = ["js"] }
|
||||
zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_ark = { path = "../zokrates_ark", default-features = false }
|
||||
zokrates_embed = { path = "../zokrates_embed", default-features = false }
|
||||
|
|
|
@ -40,9 +40,5 @@ fn export_metadata() {
|
|||
.insert("version", config["package"]["version"].as_str().unwrap())
|
||||
.unwrap();
|
||||
|
||||
fs::write(
|
||||
"metadata.js",
|
||||
format!("module.exports = {}", metadata.dump()),
|
||||
)
|
||||
.unwrap();
|
||||
fs::write("metadata.js", format!("export default {}", metadata.dump())).unwrap();
|
||||
}
|
||||
|
|
5
zokrates_js/index-node.js
Normal file
5
zokrates_js/index-node.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
// https://docs.rs/getrandom/0.2.8/getrandom/index.html#nodejs-es-module-support
|
||||
import { webcrypto } from "node:crypto";
|
||||
globalThis.crypto = webcrypto;
|
||||
|
||||
export * from "./index.js";
|
7
zokrates_js/index.d.ts
vendored
7
zokrates_js/index.d.ts
vendored
|
@ -85,13 +85,14 @@ declare module "zokrates-js" {
|
|||
args: any[],
|
||||
options?: ComputeOptions
|
||||
): ComputationResult;
|
||||
setup(program: Uint8Array): SetupKeypair;
|
||||
universalSetup(size: number): Uint8Array;
|
||||
setup(program: Uint8Array, entropy?: string): SetupKeypair;
|
||||
universalSetup(size: number, entropy?: string): Uint8Array;
|
||||
setupWithSrs(srs: Uint8Array, program: Uint8Array): SetupKeypair;
|
||||
generateProof(
|
||||
program: Uint8Array,
|
||||
witness: string,
|
||||
provingKey: Uint8Array
|
||||
provingKey: Uint8Array,
|
||||
entropy?: string
|
||||
): Proof;
|
||||
verify(verificationKey: VerificationKey, proof: Proof): boolean;
|
||||
exportSolidityVerifier(verificationKey: VerificationKey): string;
|
||||
|
|
|
@ -1,9 +1,139 @@
|
|||
import lib from "./lib.js";
|
||||
import { inflate } from "pako";
|
||||
import metadata from "./metadata.js";
|
||||
import * as wasmExports from "./wasm.js";
|
||||
|
||||
const initialize = async () => {
|
||||
const pkg = await import("./pkg/index.js");
|
||||
return lib(pkg);
|
||||
await wasmExports.init(inflate);
|
||||
|
||||
const defaultProvider = {
|
||||
compile: (source, compileOptions = {}) => {
|
||||
var {
|
||||
curve = "bn128",
|
||||
location = "main.zok",
|
||||
resolveCallback = () => null,
|
||||
config = {},
|
||||
snarkjs = false,
|
||||
} = compileOptions;
|
||||
|
||||
config = { snarkjs, ...config };
|
||||
|
||||
const ptr = wasmExports.compile(
|
||||
source,
|
||||
location,
|
||||
resolveCallback,
|
||||
config,
|
||||
curve
|
||||
);
|
||||
const result = Object.assign(
|
||||
{
|
||||
program: ptr.program(),
|
||||
abi: ptr.abi(),
|
||||
constraintCount: ptr.constraint_count(),
|
||||
},
|
||||
snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}
|
||||
);
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
computeWitness: (input, args, computeOptions = {}) => {
|
||||
const { program, abi } =
|
||||
input instanceof Uint8Array ? { program: input, abi: null } : input;
|
||||
|
||||
const { snarkjs = false, logCallback = console.log } = computeOptions;
|
||||
const ptr = wasmExports.compute_witness(
|
||||
program,
|
||||
abi,
|
||||
JSON.stringify(args),
|
||||
{
|
||||
snarkjs: snarkjs,
|
||||
},
|
||||
logCallback
|
||||
);
|
||||
|
||||
const result = Object.assign(
|
||||
{
|
||||
witness: ptr.witness(),
|
||||
output: ptr.output(),
|
||||
},
|
||||
snarkjs
|
||||
? {
|
||||
snarkjs: {
|
||||
witness: ptr.snarkjs_witness(),
|
||||
},
|
||||
}
|
||||
: {}
|
||||
);
|
||||
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
setup: (program, entropy, options) => {
|
||||
return wasmExports.setup(program, entropy, options);
|
||||
},
|
||||
universalSetup: (curve, size, entropy) => {
|
||||
return wasmExports.universal_setup(curve, size, entropy);
|
||||
},
|
||||
setupWithSrs: (srs, program, options) => {
|
||||
return wasmExports.setup_with_srs(srs, program, options);
|
||||
},
|
||||
generateProof: (program, witness, provingKey, entropy, options) => {
|
||||
return wasmExports.generate_proof(
|
||||
program,
|
||||
witness,
|
||||
provingKey,
|
||||
entropy,
|
||||
options
|
||||
);
|
||||
},
|
||||
verify: (vk, proof, options) => {
|
||||
return wasmExports.verify(vk, proof, options);
|
||||
},
|
||||
exportSolidityVerifier: (vk) => {
|
||||
return wasmExports.export_solidity_verifier(vk);
|
||||
},
|
||||
utils: {
|
||||
formatProof: (proof) => {
|
||||
return wasmExports.format_proof(proof);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const withOptions = (options) => {
|
||||
return {
|
||||
withOptions,
|
||||
compile: (source, compileOptions = {}) =>
|
||||
defaultProvider.compile(source, {
|
||||
...compileOptions,
|
||||
curve: options.curve,
|
||||
}),
|
||||
computeWitness: (artifacts, args, computeOptions = {}) =>
|
||||
defaultProvider.computeWitness(artifacts, args, computeOptions),
|
||||
setup: (program, entropy) =>
|
||||
defaultProvider.setup(program, entropy, options),
|
||||
universalSetup: (size, entropy) =>
|
||||
defaultProvider.universalSetup(options.curve, size, entropy),
|
||||
setupWithSrs: (srs, program) =>
|
||||
defaultProvider.setupWithSrs(srs, program, options),
|
||||
generateProof: (program, witness, provingKey, entropy) =>
|
||||
defaultProvider.generateProof(
|
||||
program,
|
||||
witness,
|
||||
provingKey,
|
||||
entropy,
|
||||
options
|
||||
),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof, options),
|
||||
exportSolidityVerifier: (vk) =>
|
||||
defaultProvider.exportSolidityVerifier(vk),
|
||||
utils: {
|
||||
formatProof: (proof) => defaultProvider.utils.formatProof(proof),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }),
|
||||
};
|
||||
};
|
||||
|
||||
export { initialize, metadata };
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
module.exports = (pkg) => {
|
||||
const defaultProvider = {
|
||||
compile: (source, compileOptions = {}) => {
|
||||
var {
|
||||
curve = "bn128",
|
||||
location = "main.zok",
|
||||
resolveCallback = () => null,
|
||||
config = {},
|
||||
snarkjs = false,
|
||||
} = compileOptions;
|
||||
|
||||
config = { snarkjs, ...config };
|
||||
|
||||
const ptr = pkg.compile(source, location, resolveCallback, config, curve);
|
||||
const result = Object.assign(
|
||||
{
|
||||
program: ptr.program(),
|
||||
abi: ptr.abi(),
|
||||
constraintCount: ptr.constraint_count(),
|
||||
},
|
||||
snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}
|
||||
);
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
computeWitness: (input, args, computeOptions = {}) => {
|
||||
const { program, abi } =
|
||||
input instanceof Uint8Array ? { program: input, abi: null } : input;
|
||||
|
||||
const { snarkjs = false, logCallback = console.log } = computeOptions;
|
||||
const ptr = pkg.compute_witness(
|
||||
program,
|
||||
abi,
|
||||
JSON.stringify(args),
|
||||
{
|
||||
snarkjs: snarkjs,
|
||||
},
|
||||
logCallback
|
||||
);
|
||||
|
||||
const result = Object.assign(
|
||||
{
|
||||
witness: ptr.witness(),
|
||||
output: ptr.output(),
|
||||
},
|
||||
snarkjs
|
||||
? {
|
||||
snarkjs: {
|
||||
witness: ptr.snarkjs_witness(),
|
||||
},
|
||||
}
|
||||
: {}
|
||||
);
|
||||
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
setup: (program, options) => {
|
||||
return pkg.setup(program, options);
|
||||
},
|
||||
universalSetup: (curve, size) => {
|
||||
return pkg.universal_setup(curve, size);
|
||||
},
|
||||
setupWithSrs: (srs, program, options) => {
|
||||
return pkg.setup_with_srs(srs, program, options);
|
||||
},
|
||||
generateProof: (program, witness, provingKey, options) => {
|
||||
return pkg.generate_proof(program, witness, provingKey, options);
|
||||
},
|
||||
verify: (vk, proof, options) => {
|
||||
return pkg.verify(vk, proof, options);
|
||||
},
|
||||
exportSolidityVerifier: (vk) => {
|
||||
return pkg.export_solidity_verifier(vk);
|
||||
},
|
||||
utils: {
|
||||
formatProof: (proof) => {
|
||||
return pkg.format_proof(proof);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const withOptions = (options) => {
|
||||
return {
|
||||
withOptions,
|
||||
compile: (source, compileOptions = {}) =>
|
||||
defaultProvider.compile(source, {
|
||||
...compileOptions,
|
||||
curve: options.curve,
|
||||
}),
|
||||
computeWitness: (artifacts, args, computeOptions = {}) =>
|
||||
defaultProvider.computeWitness(artifacts, args, computeOptions),
|
||||
setup: (program) => defaultProvider.setup(program, options),
|
||||
universalSetup: (size) =>
|
||||
defaultProvider.universalSetup(options.curve, size),
|
||||
setupWithSrs: (srs, program) =>
|
||||
defaultProvider.setupWithSrs(srs, program, options),
|
||||
generateProof: (program, witness, provingKey) =>
|
||||
defaultProvider.generateProof(program, witness, provingKey, options),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof, options),
|
||||
exportSolidityVerifier: (vk) =>
|
||||
defaultProvider.exportSolidityVerifier(vk),
|
||||
utils: {
|
||||
formatProof: (proof) => defaultProvider.utils.formatProof(proof),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }),
|
||||
};
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
const lib = require("../lib.js");
|
||||
const metadata = require("../metadata.js");
|
||||
|
||||
const initialize = async () => {
|
||||
return lib(require("./pkg/index.js"));
|
||||
};
|
||||
|
||||
module.exports = { initialize, metadata };
|
8133
zokrates_js/package-lock.json
generated
8133
zokrates_js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
"name": "zokrates-js",
|
||||
"version": "1.1.4",
|
||||
"module": "index.js",
|
||||
"main": "node/index.js",
|
||||
"main": "index-node.js",
|
||||
"description": "JavaScript bindings for ZoKrates",
|
||||
"contributors": [
|
||||
"Darko Macesic <darem966@gmail.com>",
|
||||
|
@ -15,38 +15,46 @@
|
|||
],
|
||||
"license": "GPLv3",
|
||||
"files": [
|
||||
"node",
|
||||
"pkg",
|
||||
"index.js",
|
||||
"index-node.js",
|
||||
"index.d.ts",
|
||||
"lib.js",
|
||||
"metadata.js"
|
||||
"wasm.js",
|
||||
"metadata.js",
|
||||
"umd.min.js"
|
||||
],
|
||||
"types": "index.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"node": "./node/index.js",
|
||||
"node": "./index-node.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"wasm-pack": "wasm-pack build --out-name index",
|
||||
"wasm-pack": "wasm-pack build --out-name index --target web",
|
||||
"prebuild": "npm install",
|
||||
"build": "npm run build:bundler && npm run build:node",
|
||||
"build:dev": "npm run build:bundler:dev && npm run build:node:dev",
|
||||
"build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg",
|
||||
"build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg",
|
||||
"build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg",
|
||||
"build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg",
|
||||
"clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts",
|
||||
"clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts",
|
||||
"pretest": "npm run build:node:dev",
|
||||
"build": "npm run wasm-pack -- --release && npm run patch && npm run bundle",
|
||||
"build:dev": "npm run wasm-pack -- --dev && npm run patch && npm run bundle",
|
||||
"pretest": "npm run build",
|
||||
"test": "npm run run-tests",
|
||||
"run-tests": "mocha --timeout 100000 --recursive tests"
|
||||
"run-tests": "mocha --timeout 100000 --recursive tests",
|
||||
"patch": "node patch.js",
|
||||
"bundle": "browserify ./index.js --standalone zokrates -t [ babelify --presets [ @babel/preset-env ] ] | uglifyjs --compress --mangle > umd.min.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dree": "^2.6.1",
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"acorn": "^8.8.1",
|
||||
"astring": "^1.8.4",
|
||||
"babelify": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"dree": "^3.4.3",
|
||||
"mocha": "^9.2.0",
|
||||
"puppeteer": "^19.6.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"snarkjs": "^0.4.25",
|
||||
"uglify-js": "^3.17.4",
|
||||
"wasm-pack": "^0.10.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"pako": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
|
75
zokrates_js/patch.js
Normal file
75
zokrates_js/patch.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
import { parse } from "acorn";
|
||||
import { generate } from "astring";
|
||||
import fs from "fs/promises";
|
||||
import pako from "pako";
|
||||
|
||||
(async function () {
|
||||
const packageObject = JSON.parse(
|
||||
await fs.readFile("pkg/package.json", { encoding: "utf-8" })
|
||||
);
|
||||
const wasmPath = packageObject.files.find((file) => file.endsWith(".wasm"));
|
||||
const wasm = await fs.readFile(`pkg/${wasmPath}`);
|
||||
|
||||
const deflated = Buffer.from(pako.deflate(wasm));
|
||||
const wasmBase64 = deflated.toString("base64");
|
||||
|
||||
const init = `export async function init(inflate) {
|
||||
const encoded = '${wasmBase64}';
|
||||
|
||||
let bytes;
|
||||
|
||||
if (typeof Buffer === "function") {
|
||||
bytes = Buffer.from(encoded, "base64");
|
||||
} else if (typeof atob === "function") {
|
||||
const binary = atob(encoded);
|
||||
bytes = new Uint8Array(binary.length);
|
||||
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unsupported platform");
|
||||
}
|
||||
|
||||
const imports = getImports();
|
||||
initMemory(imports);
|
||||
|
||||
bytes = inflate(bytes);
|
||||
|
||||
const { instance, module } = await WebAssembly.instantiate(bytes, imports);
|
||||
return finalizeInit(instance, module);
|
||||
}
|
||||
|
||||
export default init;`;
|
||||
|
||||
const generatedSource = await fs.readFile(`pkg/${packageObject.module}`, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
|
||||
const ast = parse(generatedSource, {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
});
|
||||
|
||||
let body = ast.body.filter((v) => {
|
||||
switch (v.type) {
|
||||
case "FunctionDeclaration":
|
||||
// we don't use these functions so we strip them out
|
||||
return !["load", "init", "initSync"].includes(v.id.name);
|
||||
case "ExportDefaultDeclaration":
|
||||
// we will provide our own default export
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
body.pop(); // removes `export { initSync }`
|
||||
|
||||
const source = generate({
|
||||
...ast,
|
||||
body,
|
||||
});
|
||||
|
||||
await fs.writeFile("wasm.js", source + init);
|
||||
})();
|
|
@ -24,12 +24,6 @@ if [ $NPM_VERSION = $PACKAGE_VERSION ]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
# make sure the pkg folder is present
|
||||
if [ ! -d "pkg" ]; then
|
||||
echo "pkg folder is missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# publish
|
||||
npm set //registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
npm publish
|
|
@ -4,6 +4,7 @@ mod util;
|
|||
extern crate lazy_static;
|
||||
|
||||
use crate::util::normalize_path;
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::to_string_pretty;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -25,6 +26,7 @@ use zokrates_core::compile::{compile as core_compile, CompilationArtifacts, Comp
|
|||
use zokrates_core::imports::Error;
|
||||
use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field};
|
||||
use zokrates_proof_systems::groth16::G16;
|
||||
use zokrates_proof_systems::rng::get_rng_from_entropy;
|
||||
use zokrates_proof_systems::{
|
||||
Backend, Marlin, NonUniversalBackend, NonUniversalScheme, Proof, Scheme,
|
||||
SolidityCompatibleField, SolidityCompatibleScheme, TaggedKeypair, TaggedProof,
|
||||
|
@ -220,6 +222,7 @@ impl<'a> Write for LogWriter<'a> {
|
|||
|
||||
mod internal {
|
||||
use super::*;
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
|
||||
pub fn compile<T: Field>(
|
||||
source: JsValue,
|
||||
|
@ -345,10 +348,12 @@ mod internal {
|
|||
T: Field,
|
||||
S: NonUniversalScheme<T> + Serialize,
|
||||
B: NonUniversalBackend<T, S>,
|
||||
R: RngCore + CryptoRng,
|
||||
>(
|
||||
program: ir::Prog<T>,
|
||||
rng: &mut R,
|
||||
) -> JsValue {
|
||||
let keypair = B::setup(program);
|
||||
let keypair = B::setup(program, rng);
|
||||
let tagged_keypair = TaggedKeypair::<T, S>::new(keypair);
|
||||
JsValue::from_serde(&tagged_keypair).unwrap()
|
||||
}
|
||||
|
@ -367,22 +372,29 @@ mod internal {
|
|||
Ok(JsValue::from_serde(&TaggedKeypair::<T, S>::new(keypair)).unwrap())
|
||||
}
|
||||
|
||||
pub fn universal_setup_of_size<T: Field, S: UniversalScheme<T>, B: UniversalBackend<T, S>>(
|
||||
pub fn universal_setup_of_size<
|
||||
T: Field,
|
||||
S: UniversalScheme<T>,
|
||||
B: UniversalBackend<T, S>,
|
||||
R: RngCore + CryptoRng,
|
||||
>(
|
||||
size: u32,
|
||||
rng: &mut R,
|
||||
) -> Vec<u8> {
|
||||
B::universal_setup(size)
|
||||
B::universal_setup(size, rng)
|
||||
}
|
||||
|
||||
pub fn generate_proof<T: Field, S: Scheme<T>, B: Backend<T, S>>(
|
||||
pub fn generate_proof<T: Field, S: Scheme<T>, B: Backend<T, S>, R: RngCore + CryptoRng>(
|
||||
prog: ir::Prog<T>,
|
||||
witness: JsValue,
|
||||
pk: &[u8],
|
||||
rng: &mut R,
|
||||
) -> Result<JsValue, JsValue> {
|
||||
let str_witness = witness.as_string().unwrap();
|
||||
let ir_witness: ir::Witness<T> = ir::Witness::read(str_witness.as_bytes())
|
||||
.map_err(|err| JsValue::from_str(&format!("Could not read witness: {}", err)))?;
|
||||
|
||||
let proof = B::generate_proof(prog, ir_witness, pk.to_vec());
|
||||
let proof = B::generate_proof(prog, ir_witness, pk.to_vec(), rng);
|
||||
Ok(JsValue::from_serde(&TaggedProof::<T, S>::new(proof.proof, proof.inputs)).unwrap())
|
||||
}
|
||||
|
||||
|
@ -516,7 +528,7 @@ pub fn export_solidity_verifier(vk: JsValue) -> Result<JsValue, JsValue> {
|
|||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn setup(program: &[u8], options: JsValue) -> Result<JsValue, JsValue> {
|
||||
pub fn setup(program: &[u8], entropy: JsValue, options: JsValue) -> Result<JsValue, JsValue> {
|
||||
let options: serde_json::Value = options.into_serde().unwrap();
|
||||
|
||||
let backend = BackendParameter::try_from(
|
||||
|
@ -537,25 +549,48 @@ pub fn setup(program: &[u8], options: JsValue) -> Result<JsValue, JsValue> {
|
|||
.map_err(|err| JsValue::from_str(&err))?
|
||||
.collect();
|
||||
|
||||
let mut rng = entropy
|
||||
.as_string()
|
||||
.map(|s| get_rng_from_entropy(&s))
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
match (backend, scheme) {
|
||||
(BackendParameter::Bellman, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Bellman>(p)),
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Bellman, _>(
|
||||
p, &mut rng,
|
||||
)),
|
||||
ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str(
|
||||
"Not supported: https://github.com/Zokrates/ZoKrates/issues/1200",
|
||||
)),
|
||||
_ => Err(JsValue::from_str("Not supported")),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng))
|
||||
}
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng))
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng))
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => {
|
||||
Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng))
|
||||
}
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>(
|
||||
p, &mut rng,
|
||||
)),
|
||||
ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>(
|
||||
p, &mut rng,
|
||||
)),
|
||||
ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>(
|
||||
p, &mut rng,
|
||||
)),
|
||||
ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>(
|
||||
p, &mut rng,
|
||||
)),
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported options")),
|
||||
}
|
||||
|
@ -588,27 +623,40 @@ pub fn setup_with_srs(srs: &[u8], program: &[u8], options: JsValue) -> Result<Js
|
|||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn universal_setup(curve: JsValue, size: u32) -> Result<Vec<u8>, JsValue> {
|
||||
pub fn universal_setup(curve: JsValue, size: u32, entropy: JsValue) -> Result<Vec<u8>, JsValue> {
|
||||
let curve = CurveParameter::try_from(curve.as_string().unwrap().as_str())
|
||||
.map_err(|e| JsValue::from_str(&e))?;
|
||||
|
||||
let mut rng = entropy
|
||||
.as_string()
|
||||
.map(|s| get_rng_from_entropy(&s))
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
match curve {
|
||||
CurveParameter::Bn128 => {
|
||||
Ok(internal::universal_setup_of_size::<Bn128Field, Marlin, Ark>(size))
|
||||
}
|
||||
CurveParameter::Bn128 => Ok(internal::universal_setup_of_size::<
|
||||
Bn128Field,
|
||||
Marlin,
|
||||
Ark,
|
||||
_,
|
||||
>(size, &mut rng)),
|
||||
CurveParameter::Bls12_381 => Ok(internal::universal_setup_of_size::<
|
||||
Bls12_381Field,
|
||||
Marlin,
|
||||
Ark,
|
||||
>(size)),
|
||||
_,
|
||||
>(size, &mut rng)),
|
||||
CurveParameter::Bls12_377 => Ok(internal::universal_setup_of_size::<
|
||||
Bls12_377Field,
|
||||
Marlin,
|
||||
Ark,
|
||||
>(size)),
|
||||
CurveParameter::Bw6_761 => {
|
||||
Ok(internal::universal_setup_of_size::<Bw6_761Field, Marlin, Ark>(size))
|
||||
}
|
||||
_,
|
||||
>(size, &mut rng)),
|
||||
CurveParameter::Bw6_761 => Ok(internal::universal_setup_of_size::<
|
||||
Bw6_761Field,
|
||||
Marlin,
|
||||
Ark,
|
||||
_,
|
||||
>(size, &mut rng)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -617,6 +665,7 @@ pub fn generate_proof(
|
|||
program: &[u8],
|
||||
witness: JsValue,
|
||||
pk: &[u8],
|
||||
entropy: JsValue,
|
||||
options: JsValue,
|
||||
) -> Result<JsValue, JsValue> {
|
||||
let options: serde_json::Value = options.into_serde().unwrap();
|
||||
|
@ -639,10 +688,15 @@ pub fn generate_proof(
|
|||
.map_err(|err| JsValue::from_str(&err))?
|
||||
.collect();
|
||||
|
||||
let mut rng = entropy
|
||||
.as_string()
|
||||
.map(|s| get_rng_from_entropy(&s))
|
||||
.unwrap_or_else(StdRng::from_entropy);
|
||||
|
||||
match (backend, scheme) {
|
||||
(BackendParameter::Bellman, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
internal::generate_proof::<_, G16, Bellman>(p, witness, pk)
|
||||
internal::generate_proof::<_, G16, Bellman, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str(
|
||||
"Not supported: https://github.com/Zokrates/ZoKrates/issues/1200",
|
||||
|
@ -650,35 +704,45 @@ pub fn generate_proof(
|
|||
_ => Err(JsValue::from_str("Not supported")),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk),
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, G16, Ark>(p, witness, pk)
|
||||
internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
internal::generate_proof::<_, G16, Ark>(p, witness, pk)
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk),
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark>(p, witness, pk)
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark>(p, witness, pk)
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::MARLIN) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, Marlin, Ark>(p, witness, pk),
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::MARLIN) => match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bls12_377Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
ProgEnum::Bw6_761Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng)
|
||||
}
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported options")),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const assert = require("assert");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const dree = require("dree");
|
||||
const snarkjs = require("snarkjs");
|
||||
const { initialize, metadata } = require("../node/index.js");
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import * as snarkjs from "snarkjs";
|
||||
import dree from "dree";
|
||||
import { initialize, metadata } from "../index-node.js";
|
||||
|
||||
let zokratesProvider;
|
||||
let tmpFolder;
|
||||
|
@ -65,7 +65,7 @@ describe("tests", () => {
|
|||
|
||||
it("should resolve stdlib module", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const code = `import "utils/pack/bool/unpack" as unpack;\ndef main() { return; }`;
|
||||
const code = `import "utils/pack/bool/unpack" as unpack;\ndef main() {}`;
|
||||
zokratesProvider.compile(code);
|
||||
});
|
||||
});
|
||||
|
@ -169,7 +169,7 @@ describe("tests", () => {
|
|||
it("compile", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const code = `def main(private field a, field b) -> bool {
|
||||
bool check = if (a == 0){ true} else {a * a == b};
|
||||
bool check = if (a == 0) { true } else { a * a == b };
|
||||
assert(check);
|
||||
return true;
|
||||
}`;
|
||||
|
@ -193,9 +193,33 @@ describe("tests", () => {
|
|||
assert.doesNotThrow(() => {
|
||||
if (options.scheme === "marlin") {
|
||||
const srs = provider.universalSetup(4);
|
||||
const srs2 = provider.universalSetup(4);
|
||||
// second call should return a new srs
|
||||
assert.notDeepEqual(srs, srs2);
|
||||
keypair = provider.setupWithSrs(srs, artifacts.program);
|
||||
} else {
|
||||
keypair = provider.setup(artifacts.program);
|
||||
const keypair2 = provider.setup(artifacts.program);
|
||||
// second call should return a new keypair
|
||||
assert.notDeepEqual(keypair, keypair2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("setup with user-provided entropy", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
let entropy = "f5c51ca46c331965";
|
||||
if (options.scheme === "marlin") {
|
||||
const srs = provider.universalSetup(4, entropy);
|
||||
const srs2 = provider.universalSetup(4, entropy);
|
||||
// second call with the same entropy should return the same srs
|
||||
assert.deepEqual(srs, srs2);
|
||||
keypair = provider.setupWithSrs(srs, artifacts.program);
|
||||
} else {
|
||||
keypair = provider.setup(artifacts.program, entropy);
|
||||
const keypair2 = provider.setup(artifacts.program, entropy);
|
||||
// second call with the same entropy should return the same keypair
|
||||
assert.deepEqual(keypair, keypair2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -236,6 +260,37 @@ describe("tests", () => {
|
|||
);
|
||||
assert.ok(proof !== undefined);
|
||||
assert.equal(proof.inputs.length, 2);
|
||||
|
||||
// second call should return a new proof
|
||||
let proof2 = provider.generateProof(
|
||||
artifacts.program,
|
||||
computationResult.witness,
|
||||
keypair.pk
|
||||
);
|
||||
assert.notDeepEqual(proof, proof2);
|
||||
});
|
||||
});
|
||||
|
||||
it("generate proof with user-provided entropy", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
let entropy = "326e2c864f414ffb";
|
||||
proof = provider.generateProof(
|
||||
artifacts.program,
|
||||
computationResult.witness,
|
||||
keypair.pk,
|
||||
entropy
|
||||
);
|
||||
assert.ok(proof !== undefined);
|
||||
assert.equal(proof.inputs.length, 2);
|
||||
|
||||
// second call with the same entropy should return the same proof
|
||||
let proof2 = provider.generateProof(
|
||||
artifacts.program,
|
||||
computationResult.witness,
|
||||
keypair.pk,
|
||||
entropy
|
||||
);
|
||||
assert.deepEqual(proof, proof2);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -364,8 +419,8 @@ describe("tests", () => {
|
|||
extensions: ["json"],
|
||||
};
|
||||
|
||||
dree.scan(testsPath, options, function (file) {
|
||||
const test = require(file.path);
|
||||
dree.scan(testsPath, options, async function (file) {
|
||||
const test = JSON.parse(await fs.promises.readFile(file.path));
|
||||
const testName = file.path.substring(testsPath.length + 1);
|
||||
|
||||
if (!ignoreList.some((v) => testName.startsWith(v)))
|
||||
|
|
38
zokrates_js/tests/umd/index.html
Normal file
38
zokrates_js/tests/umd/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Test Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="../../umd.min.js"></script>
|
||||
<script>
|
||||
zokrates.initialize().then((zokratesProvider) => {
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, [
|
||||
"2",
|
||||
]);
|
||||
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
|
||||
const proof = zokratesProvider.generateProof(
|
||||
artifacts.program,
|
||||
witness,
|
||||
keypair.pk
|
||||
);
|
||||
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
|
||||
var result = document.createElement("div");
|
||||
result.id = "result";
|
||||
result.innerText = isVerified;
|
||||
|
||||
document.body.appendChild(result);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
27
zokrates_js/tests/umd/tests.js
Normal file
27
zokrates_js/tests/umd/tests.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import puppeteer from "puppeteer";
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
|
||||
describe("umd web tests", () => {
|
||||
it("verify", async () => {
|
||||
const browser = await puppeteer.launch({
|
||||
headless: true,
|
||||
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
|
||||
let response = await page.goto(
|
||||
path.dirname(import.meta.url) + "/index.html"
|
||||
);
|
||||
assert(response.ok());
|
||||
|
||||
let element = await page.waitForSelector("#result", {
|
||||
timeout: 30000,
|
||||
visible: true,
|
||||
});
|
||||
let value = await element.evaluate((el) => el.textContent, element);
|
||||
assert.equal(value, "true");
|
||||
|
||||
await browser.close();
|
||||
});
|
||||
});
|
|
@ -12,5 +12,6 @@ regex = "0.2"
|
|||
cfg-if = "0.1"
|
||||
ethabi = "17.0.0"
|
||||
primitive-types = { version = "0.11", features = ["rlp"] }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
blake2 = "0.8.1"
|
||||
byteorder = "1"
|
|
@ -1,3 +1,4 @@
|
|||
pub mod rng;
|
||||
pub mod to_token;
|
||||
|
||||
mod scheme;
|
||||
|
@ -10,9 +11,8 @@ pub use tagged::{TaggedKeypair, TaggedProof, TaggedVerificationKey};
|
|||
|
||||
use zokrates_ast::ir;
|
||||
|
||||
use rand_0_8::{CryptoRng, RngCore};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use rand_0_4::Rng;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use zokrates_field::Field;
|
||||
|
@ -96,22 +96,24 @@ impl ToString for G2AffineFq2 {
|
|||
}
|
||||
|
||||
pub trait Backend<T: Field, S: Scheme<T>> {
|
||||
fn generate_proof<'a, I: IntoIterator<Item = ir::Statement<'a, T>>>(
|
||||
fn generate_proof<'a, I: IntoIterator<Item = ir::Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ir::ProgIterator<'a, T, I>,
|
||||
witness: ir::Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
rng: &mut R,
|
||||
) -> Proof<T, S>;
|
||||
|
||||
fn verify(vk: S::VerificationKey, proof: Proof<T, S>) -> bool;
|
||||
}
|
||||
pub trait NonUniversalBackend<T: Field, S: NonUniversalScheme<T>>: Backend<T, S> {
|
||||
fn setup<'a, I: IntoIterator<Item = ir::Statement<'a, T>>>(
|
||||
fn setup<'a, I: IntoIterator<Item = ir::Statement<'a, T>>, R: RngCore + CryptoRng>(
|
||||
program: ir::ProgIterator<'a, T, I>,
|
||||
rng: &mut R,
|
||||
) -> SetupKeypair<T, S>;
|
||||
}
|
||||
|
||||
pub trait UniversalBackend<T: Field, S: UniversalScheme<T>>: Backend<T, S> {
|
||||
fn universal_setup(size: u32) -> Vec<u8>;
|
||||
fn universal_setup<R: RngCore + CryptoRng>(size: u32, rng: &mut R) -> Vec<u8>;
|
||||
|
||||
fn setup<'a, I: IntoIterator<Item = ir::Statement<'a, T>>>(
|
||||
srs: Vec<u8>,
|
||||
|
@ -126,7 +128,7 @@ pub trait MpcBackend<T: Field, S: Scheme<T>> {
|
|||
output: &mut W,
|
||||
) -> Result<(), String>;
|
||||
|
||||
fn contribute<R: Read, W: Write, G: Rng>(
|
||||
fn contribute<R: Read, W: Write, G: RngCore + CryptoRng>(
|
||||
params: &mut R,
|
||||
rng: &mut G,
|
||||
output: &mut W,
|
||||
|
|
20
zokrates_proof_systems/src/rng.rs
Normal file
20
zokrates_proof_systems/src/rng.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use blake2::{Blake2b, Digest};
|
||||
use byteorder::ReadBytesExt;
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
|
||||
pub fn get_rng_from_entropy(entropy: &str) -> StdRng {
|
||||
let h = {
|
||||
let mut h = Blake2b::default();
|
||||
h.input(&entropy.as_bytes());
|
||||
h.result()
|
||||
};
|
||||
|
||||
let mut digest = &h[..];
|
||||
let mut seed = [0u8; 32];
|
||||
|
||||
for e in &mut seed {
|
||||
*e = digest.read_u8().unwrap();
|
||||
}
|
||||
|
||||
StdRng::from_seed(seed)
|
||||
}
|
|
@ -21,6 +21,7 @@ typed-arena = "1.4.1"
|
|||
wasm-bindgen-test = "^0.3.0"
|
||||
zokrates_ark = { version = "0.1", path = "../zokrates_ark" }
|
||||
zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems" }
|
||||
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
getrandom = { version = "0.2.8", features = ["js"] }
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -10,6 +10,7 @@ use zokrates_field::Bn128Field;
|
|||
use zokrates_interpreter::Interpreter;
|
||||
use zokrates_proof_systems::{Backend, NonUniversalBackend};
|
||||
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use zokrates_ark::Ark;
|
||||
use zokrates_proof_systems::groth16::G16;
|
||||
|
||||
|
@ -26,6 +27,8 @@ fn generate_proof() {
|
|||
.execute(program.clone(), &[Bn128Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bn128Field, G16>>::setup(program.clone());
|
||||
let _proof = <Ark as Backend<Bn128Field, G16>>::generate_proof(program, witness, keypair.pk);
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let keypair = <Ark as NonUniversalBackend<Bn128Field, G16>>::setup(program.clone(), rng);
|
||||
let _proof =
|
||||
<Ark as Backend<Bn128Field, G16>>::generate_proof(program, witness, keypair.pk, rng);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue