Skip to content

Commit

Permalink
[Community Edition] Prealpha release 0.1.6 (#35)
Browse files Browse the repository at this point in the history
* chore: update dependencies

* Minor: merge v0.1.1 to develop (#21)

Just cargo fixes

* feat: remove use of env vars for circuit configuration (#22)

* feat: remove use of env vars for circuit configuration

This is a companion to axiom-crypto/halo2-lib#92

* chore: remove rustfmt CI check

PSE upstream uses different rustfmt configuration than us, so some files
disagree in formatting

* chore: fix dependencies

* Feat/read pk buffer capacity (#24)

* feat: change default `read_pk` buffer capacity to 1MB

* feat: add bench for read_pk

* [Update] use ff v0.13 (#28)

* feat(snark-verifier): update to ff v0.13

* feat(snark-verifier): update examples

* feat(snark-verifier-sdk): update to ff v0.13

* fix: conversion from BaseConfigParams to AggregationConfigParams

* chore: pin poseidon rev

* refactor(sdk): add `AggregationCtxBuilder` for aggregation

Contains the populated builder after aggregating, without creating the
`AggregationCircuit`. Doesn't need config parameters and break points.

* chore: update cargo

* [Feat] Universal verifier circuit (#26)

* feat: add example with different vkey as private witness

Same aggregation circuit, verifies different snarks with different vkeys
(same standard plonk gate, but different selectors / copy constraints)

* fix: save break points when generating agg circuit for first time (#23)

* fix: save break points when generating agg circuit for first time

* chore: add circuit files to gitignore

* feat: halo2-lib universal verifier example

* chore: cargo fix

* feat: allow circuit size (number of rows) to be loaded as witness

* chore: clippy fix

* fix(n_as_witness): computation of shifts depends on `omega`

`omega` which changes when `k` changes, so all shift computations need
to be done as witness. Current implementation is likely not the most
optimal. Instead of storing `shift` as `omega^i`, we store just
`Rotation(i)`. We de-duplicate when possible using `BTreeMap` of
`Rotation`. Note you must use `Rotation` instead of `F` for `BTreeMap`
because the ordering of `omega^i` may change depending on `omega`.

* fix: temp remove pow_var

* add universal verifier range check test

* chore: do not serialize domain_as_witness if none

* Revert "fix: temp remove pow_var"

This reverts commit 69f648e.

* fix: halo2_lib example

* test: halo2_lib with variable lookup table passes

* Bump version to 0.1.3

---------

Co-authored-by: Roshan <[email protected]>

* chore: derive Default for VerifierUniversality

* feat: upgrade `revm` to support lastest hardfork (#40)

* Update: use `halo2-lib` v0.4.0 (#29)

* feat: update snark-verifier

* update: use `halo2-lib` v0.4.0

* feat: load `k` as witness and compute `n = 2^k` and `omega` from `k` (#30)

* feat: load `k` as witness and compute `n = 2^k` and `omega` from `k`

Removes need to make `omega` a public output in universal verifier.

* fix: bit_length

* Move `OptimizedPoseidonSpec` to `halo2-base` (#31)

* chore: move `OptimizedPoseidonSpec` to `halo2-base`

* Bump version to 0.1.5 and remove poseidon-rs dep

* chore: util::hash available without loader_halo2 feature

* chore: nit

* [feat] change yul code into Solidity assembly (#32)

feat: change yul code into Solidity assembly

Just changes to wrapping yul in solidity assembly block

* chore: try pragma solidity 0.8.20 with CI

* chore: make `transcript_initial_state` public

So we can read transcript initial state from `VerifyingKey`

* test: edit range_check example to trigger selector compression

* [feat] add `aggregate_snarks` function (#34)

* feat: add `aggregate_snarks` function

- Previously you could only create a new `builder` pre-populated with
  the witnesses for snark aggregation.
- This is a bad design pattern if you want to make a circuit that
  aggregates and also does other stuff.
- This function will use whatever `SinglePhaseCoreManager` and
  `RangeChip` you provide to prove the snark aggregation.

* chore: add comment

* chore: fix comment

---------

Co-authored-by: Roshan <[email protected]>
Co-authored-by: Han <[email protected]>
  • Loading branch information
3 people authored Sep 21, 2023
1 parent f07bb2c commit 7011e8c
Show file tree
Hide file tree
Showing 55 changed files with 3,598 additions and 3,201 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ jobs:
cache-on-failure: true

- name: Install solc
run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.17 && solc --version
run: (hash svm 2>/dev/null || cargo install --version 0.2.23 svm-rs) && svm install 0.8.20 && solc --version

- name: Run test
run: cargo test --all -- --nocapture

- name: Run example
working-directory: "snark-verifier-sdk"
run: cargo run --example standard_plonk

lint:
name: Lint
Expand All @@ -47,8 +50,5 @@ jobs:
with:
cache-on-failure: true

- name: Run fmt
run: cargo fmt --all -- --check

- name: Run clippy
run: cargo clippy --all --all-targets -- -D warnings
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
/target
testdata

Cargo.lock
params
agg.pk
break_points.json
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"snark-verifier",
"snark-verifier-sdk",
]
resolver = "2"

[profile.dev]
opt-level = 3
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2022-10-28
nightly-2023-08-12
20 changes: 13 additions & 7 deletions snark-verifier-sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "snark-verifier-sdk"
version = "0.1.1"
version = "0.1.6"
edition = "2021"

[dependencies]
Expand All @@ -19,13 +19,10 @@ bincode = "1.3.3"
ark-std = { version = "0.3.0", features = ["print-trace"], optional = true }
halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib.git", branch = "community-edition", default-features = false }
snark-verifier = { path = "../snark-verifier", default-features = false }
getset = "0.1.2"

# loader_evm
ethereum-types = { version = "=0.14.1", default-features = false, features = ["std"], optional = true }
# sha3 = { version = "0.10", optional = true }
# revm = { version = "2.3.1", optional = true }
# bytes = { version = "1.2", optional = true }
# rlp = { version = "0.5", default-features = false, features = ["std"], optional = true }
ethereum-types = { version = "0.14.1", default-features = false, features = ["std"], optional = true }

# zkevm benchmarks
zkevm-circuits = { git = "https://github.com/privacy-scaling-explorations/zkevm-circuits.git", rev = "f834e61", features = ["test"], optional = true }
Expand Down Expand Up @@ -53,7 +50,7 @@ parallel = ["snark-verifier/parallel"]
halo2-pse = ["snark-verifier/halo2-pse", "dep:serde_with"]
halo2-axiom = ["snark-verifier/halo2-axiom"]

zkevm = ["dep:zkevm-circuits", "dep:bus-mapping", "dep:mock", "dep:eth-types"]
# zkevm = ["dep:zkevm-circuits", "dep:bus-mapping", "dep:mock", "dep:eth-types"]

[[bench]]
name = "standard_plonk"
Expand All @@ -69,3 +66,12 @@ harness = false
name = "zkevm_plus_state"
required-features = ["loader_halo2", "loader_evm", "zkevm", "halo2-pse"]
harness = false

[[bench]]
name = "read_pk"
required-features = ["loader_halo2"]
harness = false

[[example]]
name = "standard_plonk"
required-features = ["loader_halo2", "loader_evm"]
223 changes: 223 additions & 0 deletions snark-verifier-sdk/benches/read_pk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
use ark_std::{end_timer, start_timer};
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};
use halo2_base::gates::circuit::CircuitBuilderStage;
use halo2_base::halo2_proofs;
use halo2_base::utils::fs::gen_srs;
use halo2_proofs::halo2curves as halo2_curves;
use halo2_proofs::{halo2curves::bn256::Bn256, poly::kzg::commitment::ParamsKZG};
use pprof::criterion::{Output, PProfProfiler};
use rand::rngs::OsRng;

use snark_verifier_sdk::halo2::aggregation::{AggregationConfigParams, VerifierUniversality};
use snark_verifier_sdk::{
gen_pk,
halo2::{aggregation::AggregationCircuit, gen_snark_shplonk},
Snark,
};
use snark_verifier_sdk::{read_pk_with_capacity, SHPLONK};
use std::path::Path;

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 rand::RngCore;
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, Default)]
pub struct StandardPlonk(Fr);

impl StandardPlonk {
pub fn rand<R: RngCore>(mut rng: R) -> Self {
Self(Fr::from(rng.next_u32() as u64))
}
}

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::default()
}

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| {
#[cfg(feature = "halo2-pse")]
{
region.assign_advice(|| "", config.a, 0, || Value::known(self.0))?;
region.assign_fixed(|| "", config.q_a, 0, || Value::known(-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,
|| Value::known(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)?;
}
#[cfg(feature = "halo2-axiom")]
{
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);
}

Ok(())
},
)
}
}
}

fn gen_application_snark(params: &ParamsKZG<Bn256>) -> Snark {
let circuit = application::StandardPlonk::rand(OsRng);

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

fn bench(c: &mut Criterion) {
let path = "./configs/example_evm_accumulator.json";
let params_app = gen_srs(8);

let snarks = [(); 3].map(|_| gen_application_snark(&params_app));
let agg_config = AggregationConfigParams::from_path(path);
let params = gen_srs(agg_config.degree);

let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
agg_config,
&params,
snarks,
VerifierUniversality::None,
);

std::fs::remove_file("examples/agg.pk").ok();
let start0 = start_timer!(|| "gen vk & pk");
gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
end_timer!(start0);

let mut group = c.benchmark_group("read-pk");
group.sample_size(10);
group.bench_with_input("buffer 1mb capacity", &(1024 * 1024), |b, &c| {
b.iter(|| read_pk_with_capacity::<AggregationCircuit>(c, "examples/agg.pk", agg_config))
});
group.bench_with_input("buffer 10mb capacity", &(10 * 1024 * 1024), |b, &c| {
b.iter(|| read_pk_with_capacity::<AggregationCircuit>(c, "examples/agg.pk", agg_config))
});
group.bench_with_input("buffer 100mb capacity", &(100 * 1024 * 1024), |b, &c| {
b.iter(|| read_pk_with_capacity::<AggregationCircuit>(c, "examples/agg.pk", agg_config))
});
group.bench_with_input("buffer 1gb capacity", &(1024 * 1024 * 1024), |b, &c| {
b.iter(|| read_pk_with_capacity::<AggregationCircuit>(c, "examples/agg.pk", agg_config))
});
group.finish();
std::fs::remove_file("examples/agg.pk").unwrap();
}

criterion_group! {
name = benches;
config = Criterion::default().with_profiler(PProfProfiler::new(10, Output::Flamegraph(None)));
targets = bench
}
criterion_main!(benches);
Loading

0 comments on commit 7011e8c

Please sign in to comment.