Skip to content

Commit

Permalink
chore: merge feat/universal-verifier
Browse files Browse the repository at this point in the history
  • Loading branch information
rpalakkal committed Aug 11, 2023
2 parents aa79228 + 253b5b5 commit 8643efb
Show file tree
Hide file tree
Showing 21 changed files with 625 additions and 280 deletions.
6 changes: 3 additions & 3 deletions snark-verifier-sdk/benches/standard_plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use halo2_proofs::{
use pprof::criterion::{Output, PProfProfiler};
use rand::rngs::OsRng;
use snark_verifier_sdk::evm::{evm_verify, gen_evm_proof_shplonk, gen_evm_verifier_shplonk};
use snark_verifier_sdk::halo2::aggregation::AggregationConfigParams;
use snark_verifier_sdk::halo2::aggregation::{AggregationConfigParams, VerifierUniversality};
use snark_verifier_sdk::{
gen_pk,
halo2::{aggregation::AggregationCircuit, gen_proof_shplonk, gen_snark_shplonk},
Expand Down Expand Up @@ -209,7 +209,7 @@ fn bench(c: &mut Criterion) {
lookup_bits,
params,
snarks.clone(),
false,
VerifierUniversality::None,
);
let instances = agg_circuit.instances();
gen_proof_shplonk(params, pk, agg_circuit, instances, None)
Expand All @@ -227,7 +227,7 @@ fn bench(c: &mut Criterion) {
lookup_bits,
&params,
snarks.clone(),
false,
VerifierUniversality::None,
);
let num_instances = agg_circuit.num_instance();
let instances = agg_circuit.instances();
Expand Down
5 changes: 3 additions & 2 deletions snark-verifier-sdk/examples/halo2_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use snark_verifier_sdk::{
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::Path;
use snark_verifier_sdk::halo2::aggregation::VerifierUniversality;

fn read_snark_from_file(file_name: &str) -> Snark {
let snark_path = Path::new(file_name);
Expand Down Expand Up @@ -55,7 +56,7 @@ fn main() {
lookup_bits,
&params,
vec![dummy_snark.clone()],
true,
VerifierUniversality::Full,
);
agg_circuit.config(k, Some(10));

Expand All @@ -78,7 +79,7 @@ fn main() {
lookup_bits,
&params,
vec![snark],
true,
VerifierUniversality::Full,
);
let _snark = gen_snark_shplonk(&params, &pk, agg_circuit, None::<&str>);
println!("snark {i} success");
Expand Down
Binary file not shown.
190 changes: 190 additions & 0 deletions snark-verifier-sdk/examples/n_as_witness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
use halo2_base::gates::builder::{CircuitBuilderStage, BASE_CONFIG_PARAMS};
use halo2_base::halo2_proofs;
use halo2_base::halo2_proofs::arithmetic::Field;
use halo2_base::halo2_proofs::halo2curves::bn256::Fr;
use halo2_base::halo2_proofs::poly::commitment::Params;
use halo2_base::utils::fs::gen_srs;
use halo2_proofs::halo2curves as halo2_curves;

use rand::rngs::OsRng;
use snark_verifier_sdk::halo2::aggregation::VerifierUniversality;
use snark_verifier_sdk::SHPLONK;
use snark_verifier_sdk::{
gen_pk,
halo2::{aggregation::AggregationCircuit, gen_snark_shplonk},
Snark,
};

mod application {
use super::halo2_curves::bn256::Fr;
use super::halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner, Value},
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance},
poly::Rotation,
};

use snark_verifier_sdk::CircuitExt;

#[derive(Clone, Copy)]
pub struct StandardPlonkConfig {
a: Column<Advice>,
b: Column<Advice>,
c: Column<Advice>,
q_a: Column<Fixed>,
q_b: Column<Fixed>,
q_c: Column<Fixed>,
q_ab: Column<Fixed>,
constant: Column<Fixed>,
#[allow(dead_code)]
instance: Column<Instance>,
}

impl StandardPlonkConfig {
fn configure(meta: &mut ConstraintSystem<Fr>) -> Self {
let [a, b, c] = [(); 3].map(|_| meta.advice_column());
let [q_a, q_b, q_c, q_ab, constant] = [(); 5].map(|_| meta.fixed_column());
let instance = meta.instance_column();

[a, b, c].map(|column| meta.enable_equality(column));

meta.create_gate(
"q_a·a + q_b·b + q_c·c + q_ab·a·b + constant + instance = 0",
|meta| {
let [a, b, c] =
[a, b, c].map(|column| meta.query_advice(column, Rotation::cur()));
let [q_a, q_b, q_c, q_ab, constant] = [q_a, q_b, q_c, q_ab, constant]
.map(|column| meta.query_fixed(column, Rotation::cur()));
let instance = meta.query_instance(instance, Rotation::cur());
Some(
q_a * a.clone()
+ q_b * b.clone()
+ q_c * c
+ q_ab * a * b
+ constant
+ instance,
)
},
);

StandardPlonkConfig { a, b, c, q_a, q_b, q_c, q_ab, constant, instance }
}
}

#[derive(Clone)]
pub struct StandardPlonk(pub Fr, pub usize);

impl CircuitExt<Fr> for StandardPlonk {
fn num_instance(&self) -> Vec<usize> {
vec![1]
}

fn instances(&self) -> Vec<Vec<Fr>> {
vec![vec![self.0]]
}
}

impl Circuit<Fr> for StandardPlonk {
type Config = StandardPlonkConfig;
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
Self(Fr::zero(), self.1)
}

fn configure(meta: &mut ConstraintSystem<Fr>) -> Self::Config {
meta.set_minimum_degree(4);
StandardPlonkConfig::configure(meta)
}

fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<Fr>,
) -> Result<(), Error> {
layouter.assign_region(
|| "",
|mut region| {
region.assign_advice(config.a, 0, Value::known(self.0));
region.assign_fixed(config.q_a, 0, -Fr::one());
region.assign_advice(config.a, 1, Value::known(-Fr::from(5u64)));
for (idx, column) in (1..).zip([
config.q_a,
config.q_b,
config.q_c,
config.q_ab,
config.constant,
]) {
region.assign_fixed(column, 1, Fr::from(idx as u64));
}
let a = region.assign_advice(config.a, 2, Value::known(Fr::one()));
a.copy_advice(&mut region, config.b, 3);
a.copy_advice(&mut region, config.c, 4);

// assuming <= 10 blinding factors
// fill in most of circuit with a computation
/*let n = self.1;
for offset in 5..n - 10 {
region.assign_advice(config.a, offset, Value::known(-Fr::from(5u64)));
for (idx, column) in (1..).zip([
config.q_a,
config.q_b,
config.q_c,
config.q_ab,
config.constant,
]) {
region.assign_fixed(column, offset, Fr::from(idx as u64));
}
}*/

Ok(())
},
)
}
}
}

