Groth16 proof verification uses points in struct for verification
This commit is contained in:
parent
3e55d622dd
commit
44645fc926
4 changed files with 59 additions and 13 deletions
|
@ -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>(¶meters.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 *;
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use bellman_ce::pairing::bn256::Bn256;
|
||||
use bellman_ce::pairing::bn256::{Bn256, Fq2};
|
||||
|
||||
prime_field!(
|
||||
b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
|
||||
Bn256,
|
||||
Fq2,
|
||||
"bn128"
|
||||
);
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue