From f3f1b84818276262a84033138a77f22a1af7873a Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 13 Dec 2021 19:39:36 +0100 Subject: [PATCH 1/7] support ark groth16 implementation --- Cargo.lock | 17 +++ zokrates_core/Cargo.toml | 4 +- zokrates_core/src/proof_system/ark/gm17.rs | 123 ++++++------------ zokrates_core/src/proof_system/ark/groth16.rs | 115 ++++++++++++++++ zokrates_core/src/proof_system/ark/mod.rs | 100 ++++++++++---- 5 files changed, 247 insertions(+), 112 deletions(-) create mode 100644 zokrates_core/src/proof_system/ark/groth16.rs diff --git a/Cargo.lock b/Cargo.lock index 6920d6ef..8156176a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "ark-groth16" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba848e856c96bc15eb3f68359cd8ea92747eb2be35a177a25e780d307069f38" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-marlin" version = "0.2.0" @@ -2441,9 +2456,11 @@ dependencies = [ "ark-bls12-377", "ark-bn254", "ark-bw6-761", + "ark-crypto-primitives", "ark-ec", "ark-ff", "ark-gm17", + "ark-groth16", "ark-marlin", "ark-poly", "ark-poly-commit", diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index 8042c3bd..ca6a1a0c 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -13,7 +13,7 @@ libsnark = ["cc", "cmake", "git2"] bellman = ["bellman_ce", "pairing_ce", "ff_ce", "zokrates_field/bellman"] wasm = ["bellman_ce/nolog", "bellman_ce/wasm"] multicore = ["bellman_ce/multicore"] -ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "sha2"] +ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-groth16", "ark-crypto-primitives", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "sha2"] [dependencies] log = "0.4" @@ -50,11 +50,13 @@ ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } ark-bw6-761 = { version = "^0.2.0", default-features = false, optional = true } ark-gm17 = { version = "^0.2.0", default-features = false, optional = true } +ark-groth16 = { version = "^0.2.0", default-features = false, optional = true } ark-serialize = { version = "^0.2.0", default-features = false, optional = true } ark-relations = { version = "^0.2.0", default-features = false, optional = true } ark-marlin = { version = "^0.2.0", default-features = false, optional = true } ark-poly = { version = "^0.2.0", default-features = false, optional = true } ark-poly-commit = { version = "^0.2.0", default-features = false, optional = true } +ark-crypto-primitives = { version = "^0.2.0", default-features = false, optional = true } sha2 = { version = "0.9.3", optional = true } [dev-dependencies] diff --git a/zokrates_core/src/proof_system/ark/gm17.rs b/zokrates_core/src/proof_system/ark/gm17.rs index 9f59b590..d49f96ca 100644 --- a/zokrates_core/src/proof_system/ark/gm17.rs +++ b/zokrates_core/src/proof_system/ark/gm17.rs @@ -1,43 +1,43 @@ +use ark_crypto_primitives::SNARK; use ark_gm17::{ prepare_verifying_key, verify_proof, PreparedVerifyingKey, Proof as ArkProof, ProvingKey, - VerifyingKey, + VerifyingKey, GM17 as ArkGM17, }; - use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use zokrates_field::{ArkFieldExtensions, Bw6_761Field, Field}; use crate::ir::{ProgIterator, Statement, Witness}; -use crate::proof_system::ark::Ark; -use crate::proof_system::ark::Computation; +use crate::proof_system::ark::{get_random_seed, Computation}; use crate::proof_system::ark::{parse_fr, parse_g1, parse_g2, parse_g2_fq}; +use crate::proof_system::ark::{serialization, Ark}; use crate::proof_system::gm17::{NotBw6_761Field, ProofPoints, VerificationKey, GM17}; use crate::proof_system::Scheme; use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair}; +use ark_bw6_761::BW6_761; +use rand_0_7::SeedableRng; impl NonUniversalBackend for Ark { fn setup>>( program: ProgIterator, ) -> SetupKeypair<>::VerificationKey> { - let parameters = Computation::without_witness(program).setup(); + let computation = Computation::without_witness(program); - let mut pk: Vec = Vec::new(); - parameters.serialize_uncompressed(&mut pk).unwrap(); + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let (pk, vk) = ArkGM17::::circuit_specific_setup(computation, rng).unwrap(); + + let mut pk_vec: Vec = Vec::new(); + pk.serialize_uncompressed(&mut pk_vec).unwrap(); let vk = VerificationKey { - h: parse_g2::(¶meters.vk.h_g2), - g_alpha: parse_g1::(¶meters.vk.g_alpha_g1), - h_beta: parse_g2::(¶meters.vk.h_beta_g2), - g_gamma: parse_g1::(¶meters.vk.g_gamma_g1), - h_gamma: parse_g2::(¶meters.vk.h_gamma_g2), - query: parameters - .vk - .query - .iter() - .map(|g1| parse_g1::(g1)) - .collect(), + h: parse_g2::(&vk.h_g2), + g_alpha: parse_g1::(&vk.g_alpha_g1), + h_beta: parse_g2::(&vk.h_beta_g2), + g_gamma: parse_g1::(&vk.g_gamma_g1), + h_gamma: parse_g2::(&vk.h_gamma_g2), + query: vk.query.iter().map(|g1| parse_g1::(g1)).collect(), }; - SetupKeypair::new(vk, pk) + SetupKeypair::new(vk, pk_vec) } } @@ -55,12 +55,14 @@ impl Backend for Ark { .map(parse_fr::) .collect::>(); - let params = ProvingKey::<::ArkEngine>::deserialize_uncompressed( + let pk = ProvingKey::<::ArkEngine>::deserialize_uncompressed( &mut proving_key.as_slice(), ) .unwrap(); - let proof = computation.prove(¶ms); + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let proof = ArkGM17::::prove(&pk, computation, rng).unwrap(); + let proof_points = ProofPoints { a: parse_g1::(&proof.a), b: parse_g2::(&proof.b), @@ -114,26 +116,24 @@ impl NonUniversalBackend for Ark { fn setup>>( program: ProgIterator, ) -> SetupKeypair<>::VerificationKey> { - let parameters = Computation::without_witness(program).setup(); + let computation = Computation::without_witness(program); - let mut pk: Vec = Vec::new(); - parameters.serialize_uncompressed(&mut pk).unwrap(); + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let (pk, vk) = ArkGM17::::circuit_specific_setup(computation, rng).unwrap(); + + let mut pk_vec: Vec = Vec::new(); + pk.serialize_uncompressed(&mut pk_vec).unwrap(); let vk = VerificationKey { - h: parse_g2_fq::(¶meters.vk.h_g2), - g_alpha: parse_g1::(¶meters.vk.g_alpha_g1), - h_beta: parse_g2_fq::(¶meters.vk.h_beta_g2), - g_gamma: parse_g1::(¶meters.vk.g_gamma_g1), - h_gamma: parse_g2_fq::(¶meters.vk.h_gamma_g2), - query: parameters - .vk - .query - .iter() - .map(parse_g1::) - .collect(), + h: parse_g2_fq::(&vk.h_g2), + g_alpha: parse_g1::(&vk.g_alpha_g1), + h_beta: parse_g2_fq::(&vk.h_beta_g2), + g_gamma: parse_g1::(&vk.g_gamma_g1), + h_gamma: parse_g2_fq::(&vk.h_gamma_g2), + query: vk.query.iter().map(parse_g1::).collect(), }; - SetupKeypair::new(vk, pk) + SetupKeypair::new(vk, pk_vec) } } @@ -151,13 +151,15 @@ impl Backend for Ark { .map(parse_fr::) .collect::>(); - let params = + let pk = ProvingKey::<::ArkEngine>::deserialize_uncompressed( &mut proving_key.as_slice(), ) .unwrap(); - let proof = computation.prove(¶ms); + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let proof = ArkGM17::::prove(&pk, computation, rng).unwrap(); + let proof_points = ProofPoints { a: parse_g1::(&proof.a), b: parse_g2_fq::(&proof.b), @@ -207,51 +209,6 @@ impl Backend for Ark { } } -pub mod serialization { - use crate::proof_system::{G1Affine, G2Affine, G2AffineFq}; - use ark_ec::PairingEngine; - use ark_ff::FromBytes; - use zokrates_field::ArkFieldExtensions; - - #[inline] - fn decode_hex(value: String) -> Vec { - let mut bytes = hex::decode(value.strip_prefix("0x").unwrap()).unwrap(); - bytes.reverse(); - bytes - } - - pub fn to_g1(g1: G1Affine) -> ::G1Affine { - let mut bytes = vec![]; - bytes.append(&mut decode_hex(g1.0)); - bytes.append(&mut decode_hex(g1.1)); - bytes.push(0u8); // infinity flag - - ::G1Affine::read(&*bytes).unwrap() - } - - pub fn to_g2(g2: G2Affine) -> ::G2Affine { - let mut bytes = vec![]; - bytes.append(&mut decode_hex((g2.0).0)); - bytes.append(&mut decode_hex((g2.0).1)); - bytes.append(&mut decode_hex((g2.1).0)); - bytes.append(&mut decode_hex((g2.1).1)); - bytes.push(0u8); // infinity flag - - ::G2Affine::read(&*bytes).unwrap() - } - - pub fn to_g2_fq( - g2: G2AffineFq, - ) -> ::G2Affine { - let mut bytes = vec![]; - bytes.append(&mut decode_hex(g2.0)); - bytes.append(&mut decode_hex(g2.1)); - bytes.push(0u8); // infinity flag - - ::G2Affine::read(&*bytes).unwrap() - } -} - #[cfg(test)] mod tests { use crate::flat_absy::{FlatParameter, FlatVariable}; diff --git a/zokrates_core/src/proof_system/ark/groth16.rs b/zokrates_core/src/proof_system/ark/groth16.rs new file mode 100644 index 00000000..5bfc6211 --- /dev/null +++ b/zokrates_core/src/proof_system/ark/groth16.rs @@ -0,0 +1,115 @@ +use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair}; +use ark_crypto_primitives::SNARK; +use ark_groth16::{ + prepare_verifying_key, verify_proof, Groth16, PreparedVerifyingKey, Proof as ArkProof, + ProvingKey, VerifyingKey, +}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use zokrates_field::ArkFieldExtensions; +use zokrates_field::Field; + +use crate::ir::{ProgIterator, Statement, Witness}; +use crate::proof_system::ark::Computation; +use crate::proof_system::ark::{get_random_seed, parse_fr, serialization, Ark}; +use crate::proof_system::ark::{parse_g1, parse_g2}; +use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16}; +use crate::proof_system::Scheme; +use rand_0_7::SeedableRng; + +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 Backend for Ark { + fn generate_proof>>( + program: ProgIterator, + witness: Witness, + proving_key: Vec, + ) -> Proof<>::ProofPoints> { + println!("{}", G16_WARNING); + + let computation = Computation::with_witness(program, witness); + + let inputs = computation + .public_inputs_values() + .iter() + .map(parse_fr::) + .collect::>(); + + let pk = ProvingKey::<::ArkEngine>::deserialize_uncompressed( + &mut proving_key.as_slice(), + ) + .unwrap(); + + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let proof = Groth16::::prove(&pk, computation, rng).unwrap(); + + let proof_points = ProofPoints { + a: parse_g1::(&proof.a), + b: parse_g2::(&proof.b), + c: parse_g1::(&proof.c), + }; + + Proof::new(proof_points, inputs) + } + + fn verify( + vk: >::VerificationKey, + proof: Proof<>::ProofPoints>, + ) -> bool { + let vk = VerifyingKey { + alpha_g1: serialization::to_g1::(vk.alpha), + beta_g2: serialization::to_g2::(vk.beta), + gamma_g2: serialization::to_g2::(vk.gamma), + delta_g2: serialization::to_g2::(vk.delta), + gamma_abc_g1: vk + .gamma_abc + .into_iter() + .map(serialization::to_g1::) + .collect(), + }; + + let pvk: PreparedVerifyingKey = prepare_verifying_key(&vk); + let ark_proof = ArkProof { + a: serialization::to_g1::(proof.proof.a), + b: serialization::to_g2::(proof.proof.b), + c: serialization::to_g1::(proof.proof.c), + }; + + let public_inputs: Vec<_> = proof + .inputs + .iter() + .map(|s| { + T::try_from_str(s.trim_start_matches("0x"), 16) + .unwrap() + .into_ark() + }) + .collect::>(); + + verify_proof(&pvk, &ark_proof, &public_inputs).unwrap() + } +} + +impl NonUniversalBackend for Ark { + fn setup>>( + program: ProgIterator, + ) -> SetupKeypair<>::VerificationKey> { + println!("{}", G16_WARNING); + + let computation = Computation::without_witness(program); + + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let (pk, vk) = Groth16::::circuit_specific_setup(computation, rng).unwrap(); + + let mut pk_vec: Vec = Vec::new(); + pk.serialize_uncompressed(&mut pk_vec).unwrap(); + + let vk = VerificationKey { + alpha: parse_g1::(&vk.alpha_g1), + beta: parse_g2::(&vk.beta_g2), + gamma: parse_g2::(&vk.gamma_g2), + delta: parse_g2::(&vk.delta_g2), + gamma_abc: vk.gamma_abc_g1.iter().map(|g1| parse_g1::(g1)).collect(), + }; + + SetupKeypair::new(vk, pk_vec) + } +} diff --git a/zokrates_core/src/proof_system/ark/mod.rs b/zokrates_core/src/proof_system/ark/mod.rs index a0569591..52b1ab8b 100644 --- a/zokrates_core/src/proof_system/ark/mod.rs +++ b/zokrates_core/src/proof_system/ark/mod.rs @@ -1,14 +1,9 @@ pub mod gm17; +pub mod groth16; pub mod marlin; -use crate::ir::{CanonicalLinComb, ProgIterator, Statement, Witness}; -use ark_gm17::Proof; -use ark_gm17::{ - create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, - ProvingKey, -}; - use crate::flat_absy::FlatVariable; +use crate::ir::{CanonicalLinComb, ProgIterator, Statement, Witness}; use ark_ec::PairingEngine; use ark_relations::r1cs::{ ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, LinearCombination, @@ -19,8 +14,6 @@ use zokrates_field::{ArkFieldExtensions, Field}; pub use self::parse::*; -use rand_0_7::SeedableRng; - pub struct Ark; #[derive(Clone)] @@ -148,20 +141,26 @@ impl>> ProgIt } } +pub fn get_random_seed() -> Result<[u8; 32], getrandom::Error> { + let mut seed = [0u8; 32]; + getrandom::getrandom(&mut seed)?; + Ok(seed) +} + impl>> Computation { - pub fn prove(self, params: &ProvingKey) -> Proof { - let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); - - let public_inputs = self.public_inputs_values(); - - let proof = create_random_proof(self, params, rng).unwrap(); - - let pvk = prepare_verifying_key(¶ms.vk); - - assert!(verify_proof(&pvk, &proof, &public_inputs).unwrap()); - - proof - } + // pub fn prove(self, params: &ProvingKey) -> Proof { + // let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); + // + // let public_inputs = self.public_inputs_values(); + // + // let proof = create_random_proof(self, params, rng).unwrap(); + // + // let pvk = prepare_verifying_key(¶ms.vk); + // + // assert!(verify_proof(&pvk, &proof, &public_inputs).unwrap()); + // + // proof + // } pub fn public_inputs_values(&self) -> Vec<::Fr> { self.program @@ -171,12 +170,12 @@ impl>> Comput .collect() } - pub fn setup(self) -> ProvingKey { - let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); - - // run setup phase - generate_random_parameters(self, rng).unwrap() - } + // pub fn setup(self) -> ProvingKey { + // let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); + // + // // run setup phase + // generate_random_parameters(self, rng).unwrap() + // } } impl>> @@ -276,3 +275,48 @@ mod parse { format!("0x{}", hex::encode(&bytes)) } } + +pub mod serialization { + use crate::proof_system::{G1Affine, G2Affine, G2AffineFq}; + use ark_ec::PairingEngine; + use ark_ff::FromBytes; + use zokrates_field::ArkFieldExtensions; + + #[inline] + fn decode_hex(value: String) -> Vec { + let mut bytes = hex::decode(value.strip_prefix("0x").unwrap()).unwrap(); + bytes.reverse(); + bytes + } + + pub fn to_g1(g1: G1Affine) -> ::G1Affine { + let mut bytes = vec![]; + bytes.append(&mut decode_hex(g1.0)); + bytes.append(&mut decode_hex(g1.1)); + bytes.push(0u8); // infinity flag + + ::G1Affine::read(&*bytes).unwrap() + } + + pub fn to_g2(g2: G2Affine) -> ::G2Affine { + let mut bytes = vec![]; + bytes.append(&mut decode_hex((g2.0).0)); + bytes.append(&mut decode_hex((g2.0).1)); + bytes.append(&mut decode_hex((g2.1).0)); + bytes.append(&mut decode_hex((g2.1).1)); + bytes.push(0u8); // infinity flag + + ::G2Affine::read(&*bytes).unwrap() + } + + pub fn to_g2_fq( + g2: G2AffineFq, + ) -> ::G2Affine { + let mut bytes = vec![]; + bytes.append(&mut decode_hex(g2.0)); + bytes.append(&mut decode_hex(g2.1)); + bytes.push(0u8); // infinity flag + + ::G2Affine::read(&*bytes).unwrap() + } +} From 01995f2e16a7ffad61e8836ecd1c02dd917ec404 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 14 Dec 2021 19:01:33 +0100 Subject: [PATCH 2/7] update cli --- zokrates_cli/src/helpers.rs | 18 ++- zokrates_cli/src/ops/generate_proof.rs | 17 ++- zokrates_cli/src/ops/setup.rs | 27 ++++- zokrates_cli/src/ops/universal_setup.rs | 14 ++- zokrates_cli/src/ops/verify.rs | 36 +++++- zokrates_core/src/proof_system/ark/gm17.rs | 4 +- zokrates_core/src/proof_system/ark/groth16.rs | 107 +++++++++++++++++- zokrates_core/src/proof_system/mod.rs | 7 +- zokrates_core/src/proof_system/scheme/gm17.rs | 10 +- 9 files changed, 203 insertions(+), 37 deletions(-) diff --git a/zokrates_cli/src/helpers.rs b/zokrates_cli/src/helpers.rs index 8eb17339..bb29f548 100644 --- a/zokrates_cli/src/helpers.rs +++ b/zokrates_cli/src/helpers.rs @@ -93,16 +93,28 @@ impl TryFrom<(&str, &str, &str)> for Parameters { #[cfg(feature = "bellman")] (BackendParameter::Bellman, CurveParameter::Bls12_381, SchemeParameter::G16) => Ok(()), #[cfg(feature = "ark")] - (BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::GM17) => Ok(()), + (BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::G16) => Ok(()), #[cfg(feature = "ark")] - (BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::GM17) => Ok(()), + (BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::G16) => Ok(()), + #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::G16) => Ok(()), + #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::G16) => Ok(()), #[cfg(feature = "ark")] (BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::GM17) => Ok(()), #[cfg(feature = "ark")] - (BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => Ok(()), + (BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::GM17) => Ok(()), + #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::GM17) => Ok(()), + #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::GM17) => Ok(()), #[cfg(feature = "ark")] (BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::MARLIN) => Ok(()), #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::MARLIN) => Ok(()), + #[cfg(feature = "ark")] + (BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => Ok(()), + #[cfg(feature = "ark")] (BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => Ok(()), #[cfg(feature = "libsnark")] (BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => Ok(()), diff --git a/zokrates_cli/src/ops/generate_proof.rs b/zokrates_cli/src/ops/generate_proof.rs index f7c94ffe..eb5082ce 100644 --- a/zokrates_cli/src/ops/generate_proof.rs +++ b/zokrates_cli/src/ops/generate_proof.rs @@ -112,20 +112,29 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { _ => unreachable!(), }, #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, _, SchemeParameter::G16) => match prog { + ProgEnum::Bn128Program(p) => cli_generate_proof::<_, _, G16, Ark>(p, sub_matches), + ProgEnum::Bls12_381Program(p) => cli_generate_proof::<_, _, G16, Ark>(p, sub_matches), + ProgEnum::Bls12_377Program(p) => cli_generate_proof::<_, _, G16, Ark>(p, sub_matches), + ProgEnum::Bw6_761Program(p) => cli_generate_proof::<_, _, G16, Ark>(p, sub_matches), + }, + #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, _, SchemeParameter::GM17) => match prog { + ProgEnum::Bn128Program(p) => cli_generate_proof::<_, _, GM17, Ark>(p, sub_matches), + ProgEnum::Bls12_381Program(p) => cli_generate_proof::<_, _, GM17, Ark>(p, sub_matches), ProgEnum::Bls12_377Program(p) => cli_generate_proof::<_, _, GM17, Ark>(p, sub_matches), ProgEnum::Bw6_761Program(p) => cli_generate_proof::<_, _, GM17, Ark>(p, sub_matches), - ProgEnum::Bn128Program(p) => cli_generate_proof::<_, _, GM17, Ark>(p, sub_matches), - _ => unreachable!(), }, #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, _, SchemeParameter::MARLIN) => match prog { + ProgEnum::Bn128Program(p) => cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches), + ProgEnum::Bls12_381Program(p) => { + cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches) + } ProgEnum::Bls12_377Program(p) => { cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches) } ProgEnum::Bw6_761Program(p) => cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches), - ProgEnum::Bn128Program(p) => cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches), - _ => unreachable!(), }, #[cfg(feature = "libsnark")] Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => { diff --git a/zokrates_cli/src/ops/setup.rs b/zokrates_cli/src/ops/setup.rs index 0d179bc4..0a407334 100644 --- a/zokrates_cli/src/ops/setup.rs +++ b/zokrates_cli/src/ops/setup.rs @@ -114,15 +114,30 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { _ => unreachable!(), }, #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, _, SchemeParameter::G16) => match prog { + ProgEnum::Bn128Program(p) => cli_setup_non_universal::<_, _, G16, Ark>(p, sub_matches), + ProgEnum::Bls12_381Program(p) => { + cli_setup_non_universal::<_, _, G16, Ark>(p, sub_matches) + } + ProgEnum::Bls12_377Program(p) => { + cli_setup_non_universal::<_, _, G16, Ark>(p, sub_matches) + } + ProgEnum::Bw6_761Program(p) => { + cli_setup_non_universal::<_, _, G16, Ark>(p, sub_matches) + } + }, + #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, _, SchemeParameter::GM17) => match prog { + ProgEnum::Bn128Program(p) => cli_setup_non_universal::<_, _, GM17, Ark>(p, sub_matches), + ProgEnum::Bls12_381Program(p) => { + cli_setup_non_universal::<_, _, GM17, Ark>(p, sub_matches) + } ProgEnum::Bls12_377Program(p) => { cli_setup_non_universal::<_, _, GM17, Ark>(p, sub_matches) } ProgEnum::Bw6_761Program(p) => { cli_setup_non_universal::<_, _, GM17, Ark>(p, sub_matches) } - ProgEnum::Bn128Program(p) => cli_setup_non_universal::<_, _, GM17, Ark>(p, sub_matches), - _ => unreachable!(), }, #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, _, SchemeParameter::MARLIN) => { @@ -140,16 +155,18 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { .map_err(|_| "Cannot read universal setup".to_string())?; match prog { - ProgEnum::Bls12_377Program(p) => { + ProgEnum::Bn128Program(p) => { cli_setup_universal::<_, _, Marlin, Ark>(p, setup, sub_matches) } - ProgEnum::Bn128Program(p) => { + ProgEnum::Bls12_381Program(p) => { + cli_setup_universal::<_, _, Marlin, Ark>(p, setup, sub_matches) + } + ProgEnum::Bls12_377Program(p) => { cli_setup_universal::<_, _, Marlin, Ark>(p, setup, sub_matches) } ProgEnum::Bw6_761Program(p) => { cli_setup_universal::<_, _, Marlin, Ark>(p, setup, sub_matches) } - _ => unreachable!(), } } #[cfg(feature = "libsnark")] diff --git a/zokrates_cli/src/ops/universal_setup.rs b/zokrates_cli/src/ops/universal_setup.rs index 9e7674ce..f2ce57f7 100644 --- a/zokrates_cli/src/ops/universal_setup.rs +++ b/zokrates_cli/src/ops/universal_setup.rs @@ -9,7 +9,7 @@ use std::path::Path; use zokrates_core::proof_system::ark::Ark; #[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))] use zokrates_core::proof_system::*; -use zokrates_field::{Bls12_377Field, Bn128Field, Bw6_761Field, Field}; +use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; pub fn subcommand() -> App<'static, 'static> { SubCommand::with_name("universal-setup") @@ -63,6 +63,14 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { ))?; match parameters { + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::MARLIN) => { + cli_universal_setup::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::MARLIN) => { + cli_universal_setup::(sub_matches) + } #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => { cli_universal_setup::(sub_matches) @@ -71,10 +79,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { Parameters(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => { cli_universal_setup::(sub_matches) } - #[cfg(feature = "ark")] - Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::MARLIN) => { - cli_universal_setup::(sub_matches) - } _ => unreachable!(), } } diff --git a/zokrates_cli/src/ops/verify.rs b/zokrates_cli/src/ops/verify.rs index 4a2cde55..2e174f5c 100644 --- a/zokrates_cli/src/ops/verify.rs +++ b/zokrates_cli/src/ops/verify.rs @@ -78,6 +78,30 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { cli_verify::(sub_matches) } #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::G16) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::G16) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::G16) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::G16) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::GM17) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::GM17) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::GM17) => { cli_verify::(sub_matches) } @@ -86,8 +110,12 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { cli_verify::(sub_matches) } #[cfg(feature = "ark")] - Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::GM17) => { - cli_verify::(sub_matches) + Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::MARLIN) => { + cli_verify::(sub_matches) + } + #[cfg(feature = "ark")] + Parameters(BackendParameter::Ark, CurveParameter::Bls12_381, SchemeParameter::MARLIN) => { + cli_verify::(sub_matches) } #[cfg(feature = "ark")] Parameters(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => { @@ -97,10 +125,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { Parameters(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => { cli_verify::(sub_matches) } - #[cfg(feature = "ark")] - Parameters(BackendParameter::Ark, CurveParameter::Bn128, SchemeParameter::MARLIN) => { - cli_verify::(sub_matches) - } #[cfg(feature = "libsnark")] Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => { cli_verify::(sub_matches) diff --git a/zokrates_core/src/proof_system/ark/gm17.rs b/zokrates_core/src/proof_system/ark/gm17.rs index d49f96ca..d3f52490 100644 --- a/zokrates_core/src/proof_system/ark/gm17.rs +++ b/zokrates_core/src/proof_system/ark/gm17.rs @@ -10,9 +10,9 @@ use crate::ir::{ProgIterator, Statement, Witness}; use crate::proof_system::ark::{get_random_seed, Computation}; use crate::proof_system::ark::{parse_fr, parse_g1, parse_g2, parse_g2_fq}; use crate::proof_system::ark::{serialization, Ark}; -use crate::proof_system::gm17::{NotBw6_761Field, ProofPoints, VerificationKey, GM17}; -use crate::proof_system::Scheme; +use crate::proof_system::gm17::{ProofPoints, VerificationKey, GM17}; use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair}; +use crate::proof_system::{NotBw6_761Field, Scheme}; use ark_bw6_761::BW6_761; use rand_0_7::SeedableRng; diff --git a/zokrates_core/src/proof_system/ark/groth16.rs b/zokrates_core/src/proof_system/ark/groth16.rs index 5bfc6211..87ca9935 100644 --- a/zokrates_core/src/proof_system/ark/groth16.rs +++ b/zokrates_core/src/proof_system/ark/groth16.rs @@ -1,12 +1,12 @@ -use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair}; +use crate::proof_system::{Backend, NonUniversalBackend, NotBw6_761Field, Proof, SetupKeypair}; use ark_crypto_primitives::SNARK; use ark_groth16::{ prepare_verifying_key, verify_proof, Groth16, PreparedVerifyingKey, Proof as ArkProof, ProvingKey, VerifyingKey, }; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use zokrates_field::ArkFieldExtensions; use zokrates_field::Field; +use zokrates_field::{ArkFieldExtensions, Bw6_761Field}; use crate::ir::{ProgIterator, Statement, Witness}; use crate::proof_system::ark::Computation; @@ -14,11 +14,12 @@ use crate::proof_system::ark::{get_random_seed, parse_fr, serialization, Ark}; use crate::proof_system::ark::{parse_g1, parse_g2}; use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16}; use crate::proof_system::Scheme; +use ark_bw6_761::BW6_761; use rand_0_7::SeedableRng; 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 Backend for Ark { +impl Backend for Ark { fn generate_proof>>( program: ProgIterator, witness: Witness, @@ -88,7 +89,7 @@ impl Backend for Ark { } } -impl NonUniversalBackend for Ark { +impl NonUniversalBackend for Ark { fn setup>>( program: ProgIterator, ) -> SetupKeypair<>::VerificationKey> { @@ -113,3 +114,101 @@ impl NonUniversalBackend for Ark { SetupKeypair::new(vk, pk_vec) } } + +impl Backend for Ark { + fn generate_proof>>( + program: ProgIterator, + witness: Witness, + proving_key: Vec, + ) -> Proof<>::ProofPoints> { + println!("{}", G16_WARNING); + + let computation = Computation::with_witness(program, witness); + + let inputs = computation + .public_inputs_values() + .iter() + .map(parse_fr::) + .collect::>(); + + let pk = + ProvingKey::::deserialize_uncompressed(&mut proving_key.as_slice()).unwrap(); + + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let proof = Groth16::::prove(&pk, computation, rng).unwrap(); + + let proof_points = ProofPoints { + a: parse_g1::(&proof.a), + b: parse_g2::(&proof.b), + c: parse_g1::(&proof.c), + }; + + Proof::new(proof_points, inputs) + } + + fn verify( + vk: >::VerificationKey, + proof: Proof<>::ProofPoints>, + ) -> bool { + let vk = VerifyingKey { + alpha_g1: serialization::to_g1::(vk.alpha), + beta_g2: serialization::to_g2::(vk.beta), + gamma_g2: serialization::to_g2::(vk.gamma), + delta_g2: serialization::to_g2::(vk.delta), + gamma_abc_g1: vk + .gamma_abc + .into_iter() + .map(serialization::to_g1::) + .collect(), + }; + + let pvk: PreparedVerifyingKey = prepare_verifying_key(&vk); + let ark_proof = ArkProof { + a: serialization::to_g1::(proof.proof.a), + b: serialization::to_g2::(proof.proof.b), + c: serialization::to_g1::(proof.proof.c), + }; + + let public_inputs: Vec<_> = proof + .inputs + .iter() + .map(|s| { + Bw6_761Field::try_from_str(s.trim_start_matches("0x"), 16) + .unwrap() + .into_ark() + }) + .collect::>(); + + verify_proof(&pvk, &ark_proof, &public_inputs).unwrap() + } +} + +impl NonUniversalBackend for Ark { + fn setup>>( + program: ProgIterator, + ) -> SetupKeypair<>::VerificationKey> { + println!("{}", G16_WARNING); + + let computation = Computation::without_witness(program); + + let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let (pk, vk) = Groth16::::circuit_specific_setup(computation, rng).unwrap(); + + let mut pk_vec: Vec = Vec::new(); + pk.serialize_uncompressed(&mut pk_vec).unwrap(); + + let vk = VerificationKey { + alpha: parse_g1::(&vk.alpha_g1), + beta: parse_g2::(&vk.beta_g2), + gamma: parse_g2::(&vk.gamma_g2), + delta: parse_g2::(&vk.delta_g2), + gamma_abc: vk + .gamma_abc_g1 + .iter() + .map(parse_g1::) + .collect(), + }; + + SetupKeypair::new(vk, pk_vec) + } +} diff --git a/zokrates_core/src/proof_system/mod.rs b/zokrates_core/src/proof_system/mod.rs index 7cf4f76f..957e38f7 100644 --- a/zokrates_core/src/proof_system/mod.rs +++ b/zokrates_core/src/proof_system/mod.rs @@ -14,7 +14,12 @@ pub use self::solidity::*; use crate::ir; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use zokrates_field::Field; +use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Field}; + +pub trait NotBw6_761Field {} +impl NotBw6_761Field for Bls12_377Field {} +impl NotBw6_761Field for Bls12_381Field {} +impl NotBw6_761Field for Bn128Field {} #[derive(Serialize)] pub struct SetupKeypair { diff --git a/zokrates_core/src/proof_system/scheme/gm17.rs b/zokrates_core/src/proof_system/scheme/gm17.rs index 94c1aeaf..e2c7869c 100644 --- a/zokrates_core/src/proof_system/scheme/gm17.rs +++ b/zokrates_core/src/proof_system/scheme/gm17.rs @@ -1,16 +1,12 @@ use crate::proof_system::scheme::{NonUniversalScheme, Scheme}; use crate::proof_system::solidity::{solidity_pairing_lib, SOLIDITY_G2_ADDITION_LIB}; use crate::proof_system::{ - G1Affine, G2Affine, G2AffineFq, SolidityCompatibleField, SolidityCompatibleScheme, + G1Affine, G2Affine, G2AffineFq, NotBw6_761Field, SolidityCompatibleField, + SolidityCompatibleScheme, }; use regex::Regex; use serde::{Deserialize, Serialize}; -use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; - -pub trait NotBw6_761Field {} -impl NotBw6_761Field for Bls12_377Field {} -impl NotBw6_761Field for Bls12_381Field {} -impl NotBw6_761Field for Bn128Field {} +use zokrates_field::{Bw6_761Field, Field}; #[allow(clippy::upper_case_acronyms)] pub struct GM17; From d18af2dcf734ef12217b7f47356b39a7fd5f070f Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 14 Dec 2021 19:13:47 +0100 Subject: [PATCH 3/7] add ark groth16 dimension to integration test --- zokrates_cli/tests/integration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zokrates_cli/tests/integration.rs b/zokrates_cli/tests/integration.rs index d2b02b8f..6bfc7019 100644 --- a/zokrates_cli/tests/integration.rs +++ b/zokrates_cli/tests/integration.rs @@ -215,13 +215,13 @@ mod integration { let backends = map! { "bellman" => vec!["g16"], "libsnark" => vec!["pghr13"], - "ark" => vec!["gm17", "marlin"] + "ark" => vec!["g16", "gm17", "marlin"] }; #[cfg(not(feature = "libsnark"))] let backends = map! { "bellman" => vec!["g16"], - "ark" => vec!["gm17", "marlin"] + "ark" => vec!["g16", "gm17", "marlin"] }; // GENERATE A UNIVERSAL SETUP From 414e16cbdc20096710dcad34dd1405cd77351711 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 14 Dec 2021 19:27:13 +0100 Subject: [PATCH 4/7] add changelog --- changelogs/unreleased/1071-dark64 | 1 + zokrates_core/src/proof_system/ark/mod.rs | 21 --------------------- 2 files changed, 1 insertion(+), 21 deletions(-) create mode 100644 changelogs/unreleased/1071-dark64 diff --git a/changelogs/unreleased/1071-dark64 b/changelogs/unreleased/1071-dark64 new file mode 100644 index 00000000..029314b8 --- /dev/null +++ b/changelogs/unreleased/1071-dark64 @@ -0,0 +1 @@ +Support for ark-groth16 implementation \ No newline at end of file diff --git a/zokrates_core/src/proof_system/ark/mod.rs b/zokrates_core/src/proof_system/ark/mod.rs index 52b1ab8b..33ee9c4b 100644 --- a/zokrates_core/src/proof_system/ark/mod.rs +++ b/zokrates_core/src/proof_system/ark/mod.rs @@ -148,20 +148,6 @@ pub fn get_random_seed() -> Result<[u8; 32], getrandom::Error> { } impl>> Computation { - // pub fn prove(self, params: &ProvingKey) -> Proof { - // let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); - // - // let public_inputs = self.public_inputs_values(); - // - // let proof = create_random_proof(self, params, rng).unwrap(); - // - // let pvk = prepare_verifying_key(¶ms.vk); - // - // assert!(verify_proof(&pvk, &proof, &public_inputs).unwrap()); - // - // proof - // } - pub fn public_inputs_values(&self) -> Vec<::Fr> { self.program .public_inputs(self.witness.as_ref().unwrap()) @@ -169,13 +155,6 @@ impl>> Comput .map(|v| v.clone().into_ark()) .collect() } - - // pub fn setup(self) -> ProvingKey { - // let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); - // - // // run setup phase - // generate_random_parameters(self, rng).unwrap() - // } } impl>> From ebf5369912ff4ff902d86ca7ccadd2ec36ff47b6 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 3 Jan 2022 19:07:38 +0100 Subject: [PATCH 5/7] fix missing imports --- zokrates_core/src/proof_system/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_core/src/proof_system/mod.rs b/zokrates_core/src/proof_system/mod.rs index 3a21010d..a9285edd 100644 --- a/zokrates_core/src/proof_system/mod.rs +++ b/zokrates_core/src/proof_system/mod.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize}; use std::io::{Read, Write}; #[cfg(feature = "bellman")] use zokrates_field::BellmanFieldExtensions; -use zokrates_field::Field; +use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Field}; pub trait NotBw6_761Field {} impl NotBw6_761Field for Bls12_377Field {} From 45365585609be5331f83a7a4ac5bb53f0d5da3be Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 4 Jan 2022 14:17:37 +0100 Subject: [PATCH 6/7] revert rand changes, update changelog and book --- Cargo.lock | 2 ++ changelogs/unreleased/1071-dark64 | 2 +- zokrates_book/src/toolbox/proving_schemes.md | 22 +++++++++---------- zokrates_core/Cargo.toml | 2 +- zokrates_core/src/proof_system/ark/gm17.rs | 10 ++++----- zokrates_core/src/proof_system/ark/groth16.rs | 10 ++++----- zokrates_core/src/proof_system/ark/mod.rs | 6 ----- 7 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 159ea475..1c6647b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1111,8 +1111,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] diff --git a/changelogs/unreleased/1071-dark64 b/changelogs/unreleased/1071-dark64 index 029314b8..d875abc7 100644 --- a/changelogs/unreleased/1071-dark64 +++ b/changelogs/unreleased/1071-dark64 @@ -1 +1 @@ -Support for ark-groth16 implementation \ No newline at end of file +Support for the `groth16` scheme using the ark backend, support the usage of the `bls12_381` curve with the `gm17` and `marlin` scheme \ No newline at end of file diff --git a/zokrates_book/src/toolbox/proving_schemes.md b/zokrates_book/src/toolbox/proving_schemes.md index f1b58063..a5274c8c 100644 --- a/zokrates_book/src/toolbox/proving_schemes.md +++ b/zokrates_book/src/toolbox/proving_schemes.md @@ -23,12 +23,12 @@ When not using the default, the CLI flag has to be provided for the following co ZoKrates supports different proving schemes. We identify the schemes by the reference to the paper that introduced them. Currently the options available are: -| Scheme | CLI flag | Curves | Universal | -| ---- | -------- | ------ | ------------| -| [G16](https://eprint.iacr.org/2016/260) | `--proving-scheme g16` | ALTBN_128, BLS12_381 | No | -| [GM17](https://eprint.iacr.org/2017/540) | `--proving-scheme gm17` | ALTBN_128, BLS12_377, BW6_761 | No | -| [Marlin](https://eprint.iacr.org/2019/1047) | `--proving-scheme marlin` | ALTBN_128, BLS12_377, BW6_761 | Yes | -| [PGHR13](https://eprint.iacr.org/2013/279) | `--proving-scheme pghr13` | ALTBN_128 | No | +| Scheme | CLI flag | Curves | Universal | +| ---- | -------- |------------------------------------------| ------------| +| [G16](https://eprint.iacr.org/2016/260) | `--proving-scheme g16` | ALTBN_128, BLS12_381 | No | +| [GM17](https://eprint.iacr.org/2017/540) | `--proving-scheme gm17` | ALTBN_128, BLS12_381, BLS12_377, BW6_761 | No | +| [Marlin](https://eprint.iacr.org/2019/1047) | `--proving-scheme marlin` | ALTBN_128, BLS12_381, BLS12_377, BW6_761 | Yes | +| [PGHR13](https://eprint.iacr.org/2013/279) | `--proving-scheme pghr13` | ALTBN_128 | No | All schemes have a circuit-specific setup phase called `setup`. Universal schemes also feature a preliminary, circuit-agnostic step called `universal-setup`. The advantage of universal schemes is that only the `universal-setup` step requires trust, so that it can be run a single time and reused trustlessly for many programs. @@ -45,11 +45,11 @@ When not using the default, the CLI flag has to be provided for the following co ZoKrates supports multiple backends. The options are the following: -| Backend | CLI flag | Proving schemes | Curves | -| ---- | -------- | --------------- | ------ | -| Bellman | `--backend bellman` | G16 | ALTBN_128, BLS12_381 | -| Libsnark | `--backend libsnark` | GM17, PGHR13 | ALTBN_128 | -| Ark | `--backend ark` | GM17, MARLIN | ALTBN_128, BLS12_377, BW6_761 | +| Backend | CLI flag | Proving schemes | Curves | +| ---- | -------- |-------------------|------------------------------------------| +| Bellman | `--backend bellman` | G16 | ALTBN_128, BLS12_381 | +| Libsnark | `--backend libsnark` | GM17, PGHR13 | ALTBN_128 | +| Ark | `--backend ark` | G16, GM17, MARLIN | ALTBN_128, BLS12_381, BLS12_377, BW6_761 | Default: `bellman` diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index c9525f02..59c9846b 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -35,7 +35,7 @@ zokrates_common = { path = "../zokrates_common" } zokrates_embed = { version = "0.1.0", path = "../zokrates_embed" } getrandom = { version = "0.2", features = ["js"] } rand_0_4 = { version = "0.4", package = "rand" } -rand_0_7 = { version = "0.7", package = "rand" } +rand_0_7 = { version = "0.7", package = "rand", features = ["wasm-bindgen"] } csv = "1" phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false } diff --git a/zokrates_core/src/proof_system/ark/gm17.rs b/zokrates_core/src/proof_system/ark/gm17.rs index d3f52490..2cf5f5c3 100644 --- a/zokrates_core/src/proof_system/ark/gm17.rs +++ b/zokrates_core/src/proof_system/ark/gm17.rs @@ -7,7 +7,7 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use zokrates_field::{ArkFieldExtensions, Bw6_761Field, Field}; use crate::ir::{ProgIterator, Statement, Witness}; -use crate::proof_system::ark::{get_random_seed, Computation}; +use crate::proof_system::ark::Computation; use crate::proof_system::ark::{parse_fr, parse_g1, parse_g2, parse_g2_fq}; use crate::proof_system::ark::{serialization, Ark}; use crate::proof_system::gm17::{ProofPoints, VerificationKey, GM17}; @@ -22,7 +22,7 @@ impl NonUniversalBackend SetupKeypair<>::VerificationKey> { let computation = Computation::without_witness(program); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let (pk, vk) = ArkGM17::::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); @@ -60,7 +60,7 @@ impl Backend for Ark { ) .unwrap(); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let proof = ArkGM17::::prove(&pk, computation, rng).unwrap(); let proof_points = ProofPoints { @@ -118,7 +118,7 @@ impl NonUniversalBackend for Ark { ) -> SetupKeypair<>::VerificationKey> { let computation = Computation::without_witness(program); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let (pk, vk) = ArkGM17::::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); @@ -157,7 +157,7 @@ impl Backend for Ark { ) .unwrap(); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let proof = ArkGM17::::prove(&pk, computation, rng).unwrap(); let proof_points = ProofPoints { diff --git a/zokrates_core/src/proof_system/ark/groth16.rs b/zokrates_core/src/proof_system/ark/groth16.rs index 87ca9935..01fdf8b2 100644 --- a/zokrates_core/src/proof_system/ark/groth16.rs +++ b/zokrates_core/src/proof_system/ark/groth16.rs @@ -10,7 +10,7 @@ use zokrates_field::{ArkFieldExtensions, Bw6_761Field}; use crate::ir::{ProgIterator, Statement, Witness}; use crate::proof_system::ark::Computation; -use crate::proof_system::ark::{get_random_seed, parse_fr, serialization, Ark}; +use crate::proof_system::ark::{parse_fr, serialization, Ark}; use crate::proof_system::ark::{parse_g1, parse_g2}; use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16}; use crate::proof_system::Scheme; @@ -40,7 +40,7 @@ impl Backend for Ark { ) .unwrap(); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let proof = Groth16::::prove(&pk, computation, rng).unwrap(); let proof_points = ProofPoints { @@ -97,7 +97,7 @@ impl NonUniversalBackend::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); @@ -134,7 +134,7 @@ impl Backend for Ark { let pk = ProvingKey::::deserialize_uncompressed(&mut proving_key.as_slice()).unwrap(); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let proof = Groth16::::prove(&pk, computation, rng).unwrap(); let proof_points = ProofPoints { @@ -191,7 +191,7 @@ impl NonUniversalBackend for Ark { let computation = Computation::without_witness(program); - let rng = &mut rand_0_7::rngs::StdRng::from_seed(get_random_seed().unwrap()); + let rng = &mut rand_0_7::rngs::StdRng::from_entropy(); let (pk, vk) = Groth16::::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); diff --git a/zokrates_core/src/proof_system/ark/mod.rs b/zokrates_core/src/proof_system/ark/mod.rs index 33ee9c4b..192d7303 100644 --- a/zokrates_core/src/proof_system/ark/mod.rs +++ b/zokrates_core/src/proof_system/ark/mod.rs @@ -141,12 +141,6 @@ impl>> ProgIt } } -pub fn get_random_seed() -> Result<[u8; 32], getrandom::Error> { - let mut seed = [0u8; 32]; - getrandom::getrandom(&mut seed)?; - Ok(seed) -} - impl>> Computation { pub fn public_inputs_values(&self) -> Vec<::Fr> { self.program From e494e2e804d1e03440da4a92fa573d2e874ed160 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 19 Jan 2022 12:04:34 +0100 Subject: [PATCH 7/7] add tests --- zokrates_core/src/proof_system/ark/groth16.rs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/zokrates_core/src/proof_system/ark/groth16.rs b/zokrates_core/src/proof_system/ark/groth16.rs index 01fdf8b2..bccfd66b 100644 --- a/zokrates_core/src/proof_system/ark/groth16.rs +++ b/zokrates_core/src/proof_system/ark/groth16.rs @@ -212,3 +212,65 @@ impl NonUniversalBackend for Ark { SetupKeypair::new(vk, pk_vec) } } + +#[cfg(test)] +mod tests { + use crate::flat_absy::{FlatParameter, FlatVariable}; + use crate::ir::{Interpreter, Prog, Statement}; + + use super::*; + use zokrates_field::{Bls12_377Field, Bw6_761Field}; + + #[test] + fn verify_bls12_377_field() { + let program: Prog = Prog { + arguments: vec![FlatParameter::public(FlatVariable::new(0))], + return_count: 1, + statements: vec![Statement::constraint( + FlatVariable::new(0), + FlatVariable::public(0), + )], + }; + + let keypair = >::setup(program.clone()); + let interpreter = Interpreter::default(); + + let witness = interpreter + .execute(program.clone(), &[Bls12_377Field::from(42)]) + .unwrap(); + + let proof = >::generate_proof( + program.into(), + witness, + keypair.pk, + ); + let ans = >::verify(keypair.vk, proof); + + assert!(ans); + } + + #[test] + fn verify_bw6_761_field() { + let program: Prog = Prog { + arguments: vec![FlatParameter::public(FlatVariable::new(0))], + return_count: 1, + statements: vec![Statement::constraint( + FlatVariable::new(0), + FlatVariable::public(0), + )], + }; + + let keypair = >::setup(program.clone()); + let interpreter = Interpreter::default(); + + let witness = interpreter + .execute(program.clone(), &[Bw6_761Field::from(42)]) + .unwrap(); + + let proof = + >::generate_proof(program, witness, keypair.pk); + let ans = >::verify(keypair.vk, proof); + + assert!(ans); + } +}