Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Proof aggregation circuit #523

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ebfcc84
impl in the clear
zhenfeizhang May 8, 2023
f85b0ec
implement PI aggregation in circuit
zhenfeizhang May 17, 2023
c5a2e88
fix clippy
zhenfeizhang May 17, 2023
82717c5
clean up
zhenfeizhang May 17, 2023
f4082a2
[fix] supports multiple rounds per hash for PI aggregation circuit
zhenfeizhang May 22, 2023
fd595ef
[chore] fix clippy
zhenfeizhang May 22, 2023
c4cda3f
impl SubCircuit for MultiBatchCircuit
zhenfeizhang May 22, 2023
e76e424
[refactor] pi aggregation circuit
zhenfeizhang May 31, 2023
98fba48
Merge branch 'develop' into pi-aggregation-circuit
zhenfeizhang May 31, 2023
a595c55
[chore] cargo fmt
zhenfeizhang May 31, 2023
19a7110
[feat] implement Aggregator
zhenfeizhang Jun 6, 2023
2f6bc8e
[feat] scripts for tests
zhenfeizhang Jun 6, 2023
4d66cd9
[fix] figure
zhenfeizhang Jun 6, 2023
c0f5b94
[chore] clean up; fix clippy; fix cargo fmt
zhenfeizhang Jun 6, 2023
97f3963
[fix] remove env log for tests
zhenfeizhang Jun 7, 2023
fa582d8
[chore] partial address comments
zhenfeizhang Jun 7, 2023
4f23a96
fix some audit issues (#512)
lispc Jun 6, 2023
afa2c28
[chore] update cargo lock
zhenfeizhang Jun 8, 2023
6defdc5
[chore] partial address comments
zhenfeizhang Jun 8, 2023
3ff1f02
[doc] update readme for aggregator
zhenfeizhang Jun 9, 2023
ceb68e6
[fix] fix test configs and clean up
zhenfeizhang Jun 15, 2023
87ecfa9
[chore] clean up
zhenfeizhang Jun 16, 2023
2394703
[chore] update cargo toml
zhenfeizhang Jun 16, 2023
d822823
cargo fmt
zhenfeizhang Jun 16, 2023
7c49e41
[chore] sync up with halo2-lib dev branch
zhenfeizhang Jun 20, 2023
c3e8207
[chore] update cargo lock
zhenfeizhang Jun 20, 2023
990a2d1
[fix] chain id u32 -> u64
zhenfeizhang Jun 20, 2023
df40b50
[fix] chain id len for tests
zhenfeizhang Jun 20, 2023
a3f4aef
[fix] typo in scripts
zhenfeizhang Jun 21, 2023
723f293
Merge remote-tracking branch 'scroll/develop' into proof-aggregation-…
lispc Jun 21, 2023
a6d627d
lint
lispc Jun 21, 2023
3dbdc4c
a few comments on proof aggregation circuit (#558)
huwenqing0606 Jun 21, 2023
c01fcfe
[feat] parameterize hard coded constants
zhenfeizhang Jun 21, 2023
7eb270f
Merge branch 'develop' into proof-aggregation-circuit
zhenfeizhang Jun 21, 2023
b68e644
[fix] compiling after merge
zhenfeizhang Jun 21, 2023
65912f6
[refactor] remove pi agg circuit; integrated into proof agg circuit
zhenfeizhang Jun 22, 2023
911423c
[fix] chain id to_be_bytes
zhenfeizhang Jun 22, 2023
02b0956
[feat] mock aggregation
zhenfeizhang Jun 22, 2023
2b0d19e
wip
zhenfeizhang Jun 22, 2023
4afe75a
[fix] pi length in agg circuit
zhenfeizhang Jun 23, 2023
a4d5eb9
[refactor] optimize tests
zhenfeizhang Jun 23, 2023
6b124cf
[fix] compiling error
zhenfeizhang Jun 23, 2023
ec604b6
[fix] parameters for tests
zhenfeizhang Jun 23, 2023
a04b1f0
Add a convertion from witness `Block` to `ChunkHash` (#577)
silathdiir Jun 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
.idea
*.log
*.json
*.sh
*.sh
*.txt
*.srs
34 changes: 32 additions & 2 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ members = [
"eth-types",
"external-tracer",
"mock",
"testool"
"testool",
"aggregator"
]

[patch.crates-io]
Expand Down
29 changes: 29 additions & 0 deletions aggregator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "aggregator"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
eth-types = { path = "../eth-types" }
zkevm-circuits = { path = "../zkevm-circuits" }


ark-std = "0.4.0"
env_logger = "0.10.0"
ethers-core = "0.17.0"
log = "0.4"
itertools = "0.10.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = "0.8"

halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02" }
snark-verifier = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop" }
snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop", default-features=false, features = ["loader_halo2", "loader_evm", "halo2-pse"] }


[features]
default = []
print-trace = [ "ark-std/print-trace" ]
59 changes: 59 additions & 0 deletions aggregator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Proof Aggregation
-----

![Architecture](./figures/architecture.png)

This repo does proof aggregations for zkEVM proofs.

## zkEVM circuit
A zkEVM circuits generates a ZK proof for a chunk of blocks. It takes 64 field elements as its public input, consist of
- chunk's data hash digest: each byte is encoded in an Fr element
- chunk's public input hash digest: each byte is encoded in an Fr element
The total size for a public input is 64 bytes, encoded in 64 Fr element

For the ease of testing, this repo implements a `MockCircuit` which hash same public input APIs as a zkEVM circuit.

## First compression circuit
The first compression circuit takes in a fresh snark proof and generates a new (potentially small) snark proof.
The public inputs to the new snark proof consists of
- 12 elements from the accumulators
- an accumulator consists of 2 G1 elements, which are the left and right inputs to the pairing
- this is treated as 4 Fq elements, each decomposed into 3 limbs and encoded in Fr
- 64 elements from previous snark
- re-expose the same public inputs as the original snark

The first compression circuit is configured [wide config file](./configs/compression_wide.config).

## Second compression circuit

The second compression circuit takes in a compressed snark proof and generates a new (potentially small) snark proof.
The public inputs to the new snark proof consists of
- 12 elements from the accumulators
- an accumulator consists of 2 G1 elements, which are the left and right inputs to the pairing
- this is treated as 4 Fq elements, each decomposed into 3 limbs and encoded in Fr
- accumulator from the previous snark is accumulated into the current accumulator
- 64 elements from previous snark
- skipping the first 12 elements which are previous accumulator, as they are already accumulated
- re-expose the rest 64 field elements as the public inputs

The second compression circuit is configured [thin config file](./configs/compression_thin.config).

## Aggregation circuit
An aggregation circuit takes in a batch of `k` proofs, each for a chunk of blocks.
It generates a single proof asserting the validity of all the proofs.

It also performs public input aggregation, i.e., reducing the `64k` public elements into a fixed number of `144` elements:
- 12 elements from accumulators, which accumulates all the previous `k` accumulators from each snark
- 132 elements from the hashes
- first_chunk_prev_state_root: 32 Field elements
- last_chunk_post_state_root: 32 Field elements
- last_chunk_withdraw_root: 32 Field elements
- batch_public_input_hash: 32 Field elements
- chain_id: 8 Field elements

In addition, it attests that, for chunks indexed from `0` to `k-1`,
- batch_data_hash := keccak(chunk_0.data_hash || ... || chunk_k-1.data_hash) where chunk_i.data_hash is a public input to the i-th batch snark circuit
- chunk_pi_hash := keccak(chain_id || prev_state_root || post_state_root || withdraw_root || chunk_data_hash) where chunk_data_hash is a public input to the i-th batch snark circuit
- and the related field matches public input

See [public input aggregation](./src/proof_aggregation/public_input_aggregation.rs) for the details of public input aggregation.
1 change: 1 addition & 0 deletions aggregator/configs/compression_thin.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"strategy":"Simple","degree":26,"num_advice":[1],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember @lispc mentioned that degree 25 would also work?

1 change: 1 addition & 0 deletions aggregator/configs/compression_wide.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"strategy":"Simple","degree":22,"num_advice":[8],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
Binary file added aggregator/figures/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions aggregator/src/aggregation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// Circuit implementation of aggregation circuit.
mod circuit;
/// CircuitExt implementation of compression circuit.
mod circuit_ext;
/// Config for aggregation circuit
mod config;

pub use circuit::AggregationCircuit;
pub use config::AggregationConfig;

// TODO(ZZ): update to the right degree
pub(crate) const LOG_DEGREE: u32 = 19;

// ================================
// indices for hash bytes
// ================================
//
// the preimages are arranged as
// - chain_id: 8 bytes
// - prev_state_root 32 bytes
// - post_state_root 32 bytes
// - withdraw_root 32 bytes
// - chunk_data_hash 32 bytes
//
// A chain_id is u64 and uses 8 bytes
pub(crate) const CHAIN_ID_LEN: usize = 8;
pub(crate) const PREV_STATE_ROOT_INDEX: usize = 8;
pub(crate) const POST_STATE_ROOT_INDEX: usize = 40;
pub(crate) const WITHDRAW_ROOT_INDEX: usize = 72;
pub(crate) const CHUNK_DATA_HASH_INDEX: usize = 104;

// Each round requires (NUM_ROUNDS+1) * DEFAULT_KECCAK_ROWS = 300 rows.
// This library is hard coded for this parameter.
// Modifying the following parameters may result into bugs.
// Adopted from keccak circuit
pub(crate) const DEFAULT_KECCAK_ROWS: usize = 12;
// Adopted from keccak circuit
pub(crate) const NUM_ROUNDS: usize = 24;
Loading