diff --git a/common/libzkp/impl/Cargo.lock b/common/libzkp/impl/Cargo.lock index a4ceafdbf8..ac1cf42291 100644 --- a/common/libzkp/impl/Cargo.lock +++ b/common/libzkp/impl/Cargo.lock @@ -39,9 +39,9 @@ dependencies = [ "ctor", "encoder", "env_logger 0.10.0", - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "ethers-core", - "gadgets", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "halo2-base", "halo2-ecc", "halo2_proofs", @@ -59,7 +59,41 @@ dependencies = [ "snark-verifier-sdk", "strum 0.25.0", "strum_macros 0.25.3", - "zkevm-circuits", + "zkevm-circuits 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", +] + +[[package]] +name = "aggregator" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "ark-std 0.3.0", + "bitstream-io", + "c-kzg", + "ctor", + "encoder", + "env_logger 0.10.0", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "ethers-core", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "halo2-base", + "halo2-ecc", + "halo2_proofs", + "hex", + "itertools 0.11.0", + "log", + "num-bigint", + "once_cell", + "rand", + "revm-precompile", + "revm-primitives", + "serde", + "serde_json", + "snark-verifier", + "snark-verifier-sdk", + "strum 0.25.0", + "strum_macros 0.25.3", + "zkevm-circuits 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", ] [[package]] @@ -539,18 +573,18 @@ name = "bus-mapping" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "ethers-core", "ethers-providers", "ethers-signers", - "external-tracer", - "gadgets", + "external-tracer 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "halo2_proofs", "hex", "itertools 0.11.0", "log", - "mock", - "mpt-zktrie", + "mock 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "num", "poseidon-circuit", "rand", @@ -561,6 +595,31 @@ dependencies = [ "strum_macros 0.25.3", ] +[[package]] +name = "bus-mapping" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "ethers-core", + "ethers-providers", + "ethers-signers", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "halo2_proofs", + "hex", + "itertools 0.11.0", + "log", + "mock 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "num", + "poseidon-circuit", + "revm-precompile", + "serde", + "serde_json", + "strum 0.25.0", + "strum_macros 0.25.3", +] + [[package]] name = "byte-slice-cast" version = "1.2.2" @@ -1152,6 +1211,34 @@ dependencies = [ "uint", ] +[[package]] +name = "eth-types" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "base64 0.13.1", + "ethers-core", + "ethers-signers", + "halo2curves", + "hex", + "itertools 0.11.0", + "log", + "num", + "num-bigint", + "poseidon-base", + "regex", + "revm-precompile", + "revm-primitives", + "serde", + "serde_json", + "serde_with", + "sha3 0.10.8", + "strum 0.25.0", + "strum_macros 0.25.3", + "subtle", + "uint", +] + [[package]] name = "ethabi" version = "18.0.0" @@ -1285,8 +1372,21 @@ name = "external-tracer" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "eth-types", - "geth-utils", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "geth-utils 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "log", + "serde", + "serde_json", + "serde_stacker", +] + +[[package]] +name = "external-tracer" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "geth-utils 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "log", "serde", "serde_json", @@ -1467,7 +1567,19 @@ name = "gadgets" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "halo2_proofs", + "poseidon-base", + "sha3 0.10.8", + "strum 0.25.0", +] + +[[package]] +name = "gadgets" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "halo2_proofs", "poseidon-base", "sha3 0.10.8", @@ -1495,6 +1607,16 @@ dependencies = [ "log", ] +[[package]] +name = "geth-utils" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "env_logger 0.10.0", + "gobuild", + "log", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -2239,10 +2361,25 @@ name = "mock" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "ethers-core", "ethers-signers", - "external-tracer", + "external-tracer 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "itertools 0.11.0", + "log", + "rand", + "rand_chacha", +] + +[[package]] +name = "mock" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "ethers-core", + "ethers-signers", + "external-tracer 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "itertools 0.11.0", "log", "rand", @@ -2254,7 +2391,21 @@ name = "mpt-zktrie" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "halo2curves", + "hex", + "log", + "num-bigint", + "poseidon-base", + "zktrie", +] + +[[package]] +name = "mpt-zktrie" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "halo2curves", "hex", "log", @@ -2726,14 +2877,14 @@ name = "prover" version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ - "aggregator", + "aggregator 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "anyhow", "base64 0.13.1", "blake2", - "bus-mapping", + "bus-mapping 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "chrono", "dotenvy", - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "ethers-core", "git-version", "halo2_proofs", @@ -2741,7 +2892,7 @@ dependencies = [ "itertools 0.11.0", "log", "log4rs", - "mpt-zktrie", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", "num-bigint", "rand", "rand_xorshift", @@ -2752,7 +2903,41 @@ dependencies = [ "sha2", "snark-verifier", "snark-verifier-sdk", - "zkevm-circuits", + "zkevm-circuits 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", +] + +[[package]] +name = "prover" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "aggregator 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "anyhow", + "base64 0.13.1", + "blake2", + "bus-mapping 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "chrono", + "dotenvy", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "ethers-core", + "git-version", + "halo2_proofs", + "hex", + "itertools 0.11.0", + "log", + "log4rs", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "num-bigint", + "rand", + "rand_xorshift", + "serde", + "serde_derive", + "serde_json", + "serde_stacker", + "sha2", + "snark-verifier", + "snark-verifier-sdk", + "zkevm-circuits 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", ] [[package]] @@ -4364,14 +4549,56 @@ version = "0.11.0" source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453" dependencies = [ "array-init", - "bus-mapping", + "bus-mapping 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "either", + "env_logger 0.10.0", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "ethers-core", + "ethers-signers", + "ff", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "halo2-base", + "halo2-ecc", + "halo2-mpt-circuits", + "halo2_gadgets", + "halo2_proofs", + "hex", + "itertools 0.11.0", + "log", + "misc-precompiled-circuit", + "mock 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "num", + "num-bigint", + "poseidon-circuit", + "rand", + "rand_chacha", + "rand_xorshift", + "rayon", + "serde", + "serde_json", + "sha3 0.10.8", + "snark-verifier", + "snark-verifier-sdk", + "strum 0.25.0", + "strum_macros 0.25.3", + "subtle", +] + +[[package]] +name = "zkevm-circuits" +version = "0.11.0" +source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#eb19a285031425f81c0a83abf4b20e9a6451e615" +dependencies = [ + "array-init", + "bus-mapping 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "either", "env_logger 0.10.0", - "eth-types", + "eth-types 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "ethers-core", "ethers-signers", "ff", - "gadgets", + "gadgets 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "halo2-base", "halo2-ecc", "halo2-mpt-circuits", @@ -4381,8 +4608,8 @@ dependencies = [ "itertools 0.11.0", "log", "misc-precompiled-circuit", - "mock", - "mpt-zktrie", + "mock 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", + "mpt-zktrie 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "num", "num-bigint", "poseidon-circuit", @@ -4410,7 +4637,8 @@ dependencies = [ "libc", "log", "once_cell", - "prover", + "prover 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4)", + "prover 0.11.0 (git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion)", "serde", "serde_derive", "serde_json", diff --git a/common/libzkp/impl/Cargo.toml b/common/libzkp/impl/Cargo.toml index d12c7a31a6..80e88ec817 100644 --- a/common/libzkp/impl/Cargo.toml +++ b/common/libzkp/impl/Cargo.toml @@ -25,7 +25,11 @@ bls12_381 = { git = "https://github.com/scroll-tech/bls12_381", branch = "feat/i [dependencies] halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "v1.1" } snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop", default-features = false, features = ["loader_halo2", "loader_evm", "halo2-pse"] } -prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.11.4", default-features = false, features = ["parallel_syn", "scroll"] } + +# curie +prover_v3 = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.11.4", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] } +# darwin +prover_v4 = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "feat/agg_recursion", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] } base64 = "0.13.0" env_logger = "0.9.0" diff --git a/common/libzkp/impl/src/batch.rs b/common/libzkp/impl/src/batch.rs index 9d6a8a1199..3c7925471e 100644 --- a/common/libzkp/impl/src/batch.rs +++ b/common/libzkp/impl/src/batch.rs @@ -6,18 +6,20 @@ use crate::{ }, }; use libc::c_char; -use prover::{ - aggregator::{Prover, Verifier}, +use prover_v3::BatchProof as BatchProofV3; +use prover_v4::{ + aggregator::{Prover, Verifier as VerifierV4}, check_chunk_hashes, - consts::AGG_VK_FILENAME, + consts::BATCH_VK_FILENAME, utils::{chunk_trace_to_witness_block, init_env_and_log}, - BatchProof, BatchProvingTask, BlockTrace, ChunkInfo, ChunkProof, + BatchHeader, BatchProof as BatchProofV4, BatchProvingTask, BlockTrace, BundleProof, + BundleProvingTask, ChunkInfo, ChunkProof, }; use snark_verifier_sdk::verify_evm_calldata; use std::{cell::OnceCell, env, ptr::null}; static mut PROVER: OnceCell = OnceCell::new(); -static mut VERIFIER: OnceCell = OnceCell::new(); +static mut VERIFIER_V4: OnceCell = OnceCell::new(); /// # Safety #[no_mangle] @@ -31,8 +33,8 @@ pub unsafe extern "C" fn init_batch_prover(params_dir: *const c_char, assets_dir env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir); // VK file must exist, it is optional and logged as a warning in prover. - if !file_exists(assets_dir, &AGG_VK_FILENAME) { - panic!("{} must exist in folder {}", *AGG_VK_FILENAME, assets_dir); + if !file_exists(assets_dir, &BATCH_VK_FILENAME) { + panic!("{} must exist in folder {}", *BATCH_VK_FILENAME, assets_dir); } let prover = Prover::from_dirs(params_dir, assets_dir); @@ -50,15 +52,26 @@ pub unsafe extern "C" fn init_batch_verifier(params_dir: *const c_char, assets_d // TODO: add a settings in scroll-prover. env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir); - let verifier = Verifier::from_dirs(params_dir, assets_dir); + let verifier_v4 = VerifierV4::from_dirs(params_dir, assets_dir); - VERIFIER.set(verifier).unwrap(); + VERIFIER_V4.set(verifier_v4).unwrap(); } /// # Safety #[no_mangle] pub unsafe extern "C" fn get_batch_vk() -> *const c_char { - let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_vk()); + let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_batch_vk()); + + vk_result + .ok() + .flatten() + .map_or(null(), |vk| string_to_c_char(base64::encode(vk))) +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn get_bundle_vk() -> *const c_char { + let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_bundle_vk()); vk_result .ok() @@ -104,15 +117,19 @@ pub unsafe extern "C" fn check_chunk_proofs(chunk_proofs: *const c_char) -> *con pub unsafe extern "C" fn gen_batch_proof( chunk_hashes: *const c_char, chunk_proofs: *const c_char, + batch_header: *const c_char, ) -> *const c_char { let proof_result: Result, String> = panic_catch(|| { let chunk_hashes = c_char_to_vec(chunk_hashes); let chunk_proofs = c_char_to_vec(chunk_proofs); + let batch_header = c_char_to_vec(batch_header); let chunk_hashes = serde_json::from_slice::>(&chunk_hashes) .map_err(|e| format!("failed to deserialize chunk hashes: {e:?}"))?; let chunk_proofs = serde_json::from_slice::>(&chunk_proofs) .map_err(|e| format!("failed to deserialize chunk proofs: {e:?}"))?; + let batch_header = serde_json::from_slice::(&batch_header) + .map_err(|e| format!("failed to deserialize batch header: {e:?}"))?; if chunk_hashes.len() != chunk_proofs.len() { return Err(format!("chunk hashes and chunk proofs lengths mismatch: chunk_hashes.len() = {}, chunk_proofs.len() = {}", @@ -126,12 +143,13 @@ pub unsafe extern "C" fn gen_batch_proof( check_chunk_hashes("", &chunk_hashes_proofs).map_err(|e| format!("failed to check chunk info: {e:?}"))?; let batch = BatchProvingTask { - chunk_proofs + chunk_proofs, + batch_header, }; let proof = PROVER .get_mut() .expect("failed to get mutable reference to PROVER.") - .gen_agg_evm_proof(batch, None, OUTPUT_DIR.as_deref()) + .gen_batch_proof(batch, None, OUTPUT_DIR.as_deref()) .map_err(|e| format!("failed to generate proof: {e:?}"))?; serde_json::to_vec(&proof).map_err(|e| format!("failed to serialize the proof: {e:?}")) @@ -159,30 +177,77 @@ pub unsafe extern "C" fn verify_batch_proof( fork_name: *const c_char, ) -> c_char { let proof = c_char_to_vec(proof); - let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); let fork_name_str = c_char_to_str(fork_name); let fork_id = match fork_name_str { - "bernoulli" => 2, "curie" => 3, + "darwin" => 4, _ => { - log::warn!("unexpected fork_name {fork_name_str}, treated as curie"); - 3 + log::warn!("unexpected fork_name {fork_name_str}, treated as darwin"); + 4 } }; let verified = panic_catch(|| { - if fork_id == 2 { - // before upgrade#3(DA Compression) + if fork_id == 3 { + // As of upgrade #3 (Curie), we verify batch proofs on-chain (EVM). + let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); verify_evm_calldata( include_bytes!("plonk_verifier_0.10.3.bin").to_vec(), + // TODO(infra): include_bytes!("plonk_verifier_0.11.4.bin").to_vec(), proof.calldata(), ) } else { - VERIFIER.get().unwrap().verify_agg_evm_proof(proof) + // Post upgrade #4 (Darwin), batch proofs are not EVM-verifiable. Instead they are + // halo2 proofs meant to be bundled recursively. + let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); + VERIFIER_V4.get().unwrap().verify_batch_proof(proof) } }); verified.unwrap_or(false) as c_char } +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn gen_bundle_proof(batch_proofs: *const c_char) -> *const c_char { + let proof_result: Result, String> = panic_catch(|| { + let batch_proofs = c_char_to_vec(batch_proofs); + let batch_proofs = serde_json::from_slice::>(&batch_proofs) + .map_err(|e| format!("failed to deserialize batch proofs: {e:?}"))?; + + let bundle = BundleProvingTask { batch_proofs }; + let proof = PROVER + .get_mut() + .expect("failed to get mutable reference to PROVER.") + .gen_bundle_proof(bundle, None, OUTPUT_DIR.as_deref()) + .map_err(|e| format!("failed to generate bundle proof: {e:?}"))?; + + serde_json::to_vec(&proof) + .map_err(|e| format!("failed to serialize the bundle proof: {e:?}")) + }) + .unwrap_or_else(|e| Err(format!("unwind error: {e:?}"))); + + let r = match proof_result { + Ok(proof_bytes) => ProofResult { + message: Some(proof_bytes), + error: None, + }, + Err(err) => ProofResult { + message: None, + error: Some(err), + }, + }; + + serde_json::to_vec(&r).map_or(null(), vec_to_c_char) +} + +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn verify_bundle_proof(proof: *const c_char) -> c_char { + let proof = c_char_to_vec(proof); + let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); + let verified = panic_catch(|| VERIFIER_V4.get().unwrap().verify_bundle_proof(proof)); + verified.unwrap_or(false) as c_char +} + // This function is only used for debugging on Go side. /// # Safety #[no_mangle] diff --git a/common/libzkp/impl/src/chunk.rs b/common/libzkp/impl/src/chunk.rs index bbd24341d2..3d06f34755 100644 --- a/common/libzkp/impl/src/chunk.rs +++ b/common/libzkp/impl/src/chunk.rs @@ -6,16 +6,18 @@ use crate::{ }, }; use libc::c_char; -use prover::{ +use prover_v3::{zkevm::Verifier as VerifierV3, ChunkProof as ChunkProofV3}; +use prover_v4::{ consts::CHUNK_VK_FILENAME, utils::init_env_and_log, - zkevm::{Prover, Verifier}, - BlockTrace, ChunkProof, ChunkProvingTask, + zkevm::{Prover, Verifier as VerifierV4}, + BlockTrace, ChunkProof as ChunkProofV4, ChunkProvingTask, }; use std::{cell::OnceCell, env, ptr::null}; static mut PROVER: OnceCell = OnceCell::new(); -static mut VERIFIER: OnceCell = OnceCell::new(); +static mut VERIFIER_V3: OnceCell = OnceCell::new(); +static mut VERIFIER_V4: OnceCell = OnceCell::new(); /// # Safety #[no_mangle] @@ -48,9 +50,11 @@ pub unsafe extern "C" fn init_chunk_verifier(params_dir: *const c_char, assets_d // TODO: add a settings in scroll-prover. env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir); - let verifier = Verifier::from_dirs(params_dir, assets_dir); + let verifier_v3 = VerifierV3::from_dirs(params_dir, assets_dir); + let verifier_v4 = VerifierV4::from_dirs(params_dir, assets_dir); - VERIFIER.set(verifier).unwrap(); + VERIFIER_V3.set(verifier_v3).unwrap(); + VERIFIER_V4.set(verifier_v4).unwrap(); } /// # Safety @@ -99,10 +103,29 @@ pub unsafe extern "C" fn gen_chunk_proof(block_traces: *const c_char) -> *const /// # Safety #[no_mangle] -pub unsafe extern "C" fn verify_chunk_proof(proof: *const c_char) -> c_char { +pub unsafe extern "C" fn verify_chunk_proof( + proof: *const c_char, + fork_name: *const c_char, +) -> c_char { let proof = c_char_to_vec(proof); - let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); - let verified = panic_catch(|| VERIFIER.get().unwrap().verify_chunk_proof(proof)); + let fork_name_str = c_char_to_str(fork_name); + let fork_id = match fork_name_str { + "curie" => 3, + "darwin" => 4, + _ => { + log::warn!("unexpected fork_name {fork_name_str}, treated as darwin"); + 4 + } + }; + let verified = panic_catch(|| { + if fork_id == 3 { + let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); + VERIFIER_V3.get().unwrap().verify_chunk_proof(proof) + } else { + let proof = serde_json::from_slice::(proof.as_slice()).unwrap(); + VERIFIER_V4.get().unwrap().verify_chunk_proof(proof) + } + }); verified.unwrap_or(false) as c_char } diff --git a/common/libzkp/interface/libzkp.h b/common/libzkp/interface/libzkp.h index dab60b7bed..99cb8f3a3a 100644 --- a/common/libzkp/interface/libzkp.h +++ b/common/libzkp/interface/libzkp.h @@ -1,15 +1,26 @@ +// BatchProver is used to: +// - Batch a list of chunk proofs +// - Bundle a list of batch proofs void init_batch_prover(char* params_dir, char* assets_dir); +// BatchVerifier is used to: +// - Verify a batch proof +// - Verify a bundle proof void init_batch_verifier(char* params_dir, char* assets_dir); + char* get_batch_vk(); char* check_chunk_proofs(char* chunk_proofs); -char* gen_batch_proof(char* chunk_hashes, char* chunk_proofs); +char* gen_batch_proof(char* chunk_hashes, char* chunk_proofs, char* batch_header); char verify_batch_proof(char* proof, char* fork_name); +char* get_bundle_vk(); +char* gen_bundle_proof(char* batch_proofs); +char verify_bundle_proof(char* proof); + void init_chunk_prover(char* params_dir, char* assets_dir); void init_chunk_verifier(char* params_dir, char* assets_dir); char* get_chunk_vk(); char* gen_chunk_proof(char* block_traces); -char verify_chunk_proof(char* proof); +char verify_chunk_proof(char* proof, char* fork_name); char* block_traces_to_chunk_info(char* block_traces); void free_c_chars(char* ptr); diff --git a/common/types/message/message.go b/common/types/message/message.go index d88d19988c..7769e053e9 100644 --- a/common/types/message/message.go +++ b/common/types/message/message.go @@ -52,22 +52,14 @@ type ChunkTaskDetail struct { // BatchTaskDetail is a type containing BatchTask detail. type BatchTaskDetail struct { - ChunkInfos []*ChunkInfo `json:"chunk_infos"` - ChunkProofs []*ChunkProof `json:"chunk_proofs"` - ParentStateRoot common.Hash `json:"parent_state_root"` - ParentBatchHash common.Hash `json:"parent_batch_hash"` - BatchHeader *codecv3.DABatch `json:"batch_header"` + ChunkInfos []*ChunkInfo `json:"chunk_infos"` + ChunkProofs []*ChunkProof `json:"chunk_proofs"` + BatchHeader *codecv3.DABatch `json:"batch_header"` } // BundleTaskDetail consists of all the information required to describe the task to generate a proof for a bundle of batches. type BundleTaskDetail struct { - ChainID uint64 `json:"chain_id"` - FinalizedBatchHash common.Hash `json:"finalized_batch_hash"` - FinalizedStateRoot common.Hash `json:"finalized_state_root"` - PendingBatchHash common.Hash `json:"pending_batch_hash"` - PendingStateRoot common.Hash `json:"pending_state_root"` - PendingWithdrawRoot common.Hash `json:"pending_withdraw_root"` - BatchProofs []*BatchProof `json:"batch_proofs"` + BatchProofs []*BatchProof `json:"batch_proofs"` } // ChunkInfo is for calculating pi_hash for chunk @@ -107,8 +99,8 @@ type BatchProof struct { Instances []byte `json:"instances"` Vk []byte `json:"vk"` // cross-reference between cooridinator computation and prover compution - BatchHash common.Hash `json:"batch_hash"` - GitVersion string `json:"git_version,omitempty"` + BatchHeader *codecv3.DABatch `json:"batch_header"` + GitVersion string `json:"git_version,omitempty"` } // SanityCheck checks whether a BatchProof is in a legal format diff --git a/coordinator/internal/logic/submitproof/proof_receiver.go b/coordinator/internal/logic/submitproof/proof_receiver.go index 45234ea362..ffc5df4147 100644 --- a/coordinator/internal/logic/submitproof/proof_receiver.go +++ b/coordinator/internal/logic/submitproof/proof_receiver.go @@ -169,7 +169,8 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor if getHardForkErr != nil { return ErrGetHardForkNameFailed } - // only verify batch proof. chunk proof verifier have been disabled after Bernoulli + // Post-Bernoulli we do not verify chunk proofs. + // Verify batch proof if message.ProofType(proofParameter.TaskType) == message.ProofTypeBatch { var batchProof message.BatchProof if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &batchProof); unmarshalErr != nil { @@ -177,9 +178,13 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor } success, verifyErr = m.verifier.VerifyBatchProof(&batchProof, hardForkName) } - + // Verify bundle proof if message.ProofType(proofParameter.TaskType) == message.ProofTypeBundle { - // TODO add bundle check here + var bundleProof message.BundleProof + if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &bundleProof); unmarshalErr != nil { + return unmarshalErr + } + success, verifyErr = m.verifier.VerifyBundleProof(&bundleProof) } if verifyErr != nil || !success { diff --git a/coordinator/internal/logic/verifier/verifier.go b/coordinator/internal/logic/verifier/verifier.go index 478c737c87..febb9d16c8 100644 --- a/coordinator/internal/logic/verifier/verifier.go +++ b/coordinator/internal/logic/verifier/verifier.go @@ -30,9 +30,10 @@ import ( // NewVerifier Sets up a rust ffi to call verify. func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) { if cfg.MockMode { - batchVKMap := map[string]string{cfg.ForkName: "mock_vk"} chunkVKMap := map[string]string{cfg.ForkName: "mock_vk"} - return &Verifier{cfg: cfg, ChunkVKMap: chunkVKMap, BatchVKMap: batchVKMap}, nil + batchVKMap := map[string]string{cfg.ForkName: "mock_vk"} + bundleVKMap := map[string]string{cfg.ForkName: "mock_vk"} + return &Verifier{cfg: cfg, ChunkVKMap: chunkVKMap, BatchVKMap: batchVKMap, BundleVkMap: bundleVKMap}, nil } paramsPathStr := C.CString(cfg.ParamsPath) assetsPathStr := C.CString(cfg.AssetsPath) @@ -50,15 +51,15 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) { BatchVKMap: make(map[string]string), } - bundleVK, err := v.readVK(path.Join(cfg.AssetsPath, "bundle_vk.vkey")) + bundleVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_bundle.vkey")) if err != nil { return nil, err } - batchVK, err := v.readVK(path.Join(cfg.AssetsPath, "batch_vk.vkey")) + batchVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_batch.vkey")) if err != nil { return nil, err } - chunkVK, err := v.readVK(path.Join(cfg.AssetsPath, "chunk_vk.vkey")) + chunkVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_chunk.vkey")) if err != nil { return nil, err } @@ -100,7 +101,32 @@ func (v *Verifier) VerifyBatchProof(proof *coordinatorType.BatchProof, forkName } // VerifyChunkProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier. -func (v *Verifier) VerifyChunkProof(proof *coordinatorType.ChunkProof) (bool, error) { +func (v *Verifier) VerifyChunkProof(proof *coordinatorType.ChunkProof, forkName string) (bool, error) { + if v.cfg.MockMode { + log.Info("Mock mode, verifier disabled") + if string(proof.Proof) == InvalidTestProof { + return false, nil + } + return true, nil + + } + buf, err := json.Marshal(proof) + if err != nil { + return false, err + } + + proofStr := C.CString(string(buf)) + defer func() { + C.free(unsafe.Pointer(proofStr)) + }() + + log.Info("Start to verify chunk proof", "forkName", forkName) + verified := C.verify_chunk_proof(proofStr, forkName) + return verified != 0, nil +} + +// VerifyBundleProof Verify a ZkProof for a bundle of batches, by marshaling it and verifying it via the EVM verifier. +func (v *Verifier) VerifyBundleProof(proof *coordinatorType.BundleProof) (bool, error) { if v.cfg.MockMode { log.Info("Mock mode, verifier disabled") if string(proof.Proof) == InvalidTestProof { @@ -119,8 +145,8 @@ func (v *Verifier) VerifyChunkProof(proof *coordinatorType.ChunkProof) (bool, er C.free(unsafe.Pointer(proofStr)) }() - log.Info("Start to verify chunk proof ...") - verified := C.verify_chunk_proof(proofStr) + log.Info("Start to verify bundle proof ...") + verified := C.verify_bundle_proof(proofStr) return verified != 0, nil }