fn gen_application_snark(k: u32) -> Snark {
let params = gen_srs(k);
let circuit = application::StandardPlonk(Fr::random(OsRng), params.n() as usize);

let pk = gen_pk(&params, &circuit, None);
gen_snark_shplonk(&params, &pk, circuit, None::<&str>)
}

fn main() {
let dummy_snark = gen_application_snark(8);

let k = 15u32;
let params = gen_srs(k);
let lookup_bits = k as usize - 1;
BASE_CONFIG_PARAMS.with(|config| {
config.borrow_mut().lookup_bits = Some(lookup_bits);
config.borrow_mut().k = k as usize;
});
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
None,
lookup_bits,
&params,
vec![dummy_snark],
VerifierUniversality::Full,
);
agg_circuit.config(k, Some(10));

let pk = gen_pk(&params, &agg_circuit, None);
let break_points = agg_circuit.break_points();

let snarks = [8, 12, 15, 20].map(|k| (k, gen_application_snark(k)));
for (k, snark) in snarks {
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
Some(break_points.clone()),
lookup_bits,
&params,
vec![snark],
VerifierUniversality::Full,
);
let _snark = gen_snark_shplonk(&params, &pk, agg_circuit, None::<&str>);
println!("snark with k = {k} success");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use application::ComputeFlag;
use ark_std::{end_timer, start_timer};
use halo2_base::gates::builder::{CircuitBuilderStage, BASE_CONFIG_PARAMS};
use halo2_base::halo2_proofs;
use halo2_base::halo2_proofs::arithmetic::Field;
Expand All @@ -9,15 +8,13 @@ use halo2_proofs::halo2curves as halo2_curves;

