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

Commit f339984

Browse files
committed
clean up + refactor
1 parent f9d59f2 commit f339984

File tree

7 files changed

+115
-83
lines changed

7 files changed

+115
-83
lines changed

aggregator/src/aggregation.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,43 @@ pub(crate) use rlc::{RlcConfig, POWS_OF_256};
1919

2020
pub use circuit::BatchCircuit;
2121
pub use config::BatchCircuitConfig;
22+
use halo2_base::halo2_proofs::halo2curves::bn256::{Fr, G1Affine};
23+
use snark_verifier::Protocol;
24+
25+
/// Alias for a list of G1 points.
26+
pub type PreprocessedPolyCommits = Vec<G1Affine>;
27+
/// Alias for the transcript's initial state.
28+
pub type TranscriptInitState = Fr;
29+
30+
/// Alias for the fixed part of the protocol which consists of the commitments to the preprocessed
31+
/// polynomials and the initial state of the transcript.
32+
#[derive(Clone)]
33+
pub struct FixedProtocol {
34+
/// The commitments to the preprocessed polynomials.
35+
pub preprocessed: PreprocessedPolyCommits,
36+
/// The initial state of the transcript.
37+
pub init_state: TranscriptInitState,
38+
}
39+
40+
impl From<Protocol<G1Affine>> for FixedProtocol {
41+
fn from(protocol: Protocol<G1Affine>) -> Self {
42+
Self {
43+
preprocessed: protocol.preprocessed,
44+
init_state: protocol
45+
.transcript_initial_state
46+
.expect("protocol transcript init state None"),
47+
}
48+
}
49+
}
50+
51+
impl From<&Protocol<G1Affine>> for FixedProtocol {
52+
fn from(protocol: &Protocol<G1Affine>) -> Self {
53+
Self {
54+
preprocessed: protocol.preprocessed.clone(),
55+
init_state: protocol
56+
.transcript_initial_state
57+
.clone()
58+
.expect("protocol transcript init state None"),
59+
}
60+
}
61+
}

