From efa352c7b4afc1cdf0e4f2e1836a3d5857592d4d Mon Sep 17 00:00:00 2001 From: zhenfei Date: Thu, 14 Sep 2023 19:27:27 -0400 Subject: [PATCH 1/8] re-randomize srs --- prover/Cargo.toml | 2 ++ prover/src/utils.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/prover/Cargo.toml b/prover/Cargo.toml index f451efa415..f3be010547 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -29,7 +29,9 @@ log4rs = { version = "1.2.0", default_features = false, features = ["console_app num-bigint = "0.4.3" once_cell = "1.8.0" rand = "0.8" +rand_chacha = "0.3.1" rand_xorshift = "0.3" +rayon = "1.5.1" serde = "1.0" serde_derive = "1.0" serde_json = { version = "1.0.66", features = ["unbounded_depth"] } diff --git a/prover/src/utils.rs b/prover/src/utils.rs index bef28a9f3f..7991c2d537 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -7,7 +7,11 @@ use chrono::Utc; use eth_types::{l2_types::BlockTrace, Address}; use git_version::git_version; use halo2_proofs::{ - halo2curves::bn256::{Bn256, Fr}, + arithmetic::{g_to_lagrange, Field}, + halo2curves::{ + bn256::{Bn256, Fr, G1}, + group::Curve, + }, poly::kzg::commitment::ParamsKZG, SerdeFormat, }; @@ -20,7 +24,9 @@ use log4rs::{ config::{Appender, Config, Root}, }; use rand::{Rng, SeedableRng}; +use rand_chacha::ChaCha20Rng; use rand_xorshift::XorShiftRng; +use rayon::prelude::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::{ fs::{self, metadata, File}, io::{BufReader, Read}, @@ -85,6 +91,30 @@ pub fn load_params( Ok(p) } +pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { + let mut rng = ChaCha20Rng::from_seed(*seed); + let secret = Fr::random(&mut rng); + + // Old g = [G1, [s] G1, [s^2] G1, ..., [s^(n-1)] G1] + // we multiply each g by secret^i + // and the new secret becomes s*secret + let mut powers = vec![Fr::one(), secret]; + for _ in 0..param.n - 2 { + powers.push(secret * powers.last().unwrap()) + } + + let new_g_proj = param + .g + .par_iter() + .zip(powers.par_iter()) + .map(|(gi, power)| gi * power) + .collect::>(); + G1::batch_normalize(&new_g_proj, &mut param.g); + + param.g_lagrange = g_to_lagrange(new_g_proj, param.k); + param.s_g2 = (param.s_g2 * secret).into(); +} + /// get a block-result from file pub fn get_block_trace_from_file>(path: P) -> BlockTrace { let mut buffer = Vec::new(); From 5e367c961273ec85f6db0ee89ab1802c5e373d56 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 11:40:05 -0400 Subject: [PATCH 2/8] add unit tests for nre-randomize param --- prover/Cargo.toml | 1 + prover/src/utils.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/prover/Cargo.toml b/prover/Cargo.toml index f3be010547..2af2ad1aa1 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -15,6 +15,7 @@ zkevm-circuits = { path = "../zkevm-circuits", default-features = false } snark-verifier = { git = "https://github.com/scroll-tech/snark-verifier", tag = "v0.1.5" } snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", tag = "v0.1.5", default-features=false, features = ["loader_halo2", "loader_evm", "halo2-pse"] } +ark-std = "0.4.0" anyhow = "1.0" base64 = "0.13.0" blake2 = "0.10.3" diff --git a/prover/src/utils.rs b/prover/src/utils.rs index 7991c2d537..2441d47828 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -270,3 +270,112 @@ pub fn short_git_version() -> String { commit_version[1..8].to_string() } } +#[cfg(test)] +mod tests { + + use aggregator::RlcConfig; + use ark_std::test_rng; + use halo2_proofs::{ + circuit::*, + halo2curves::bn256::{Bn256, Fr}, + plonk::*, + poly::kzg::commitment::ParamsKZG, + }; + use snark_verifier_sdk::{gen_pk, gen_snark_shplonk, verify_snark_shplonk, CircuitExt}; + use zkevm_circuits::util::Challenges; + + use crate::utils::re_randomize_srs; + + #[derive(Clone, Default)] + struct MyCircuit { + f1: Fr, + f2: Fr, + f3: Fr, + } + + impl Circuit for MyCircuit { + type Config = RlcConfig; + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + Self::default() + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let challenges = Challenges::construct(meta); + RlcConfig::configure(meta, challenges) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let mut first_pass = true; + layouter.assign_region( + || "test field circuit", + |mut region| -> Result<(), Error> { + if first_pass { + first_pass = false; + return Ok(()); + } + + config.init(&mut region)?; + + let mut offset = 0; + + let f1 = config.load_private(&mut region, &self.f1, &mut offset)?; + let f2 = config.load_private(&mut region, &self.f2, &mut offset)?; + let f3 = config.load_private(&mut region, &self.f3, &mut offset)?; + { + let f3_rec = config.add(&mut region, &f1, &f2, &mut offset)?; + region.constrain_equal(f3.cell(), f3_rec.cell())?; + } + + Ok(()) + }, + )?; + Ok(()) + } + } + + impl CircuitExt for MyCircuit { + fn num_instance(&self) -> Vec { + vec![] + } + + fn instances(&self) -> Vec> { + vec![] + } + + fn accumulator_indices() -> Option> { + None + } + + fn selectors(_config: &Self::Config) -> Vec { + vec![] + } + } + + #[test] + fn test_srs_rerandomization() { + let k = 5; + let mut rng = test_rng(); + let mut param = ParamsKZG::::unsafe_setup(k); + re_randomize_srs(&mut param, &[0; 32]); + + let circuit = MyCircuit { + f1: Fr::from(10), + f2: Fr::from(15), + f3: Fr::from(25), + }; + + let pk = gen_pk(¶m, &circuit, None); + let snark = gen_snark_shplonk(¶m, &pk, circuit, &mut rng, None::); + assert!(verify_snark_shplonk::( + ¶m, + snark.clone(), + pk.get_vk() + )); + } +} From fd6afbde0b440a25ee65d95db6889a236b32a377 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 19:26:49 -0400 Subject: [PATCH 3/8] expose rlc apis --- Cargo.lock | 3 +++ aggregator/src/aggregation.rs | 2 +- aggregator/src/aggregation/rlc.rs | 2 +- aggregator/src/aggregation/rlc/config.rs | 2 +- aggregator/src/aggregation/rlc/gates.rs | 7 +++---- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af169f2c63..ab0f8c0afb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3987,6 +3987,7 @@ version = "0.1.0" dependencies = [ "aggregator", "anyhow", + "ark-std 0.4.0", "base64 0.13.1", "blake2", "bus-mapping", @@ -4004,7 +4005,9 @@ dependencies = [ "num-bigint", "once_cell", "rand", + "rand_chacha", "rand_xorshift", + "rayon", "serde", "serde_derive", "serde_json", diff --git a/aggregator/src/aggregation.rs b/aggregator/src/aggregation.rs index 4af10408c1..9401fd7bd3 100644 --- a/aggregator/src/aggregation.rs +++ b/aggregator/src/aggregation.rs @@ -7,4 +7,4 @@ mod rlc; pub use circuit::AggregationCircuit; pub use config::AggregationConfig; -pub(crate) use rlc::RlcConfig; +pub use rlc::RlcConfig; diff --git a/aggregator/src/aggregation/rlc.rs b/aggregator/src/aggregation/rlc.rs index e89a4d31c9..790ca36f2c 100644 --- a/aggregator/src/aggregation/rlc.rs +++ b/aggregator/src/aggregation/rlc.rs @@ -1,4 +1,4 @@ mod config; mod gates; -pub(crate) use config::RlcConfig; +pub use config::RlcConfig; diff --git a/aggregator/src/aggregation/rlc/config.rs b/aggregator/src/aggregation/rlc/config.rs index a5fd32f073..48dafd1f40 100644 --- a/aggregator/src/aggregation/rlc/config.rs +++ b/aggregator/src/aggregation/rlc/config.rs @@ -22,7 +22,7 @@ pub struct RlcConfig { } impl RlcConfig { - pub(crate) fn configure(meta: &mut ConstraintSystem, challenge: Challenges) -> Self { + pub fn configure(meta: &mut ConstraintSystem, challenge: Challenges) -> Self { let selector = meta.complex_selector(); let enable_challenge = meta.complex_selector(); let challenge_expr = challenge.exprs(meta); diff --git a/aggregator/src/aggregation/rlc/gates.rs b/aggregator/src/aggregation/rlc/gates.rs index b302a5e937..1c1149030f 100644 --- a/aggregator/src/aggregation/rlc/gates.rs +++ b/aggregator/src/aggregation/rlc/gates.rs @@ -12,7 +12,7 @@ use super::RlcConfig; impl RlcConfig { /// initialize the chip with fixed cells - pub(crate) fn init(&self, region: &mut Region) -> Result<(), Error> { + pub fn init(&self, region: &mut Region) -> Result<(), Error> { region.assign_fixed(|| "const zero", self.fixed, 0, || Value::known(Fr::zero()))?; region.assign_fixed(|| "const one", self.fixed, 1, || Value::known(Fr::one()))?; region.assign_fixed(|| "const two", self.fixed, 2, || Value::known(Fr::from(2)))?; @@ -115,7 +115,7 @@ impl RlcConfig { } } - pub(crate) fn load_private( + pub fn load_private( &self, region: &mut Region, f: &Fr, @@ -171,8 +171,7 @@ impl RlcConfig { } /// Enforce res = a + b - #[allow(dead_code)] - pub(crate) fn add( + pub fn add( &self, region: &mut Region, a: &AssignedCell, From b988452e21e709f7c6cff3f95d5ea486faf2779c Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 19:30:36 -0400 Subject: [PATCH 4/8] disable default g2 check for randomized srs --- prover/Cargo.toml | 3 ++- prover/src/utils.rs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 2af2ad1aa1..03c80ddcb6 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -40,7 +40,8 @@ serde_stacker = "0.1" sha2 ="0.10.2" [features] -default = [] +default = [ "unrandomized_srs" ] parallel_syn = ["halo2_proofs/parallel_syn", "zkevm-circuits/parallel_syn"] scroll = ["bus-mapping/scroll", "eth-types/scroll", "zkevm-circuits/scroll"] shanghai = ["bus-mapping/shanghai", "eth-types/shanghai", "zkevm-circuits/shanghai"] +unrandomized_srs = [] \ No newline at end of file diff --git a/prover/src/utils.rs b/prover/src/utils.rs index 2441d47828..49ac695ce6 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -41,6 +41,8 @@ pub static LOGGER: Once = Once::new(); pub const DEFAULT_SERDE_FORMAT: SerdeFormat = SerdeFormat::RawBytesUnchecked; pub const GIT_VERSION: &str = git_version!(args = ["--abbrev=7", "--always"]); +// FIXME: update me once the the srs is re-randomized +#[cfg(feature="unrandomized_srs")] pub const PARAMS_G2_SECRET_POWER: &str = "(Fq2 { c0: 0x17944351223333f260ddc3b4af45191b856689eda9eab5cbcddbbe570ce860d2, c1: 0x186282957db913abd99f91db59fe69922e95040603ef44c0bd7aa3adeef8f5ac }, Fq2 { c0: 0x297772d34bc9aa8ae56162486363ffe417b02dc7e8c207fc2cc20203e67a02ad, c1: 0x298adc7396bd3865cbf6d6df91bae406694e6d2215baa893bdeadb63052895f4 })"; /// Load setup params from a file. @@ -83,6 +85,8 @@ pub fn load_params( } let p = ParamsKZG::::read_custom::<_>(&mut BufReader::new(f), serde_fmt)?; + + #[cfg(feature="unrandomized_srs")] if format!("{:?}", p.s_g2()) != PARAMS_G2_SECRET_POWER { bail!("Wrong params file of degree {}", degree); } From 10401dabf226faecbe017f2954323bcf1cf35c96 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 19:31:57 -0400 Subject: [PATCH 5/8] disable default g2 check for randomized srs --- prover/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 03c80ddcb6..e3eb84ce64 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -44,4 +44,5 @@ default = [ "unrandomized_srs" ] parallel_syn = ["halo2_proofs/parallel_syn", "zkevm-circuits/parallel_syn"] scroll = ["bus-mapping/scroll", "eth-types/scroll", "zkevm-circuits/scroll"] shanghai = ["bus-mapping/shanghai", "eth-types/shanghai", "zkevm-circuits/shanghai"] +# todo: remove once srs is randomized and finalized unrandomized_srs = [] \ No newline at end of file From 8ffbbc2437a1dadba1be5763eb590844bef06573 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 19:47:37 -0400 Subject: [PATCH 6/8] verify evm instead of snark --- prover/src/utils.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/prover/src/utils.rs b/prover/src/utils.rs index 49ac695ce6..faded9daa6 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -42,7 +42,7 @@ pub const DEFAULT_SERDE_FORMAT: SerdeFormat = SerdeFormat::RawBytesUnchecked; pub const GIT_VERSION: &str = git_version!(args = ["--abbrev=7", "--always"]); // FIXME: update me once the the srs is re-randomized -#[cfg(feature="unrandomized_srs")] +#[cfg(feature = "unrandomized_srs")] pub const PARAMS_G2_SECRET_POWER: &str = "(Fq2 { c0: 0x17944351223333f260ddc3b4af45191b856689eda9eab5cbcddbbe570ce860d2, c1: 0x186282957db913abd99f91db59fe69922e95040603ef44c0bd7aa3adeef8f5ac }, Fq2 { c0: 0x297772d34bc9aa8ae56162486363ffe417b02dc7e8c207fc2cc20203e67a02ad, c1: 0x298adc7396bd3865cbf6d6df91bae406694e6d2215baa893bdeadb63052895f4 })"; /// Load setup params from a file. @@ -86,7 +86,7 @@ pub fn load_params( let p = ParamsKZG::::read_custom::<_>(&mut BufReader::new(f), serde_fmt)?; - #[cfg(feature="unrandomized_srs")] + #[cfg(feature = "unrandomized_srs")] if format!("{:?}", p.s_g2()) != PARAMS_G2_SECRET_POWER { bail!("Wrong params file of degree {}", degree); } @@ -285,7 +285,9 @@ mod tests { plonk::*, poly::kzg::commitment::ParamsKZG, }; - use snark_verifier_sdk::{gen_pk, gen_snark_shplonk, verify_snark_shplonk, CircuitExt}; + use snark_verifier_sdk::{ + evm_verify, gen_evm_proof_shplonk, gen_evm_verifier_shplonk, gen_pk, CircuitExt, + }; use zkevm_circuits::util::Challenges; use crate::utils::re_randomize_srs; @@ -375,11 +377,14 @@ mod tests { }; let pk = gen_pk(¶m, &circuit, None); - let snark = gen_snark_shplonk(¶m, &pk, circuit, &mut rng, None::); - assert!(verify_snark_shplonk::( + let proof = + gen_evm_proof_shplonk(¶m, &pk, circuit.clone(), circuit.instances(), &mut rng); + let deployment_code = gen_evm_verifier_shplonk::( ¶m, - snark.clone(), - pk.get_vk() - )); + pk.get_vk(), + circuit.num_instance(), + None, + ); + evm_verify(deployment_code, circuit.instances(), proof.clone()); } } From db4769cade49f17f497aec7db95fdd7ef5cfdbf9 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 20:31:28 -0400 Subject: [PATCH 7/8] better parallelization for params --- prover/src/utils.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/prover/src/utils.rs b/prover/src/utils.rs index faded9daa6..2bf08f4b73 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -7,9 +7,9 @@ use chrono::Utc; use eth_types::{l2_types::BlockTrace, Address}; use git_version::git_version; use halo2_proofs::{ - arithmetic::{g_to_lagrange, Field}, + arithmetic::{g_to_lagrange, parallelize, Field}, halo2curves::{ - bn256::{Bn256, Fr, G1}, + bn256::{Bn256, Fr, G1Affine, G1}, group::Curve, }, poly::kzg::commitment::ParamsKZG, @@ -98,7 +98,8 @@ pub fn load_params( pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { let mut rng = ChaCha20Rng::from_seed(*seed); let secret = Fr::random(&mut rng); - + let num_threads = rayon::current_num_threads(); + let chunk_size = param.n as usize / num_threads; // Old g = [G1, [s] G1, [s^2] G1, ..., [s^(n-1)] G1] // we multiply each g by secret^i // and the new secret becomes s*secret @@ -111,9 +112,16 @@ pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { .g .par_iter() .zip(powers.par_iter()) - .map(|(gi, power)| gi * power) + .chunks(chunk_size) + .flat_map_iter(|pair| pair.iter().map(|(g, s)| *g * *s).collect::>()) .collect::>(); - G1::batch_normalize(&new_g_proj, &mut param.g); + param.g = { + let mut g = vec![G1Affine::default(); param.n as usize]; + parallelize(&mut g, |g, starts| { + G1::batch_normalize(&new_g_proj[starts..(starts + g.len())], g); + }); + g + }; param.g_lagrange = g_to_lagrange(new_g_proj, param.k); param.s_g2 = (param.s_g2 * secret).into(); From fb59d6d2c529ead3de9fedfb6b75310c99296ef2 Mon Sep 17 00:00:00 2001 From: zhenfei Date: Mon, 18 Sep 2023 20:34:44 -0400 Subject: [PATCH 8/8] more logs --- prover/src/utils.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/prover/src/utils.rs b/prover/src/utils.rs index 2bf08f4b73..e24ae86b56 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -96,6 +96,7 @@ pub fn load_params( } pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { + log::info!("start re-randomization"); let mut rng = ChaCha20Rng::from_seed(*seed); let secret = Fr::random(&mut rng); let num_threads = rayon::current_num_threads(); @@ -103,11 +104,12 @@ pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { // Old g = [G1, [s] G1, [s^2] G1, ..., [s^(n-1)] G1] // we multiply each g by secret^i // and the new secret becomes s*secret + log::info!("generating new seed"); let mut powers = vec![Fr::one(), secret]; for _ in 0..param.n - 2 { powers.push(secret * powers.last().unwrap()) } - + log::info!("build new params"); let new_g_proj = param .g .par_iter() @@ -115,6 +117,8 @@ pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { .chunks(chunk_size) .flat_map_iter(|pair| pair.iter().map(|(g, s)| *g * *s).collect::>()) .collect::>(); + + log::info!("normalizing new params"); param.g = { let mut g = vec![G1Affine::default(); param.n as usize]; parallelize(&mut g, |g, starts| { @@ -122,9 +126,11 @@ pub fn re_randomize_srs(param: &mut ParamsKZG, seed: &[u8; 32]) { }); g }; - + log::info!("converting to lagrange basis"); param.g_lagrange = g_to_lagrange(new_g_proj, param.k); param.s_g2 = (param.s_g2 * secret).into(); + + log::info!("finished re-randomization"); } /// get a block-result from file