Skip to content

Commit

Permalink
Documentations; subcircuit for aggregation (scroll-tech#13)
Browse files Browse the repository at this point in the history
* wip

* [refactor] refactoring sdk

* [refactor] halo2 api

* [chore] update cargo.toml

* [feat] impl sub-circuit for proof aggregation circuit

* [feat] impl sub circuit for multi aggregation

* [chore] clean up

* [chore] update cargo branch
  • Loading branch information
zhenfeizhang authored Jun 20, 2023
1 parent ae6a9ef commit a8b277a
Show file tree
Hide file tree
Showing 56 changed files with 3,181 additions and 1,303 deletions.
2,053 changes: 1,804 additions & 249 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ inherits = "release"
debug = true

[patch."https://github.com/privacy-scaling-explorations/halo2.git"]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "halo2-ecc-snark-verifier-0323" }
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }
[patch."https://github.com/privacy-scaling-explorations/poseidon.git"]
poseidon = { git = "https://github.com/scroll-tech/poseidon.git", branch = "scroll-dev-0220" }
[patch."https://github.com/privacy-scaling-explorations/halo2wrong.git"]
ecc = { git = "https://github.com/scroll-tech/halo2wrong.git", branch = "halo2-ecc-snark-verifier-0323" }
halo2wrong = { git = "https://github.com/scroll-tech/halo2wrong.git", branch = "halo2-ecc-snark-verifier-0323" }
maingate = { git = "https://github.com/scroll-tech/halo2wrong", branch = "halo2-ecc-snark-verifier-0323" }
[patch."https://github.com/privacy-scaling-explorations/halo2curves.git"]
halo2curves = { git = "https://github.com/scroll-tech/halo2curves.git", branch = "0.3.1-derive-serde" }
2 changes: 1 addition & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
max_width = 100
use_small_heuristics = "Max"
use_small_heuristics = "Max"
6 changes: 3 additions & 3 deletions snark-verifier-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ serde_json = "1.0"
bincode = "1.3.3"
ark-std = { version = "0.3.0", features = ["print-trace"], optional = true }

halo2-base = { git = "https://github.com/scroll-tech/halo2-lib.git", branch = "minimize-diff", default-features=false, features=["halo2-pse","display"] }
halo2-base = { git = "https://github.com/scroll-tech/halo2-lib.git", branch = "develop", default-features=false, features=["halo2-pse","display"] }
snark-verifier = { path = "../snark-verifier", default-features = false }
zkevm-circuits = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" }
eth-types = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "develop" }

# loader_evm
ethereum-types = { version = "0.14", default-features = false, features = ["std"], optional = true }
Expand Down Expand Up @@ -50,8 +52,6 @@ parallel = ["snark-verifier/parallel"]
halo2-pse = ["snark-verifier/halo2-pse"]
halo2-axiom = ["snark-verifier/halo2-axiom"]

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

[[bench]]
name = "standard_plonk"
required-features = ["loader_halo2"]
Expand Down
5 changes: 1 addition & 4 deletions snark-verifier-sdk/benches/standard_plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ use halo2_proofs::{
use rand::rngs::OsRng;
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;
use snark_verifier_sdk::CircuitExt;
use snark_verifier_sdk::{
gen_pk,
halo2::{aggregation::AggregationCircuit, gen_proof_shplonk, gen_snark_shplonk},
Snark,
gen_pk, gen_proof_shplonk, gen_snark_shplonk, AggregationCircuit, CircuitExt, Snark,
};

mod application {
Expand Down
32 changes: 5 additions & 27 deletions snark-verifier-sdk/benches/zkevm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use snark_verifier_sdk::{
gen_evm_verifier_shplonk,
},
gen_pk,
halo2::{
halo2_api::{
aggregation::load_verify_circuit_degree, aggregation::AggregationCircuit, gen_proof_gwc,
gen_proof_shplonk, gen_snark_gwc, gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC,
},
Expand Down Expand Up @@ -66,14 +66,8 @@ fn bench(c: &mut Criterion) {
let circuit = zkevm::test_circuit();
let params_app = gen_srs(k);
let pk = gen_pk(&params_app, &circuit, Some(Path::new("data/zkevm_evm.pkey")));
let snark = gen_snark_gwc(
&params_app,
&pk,
circuit,
&mut transcript,
&mut rng,
Some(Path::new("data/zkevm_evm.snark")),
);
let snark =
gen_snark_gwc(&params_app, &pk, circuit, &mut rng, Some(Path::new("data/zkevm_evm.snark")));
let snarks = [snark];
// === finished zkevm evm circuit ===

Expand All @@ -96,15 +90,7 @@ fn bench(c: &mut Criterion) {
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_shplonk(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
gen_proof_shplonk(params, pk, agg_circuit.clone(), instances, &mut rng, None);
})
},
);
Expand All @@ -118,15 +104,7 @@ fn bench(c: &mut Criterion) {
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_gwc(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
gen_proof_gwc(params, pk, agg_circuit.clone(), instances, &mut rng, None);
})
},
);
Expand Down
24 changes: 3 additions & 21 deletions snark-verifier-sdk/benches/zkevm_plus_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use snark_verifier_sdk::{
gen_evm_verifier_shplonk,
},
gen_pk,
halo2::{
halo2_api::{
aggregation::load_verify_circuit_degree, aggregation::AggregationCircuit, gen_proof_gwc,
gen_proof_shplonk, gen_snark_gwc, gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC,
},
Expand Down Expand Up @@ -80,7 +80,6 @@ fn bench(c: &mut Criterion) {
&params_app,
&pk,
evm_circuit,
&mut transcript,
&mut rng,
Some(Path::new("data/zkevm_evm.snark")),
)
Expand All @@ -91,7 +90,6 @@ fn bench(c: &mut Criterion) {
&params_app,
&pk,
state_circuit,
&mut transcript,
&mut rng,
Some(Path::new("data/zkevm_state.snark")),
)
Expand All @@ -118,15 +116,7 @@ fn bench(c: &mut Criterion) {
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_shplonk(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
gen_proof_shplonk(params, pk, agg_circuit.clone(), instances, &mut rng, None);
})
},
);
Expand All @@ -140,15 +130,7 @@ fn bench(c: &mut Criterion) {
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_gwc(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
gen_proof_gwc(params, pk, agg_circuit.clone(), instances, &mut rng, None);
})
},
);
Expand Down
131 changes: 131 additions & 0 deletions snark-verifier-sdk/src/aggregation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#![allow(clippy::clone_on_copy)]
use crate::{
types::{BaseFieldEccChip, Halo2Loader, Plonk, PoseidonTranscript, POSEIDON_SPEC},
SnarkWitness,
};
#[cfg(feature = "display")]
use ark_std::end_timer;
#[cfg(feature = "display")]
use ark_std::start_timer;
use halo2_base::{
halo2_proofs::{
circuit::Value,
halo2curves::bn256::{Fr, G1Affine},
},
AssignedValue,
};
use itertools::Itertools;
use snark_verifier::{
loader::halo2::EccInstructions,
pcs::{
kzg::{KzgAccumulator, KzgAs},
AccumulationScheme, MultiOpenScheme, PolynomialCommitmentScheme,
},
verifier::PlonkVerifier,
};
use std::{fs::File, rc::Rc};