use halo2_proofs::{halo2curves::bn256::Bn256, poly::kzg::commitment::ParamsKZG};
use rand::rngs::OsRng;
use snark_verifier_sdk::halo2::aggregation::VerifierUniversality;
use snark_verifier_sdk::SHPLONK;
use snark_verifier_sdk::{
gen_pk,
halo2::{aggregation::AggregationCircuit, gen_snark_shplonk},
Snark,
};
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::Path;

mod application {
use super::halo2_curves::bn256::Fr;
Expand Down Expand Up @@ -172,7 +169,7 @@ fn main() {
let params_app = gen_srs(8);
let dummy_snark = gen_application_snark(&params_app, ComputeFlag::All);

let k = 14u32;
let k = 15u32;
let params = gen_srs(k);
let lookup_bits = k as usize - 1;
BASE_CONFIG_PARAMS.with(|config| {
Expand All @@ -185,14 +182,12 @@ fn main() {
lookup_bits,
&params,
vec![dummy_snark],
true,
VerifierUniversality::PreprocessedAsWitness,
);
agg_circuit.config(k, Some(10));

let start0 = start_timer!(|| "gen vk & pk");
let pk = gen_pk(&params, &agg_circuit, Some(Path::new("./examples/agg.pk")));
end_timer!(start0);
let break_points = gen_agg_break_points(agg_circuit, Path::new("./examples/break_points.json"));
let pk = gen_pk(&params, &agg_circuit, None);
let break_points = agg_circuit.break_points();

let snarks = [ComputeFlag::All, ComputeFlag::SkipFixed, ComputeFlag::SkipCopy]
.map(|flag| gen_application_snark(&params_app, flag));
Expand All @@ -203,27 +198,9 @@ fn main() {
lookup_bits,
&params,
vec![snark],
true,
VerifierUniversality::PreprocessedAsWitness,
);
let _snark = gen_snark_shplonk(&params, &pk, agg_circuit, None::<&str>);
println!("snark {i} success");
}

/*
#[cfg(feature = "loader_evm")]
{
// do one more time to verify
let num_instances = agg_circuit.num_instance();
let instances = agg_circuit.instances();
let proof_calldata = gen_evm_proof_shplonk(&params, &pk, agg_circuit, instances.clone());
let deployment_code = gen_evm_verifier_shplonk::<AggregationCircuit<SHPLONK>>(
&params,
pk.get_vk(),
num_instances,
Some(Path::new("./examples/standard_plonk.yul")),
);
evm_verify(deployment_code, instances, proof_calldata);
}
*/
}
34 changes: 20 additions & 14 deletions snark-verifier-sdk/src/halo2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use snark_verifier::{
AccumulationScheme, PolynomialCommitmentScheme, Query,
},
system::halo2::{compile, Config},
util::arithmetic::Rotation,
util::transcript::TranscriptWrite,
verifier::plonk::PlonkProof,
};
Expand Down Expand Up @@ -122,20 +123,25 @@ where
end_timer!(proof_time);

// validate proof before caching
assert!({
let mut transcript_read =
PoseidonTranscript::<NativeLoader, &[u8]>::from_spec(&proof[..], POSEIDON_SPEC.clone());
VerificationStrategy::<_, V>::finalize(
verify_proof::<_, V, _, _, _>(
params.verifier_params(),
pk.get_vk(),
AccumulatorStrategy::new(params.verifier_params()),
&[instances.as_slice()],
&mut transcript_read,
assert!(
{
let mut transcript_read = PoseidonTranscript::<NativeLoader, &[u8]>::from_spec(
&proof[..],
POSEIDON_SPEC.clone(),
);
VerificationStrategy::<_, V>::finalize(
verify_proof::<_, V, _, _, _>(
params.verifier_params(),
pk.get_vk(),
AccumulatorStrategy::new(params.verifier_params()),
&[instances.as_slice()],
&mut transcript_read,
)
.unwrap(),
)
.unwrap(),
)
});
},
"SNARK proof failed to verify"
);

if let Some((instance_path, proof_path)) = path {
write_instances(&instances, instance_path);
Expand Down Expand Up @@ -286,7 +292,7 @@ where
NativeLoader,
Accumulator = KzgAccumulator<G1Affine, NativeLoader>,
VerifyingKey = KzgAsVerifyingKey,
> + CostEstimation<G1Affine, Input = Vec<Query<Fr>>>,
> + CostEstimation<G1Affine, Input = Vec<Query<Rotation>>>,
{
struct CsProxy<F, C>(PhantomData<(F, C)>);

Expand Down
Loading

0 comments on commit 8643efb

Please sign in to comment.