1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

Groth16 proof verification uses points in struct for verification

This commit is contained in:
ErikP0 2020-07-16 14:53:36 +02:00
parent 3e55d622dd
commit 44645fc926
4 changed files with 59 additions and 13 deletions

View file

@ -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<T: Field>(self) -> BellmanProof<T::BellmanEngine> {
BellmanProof {
a: serialization::to_g1::<T::BellmanEngine>(self.a),
b: serialization::to_g2::<T>(self.b),
c: serialization::to_g1::<T::BellmanEngine>(self.c),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct VerificationKey {
alpha: G1Affine,
@ -32,9 +43,23 @@ pub struct VerificationKey {
gamma: G2Affine,
delta: G2Affine,
gamma_abc: Vec<G1Affine>,
raw: String,
}
impl VerificationKey {
fn into_bellman<T: Field>(self) -> VerifyingKey<T::BellmanEngine> {
VerifyingKey {
alpha_g1: serialization::to_g1::<T::BellmanEngine>(self.alpha),
beta_g1: <T::BellmanEngine as Engine>::G1Affine::one(), // not used during verification
beta_g2: serialization::to_g2::<T>(self.beta),
gamma_g2: serialization::to_g2::<T>(self.gamma),
delta_g1: <T::BellmanEngine as Engine>::G1Affine::one(), // not used during verification
delta_g2: serialization::to_g2::<T>(self.delta),
ic: self.gamma_abc.into_iter().map(|g1| serialization::to_g1::<T::BellmanEngine>(g1)).collect()
}
}
}
impl<T: Field> ProofSystem<T> for G16 {
type VerificationKey = VerificationKey;
type ProofPoints = ProofPoints;
@ -47,10 +72,8 @@ impl<T: Field> ProofSystem<T> for G16 {
let parameters = Computation::without_witness(program).setup();
let mut pk: Vec<u8> = Vec::new();
let mut vk_raw: Vec<u8> = Vec::new();
parameters.write(&mut pk).unwrap();
parameters.vk.write(&mut vk_raw).unwrap();
let vk = VerificationKey {
alpha: parse_g1::<T>(&parameters.vk.alpha_g1),
@ -63,7 +86,6 @@ impl<T: Field> ProofSystem<T> for G16 {
.iter()
.map(|g1| parse_g1::<T>(g1))
.collect(),
raw: hex::encode(vk_raw),
};
SetupKeypair::new(vk, pk)
@ -179,15 +201,11 @@ impl<T: Field> ProofSystem<T> for G16 {
}
fn verify(vk: VerificationKey, proof: Proof<ProofPoints>) -> bool {
let vk_raw = hex::decode(vk.raw.clone()).unwrap();
let proof_raw = hex::decode(proof.raw.clone()).unwrap();
let vk: VerifyingKey<T::BellmanEngine> = VerifyingKey::read(vk_raw.as_slice()).unwrap();
let vk: VerifyingKey<T::BellmanEngine> = vk.into_bellman::<T>();
let pvk: PreparedVerifyingKey<T::BellmanEngine> = prepare_verifying_key(&vk);
let bellman_proof: BellmanProof<T::BellmanEngine> =
BellmanProof::read(proof_raw.as_slice()).unwrap();
let bellman_proof: BellmanProof<T::BellmanEngine> = proof.proof.into_bellman::<T>();
let public_inputs: Vec<_> = proof
.inputs
@ -203,6 +221,23 @@ impl<T: Field> ProofSystem<T> for G16 {
}
}
mod serialization {
use proof_system::{G1Affine, G2Affine};
use zokrates_field::Field;
use pairing::{CurveAffine, Engine, from_hex};
pub fn to_g1<E: Engine>(g1: G1Affine) -> E::G1Affine {
E::G1Affine::from_xy_checked(from_hex(&g1.0).unwrap(), from_hex(&g1.1).unwrap())
.unwrap()
}
pub fn to_g2<T: Field>(g2: G2Affine) -> <T::BellmanEngine as Engine>::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);
<T::BellmanEngine as Engine>::G2Affine::from_xy_checked(x,y).unwrap()
}
}
const CONTRACT_TEMPLATE_V2: &str = r#"
contract Verifier {
using Pairing for *;

View file

@ -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"
);

View file

@ -1,8 +1,9 @@
use bellman_ce::pairing::bn256::Bn256;
use bellman_ce::pairing::bn256::{Bn256, Fq2};
prime_field!(
b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
Bn256,
Fq2,
"bn128"
);

View file

@ -63,6 +63,8 @@ pub trait Field:
<Self::BellmanEngine as ScalarEngine>::Fr::from_str(&s).unwrap()
}
fn new_fq2(c0: &str, c1: &str) -> <Self::BellmanEngine as Engine>::Fqe;
/// Returns this `Field`'s contents as little-endian byte vector
fn into_byte_vector(&self) -> Vec<u8>;
/// Returns an element of this `Field` from a little-endian byte vector
@ -111,7 +113,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};
@ -135,6 +137,13 @@ mod prime_field {
impl Field for FieldPrime {
type BellmanEngine = $bellman_type;
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()
}