Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 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
c7f7a9f
[refactor] remove aggregation circuit
zhenfeizhang Jun 28, 2023
6679ca5
[fix] clippy
zhenfeizhang Jun 28, 2023
a43ead6
[fix] tests
zhenfeizhang Jun 28, 2023
d08ae38
[fix] address comments
zhenfeizhang Jun 28, 2023
c9b669d
[fix] remove unwrap for non-testing code
zhenfeizhang Jun 28, 2023
fbfcb73
[fix] tests
zhenfeizhang Jun 28, 2023
2f288d5
address comments
zhenfeizhang Jun 29, 2023
b07cbef
[fix] address comments
zhenfeizhang Jul 3, 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
20 changes: 20 additions & 0 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.3.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}
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.
66 changes: 66 additions & 0 deletions aggregator/src/chunk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! This module implements `Chunk` related data types.
//! A chunk is a list of blocks.
use eth_types::H256;
use ethers_core::utils::keccak256;

#[derive(Default, Debug, Clone, Copy)]
/// A chunk is a set of continuous blocks.
/// A ChunkHash consists of 4 hashes, representing the changes incurred by this chunk of blocks:
/// - state root before this chunk
/// - state root after this chunk
/// - the withdraw root of this chunk
/// - the data hash of this chunk
pub struct ChunkHash {
/// Chain identifier
pub(crate) chain_id: u64,
/// state root before this chunk
pub(crate) prev_state_root: H256,
/// state root after this chunk
pub(crate) post_state_root: H256,
/// the withdraw root of this chunk
pub(crate) withdraw_root: H256,
/// the data hash of this chunk
pub(crate) data_hash: H256,
}

impl ChunkHash {
/// Sample a chunk hash from random (for testing)
#[cfg(test)]
pub(crate) fn mock_chunk_hash<R: rand::RngCore>(r: &mut R) -> Self {
let mut prev_state_root = [0u8; 32];
r.fill_bytes(&mut prev_state_root);
let mut post_state_root = [0u8; 32];
r.fill_bytes(&mut post_state_root);
let mut withdraw_root = [0u8; 32];
r.fill_bytes(&mut withdraw_root);
let mut data_hash = [0u8; 32];
r.fill_bytes(&mut data_hash);
Self {
chain_id: 0,
prev_state_root: prev_state_root.into(),
post_state_root: post_state_root.into(),
withdraw_root: withdraw_root.into(),
data_hash: data_hash.into(),
}
}

/// Public input hash for a given chunk is defined as
/// keccak( chain id || prev state root || post state root || withdraw root || data hash )
pub fn public_input_hash(&self) -> H256 {
let preimage = self.extract_hash_preimage();
keccak256::<&[u8]>(preimage.as_ref()).into()
}

/// Extract the preimage for the hash
/// chain id || prev state root || post state root || withdraw root || data hash
pub fn extract_hash_preimage(&self) -> Vec<u8> {
[
self.chain_id.to_be_bytes().as_ref(),
self.prev_state_root.as_bytes(),
self.post_state_root.as_bytes(),
self.withdraw_root.as_bytes(),
self.data_hash.as_bytes(),
]
.concat()
}
}
14 changes: 14 additions & 0 deletions aggregator/src/compression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Input a proof, a compression circuit generates a new proof that may have smaller size.
//!
//! It re-exposes same public inputs from the input snark.
//! All this circuit does is to reduce the proof size.

/// Circuit implementation of compression circuit.
mod circuit;
/// CircuitExt implementation of compression circuit.
mod circuit_ext;
/// Config for compression circuit
mod config;

pub use circuit::CompressionCircuit;
pub use config::CompressionConfig;
Loading