aggregator/src/aggregation/circuit.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use snark_verifier::{
1515
fields::{fp::FpConfig, FieldChip},
1616
halo2_base::{
1717
gates::{GateInstructions, RangeInstructions},
18-
utils::fe_to_biguint,
1918
AssignedValue, Context, ContextParams,
2019
QuantumCell::Existing,
2120
},
@@ -34,12 +33,12 @@ use crate::{
3433
aggregation::{decoder::WORKED_EXAMPLE, witgen::process, BatchCircuitConfig, BatchData},
3534
batch::BatchHash,
3635
blob_consistency::BlobConsistencyConfig,
37-
constants::{ACC_LEN, DIGEST_LEN, FIXED_PROTOCOL_HALO2, FIXED_PROTOCOL_SP1},
36+
constants::{ACC_LEN, DIGEST_LEN},
3837
core::{assign_batch_hashes, extract_proof_and_instances_with_pairing_check},
3938
util::parse_hash_digest_cells,
4039
witgen::{zstd_encode, MultiBlockProcessResult},
41-
ConfigParams, LOG_DEGREE, PI_CHAIN_ID, PI_CURRENT_BATCH_HASH, PI_CURRENT_STATE_ROOT,
42-
PI_CURRENT_WITHDRAW_ROOT, PI_PARENT_BATCH_HASH, PI_PARENT_STATE_ROOT,
40+
ConfigParams, FixedProtocol, LOG_DEGREE, PI_CHAIN_ID, PI_CURRENT_BATCH_HASH,
41+
PI_CURRENT_STATE_ROOT, PI_CURRENT_WITHDRAW_ROOT, PI_PARENT_BATCH_HASH, PI_PARENT_STATE_ROOT,
4342
};
4443

4544
/// Batch circuit, the chunk aggregation routine below recursion circuit
@@ -63,14 +62,21 @@ pub struct BatchCircuit<const N_SNARKS: usize> {
6362
// batch hash circuit for which the snarks are generated
6463
// the chunks in this batch are also padded already
6564
pub batch_hash: BatchHash<N_SNARKS>,
65+
66+
/// The SNARK protocol from the halo2-based inner circuit route.
67+
pub halo2_protocol: FixedProtocol,
68+
/// The SNARK protocol from the sp1-based inner circuit route.
69+
pub sp1_protocol: FixedProtocol,
6670
}
6771

6872
impl<const N_SNARKS: usize> BatchCircuit<N_SNARKS> {
69-
pub fn new(
73+
pub fn new<P: Into<FixedProtocol>>(
7074
params: &ParamsKZG<Bn256>,
7175
snarks_with_padding: &[Snark],
7276
rng: impl Rng + Send,
7377
batch_hash: BatchHash<N_SNARKS>,
78+
halo2_protocol: P,
79+
sp1_protocol: P,
7480
) -> Result<Self, snark_verifier::Error> {
7581
let timer = start_timer!(|| "generate aggregation circuit");
7682

@@ -128,6 +134,8 @@ impl<const N_SNARKS: usize> BatchCircuit<N_SNARKS> {
128134
flattened_instances,
129135
as_proof: Value::known(as_proof),
130136
batch_hash,
137+
halo2_protocol: halo2_protocol.into(),
138+
sp1_protocol: sp1_protocol.into(),
131139
})
132140
}
133141

@@ -252,9 +260,7 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
252260
log::trace!("{}-th instance: {:?}", i, e.value)
253261
}
254262

255-
loader
256-
.ctx_mut()
257-
.print_stats(&["snark aggregation"]);
263+
loader.ctx_mut().print_stats(&["snark aggregation"]);
258264

259265
let mut ctx = Rc::into_inner(loader).unwrap().into_ctx();
260266

@@ -266,11 +272,8 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
266272
log::info!("populating constants");
267273
let mut preprocessed_polys_halo2 = Vec::with_capacity(7);
268274
let mut preprocessed_polys_sp1 = Vec::with_capacity(7);
269-
let (fixed_preprocessed_polys_halo2, fixed_transcript_init_state_halo2) =
270-
FIXED_PROTOCOL_HALO2.clone();
271-
let (fixed_preprocessed_polys_sp1, fixed_transcript_init_state_sp1) =
272-
FIXED_PROTOCOL_SP1.clone();
273-
for (i, &preprocessed_poly) in fixed_preprocessed_polys_halo2.iter().enumerate()
275+
for (i, &preprocessed_poly) in
276+
self.halo2_protocol.preprocessed.iter().enumerate()
274277
{
275278
log::debug!("load const {i}");
276279
preprocessed_polys_halo2.push(
@@ -280,7 +283,8 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
280283
);
281284
log::debug!("load const {i} OK");
282285
}
283-
for (i, &preprocessed_poly) in fixed_preprocessed_polys_sp1.iter().enumerate() {
286+
for (i, &preprocessed_poly) in self.sp1_protocol.preprocessed.iter().enumerate()
287+
{
284288
log::debug!("load const (sp1) {i}");
285289
preprocessed_polys_sp1.push(
286290
config
@@ -294,15 +298,15 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
294298
.field_chip()
295299
.range()
296300
.gate()
297-
.assign_constant(&mut ctx, fixed_transcript_init_state_halo2)
301+
.assign_constant(&mut ctx, self.halo2_protocol.init_state)
298302
.expect("IntegerInstructions::assign_constant infallible");
299303
log::debug!("load transcript OK");
300304
let transcript_init_state_sp1 = config
301305
.ecc_chip()
302306
.field_chip()
303307
.range()
304308
.gate()
305-
.assign_constant(&mut ctx, fixed_transcript_init_state_sp1)
309+
.assign_constant(&mut ctx, self.sp1_protocol.init_state)
306310
.expect("IntegerInstructions::assign_constant infallible");
307311
log::info!("populating constants OK");
308312

aggregator/src/constants.rs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use halo2_proofs::halo2curves::bn256::{Fr, G1Affine};
2-
use std::sync::LazyLock;
3-
41
// A chain_id is u64 and uses 8 bytes
52
pub(crate) const CHAIN_ID_LEN: usize = 8;
63

@@ -91,61 +88,3 @@ pub const MAX_AGG_SNARKS: usize = 45;
9188

9289
// Number of bytes in a u256.
9390
pub const N_BYTES_U256: usize = 32;
94-
95-
/// Alias for a list of G1 points.
96-
type PreprocessedPolyCommits = Vec<G1Affine>;
97-
/// Alias for the transcript's initial state.
98-
type TranscriptInitState = Fr;
99-
/// Alias for the fixed part of the protocol which consists of the commitments to the preprocessed
100-
/// polynomials and the initial state of the transcript.
101-
type FixedProtocol = (PreprocessedPolyCommits, TranscriptInitState);
102-
103-
/// The [`Batch Circuit`] supports aggregation of up to [`MAX_AGG_SNARKS`] SNARKs, where either
104-
/// SNARK is of 2 kinds, namely:
105-
///
106-
/// 1. halo2-based [`SuperCircuit`] -> [`CompressionCircuit`] (wide) -> `CompressionCircuit` (thin)
107-
/// 2. sp1-based STARK -> halo2-based backend -> `CompressionCircuit` (thin)
108-
///
109-
/// For each SNARK witness provided for aggregation, we require that the commitments to the
110-
/// preprocessed polynomials and the transcript's initial state belong to a fixed set, one
111-
/// belonging to each of the above SNARK kinds.
112-
///
113-
/// Represents the fixed commitments to the preprocessed polynomials and the initial state of the
114-
/// transcript for [`ChunkKind::Halo2`].
115-
pub static FIXED_PROTOCOL_HALO2: LazyLock<FixedProtocol> = LazyLock::new(|| {
116-
let name =
117-
std::env::var("HALO2_CHUNK_PROTOCOL").unwrap_or("chunk_chunk_halo2.protocol".to_string());
118-
let dir =
119-
std::env::var("SCROLL_PROVER_ASSETS_DIR").unwrap_or("./tests/test_assets".to_string());
120-
let path = std::path::Path::new(&dir).join(name);
121-
let file = std::fs::File::open(&path).expect("could not open file");
122-
let reader = std::io::BufReader::new(file);
123-
let protocol: snark_verifier::Protocol<G1Affine> =
124-
serde_json::from_reader(reader).expect("could not deserialise protocol");
125-
(
126-
protocol.preprocessed,
127-
protocol
128-
.transcript_initial_state
129-
.expect("transcript initial state is None"),
130-
)
131-
});
132-
133-
/// Represents the fixed commitments to the preprocessed polynomials and the initial state of the
134-
/// transcript for [`ChunkKind::Sp1`].
135-
pub static FIXED_PROTOCOL_SP1: LazyLock<FixedProtocol> = LazyLock::new(|| {
136-
let name =
137-
std::env::var("SP1_CHUNK_PROTOCOL").unwrap_or("chunk_chunk_sp1.protocol".to_string());
138-
let dir =
139-
std::env::var("SCROLL_PROVER_ASSETS_DIR").unwrap_or("./tests/test_assets".to_string());
140-
let path = std::path::Path::new(&dir).join(name);
141-
let file = std::fs::File::open(&path).expect("could not open file");
142-
let reader = std::io::BufReader::new(file);
143-
let protocol: snark_verifier::Protocol<G1Affine> =
144-
serde_json::from_reader(reader).expect("could not deserialise protocol");
145-
(
146-
protocol.preprocessed,
147-
protocol
148-
.transcript_initial_state
149-
.expect("transcript initial state is None"),
150-
)
151-
});

aggregator/src/tests/aggregation.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ fn build_new_batch_circuit<const N_SNARKS: usize>(
209209
})
210210
.collect_vec()
211211
};
212+
let snark_protocol = real_snarks[0].protocol.clone();
212213

213214
// ==========================
214215
// padded chunks
@@ -225,6 +226,8 @@ fn build_new_batch_circuit<const N_SNARKS: usize>(
225226
[real_snarks, padded_snarks].concat().as_ref(),
226227
rng,
227228
batch_hash,
229+
&snark_protocol,
230+
&snark_protocol,
228231
)
229232
.unwrap()
230233
}
@@ -293,6 +296,8 @@ fn build_batch_circuit_skip_encoding<const N_SNARKS: usize>() -> BatchCircuit<N_
293296
})
294297
.collect_vec()
295298
};
299+
let snark_protocol = real_snarks[0].protocol.clone();
300+
296301
// ==========================
297302
// padded chunks
298303
// ==========================
@@ -302,6 +307,8 @@ fn build_batch_circuit_skip_encoding<const N_SNARKS: usize>() -> BatchCircuit<N_
302307
[real_snarks, padded_snarks].concat().as_ref(),
303308
rng,
304309
batch_hash,
310+
&snark_protocol,
311+
&snark_protocol,
305312
)
306313
.unwrap()
307314
}

