Skip to content

Commit

Permalink
Verify subproof part in aggregate proof (#119)
Browse files Browse the repository at this point in the history
* update dependencies from bellman_ce to franklin_crypto

* induce verification of aggregation part in recursive proof

Co-authored-by: Ho <ho@fluidex.com>
  • Loading branch information
noel2004 and Ho authored Oct 21, 2021
1 parent 764014b commit 84da93c
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 46 deletions.
10 changes: 4 additions & 6 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ path = "src/bin/main.rs"

[dependencies]
anyhow = "1.0.34"
bellman_ce = { git = "https://github.com/matter-labs/bellman", branch = "beta", default-features = false, features = [ "plonk" ] } # active features depend on build type
# bellman_ce = { git = "https://github.com/matter-labs/bellman", branch = "beta", default-features = false, features = [ "plonk" ] } # active features depend on build type
bellman_vk_codegen = { git = "https://github.com/fluidex/solidity_plonk_verifier.git" }
byteorder = "1"
clap = { package = "clap-v3", version = "3.0.0-beta.1" } # todo: replace with official v3 when it's released to crates.io
Expand All @@ -23,13 +23,13 @@ franklin-crypto = { git = "https://github.com/matter-labs/franklin-crypto", bran
hex-literal = "0.2.1"
itertools = "0.8.1"
log = "0.4.11"
num-bigint = "0.2.3"
num-bigint = "0.3.3"
num-traits = "0.2.8"
rand = "0.4"
recursive_aggregation_circuit = { package = "recursive_aggregation_circuit", version = "1.0.0", git = "https://github.com/matter-labs/recursive_aggregation_circuit.git", branch = "master" }
# recursive_aggregation_circuit = { package = "recursive_aggregation_circuit", version = "1.0.0", git = "https://github.com/matter-labs/recursive_aggregation_circuit.git", branch = "master" }
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
recurisive_vk_codegen = { package = "solidity_recursive_plonk_verifier", git = "https://github.com/fluidex/solidity_recursive_plonk_verifier.git" }

[features]
default = [ "bellman_ce/multicore" ]
default = [ ]
3 changes: 1 addition & 2 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![cfg(not(tarpaulin_include))]

extern crate bellman_ce;
extern crate bellman_vk_codegen;
extern crate clap;
extern crate plonkit;
Expand All @@ -10,7 +9,7 @@ use std::fs::File;
use std::path::Path;
use std::str;

use bellman_ce::pairing::bn256::Bn256;
use plonkit::bellman_ce::pairing::bn256::Bn256;

use plonkit::circom_circuit::CircomCircuit;
use plonkit::plonk;
Expand Down
3 changes: 1 addition & 2 deletions src/circom_circuit.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#![allow(clippy::needless_range_loop)]
extern crate bellman_ce;
extern crate rand;

use itertools::Itertools;
use std::collections::BTreeMap;
use std::str;

use bellman_ce::{
use crate::bellman_ce::{
pairing::{ff::PrimeField, ff::ScalarEngine, Engine},
Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable,
};
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
extern crate serde;
#[macro_use]
extern crate hex_literal;
extern crate bellman_ce;
extern crate bellman_vk_codegen;
extern crate byteorder;
extern crate franklin_crypto;
extern crate itertools;
extern crate num_bigint;
extern crate num_traits;
Expand All @@ -20,5 +20,7 @@ pub mod recursive;
pub mod transpile;
pub mod utils;

pub use franklin_crypto::bellman as bellman_ce;

#[cfg(test)]
mod tests;
16 changes: 10 additions & 6 deletions src/plonk.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Most of this file is forked from source codes of [Matter Labs's zkSync](https://github.com/matter-labs/zksync)
use crate::circom_circuit::CircomCircuit;
use crate::transpile::{transpile_with_gates_count, ConstraintStat, TranspilerWrapper};
use bellman_ce::bn256::Bn256;
use bellman_ce::{
use crate::bellman_ce::bn256::Bn256;
use crate::bellman_ce::{
kate_commitment::{Crs, CrsForLagrangeForm, CrsForMonomialForm},
pairing::Engine,
plonk::{
Expand All @@ -15,6 +13,8 @@ use bellman_ce::{
worker::Worker,
Circuit, ScalarEngine, SynthesisError,
};
use crate::circom_circuit::CircomCircuit;
use crate::transpile::{transpile_with_gates_count, ConstraintStat, TranspilerWrapper};

type E = Bn256;
use franklin_crypto::plonk::circuit::bigint::field::RnsParameters;
Expand Down Expand Up @@ -193,11 +193,15 @@ pub fn verify(
) -> Result<bool, SynthesisError> {
match transcript {
"keccak" => {
bellman_ce::plonk::better_cs::verifier::verify::<_, _, RollingKeccakTranscript<<E as ScalarEngine>::Fr>>(proof, vk, None)
crate::bellman_ce::plonk::better_cs::verifier::verify::<_, _, RollingKeccakTranscript<<E as ScalarEngine>::Fr>>(proof, vk, None)
}
"rescue" => {
let (bn256_param, rns_param) = get_default_rescue_transcript_params();
bellman_ce::plonk::better_cs::verifier::verify::<_, _, RescueTranscriptForRNS<E>>(proof, vk, Some((&bn256_param, &rns_param)))
crate::bellman_ce::plonk::better_cs::verifier::verify::<_, _, RescueTranscriptForRNS<E>>(
proof,
vk,
Some((&bn256_param, &rns_param)),
)
}
_ => {
unimplemented!("invalid transcript. use 'keccak' or 'rescue'");
Expand Down
6 changes: 3 additions & 3 deletions src/r1cs_file.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// some codes borrowed from https://github.com/poma/zkutil/blob/master/src/r1cs_reader.rs
#![allow(unused_variables, dead_code)]
use crate::circom_circuit::Constraint;
use bellman_ce::pairing::{
use crate::bellman_ce::pairing::{
bn256::Bn256,
ff::{Field, PrimeField, PrimeFieldRepr},
Engine,
};
use crate::circom_circuit::Constraint;
use byteorder::{LittleEndian, ReadBytesExt};
use std::io::{Error, ErrorKind, Read, Result};

Expand Down Expand Up @@ -192,7 +192,7 @@ mod tests {
"
);

use bellman_ce::pairing::ff;
use crate::bellman_ce::pairing::ff;
let file = from_reader(&data[..]).unwrap();
assert_eq!(file.version, 1);

Expand Down
2 changes: 1 addition & 1 deletion src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, Read};
use std::str;

use bellman_ce::{
use crate::bellman_ce::{
kate_commitment::{Crs, CrsForLagrangeForm, CrsForMonomialForm},
pairing::{bn256::Bn256, ff::PrimeField, Engine},
plonk::{
Expand Down
80 changes: 62 additions & 18 deletions src/recursive/mod.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
#![allow(clippy::needless_range_loop)]

use crate::{bellman_ce, utils};
use bellman_ce::kate_commitment::{Crs, CrsForMonomialForm};
use bellman_ce::pairing::bn256;
use bellman_ce::pairing::bn256::Bn256;
use bellman_ce::pairing::ff::ScalarEngine;
use bellman_ce::pairing::{CurveAffine, Engine};
use bellman_ce::plonk::better_better_cs::cs::PlonkCsWidth4WithNextStepAndCustomGatesParams;
use bellman_ce::plonk::better_better_cs::cs::ProvingAssembly;
use bellman_ce::plonk::better_better_cs::cs::TrivialAssembly;
use bellman_ce::plonk::better_better_cs::cs::Width4MainGateWithDNext;
use bellman_ce::plonk::better_better_cs::cs::{Circuit, Setup};
use bellman_ce::plonk::better_better_cs::setup::VerificationKey;
use bellman_ce::plonk::better_better_cs::verifier::verify as core_verify;
use bellman_ce::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript;
use bellman_ce::plonk::{
better_cs::cs::PlonkCsWidth4WithNextStepParams,
better_cs::keys::{Proof as OldProof, VerificationKey as OldVerificationKey},
};
use bellman_ce::SynthesisError;
use franklin_crypto::bellman::pairing::bn256;
use franklin_crypto::bellman::pairing::bn256::Bn256;
use franklin_crypto::bellman::pairing::ff::ScalarEngine;
use franklin_crypto::bellman::pairing::{CurveAffine, Engine};
use franklin_crypto::bellman::plonk::better_better_cs::cs::PlonkCsWidth4WithNextStepAndCustomGatesParams;
use franklin_crypto::bellman::plonk::better_better_cs::cs::ProvingAssembly;
use franklin_crypto::bellman::plonk::better_better_cs::cs::TrivialAssembly;
use franklin_crypto::bellman::plonk::better_better_cs::cs::Width4MainGateWithDNext;
use franklin_crypto::bellman::plonk::better_better_cs::cs::{Circuit, Setup};
use franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey;
use franklin_crypto::bellman::plonk::better_better_cs::verifier::verify as core_verify;
use franklin_crypto::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript;
use franklin_crypto::bellman::worker::Worker;
use bellman_ce::worker::Worker;
use bellman_ce::{Field, SynthesisError};
use franklin_crypto::plonk::circuit::bigint::field::RnsParameters;
use franklin_crypto::plonk::circuit::verifier_circuit::affine_point_wrapper::aux_data::{AuxData, BN256AuxData};
use franklin_crypto::plonk::circuit::verifier_circuit::data_structs::IntoLimbedWitness;
use franklin_crypto::plonk::circuit::Width4WithCustomGates;
use franklin_crypto::rescue::bn256::Bn256RescueParams;
use itertools::Itertools;
pub use recurisive_vk_codegen::types::{AggregatedProof, RecursiveVerificationKey};
use recursive_aggregation_circuit::circuit::{
use recurisive_vk_codegen::circuit::{
create_recursive_circuit_setup, create_recursive_circuit_vk_and_setup, create_vks_tree, make_aggregate,
make_public_input_and_limbed_aggregate, RecursiveAggregationCircuitBn256,
};
pub use recurisive_vk_codegen::types::{AggregatedProof, RecursiveVerificationKey};

// only support depth<8. different depths don't really make performance different
const VK_TREE_DEPTH: usize = 7;
Expand Down Expand Up @@ -135,6 +135,42 @@ pub fn prove(
})
}

fn verify_subproof_limbs(
proof: &AggregatedProof,
vk: &VerificationKey<Bn256, RecursiveAggregationCircuitBn256>,
) -> Result<bool, SynthesisError> {
let mut rns_params = RnsParameters::<Bn256, <Bn256 as Engine>::Fq>::new_for_field(68, 110, 4);

//keep the behavior same as recursive_aggregation_circuit
rns_params.set_prefer_single_limb_allocation(true);

let aggr_limbs_nums: Vec<utils::BigUint> = proof.aggr_limbs.iter().map(utils::fe_to_biguint).collect();
//we need 4 Fr to build 2 G1Affine ...
let num_consume = rns_params.num_limbs_for_in_field_representation;
assert_eq!(num_consume * 4, aggr_limbs_nums.len());

let mut start = 0;
let pg_x = utils::witness_to_field(&aggr_limbs_nums[start..start + num_consume], &rns_params);
start += num_consume;
let pg_y = utils::witness_to_field(&aggr_limbs_nums[start..start + num_consume], &rns_params);
start += num_consume;
let px_x = utils::witness_to_field(&aggr_limbs_nums[start..start + num_consume], &rns_params);
start += num_consume;
let px_y = utils::witness_to_field(&aggr_limbs_nums[start..start + num_consume], &rns_params);

let pair_with_generator = bn256::G1Affine::from_xy_checked(pg_x, pg_y).map_err(|_| SynthesisError::Unsatisfiable)?;
let pair_with_x = bn256::G1Affine::from_xy_checked(px_x, px_y).map_err(|_| SynthesisError::Unsatisfiable)?;

let valid = Bn256::final_exponentiation(&Bn256::miller_loop(&[
(&pair_with_generator.prepare(), &vk.g2_elements[0].prepare()),
(&pair_with_x.prepare(), &vk.g2_elements[1].prepare()),
]))
.ok_or(SynthesisError::Unsatisfiable)?
== <Bn256 as Engine>::Fqk::one();

Ok(valid)
}

// verify a recursive proof by using a corresponding verification key
pub fn verify(
vk: VerificationKey<Bn256, RecursiveAggregationCircuitBn256>,
Expand All @@ -145,7 +181,15 @@ pub fn verify(
inputs.push(chunk);
}
log::info!("individual_inputs: {:#?}", inputs);
core_verify::<_, _, RollingKeccakTranscript<<Bn256 as ScalarEngine>::Fr>>(&vk, &aggregated_proof.proof, None)
//notice in PlonkCore.sol the aggregate pairs from subproofs and recursive proofs are combined: 1 * inner + challenge * outer
//and only one verify on pairing has been run to save some gas
//here we just verify them respectively
let valid = core_verify::<_, _, RollingKeccakTranscript<<Bn256 as ScalarEngine>::Fr>>(&vk, &aggregated_proof.proof, None)?;
if !valid {
return Ok(valid);
}
log::info!("aggregated proof is valid");
verify_subproof_limbs(&aggregated_proof, &vk)
}

// export a verification key for a recursion circuit
Expand Down
2 changes: 1 addition & 1 deletion src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::fs;

use crate::bellman_ce::bn256::Bn256;
use crate::circom_circuit::CircomCircuit;
use crate::{plonk, reader};
use bellman_ce::bn256::Bn256;

const CIRCUIT_FILE: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/test/circuits/simple/circuit.r1cs.json");
const WITNESS_FILE: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/test/circuits/simple/witness.json");
Expand Down
1 change: 1 addition & 0 deletions src/transpile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::bellman_ce;
use bellman_ce::pairing::Engine;
use bellman_ce::plonk::better_cs::adaptor::{TranspilationVariant, Transpiler};
use bellman_ce::plonk::better_cs::cs::{
Expand Down
Loading

0 comments on commit 84da93c

Please sign in to comment.