diff --git a/zokrates_cli/tests/integration.rs b/zokrates_cli/tests/integration.rs index 1266d60b..e8bf9bb1 100644 --- a/zokrates_cli/tests/integration.rs +++ b/zokrates_cli/tests/integration.rs @@ -269,8 +269,23 @@ mod integration { .succeeds() .unwrap(); - // TEST VERIFIER + // CLI VERIFICATION + assert_cli::Assert::command(&[ + "../target/release/zokrates", + "verify", + "--backend", + backend, + "--proving-scheme", + scheme, + "-j", + proof_path.to_str().unwrap(), + "-v", + verification_key_path.to_str().unwrap(), + ]) + .succeeds() + .unwrap(); + // TEST VERIFIER assert_cli::Assert::command(&[ "node", "test.js", diff --git a/zokrates_core/src/proof_system/bellman/groth16.rs b/zokrates_core/src/proof_system/bellman/groth16.rs index aa3d8752..9a66fb83 100644 --- a/zokrates_core/src/proof_system/bellman/groth16.rs +++ b/zokrates_core/src/proof_system/bellman/groth16.rs @@ -2,6 +2,7 @@ use bellman::groth16::{ prepare_verifying_key, verify_proof, Parameters, PreparedVerifyingKey, Proof as BellmanProof, VerifyingKey, }; +use pairing::{CurveAffine, Engine}; use regex::Regex; use zokrates_field::Field; @@ -25,6 +26,16 @@ pub struct ProofPoints { c: G1Affine, } +impl ProofPoints { + fn into_bellman(self) -> BellmanProof { + BellmanProof { + a: serialization::to_g1::(self.a), + b: serialization::to_g2::(self.b), + c: serialization::to_g1::(self.c), + } + } +} + #[derive(Serialize, Deserialize)] pub struct VerificationKey { alpha: G1Affine, @@ -32,7 +43,24 @@ pub struct VerificationKey { gamma: G2Affine, delta: G2Affine, gamma_abc: Vec, - raw: String, +} + +impl VerificationKey { + fn into_bellman(self) -> VerifyingKey { + VerifyingKey { + alpha_g1: serialization::to_g1::(self.alpha), + beta_g1: ::G1Affine::one(), // not used during verification + beta_g2: serialization::to_g2::(self.beta), + gamma_g2: serialization::to_g2::(self.gamma), + delta_g1: ::G1Affine::one(), // not used during verification + delta_g2: serialization::to_g2::(self.delta), + ic: self + .gamma_abc + .into_iter() + .map(|g1| serialization::to_g1::(g1)) + .collect(), + } + } } impl ProofSystem for G16 { @@ -47,10 +75,8 @@ impl ProofSystem for G16 { let parameters = Computation::without_witness(program).setup(); let mut pk: Vec = Vec::new(); - let mut vk_raw: Vec = Vec::new(); parameters.write(&mut pk).unwrap(); - parameters.vk.write(&mut vk_raw).unwrap(); let vk = VerificationKey { alpha: parse_g1::(¶meters.vk.alpha_g1), @@ -63,7 +89,6 @@ impl ProofSystem for G16 { .iter() .map(|g1| parse_g1::(g1)) .collect(), - raw: hex::encode(vk_raw), }; SetupKeypair::new(vk, pk) @@ -179,15 +204,11 @@ impl ProofSystem for G16 { } fn verify(vk: VerificationKey, proof: Proof) -> bool { - let vk_raw = hex::decode(vk.raw.clone()).unwrap(); - let proof_raw = hex::decode(proof.raw.clone()).unwrap(); - - let vk: VerifyingKey = VerifyingKey::read(vk_raw.as_slice()).unwrap(); + let vk: VerifyingKey = vk.into_bellman::(); let pvk: PreparedVerifyingKey = prepare_verifying_key(&vk); - let bellman_proof: BellmanProof = - BellmanProof::read(proof_raw.as_slice()).unwrap(); + let bellman_proof: BellmanProof = proof.proof.into_bellman::(); let public_inputs: Vec<_> = proof .inputs @@ -203,6 +224,26 @@ impl ProofSystem for G16 { } } +mod serialization { + use pairing::{from_hex, CurveAffine, Engine}; + use proof_system::{G1Affine, G2Affine}; + use zokrates_field::Field; + + pub fn to_g1(g1: G1Affine) -> ::G1Affine { + ::G1Affine::from_xy_checked( + from_hex(&g1.0).unwrap(), + from_hex(&g1.1).unwrap(), + ) + .unwrap() + } + pub fn to_g2(g2: G2Affine) -> ::G2Affine { + // apparently the order is reversed + let x = T::new_fq2(&(g2.0).1, &(g2.0).0); + let y = T::new_fq2(&(g2.1).1, &(g2.1).0); + ::G2Affine::from_xy_checked(x, y).unwrap() + } +} + const CONTRACT_TEMPLATE_V2: &str = r#" contract Verifier { using Pairing for *; diff --git a/zokrates_field/src/bls12_381.rs b/zokrates_field/src/bls12_381.rs index 852c9a9f..08abcacc 100644 --- a/zokrates_field/src/bls12_381.rs +++ b/zokrates_field/src/bls12_381.rs @@ -1,7 +1,8 @@ -use bellman_ce::pairing::bls12_381::Bls12; +use bellman_ce::pairing::bls12_381::{Bls12, Fq2}; prime_field!( b"52435875175126190479447740508185965837690552500527637822603658699938581184513", Bls12, + Fq2, "bls12_381" ); diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index 2059b099..99396f7c 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -1,8 +1,9 @@ -use bellman_ce::pairing::bn256::Bn256; +use bellman_ce::pairing::bn256::{Bn256, Fq2}; prime_field!( b"21888242871839275222246405745257275088548364400416034343698204186575808495617", Bn256, + Fq2, "bn128" ); diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index 52a58981..ab5a2a7a 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -67,6 +67,8 @@ pub trait Field: ::Fr::from_str(&s).unwrap() } + fn new_fq2(c0: &str, c1: &str) -> ::Fqe; + /// Returns this `Field`'s contents as little-endian byte vector fn into_byte_vector(&self) -> Vec; /// Returns an element of this `Field` from a little-endian byte vector @@ -120,7 +122,7 @@ pub trait Field: #[macro_use] mod prime_field { macro_rules! prime_field { - ($modulus:expr, $bellman_type:ty, $name:expr) => { + ($modulus:expr, $bellman_type:ty, $fq2_type: ident, $name:expr) => { use crate::{Field, Pow}; use lazy_static::lazy_static; use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; @@ -148,6 +150,13 @@ mod prime_field { self.value.bits() as u32 } + fn new_fq2(c0: &str, c1: &str) -> $fq2_type { + $fq2_type { + c0: bellman_ce::pairing::from_hex(c0).unwrap(), + c1: bellman_ce::pairing::from_hex(c1).unwrap(), + } + } + fn to_biguint(&self) -> BigUint { self.value.to_biguint().unwrap() }