prover/src/aggregator/prover.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ impl<'params> Prover<'params> {
228228
LayerId::Layer3.id(),
229229
LayerId::Layer3.degree(),
230230
batch_info,
231+
&self.halo2_protocol,
232+
&self.sp1_protocol,
231233
&layer2_snarks,
232234
output_dir,
233235
)?;

prover/src/common/prover/aggregation.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
};
77
use aggregator::{BatchCircuit, BatchHash};
88
use anyhow::{anyhow, Result};
9+
use halo2_proofs::halo2curves::bn256::G1Affine;
910
use rand::Rng;
1011
use snark_verifier_sdk::Snark;
1112
use std::env;
@@ -17,13 +18,26 @@ impl<'params> Prover<'params> {
1718
degree: u32,
1819
mut rng: impl Rng + Send,
1920
batch_info: BatchHash<N_SNARKS>,
21+
halo2_protocol: &[u8],
22+
sp1_protocol: &[u8],
2023
previous_snarks: &[Snark],
2124
) -> Result<Snark> {
2225
env::set_var("AGGREGATION_CONFIG", layer_config_path(id));
2326

24-
let circuit: BatchCircuit<N_SNARKS> =
25-
BatchCircuit::new(self.params(degree), previous_snarks, &mut rng, batch_info)
26-
.map_err(|err| anyhow!("Failed to construct aggregation circuit: {err:?}"))?;
27+
let halo2_protocol =
28+
serde_json::from_slice::<snark_verifier::Protocol<G1Affine>>(halo2_protocol)?;
29+
let sp1_protocol =
30+
serde_json::from_slice::<snark_verifier::Protocol<G1Affine>>(sp1_protocol)?;
31+
32+
let circuit: BatchCircuit<N_SNARKS> = BatchCircuit::new(
33+
self.params(degree),
34+
previous_snarks,
35+
&mut rng,
36+
batch_info,
37+
halo2_protocol,
38+
sp1_protocol,
39+
)
40+
.map_err(|err| anyhow!("Failed to construct aggregation circuit: {err:?}"))?;
2741

2842
self.gen_snark(id, degree, &mut rng, circuit, "gen_agg_snark")
2943
}
@@ -34,6 +48,8 @@ impl<'params> Prover<'params> {
3448
id: &str,
3549
degree: u32,
3650
batch_info: BatchHash<N_SNARKS>,
51+
halo2_protocol: &[u8],
52+
sp1_protocol: &[u8],
3753
previous_snarks: &[Snark],
3854
output_dir: Option<&str>,
3955
) -> Result<Snark> {
@@ -48,7 +64,15 @@ impl<'params> Prover<'params> {
4864
Some(snark) => Ok(snark),
4965
None => {
5066
let rng = gen_rng();
51-
let result = self.gen_agg_snark(id, degree, rng, batch_info, previous_snarks);
67+
let result = self.gen_agg_snark(
68+
id,
69+
degree,
70+
rng,
71+
batch_info,
72+
halo2_protocol,
73+
sp1_protocol,
74+
previous_snarks,
75+
);
5276
if let (Some(_), Ok(snark)) = (output_dir, &result) {
5377
write_snark(&file_path, snark);
5478
}

prover/src/consts.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,24 @@ pub fn chunk_vk_filename() -> String {
1313
read_env_var("CHUNK_VK_FILENAME", "vk_chunk.vkey".to_string())
1414
}
1515

16-
pub static CHUNK_PROTOCOL_FILENAME: LazyLock<String> =
17-
LazyLock::new(|| read_env_var("CHUNK_PROTOCOL_FILENAME", "chunk.protocol".to_string()));
16+
/// The file descriptor for the JSON serialised SNARK [`protocol`][protocol] that
17+
/// defines the [`CompressionCircuit`][compr_circuit] SNARK that uses halo2-based
18+
/// [`SuperCircuit`][super_circuit].
19+
///
20+
/// [protocol]: snark_verifier::Protocol
21+
/// [compr_circuit]: aggregator::CompressionCircuit
22+
/// [super_circuit]: zkevm_circuits::super_circuit::SuperCircuit
23+
pub static FD_HALO2_CHUNK_PROTOCOL: LazyLock<String> =
24+
LazyLock::new(|| read_env_var("HALO2_CHUNK_PROTOCOL", "chunk_halo2.protocol".to_string()));
25+
26+
/// The file descriptor for the JSON serialised SNARK [`protocol`][protocol] that
27+
/// defines the [`CompressionCircuit`][compr_circuit] SNARK that uses sp1-based
28+
/// STARK that is SNARKified using a halo2-backend.
29+
///
30+
/// [protocol]: snark_verifier::Protocol
31+
/// [compr_circuit]: aggregator::CompressionCircuit
32+
pub static FD_SP1_CHUNK_PROTOCOL: LazyLock<String> =
33+
LazyLock::new(|| read_env_var("SP1_CHUNK_PROTOCOL", "chunk_sp1.protocol".to_string()));
1834

1935
pub static CHUNK_VK_FILENAME: LazyLock<String> = LazyLock::new(chunk_vk_filename);
2036
pub static BATCH_VK_FILENAME: LazyLock<String> = LazyLock::new(batch_vk_filename);

0 commit comments

Comments
 (0)