Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 21 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"zokrates_interpreter",
"zokrates_embed",
"zokrates_bellman",
"zokrates_bellman_plonk",
"zokrates_proof_systems",
"zokrates_js",
"zokrates_circom"
Expand Down
16 changes: 5 additions & 11 deletions zokrates_ark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ mod parse {
use super::*;
use ark_ff::ToBytes;
use zokrates_field::G2Type;
use zokrates_proof_systems::{Fq2, Fr, G1Affine, G2Affine, G2AffineFq, GAffine};
use zokrates_proof_systems::{Fq2, Fr, G1Affine, G2Affine, G2AffineFq, G2AffineFq2};

pub fn parse_g1<T: Field + ArkFieldExtensions>(
e: &<T::ArkEngine as PairingEngine>::G1Affine,
Expand Down Expand Up @@ -201,7 +201,7 @@ mod parse {
elements.push(e);
}

G2Affine::Fq2(GAffine::new(
G2Affine::Fq2(G2AffineFq2::new(
Fq2(
format!("0x{}", hex::encode(&elements[0])),
format!("0x{}", hex::encode(&elements[1])),
Expand Down Expand Up @@ -252,12 +252,10 @@ pub mod serialization {
}

pub fn to_g1<T: ArkFieldExtensions>(g1: G1Affine) -> <T::ArkEngine as PairingEngine>::G1Affine {
let infinity_flag = if g1.is_infinity { 1u8 } else { 0u8 };

let mut bytes = vec![];
bytes.append(&mut decode_hex(g1.x));
bytes.append(&mut decode_hex(g1.y));
bytes.push(infinity_flag); // infinity flag
bytes.push(0u8); // infinity flag

<T::ArkEngine as PairingEngine>::G1Affine::read(&*bytes).unwrap()
}
Expand All @@ -267,20 +265,16 @@ pub mod serialization {

match g2 {
G2Affine::Fq(g2) => {
let infinity_flag = if g2.is_infinity { 1u8 } else { 0u8 };

bytes.append(&mut decode_hex(g2.x));
bytes.append(&mut decode_hex(g2.y));
bytes.push(infinity_flag); // infinity flag
bytes.push(0u8); // infinity flag
}
G2Affine::Fq2(g2) => {
let infinity_flag = if g2.is_infinity { 1u8 } else { 0u8 };

bytes.append(&mut decode_hex((g2.x).0));
bytes.append(&mut decode_hex((g2.x).1));
bytes.append(&mut decode_hex((g2.y).0));
bytes.append(&mut decode_hex((g2.y).1));
bytes.push(infinity_flag); // infinity flag
bytes.push(0u8); // infinity flag
}
};

Expand Down
8 changes: 4 additions & 4 deletions zokrates_bellman/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ version = "0.1.0"
edition = "2021"

[features]
wasm = ["bellman_ce/nolog", "bellman_ce/wasm"]
multicore = ["bellman_ce/multicore", "phase2/multicore"]
wasm = ["bellman/nolog", "bellman/wasm"]
multicore = ["bellman/multicore", "phase2/multicore"]

[dependencies]
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false }
zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", default-features = false }

bellman_ce = { git = "https://github.com/georgwiese/bellman", rev="b356c7001f30da23bfad2b43eb0b7ca9804c8252", default-features = false, features = ["plonk", "multicore"] }
# pairing = { package = "pairing_ce", version = "^0.21" }
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"] }
Expand Down
178 changes: 103 additions & 75 deletions zokrates_bellman/src/groth16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ use bellman::groth16::{
prepare_verifying_key, verify_proof, Parameters, PreparedVerifyingKey, Proof as BellmanProof,
VerifyingKey,
};
use bellman::pairing::{ff::to_hex, CurveAffine, Engine};
use pairing::{ff::to_hex, CurveAffine, Engine};

use zokrates_field::BellmanFieldExtensions;
use zokrates_field::Field;
use zokrates_proof_systems::{
Backend, G1Affine, G2Affine, NonUniversalBackend, Proof, SetupKeypair,
};
use zokrates_proof_systems::{Backend, MpcBackend, NonUniversalBackend, Proof, SetupKeypair};

use crate::Bellman;
use crate::Computation;
use crate::{parse_g1, parse_g2, serialization};
use crate::{parse_g1, parse_g2};
use phase2::MPCParameters;
use rand_0_4::Rng;
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;
Expand Down Expand Up @@ -92,80 +93,107 @@ impl<T: Field + BellmanFieldExtensions> NonUniversalBackend<T, G16> for Bellman
let mut pk: Vec<u8> = Vec::new();
parameters.write(&mut pk).unwrap();

let vk = parameters_to_verification_key::<T>(&parameters);
let vk = serialization::parameters_to_verification_key::<T>(&parameters);
SetupKeypair::new(vk, pk)
}
}

// impl<T: Field + BellmanFieldExtensions> MpcBackend<T, G16> for Bellman {
// fn initialize<R: Read, W: Write, I: IntoIterator<Item = Statement<T>>>(
// program: ProgIterator<T, I>,
// phase1_radix: &mut R,
// output: &mut W,
// ) -> Result<(), String> {
// let circuit = Computation::without_witness(program);
// let params = MPCParameters::new(circuit, phase1_radix).map_err(|e| e.to_string())?;
// params.write(output).map_err(|e| e.to_string())?;
// Ok(())
// }

// fn contribute<R: Read, W: Write, G: Rng>(
// params: &mut R,
// rng: &mut G,
// output: &mut W,
// ) -> Result<[u8; 64], String> {
// let mut params =
// MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

// let hash = params.contribute(rng);
// params.write(output).map_err(|e| e.to_string())?;

// Ok(hash)
// }

// fn verify<P: Read, R: Read, I: IntoIterator<Item = Statement<T>>>(
// params: &mut P,
// program: ProgIterator<T, I>,
// phase1_radix: &mut R,
// ) -> Result<Vec<[u8; 64]>, String> {
// let params =
// MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

// let circuit = Computation::without_witness(program);
// let hashes = params
// .verify(circuit, phase1_radix)
// .map_err(|_| "parameters malformed".to_string())?;

// Ok(hashes)
// }

// fn export_keypair<R: Read>(params: &mut R) -> Result<SetupKeypair<T, G16>, String> {
// let params =
// MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

// let params = params.get_params();
// let mut pk: Vec<u8> = Vec::new();
// params.write(&mut pk).map_err(|e| e.to_string())?;

// let vk = serialization::parameters_to_verification_key::<T>(params);
// Ok(SetupKeypair::new(vk, pk))
// }
// }

pub fn parameters_to_verification_key<T: Field + BellmanFieldExtensions>(
parameters: &Parameters<T::BellmanEngine>,
) -> VerificationKey<G1Affine, G2Affine> {
VerificationKey {
alpha: parse_g1::<T>(&parameters.vk.alpha_g1),
beta: parse_g2::<T>(&parameters.vk.beta_g2),
gamma: parse_g2::<T>(&parameters.vk.gamma_g2),
delta: parse_g2::<T>(&parameters.vk.delta_g2),
gamma_abc: parameters
.vk
.ic
.iter()
.map(|g1| parse_g1::<T>(g1))
.collect(),
impl<T: Field + BellmanFieldExtensions> MpcBackend<T, G16> for Bellman {
fn initialize<R: Read, W: Write, I: IntoIterator<Item = Statement<T>>>(
program: ProgIterator<T, I>,
phase1_radix: &mut R,
output: &mut W,
) -> Result<(), String> {
let circuit = Computation::without_witness(program);
let params = MPCParameters::new(circuit, phase1_radix).map_err(|e| e.to_string())?;
params.write(output).map_err(|e| e.to_string())?;
Ok(())
}

fn contribute<R: Read, W: Write, G: Rng>(
params: &mut R,
rng: &mut G,
output: &mut W,
) -> Result<[u8; 64], String> {
let mut params =
MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

let hash = params.contribute(rng);
params.write(output).map_err(|e| e.to_string())?;

Ok(hash)
}

fn verify<P: Read, R: Read, I: IntoIterator<Item = Statement<T>>>(
params: &mut P,
program: ProgIterator<T, I>,
phase1_radix: &mut R,
) -> Result<Vec<[u8; 64]>, String> {
let params =
MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

let circuit = Computation::without_witness(program);
let hashes = params
.verify(circuit, phase1_radix)
.map_err(|_| "parameters malformed".to_string())?;

Ok(hashes)
}

fn export_keypair<R: Read>(params: &mut R) -> Result<SetupKeypair<T, G16>, String> {
let params =
MPCParameters::<T::BellmanEngine>::read(params, true).map_err(|e| e.to_string())?;

let params = params.get_params();
let mut pk: Vec<u8> = Vec::new();
params.write(&mut pk).map_err(|e| e.to_string())?;

let vk = serialization::parameters_to_verification_key::<T>(params);
Ok(SetupKeypair::new(vk, pk))
}
}

pub mod serialization {
use super::*;
use pairing::from_hex;
use zokrates_proof_systems::{G1Affine, G2Affine};

pub fn parameters_to_verification_key<T: Field + BellmanFieldExtensions>(
parameters: &Parameters<T::BellmanEngine>,
) -> VerificationKey<G1Affine, G2Affine> {
VerificationKey {
alpha: parse_g1::<T>(&parameters.vk.alpha_g1),
beta: parse_g2::<T>(&parameters.vk.beta_g2),
gamma: parse_g2::<T>(&parameters.vk.gamma_g2),
delta: parse_g2::<T>(&parameters.vk.delta_g2),
gamma_abc: parameters
.vk
.ic
.iter()
.map(|g1| parse_g1::<T>(g1))
.collect(),
}
}

pub fn to_g1<T: BellmanFieldExtensions>(
Comment thread
georgwiese marked this conversation as resolved.
Outdated
g1: G1Affine,
) -> <T::BellmanEngine as Engine>::G1Affine {
<T::BellmanEngine as Engine>::G1Affine::from_xy_unchecked(
from_hex(&g1.x).unwrap(),
from_hex(&g1.y).unwrap(),
)
}
pub fn to_g2<T: BellmanFieldExtensions>(
g2: G2Affine,
) -> <T::BellmanEngine as Engine>::G2Affine {
match g2 {
G2Affine::Fq2(g2) => {
let x = T::new_fq2(&(g2.x).0, &(g2.x).1);
let y = T::new_fq2(&(g2.y).0, &(g2.y).1);
<T::BellmanEngine as Engine>::G2Affine::from_xy_unchecked(x, y)
}
_ => unreachable!(),
}
}
}

Expand Down
Loading