use config::AggregationConfigParams;

pub mod aggregation_circuit;
pub mod config;
pub mod multi_aggregation_circuit;

pub fn load_verify_circuit_degree() -> u32 {
let path = std::env::var("VERIFY_CONFIG")
.unwrap_or_else(|_| "./configs/verify_circuit.config".to_string());
let params: AggregationConfigParams = serde_json::from_reader(
File::open(path.as_str()).unwrap_or_else(|_| panic!("{path} does not exist")),
)
.unwrap();
params.degree
}

pub fn flatten_accumulator<'a>(
accumulator: KzgAccumulator<G1Affine, Rc<Halo2Loader<'a>>>,
) -> Vec<AssignedValue<Fr>> {
let KzgAccumulator { lhs, rhs } = accumulator;
let lhs = lhs.into_assigned();
let rhs = rhs.into_assigned();

lhs.x
.truncation
.limbs
.into_iter()
.chain(lhs.y.truncation.limbs.into_iter())
.chain(rhs.x.truncation.limbs.into_iter())
.chain(rhs.y.truncation.limbs.into_iter())
.collect()
}

#[allow(clippy::type_complexity)]
/// Core function used in `synthesize` to aggregate multiple `snarks`.
///
/// Returns the assigned instances of previous snarks and the new final pair that needs to be verified in a pairing check.
/// For each previous snark, we concatenate all instances into a single vector. We return a vector of vectors,
/// one vector per snark, for convenience.
pub fn aggregate<'a, PCS>(
svk: &PCS::SuccinctVerifyingKey,
loader: &Rc<Halo2Loader<'a>>,
snarks: &[SnarkWitness],
as_proof: Value<&'_ [u8]>,
) -> (
Vec<Vec<<BaseFieldEccChip as EccInstructions<'a, G1Affine>>::AssignedScalar>>,
KzgAccumulator<G1Affine, Rc<Halo2Loader<'a>>>,
)
where
PCS: PolynomialCommitmentScheme<
G1Affine,
Rc<Halo2Loader<'a>>,
Accumulator = KzgAccumulator<G1Affine, Rc<Halo2Loader<'a>>>,
> + MultiOpenScheme<G1Affine, Rc<Halo2Loader<'a>>>,
{
let assign_instances = |instances: &[Vec<Value<Fr>>]| {
instances
.iter()
.map(|instances| {
instances.iter().map(|instance| loader.assign_scalar(*instance)).collect_vec()
})
.collect_vec()
};

// TODO pre-allocate capacity better
let mut previous_instances = Vec::with_capacity(snarks.len());
let mut transcript = PoseidonTranscript::<Rc<Halo2Loader<'a>>, _>::from_spec(
loader,
Value::unknown(),
POSEIDON_SPEC.clone(),
);

let mut accumulators = snarks
.iter()
.flat_map(|snark| {
let protocol = snark.protocol.loaded(loader);
// TODO use 1d vector
let instances = assign_instances(&snark.instances);

// read the transcript and perform Fiat-Shamir
// run through verification computation and produce the final pair `succinct`
transcript.new_stream(snark.proof());
let proof = Plonk::<PCS>::read_proof(svk, &protocol, &instances, &mut transcript);
let accumulator = Plonk::<PCS>::succinct_verify(svk, &protocol, &instances, &proof);

previous_instances.push(
instances.into_iter().flatten().map(|scalar| scalar.into_assigned()).collect(),
);

accumulator
})
.collect_vec();

let accumulator = if accumulators.len() > 1 {
transcript.new_stream(as_proof);
let proof =
KzgAs::<PCS>::read_proof(&Default::default(), &accumulators, &mut transcript).unwrap();
KzgAs::<PCS>::verify(&Default::default(), &accumulators, &proof).unwrap()
} else {
accumulators.pop().unwrap()
};

(previous_instances, accumulator)
}
Loading

0 comments on commit a8b277a

Please sign in to comment.