Skip to content

Commit

Permalink
Release v0.1.7 (#42)
Browse files Browse the repository at this point in the history
- #37

Note on commit history:
#37 was merged first
into this branch at
c7d7a8f,
then some changes were made to `release-0.1.6-rc0`, so I rebased
`release-0.1.6-rc0` onto this branch and force pushed.

Utilities to generate dummy snarks to help with proving key generation
of aggregation circuits:
* #48
* #49

Merge after:
- [x] v0.1.6 merged to main
- [x] halo2-lib v0.4.1 merged to main
  • Loading branch information
jonathanpwang authored Jan 18, 2024
2 parents 229ceab + 6b47987 commit 8effca5
Show file tree
Hide file tree
Showing 12 changed files with 498 additions and 154 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name: CI
name: Release

on:
pull_request:
branches:
- ["main", "release-*"]
branches: ["main", "release-*"]
push:
branches:
- main
branches: ["main"]

jobs:
test:
Expand Down
31 changes: 19 additions & 12 deletions Cargo.lock

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

20 changes: 6 additions & 14 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.6"
version = "0.1.7"
authors = ["Privacy Scaling Explorations Team", "Intrinsic Technologies"]
license = "MIT"
edition = "2021"
Expand All @@ -24,15 +24,13 @@ serde_json = "1.0"
serde_with = { version = "2.2", optional = true }
bincode = "1.3.3"
ark-std = { version = "0.3.0", features = ["print-trace"], optional = true }
halo2-base = { version = "=0.4.0", default-features = false }
# halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib.git", branch = "release-0.4.0-rc", default-features = false }
snark-verifier = { version = "=0.1.6", path = "../snark-verifier", default-features = false }
halo2-base = { version = "=0.4.1", default-features = false }
#halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib.git", branch = "main", default-features = false }
snark-verifier = { version = "=0.1.7", 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 }
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 = [
Expand All @@ -53,13 +51,7 @@ crossterm = { version = "0.25" }
ratatui = { version = "0.24", default-features = false, features = ["crossterm"] }

[features]
default = [
"loader_halo2",
"loader_evm",
"halo2-axiom",
"halo2-base/jemallocator",
"display",
]
default = ["loader_halo2", "loader_evm", "halo2-axiom", "halo2-base/jemallocator", "display"]
display = ["snark-verifier/display", "dep:ark-std"]
loader_halo2 = ["snark-verifier/loader_halo2"]
loader_evm = ["snark-verifier/loader_evm", "dep:ethereum-types"]
Expand Down
27 changes: 21 additions & 6 deletions snark-verifier-sdk/examples/range_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use snark_verifier_sdk::{
Snark,
};

fn generate_circuit(k: u32) -> Snark {
fn generate_circuit(k: u32, fill: bool) -> Snark {
let lookup_bits = k as usize - 1;
let circuit_params = BaseCircuitParams {
k: k as usize,
Expand All @@ -30,20 +30,31 @@ fn generate_circuit(k: u32) -> Snark {
let ctx = builder.main(0);

let x = ctx.load_witness(Fr::from(14));
range.range_check(ctx, x, 2 * lookup_bits + 1);
range.gate().add(ctx, x, x);
if fill {
for _ in 0..2 << k {
range.gate().add(ctx, x, x);
}
}

let params = gen_srs(k);
// do not call calculate_params, we want to use fixed params
let pk = gen_pk(&params, &builder, None);
// std::fs::remove_file(Path::new("examples/app.pk")).ok();
// let _pk = gen_pk(&params, &builder, Some(Path::new("examples/app.pk")));
// let pk = read_pk::<BaseCircuitBuilder<_>>(
// Path::new("examples/app.pk"),
// builder.config_params.clone(),
// )
// .unwrap();
// std::fs::remove_file(Path::new("examples/app.pk")).ok();
// builder now has break_point set
gen_snark_shplonk(&params, &pk, builder, None::<&str>)
}

fn main() {
let dummy_snark = generate_circuit(9);
let dummy_snark = generate_circuit(9, false);

let k = 14u32;
let k = 16u32;
let lookup_bits = k as usize - 1;
let params = gen_srs(k);
let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
Expand All @@ -57,10 +68,14 @@ fn main() {

let start0 = start_timer!(|| "gen vk & pk");
let pk = gen_pk(&params, &agg_circuit, None);
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
let break_points = agg_circuit.break_points();

let snarks = (10..16).map(generate_circuit).collect_vec();
let snarks = (10..16).map(|k| generate_circuit(k, true)).collect_vec();
for (i, snark) in snarks.into_iter().enumerate() {
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
Expand Down
111 changes: 88 additions & 23 deletions snark-verifier-sdk/src/halo2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use snark_verifier::{
system::halo2::{compile, Config},
util::arithmetic::Rotation,
util::transcript::TranscriptWrite,
verifier::plonk::PlonkProof,
verifier::plonk::{PlonkProof, PlonkProtocol},
};
use std::{
fs::{self, File},
Expand All @@ -46,6 +46,7 @@ use std::{
};

pub mod aggregation;
pub mod utils;

// Poseidon parameters
// We use the same ones Scroll uses for security: https://github.com/scroll-tech/poseidon-circuit/blob/714f50c7572a4ff6f2b1fa51a9604a99cd7b6c71/src/poseidon/primitives/bn256/fp.rs
Expand Down Expand Up @@ -274,38 +275,67 @@ pub fn read_snark(path: impl AsRef<Path>) -> Result<Snark, bincode::Error> {
bincode::deserialize_from(f)
}

pub trait NativeKzgAccumulationScheme = PolynomialCommitmentScheme<
G1Affine,
NativeLoader,
VerifyingKey = KzgSuccinctVerifyingKey<G1Affine>,
Output = KzgAccumulator<G1Affine, NativeLoader>,
> + AccumulationScheme<
G1Affine,
NativeLoader,
Accumulator = KzgAccumulator<G1Affine, NativeLoader>,
VerifyingKey = KzgAsVerifyingKey,
> + CostEstimation<G1Affine, Input = Vec<Query<Rotation>>>;

// copied from snark_verifier --example recursion
pub fn gen_dummy_snark<ConcreteCircuit, AS>(
params: &ParamsKZG<Bn256>,
vk: Option<&VerifyingKey<G1Affine>>,
num_instance: Vec<usize>,
circuit_params: ConcreteCircuit::Params,
) -> Snark
where
ConcreteCircuit: CircuitExt<Fr>,
AS: PolynomialCommitmentScheme<
G1Affine,
NativeLoader,
VerifyingKey = KzgSuccinctVerifyingKey<G1Affine>,
Output = KzgAccumulator<G1Affine, NativeLoader>,
> + AccumulationScheme<
G1Affine,
NativeLoader,
Accumulator = KzgAccumulator<G1Affine, NativeLoader>,
VerifyingKey = KzgAsVerifyingKey,
> + CostEstimation<G1Affine, Input = Vec<Query<Rotation>>>,
ConcreteCircuit::Params: Clone,
AS: NativeKzgAccumulationScheme,
{
struct CsProxy<F, C>(PhantomData<(F, C)>);
#[derive(Clone)]
struct CsProxy<F: Field, C: Circuit<F>> {
params: C::Params,
_marker: PhantomData<F>,
}

impl<F: Field, C: CircuitExt<F>> Circuit<F> for CsProxy<F, C> {
impl<F: Field, C: Circuit<F>> CsProxy<F, C> {
pub fn new(params: C::Params) -> Self {
Self { params, _marker: PhantomData }
}
}

impl<F: Field, C: CircuitExt<F>> Circuit<F> for CsProxy<F, C>
where
C::Params: Clone,
{
type Config = C::Config;
type FloorPlanner = C::FloorPlanner;
type Params = C::Params;

fn without_witnesses(&self) -> Self {
CsProxy(PhantomData)
Self::new(self.params.clone())
}

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
C::configure(meta)
fn params(&self) -> Self::Params {
self.params.clone()
}

fn configure_with_params(
meta: &mut ConstraintSystem<F>,
params: Self::Params,
) -> Self::Config {
C::configure_with_params(meta, params)
}

fn configure(_: &mut ConstraintSystem<F>) -> Self::Config {
unreachable!("must use configure_with_params")
}

fn synthesize(
Expand All @@ -330,15 +360,50 @@ where

let dummy_vk = vk
.is_none()
.then(|| keygen_vk(params, &CsProxy::<Fr, ConcreteCircuit>(PhantomData)).unwrap());
let protocol = compile(
.then(|| keygen_vk(params, &CsProxy::<Fr, ConcreteCircuit>::new(circuit_params)).unwrap());

gen_dummy_snark_from_vk::<AS>(
params,
vk.or(dummy_vk.as_ref()).unwrap(),
Config::kzg()
.with_num_instance(num_instance.clone())
.with_accumulator_indices(ConcreteCircuit::accumulator_indices()),
num_instance,
ConcreteCircuit::accumulator_indices(),
)
}

/// Creates a dummy snark in the correct shape corresponding to the given verifying key.
/// This dummy snark will **not** verify.
/// This snark can be used as a placeholder input into an aggregation circuit expecting a snark
/// with this verifying key.
///
/// Note that this function does not need to know the concrete `Circuit` type.
pub fn gen_dummy_snark_from_vk<AS>(
params: &ParamsKZG<Bn256>,
vk: &VerifyingKey<G1Affine>,
num_instance: Vec<usize>,
accumulator_indices: Option<Vec<(usize, usize)>>,
) -> Snark
where
AS: NativeKzgAccumulationScheme,
{
let protocol = compile(
params,
vk,
Config::kzg().with_num_instance(num_instance).with_accumulator_indices(accumulator_indices),
);
let instances = num_instance.into_iter().map(|n| vec![Fr::default(); n]).collect();
gen_dummy_snark_from_protocol::<AS>(protocol)
}

/// Creates a dummy snark in the correct shape corresponding to the given Plonk protocol.
/// This dummy snark will **not** verify.
/// This snark can be used as a placeholder input into an aggregation circuit expecting a snark
/// with this protocol.
///
/// Note that this function does not need to know the concrete `Circuit` type.
pub fn gen_dummy_snark_from_protocol<AS>(protocol: PlonkProtocol<G1Affine>) -> Snark
where
AS: NativeKzgAccumulationScheme,
{
let instances = protocol.num_instance.iter().map(|&n| vec![Fr::default(); n]).collect();
let proof = {
let mut transcript = PoseidonTranscript::<NativeLoader, _>::new::<SECURE_MDS>(Vec::new());
for _ in 0..protocol
Expand Down
Loading

0 comments on commit 8effca5

Please sign in to comment.