From ad9dbab467e152d74c90cb8924c0f49b8687d49c Mon Sep 17 00:00:00 2001 From: "sm.wu" Date: Thu, 5 Feb 2026 23:17:02 +0800 Subject: [PATCH 1/2] wip attempt: native rust loop for verify_chip_proof --- Cargo.lock | 50 +------ Cargo.toml | 56 ++++---- ceno_recursion/Cargo.toml | 7 +- ceno_recursion/src/zkvm_verifier/verifier.rs | 134 ++++++++++-------- ceno_zkvm/src/precompiles/bitwise_keccakf.rs | 2 +- ceno_zkvm/src/precompiles/lookup_keccakf.rs | 2 +- ceno_zkvm/src/precompiles/uint256.rs | 2 +- .../weierstrass/weierstrass_add.rs | 2 +- .../weierstrass/weierstrass_decompress.rs | 2 +- .../weierstrass/weierstrass_double.rs | 2 +- ceno_zkvm/src/scheme/verifier.rs | 2 +- gkr_iop/src/gkr.rs | 3 +- 12 files changed, 118 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18a12f83e..585e26535 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3588,7 +3588,6 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "openvm" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "bytemuck", "num-bigint 0.4.6", @@ -3601,7 +3600,6 @@ dependencies = [ [[package]] name = "openvm-algebra-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -3630,7 +3628,6 @@ dependencies = [ [[package]] name = "openvm-algebra-complex-macros" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-macros-common", "quote", @@ -3640,7 +3637,6 @@ dependencies = [ [[package]] name = "openvm-algebra-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "halo2curves-axiom", "num-bigint 0.4.6", @@ -3656,7 +3652,6 @@ dependencies = [ [[package]] name = "openvm-algebra-moduli-macros" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "num-bigint 0.4.6", "num-prime", @@ -3668,7 +3663,6 @@ dependencies = [ [[package]] name = "openvm-algebra-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-algebra-guest", "openvm-instructions", @@ -3682,7 +3676,6 @@ dependencies = [ [[package]] name = "openvm-bigint-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -3705,7 +3698,6 @@ dependencies = [ [[package]] name = "openvm-bigint-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-platform", "strum_macros", @@ -3714,7 +3706,6 @@ dependencies = [ [[package]] name = "openvm-bigint-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-bigint-guest", "openvm-instructions", @@ -3729,7 +3720,6 @@ dependencies = [ [[package]] name = "openvm-build" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cargo_metadata 0.18.1", "eyre", @@ -3741,7 +3731,6 @@ dependencies = [ [[package]] name = "openvm-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "backtrace", "cfg-if", @@ -3780,7 +3769,6 @@ dependencies = [ [[package]] name = "openvm-circuit-derive" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "itertools 0.14.0", "proc-macro2", @@ -3791,7 +3779,6 @@ dependencies = [ [[package]] name = "openvm-circuit-primitives" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "derive-new 0.6.0", "itertools 0.14.0", @@ -3809,7 +3796,6 @@ dependencies = [ [[package]] name = "openvm-circuit-primitives-derive" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "itertools 0.14.0", "quote", @@ -3819,7 +3805,6 @@ dependencies = [ [[package]] name = "openvm-continuations" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "derivative", "openvm-circuit", @@ -3889,7 +3874,6 @@ dependencies = [ [[package]] name = "openvm-custom-insn" version = "0.1.0" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "proc-macro2", "quote", @@ -3899,7 +3883,6 @@ dependencies = [ [[package]] name = "openvm-ecc-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -3928,7 +3911,6 @@ dependencies = [ [[package]] name = "openvm-ecc-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve", @@ -3947,7 +3929,6 @@ dependencies = [ [[package]] name = "openvm-ecc-sw-macros" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-macros-common", "quote", @@ -3957,7 +3938,6 @@ dependencies = [ [[package]] name = "openvm-ecc-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-ecc-guest", "openvm-instructions", @@ -3971,7 +3951,6 @@ dependencies = [ [[package]] name = "openvm-instructions" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "backtrace", "derive-new 0.6.0", @@ -3988,7 +3967,6 @@ dependencies = [ [[package]] name = "openvm-instructions-derive" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "quote", "syn 2.0.101", @@ -3997,7 +3975,6 @@ dependencies = [ [[package]] name = "openvm-keccak256-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4022,7 +3999,6 @@ dependencies = [ [[package]] name = "openvm-keccak256-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-platform", ] @@ -4030,7 +4006,6 @@ dependencies = [ [[package]] name = "openvm-keccak256-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-instructions", "openvm-instructions-derive", @@ -4044,7 +4019,6 @@ dependencies = [ [[package]] name = "openvm-macros-common" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "syn 2.0.101", ] @@ -4052,7 +4026,6 @@ dependencies = [ [[package]] name = "openvm-mod-circuit-builder" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "itertools 0.14.0", "num-bigint 0.4.6", @@ -4070,7 +4043,6 @@ dependencies = [ [[package]] name = "openvm-native-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4101,10 +4073,10 @@ dependencies = [ [[package]] name = "openvm-native-compiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "backtrace", "itertools 0.14.0", + "metrics", "num-bigint 0.4.6", "num-integer", "openvm-circuit", @@ -4123,7 +4095,6 @@ dependencies = [ [[package]] name = "openvm-native-compiler-derive" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "quote", "syn 2.0.101", @@ -4132,11 +4103,11 @@ dependencies = [ [[package]] name = "openvm-native-recursion" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "itertools 0.14.0", "lazy_static", + "metrics", "openvm-circuit", "openvm-native-circuit", "openvm-native-compiler", @@ -4156,7 +4127,6 @@ dependencies = [ [[package]] name = "openvm-native-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-instructions", "openvm-transpiler", @@ -4166,7 +4136,6 @@ dependencies = [ [[package]] name = "openvm-pairing-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4195,7 +4164,6 @@ dependencies = [ [[package]] name = "openvm-pairing-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "halo2curves-axiom", "hex-literal", @@ -4216,7 +4184,6 @@ dependencies = [ [[package]] name = "openvm-pairing-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-instructions", "openvm-pairing-guest", @@ -4229,7 +4196,6 @@ dependencies = [ [[package]] name = "openvm-platform" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "libm", "openvm-custom-insn", @@ -4239,7 +4205,6 @@ dependencies = [ [[package]] name = "openvm-poseidon2-air" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "derivative", "lazy_static", @@ -4257,7 +4222,6 @@ dependencies = [ [[package]] name = "openvm-rv32-adapters" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "derive-new 0.6.0", "itertools 0.14.0", @@ -4274,7 +4238,6 @@ dependencies = [ [[package]] name = "openvm-rv32im-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4297,7 +4260,6 @@ dependencies = [ [[package]] name = "openvm-rv32im-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-custom-insn", "p3-field", @@ -4307,7 +4269,6 @@ dependencies = [ [[package]] name = "openvm-rv32im-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-instructions", "openvm-instructions-derive", @@ -4323,7 +4284,6 @@ dependencies = [ [[package]] name = "openvm-sdk" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "bitcode", "bon", @@ -4377,7 +4337,6 @@ dependencies = [ [[package]] name = "openvm-sha256-air" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-circuit-primitives", "openvm-stark-backend", @@ -4388,7 +4347,6 @@ dependencies = [ [[package]] name = "openvm-sha256-circuit" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4411,7 +4369,6 @@ dependencies = [ [[package]] name = "openvm-sha256-guest" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-platform", ] @@ -4419,7 +4376,6 @@ dependencies = [ [[package]] name = "openvm-sha256-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "openvm-instructions", "openvm-instructions-derive", @@ -4498,7 +4454,6 @@ dependencies = [ [[package]] name = "openvm-transpiler" version = "1.4.1" -source = "git+https://github.com/scroll-tech/openvm.git?branch=feat%2Fv1.4.1-scroll-ext#ef22e8ecb9965091783d2c0369b8379e7f683f53" dependencies = [ "elf", "eyre", @@ -4506,6 +4461,7 @@ dependencies = [ "openvm-platform", "openvm-stark-backend", "rrs-lib", + "rustc-demangle", "thiserror 1.0.69", ] diff --git a/Cargo.toml b/Cargo.toml index f205a9223..e13df1f37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,16 @@ [workspace] members = [ - "ceno_cli", - "ceno_emul", - "ceno_host", - "ceno_serde", - "ceno_rt", - "ceno_zkvm", - "ceno_recursion", - "derive", - "examples-builder", - "examples", - "guest_libs/*", + "ceno_cli", + "ceno_emul", + "ceno_host", + "ceno_serde", + "ceno_rt", + "ceno_zkvm", + "ceno_recursion", + "derive", + "examples-builder", + "examples", + "guest_libs/*", ] resolver = "2" @@ -66,11 +66,11 @@ secp = "0.4.1" serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" smallvec = { version = "1.13.2", features = [ - "const_generics", - "const_new", - "serde", - "union", - "write", + "const_generics", + "const_new", + "serde", + "union", + "write", ] } strum = "0.26" strum_macros = "0.26" @@ -79,7 +79,7 @@ thiserror = "2" thread_local = "1.1" tiny-keccak = { version = "2.0.2", features = ["keccak"] } tracing = { version = "0.1", features = [ - "attributes", + "attributes", ] } tracing-forest = { version = "0.1.6" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } @@ -142,14 +142,14 @@ lto = "thin" #whir = { path = "../gkr-backend/crates/whir", package = "whir" } #witness = { path = "../gkr-backend/crates/witness", package = "witness" } -# [patch."https://github.com/scroll-tech/openvm.git"] -# openvm = { path = "../openvm-scroll-tech/crates/toolchain/openvm", default-features = false } -# openvm-circuit = { path = "../openvm-scroll-tech/crates/vm", default-features = false } -# openvm-continuations = { path = "../openvm-scroll-tech/crates/continuations", default-features = false } -# openvm-instructions = { path = "../openvm-scroll-tech/crates/toolchain/instructions", default-features = false } -# openvm-native-circuit = { path = "../openvm-scroll-tech/extensions/native/circuit", default-features = false } -# openvm-native-compiler = { path = "../openvm-scroll-tech/extensions/native/compiler", default-features = false } -# openvm-native-compiler-derive = { path = "../openvm-scroll-tech/extensions/native/compiler/derive", default-features = false } -# openvm-native-recursion = { path = "../openvm-scroll-tech/extensions/native/recursion", default-features = false } -# openvm-rv32im-circuit = { path = "../openvm-scroll-tech/extensions/rv32im/circuit", default-features = false } -# openvm-sdk = { path = "../openvm-scroll-tech/crates/sdk", default-features = false } +[patch."https://github.com/scroll-tech/openvm.git"] +openvm = { path = "../openvm/crates/toolchain/openvm", default-features = false } +openvm-circuit = { path = "../openvm/crates/vm", default-features = false } +openvm-continuations = { path = "../openvm/crates/continuations", default-features = false } +openvm-instructions = { path = "../openvm/crates/toolchain/instructions", default-features = false } +openvm-native-circuit = { path = "../openvm/extensions/native/circuit", default-features = false } +openvm-native-compiler = { path = "../openvm/extensions/native/compiler", default-features = false } +openvm-native-compiler-derive = { path = "../openvm/extensions/native/compiler/derive", default-features = false } +openvm-native-recursion = { path = "../openvm/extensions/native/recursion", default-features = false } +openvm-rv32im-circuit = { path = "../openvm/extensions/rv32im/circuit", default-features = false } +openvm-sdk = { path = "../openvm/crates/sdk", default-features = false } diff --git a/ceno_recursion/Cargo.toml b/ceno_recursion/Cargo.toml index 5e3aef6a5..ccff81e82 100644 --- a/ceno_recursion/Cargo.toml +++ b/ceno_recursion/Cargo.toml @@ -52,11 +52,12 @@ name = "e2e_aggregate" path = "src/bin/e2e_aggregate.rs" [features] -bench-metrics = ["openvm-circuit/metrics"] +bench-metrics = ["openvm-sdk/metrics"] +perf-metrics = ["openvm-sdk/perf-metrics"] default = ["parallel", "nightly-features"] gpu = ["ceno_zkvm/gpu", "openvm-circuit/cuda", "openvm-native-circuit/cuda", "dep:openvm-cuda-backend"] nightly-features = [ - "ceno_zkvm/nightly-features", - "openvm-stark-sdk/nightly-features", + "ceno_zkvm/nightly-features", + "openvm-stark-sdk/nightly-features", ] parallel = ["openvm-stark-backend/parallel"] diff --git a/ceno_recursion/src/zkvm_verifier/verifier.rs b/ceno_recursion/src/zkvm_verifier/verifier.rs index 7fe8d7eec..169a26a19 100644 --- a/ceno_recursion/src/zkvm_verifier/verifier.rs +++ b/ceno_recursion/src/zkvm_verifier/verifier.rs @@ -340,7 +340,8 @@ pub fn verify_zkvm_proof>( builder.assign(&logup_sum, logup_sum + chip_logup_sum); } - builder.cycle_tracker_start("Verify chip proof"); + builder + .cycle_tracker_start(format!("Verify chip proof: {}", circuit_name).as_str()); let (input_opening_point, chip_shard_ec_sum) = verify_chip_proof( circuit_name, builder, @@ -354,7 +355,7 @@ pub fn verify_zkvm_proof>( &unipoly_extrapolator, &mut poly_evaluator, ); - builder.cycle_tracker_end("Verify chip proof"); + builder.cycle_tracker_end(format!("Verify chip proof: {}", circuit_name).as_str()); let point_clone: Array> = builder.eval(input_opening_point.clone()); @@ -540,15 +541,14 @@ pub fn verify_chip_proof( } = &composed_cs; let one: Ext = builder.constant(C::EF::ONE); + builder + .cycle_tracker_start(format!("Pre-verify tower proof for opcode {circuit_name}",).as_str()); let r_len = cs.r_expressions.len() + cs.r_table_expressions.len(); let w_len = cs.w_expressions.len() + cs.w_table_expressions.len(); let lk_len = cs.lk_expressions.len() + cs.lk_table_expressions.len(); - let num_batched = r_len + w_len + lk_len; + let num_batched_usize = r_len + w_len + lk_len; - let r_counts_per_instance: Usize = Usize::from(r_len); - let w_counts_per_instance: Usize = Usize::from(w_len); let lk_counts_per_instance: Usize = Usize::from(lk_len); - let num_batched: Usize = Usize::from(num_batched); let log2_num_instances = chip_proof.log2_num_instances.clone(); if composed_cs.has_ecc_ops() { @@ -584,16 +584,22 @@ pub fn verify_chip_proof( } let tower_proof = &chip_proof.tower_proof; - let num_variables: Array> = builder.dyn_array(num_batched); - builder - .range(0, num_variables.len()) - .for_each(|idx_vec, builder| { - builder.set(&num_variables, idx_vec[0], num_var_with_rotation.clone()); - }); + let num_variables: Array> = builder.uninit_fixed_array(num_batched_usize); + // Every entry of `num_variables` is identical, so emit straight-line assignments + // with a compile-time bound driven by the verifying key. + for idx in 0..num_batched_usize { + builder.set( + &num_variables, + Usize::from(idx), + num_var_with_rotation.clone(), + ); + } let prod_out_evals: Array>> = concat(builder, &chip_proof.r_out_evals, &chip_proof.w_out_evals); let num_fanin: Usize = Usize::from(NUM_FANIN); + builder + .cycle_tracker_end(format!("Pre-verify tower proof for opcode {circuit_name}",).as_str()); builder.cycle_tracker_start(format!("verify tower proof for opcode {circuit_name}",).as_str()); let (_, record_evals, logup_p_evals, logup_q_evals) = verify_tower_proof( @@ -609,63 +615,71 @@ pub fn verify_chip_proof( ); builder.cycle_tracker_end(format!("verify tower proof for opcode {circuit_name}",).as_str()); + builder.cycle_tracker_start( + format!("post-verify tower proof for opcode {circuit_name}",).as_str(), + ); if cs.lk_table_expressions.is_empty() { - builder - .range(0, logup_p_evals.len()) - .for_each(|idx_vec, builder| { - let eval = builder.get(&logup_p_evals, idx_vec[0]).eval; - builder.assert_ext_eq(eval, one); - }); + builder.cycle_tracker_start(format!("check tower proof p {circuit_name}",).as_str()); + for idx in 0..lk_len { + let eval = builder.get(&logup_p_evals, Usize::from(idx)).eval; + builder.assert_ext_eq(eval, one); + } + builder.cycle_tracker_end(format!("check tower proof p {circuit_name}",).as_str()); } - let num_rw_records: Usize = builder.eval(r_counts_per_instance + w_counts_per_instance); + let num_rw_records_usize = r_len + w_len; + let num_rw_records: Usize = Usize::from(num_rw_records_usize); builder.assert_usize_eq(record_evals.len(), num_rw_records.clone()); builder.assert_usize_eq(logup_p_evals.len(), lk_counts_per_instance.clone()); builder.assert_usize_eq(logup_q_evals.len(), lk_counts_per_instance.clone()); + builder + .cycle_tracker_end(format!("post-verify tower proof for opcode {circuit_name}",).as_str()); + builder.cycle_tracker_start(format!("pre-Verify GKR Circuit {circuit_name}",).as_str()); // GKR circuit - let out_evals_len: Usize = if cs.lk_table_expressions.is_empty() { - builder.eval(record_evals.len() + logup_q_evals.len()) + // The number of outputs the GKR verifier needs to check is fully determined by + // the constraint system metadata: record evaluations (r/w) plus one or two + // lookup vectors depending on whether a lookup table is present. + let out_evals_capacity = if cs.lk_table_expressions.is_empty() { + num_rw_records_usize + lk_len } else { - builder.eval(record_evals.len() + logup_p_evals.len() + logup_q_evals.len()) + num_rw_records_usize + 2 * lk_len }; - let out_evals: Array> = builder.dyn_array(out_evals_len.clone()); + let out_evals: Array> = builder.dyn_array(out_evals_capacity); - builder - .range(0, record_evals.len()) - .for_each(|idx_vec, builder| { - let cpt = builder.get(&record_evals, idx_vec[0]); - builder.set(&out_evals, idx_vec[0], cpt); - }); + for idx in 0..num_rw_records_usize { + let record_idx = Usize::from(idx); + let cpt = builder.get(&record_evals, record_idx.clone()); + builder.set(&out_evals, record_idx, cpt); + } - let end: Usize = Usize::uninit(builder); + let mut end = num_rw_records_usize; if !cs.lk_table_expressions.is_empty() { - builder.assign(&end, record_evals.len() + logup_p_evals.len()); - let p_slice = out_evals.slice(builder, record_evals.len(), end.clone()); - - builder - .range(0, logup_p_evals.len()) - .for_each(|idx_vec, builder| { - let cpt = builder.get(&logup_p_evals, idx_vec[0]); - builder.set(&p_slice, idx_vec[0], cpt); - }); - } else { - builder.assign(&end, record_evals.len()); + let next_end = end + lk_len; + let p_slice = out_evals.slice(builder, end, next_end); + for idx in 0..lk_len { + let lk_idx = Usize::from(idx); + let cpt = builder.get(&logup_p_evals, lk_idx.clone()); + builder.set(&p_slice, lk_idx, cpt); + } + end = next_end; } - let q_slice = out_evals.slice(builder, end, out_evals_len); - builder - .range(0, logup_q_evals.len()) - .for_each(|idx_vec, builder| { - let cpt = builder.get(&logup_q_evals, idx_vec[0]); - builder.set(&q_slice, idx_vec[0], cpt); - }); - let gkr_circuit = gkr_circuit.clone().unwrap(); + let q_slice = out_evals.slice(builder, end, out_evals_capacity); + for idx in 0..lk_len { + let lk_idx = Usize::from(idx); + let cpt = builder.get(&logup_q_evals, lk_idx.clone()); + builder.set(&q_slice, lk_idx, cpt); + } + let gkr_circuit = gkr_circuit.as_ref().unwrap(); - let zero_bit_decomps: Array> = builder.dyn_array(32); + let zero_bit_decomps: Array> = builder.uninit_fixed_array(32); + builder.cycle_tracker_end(format!("pre-Verify GKR Circuit {circuit_name}",).as_str()); + builder.cycle_tracker_start("Eval Selector"); let selector_ctxs: Vec> = if cs.ec_final_sum.is_empty() { builder.assert_usize_eq(chip_proof.num_instances.len(), Usize::from(1)); - let num_instances_bit_decomps: Array>> = builder.dyn_array(1); + let num_instances_bit_decomps: Array>> = + builder.uninit_fixed_array(1); builder.set( &num_instances_bit_decomps, 0, @@ -678,7 +692,7 @@ pub fn verify_chip_proof( offset: Usize::from(0), offset_bit_decomps: zero_bit_decomps, num_instances: chip_proof.sum_num_instances.clone(), - num_instances_layered_ns: builder.dyn_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ + num_instances_layered_ns: builder.uninit_fixed_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ num_instances_bit_decomps, offset_instance_sum_bit_decomps: chip_proof .sum_num_instances_minus_one_bit_decomposition @@ -694,9 +708,10 @@ pub fn verify_chip_proof( } else { builder.assert_usize_eq(chip_proof.num_instances.len(), Usize::from(2)); - let num_inst_0_bit_decomps: Array>> = builder.dyn_array(1); - let num_inst_1_bit_decomps: Array>> = builder.dyn_array(1); - let num_inst_sum_bit_decomps: Array>> = builder.dyn_array(1); + let num_inst_0_bit_decomps: Array>> = builder.uninit_fixed_array(1); + let num_inst_1_bit_decomps: Array>> = builder.uninit_fixed_array(1); + let num_inst_sum_bit_decomps: Array>> = + builder.uninit_fixed_array(1); builder.set( &num_inst_0_bit_decomps, @@ -721,7 +736,7 @@ pub fn verify_chip_proof( offset: Usize::from(0), offset_bit_decomps: zero_bit_decomps.clone(), num_instances: Usize::Var(builder.get(&chip_proof.num_instances, 0)), - num_instances_layered_ns: builder.dyn_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ + num_instances_layered_ns: builder.uninit_fixed_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ num_instances_bit_decomps: num_inst_0_bit_decomps, offset_instance_sum_bit_decomps: chip_proof.n_inst_0_bit_decomps.clone(), num_vars: num_var_with_rotation.clone(), @@ -730,7 +745,7 @@ pub fn verify_chip_proof( offset: Usize::Var(builder.get(&chip_proof.num_instances, 0)), offset_bit_decomps: chip_proof.n_inst_0_bit_decomps.clone(), num_instances: Usize::Var(builder.get(&chip_proof.num_instances, 1)), - num_instances_layered_ns: builder.dyn_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ + num_instances_layered_ns: builder.uninit_fixed_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ num_instances_bit_decomps: num_inst_1_bit_decomps, offset_instance_sum_bit_decomps: chip_proof .sum_num_instances_minus_one_bit_decomposition @@ -741,7 +756,7 @@ pub fn verify_chip_proof( offset: Usize::from(0), offset_bit_decomps: zero_bit_decomps, num_instances: chip_proof.sum_num_instances.clone(), - num_instances_layered_ns: builder.dyn_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ + num_instances_layered_ns: builder.uninit_fixed_array(0), /* Only used in QuarkBinaryTreeLessThan(Expression) */ num_instances_bit_decomps: num_inst_sum_bit_decomps, offset_instance_sum_bit_decomps: chip_proof .sum_num_instances_minus_one_bit_decomposition @@ -750,6 +765,7 @@ pub fn verify_chip_proof( }, ] }; + builder.cycle_tracker_end("Eval Selector"); builder.cycle_tracker_start("Verify GKR Circuit"); let rt = verify_gkr_circuit( @@ -777,7 +793,7 @@ pub fn verify_gkr_circuit( builder: &mut Builder, challenger: &mut DuplexChallengerVariable, max_num_variables: Usize, - gkr_circuit: GKRCircuit, + gkr_circuit: &GKRCircuit, gkr_proof: &GKRProofVariable, challenges: &Array>, pub_io_evals: &Array>, diff --git a/ceno_zkvm/src/precompiles/bitwise_keccakf.rs b/ceno_zkvm/src/precompiles/bitwise_keccakf.rs index 78c8bfe95..3607d26f4 100644 --- a/ceno_zkvm/src/precompiles/bitwise_keccakf.rs +++ b/ceno_zkvm/src/precompiles/bitwise_keccakf.rs @@ -1000,7 +1000,7 @@ pub fn run_keccakf + 'stat .verify( log2_num_instances, gkr_proof, - &out_evals, + out_evals, &[], &[], &[], diff --git a/ceno_zkvm/src/precompiles/lookup_keccakf.rs b/ceno_zkvm/src/precompiles/lookup_keccakf.rs index 52391267a..fdcefcd0a 100644 --- a/ceno_zkvm/src/precompiles/lookup_keccakf.rs +++ b/ceno_zkvm/src/precompiles/lookup_keccakf.rs @@ -1261,7 +1261,7 @@ pub fn run_lookup_keccakf .verify( log2_num_instance_rounds, gkr_proof.clone(), - &out_evals, + out_evals, &[], &[], &challenges, diff --git a/ceno_zkvm/src/precompiles/uint256.rs b/ceno_zkvm/src/precompiles/uint256.rs index e59e97c55..0d476d01e 100644 --- a/ceno_zkvm/src/precompiles/uint256.rs +++ b/ceno_zkvm/src/precompiles/uint256.rs @@ -942,7 +942,7 @@ pub fn run_uint256_mul + ' .verify( log2_num_instance, gkr_proof.clone(), - &out_evals, + out_evals, &[], &[], &challenges, diff --git a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_add.rs b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_add.rs index 012dcab80..a6270831d 100644 --- a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_add.rs +++ b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_add.rs @@ -776,7 +776,7 @@ pub fn run_weierstrass_add< .verify( log2_num_instance, gkr_proof.clone(), - &out_evals, + out_evals, &[], &[], &challenges, diff --git a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_decompress.rs b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_decompress.rs index d6400a2d7..231c0caa6 100644 --- a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_decompress.rs +++ b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_decompress.rs @@ -756,7 +756,7 @@ pub fn run_weierstrass_decompress< .verify( log2_num_instance, gkr_proof.clone(), - &out_evals, + out_evals, &[], &[], &challenges, diff --git a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_double.rs b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_double.rs index 686baa397..073ee4066 100644 --- a/ceno_zkvm/src/precompiles/weierstrass/weierstrass_double.rs +++ b/ceno_zkvm/src/precompiles/weierstrass/weierstrass_double.rs @@ -778,7 +778,7 @@ pub fn run_weierstrass_double< .verify( log2_num_instance, gkr_proof.clone(), - &out_evals, + out_evals, &[], &[], &challenges, diff --git a/ceno_zkvm/src/scheme/verifier.rs b/ceno_zkvm/src/scheme/verifier.rs index a040108ab..65c9d944d 100644 --- a/ceno_zkvm/src/scheme/verifier.rs +++ b/ceno_zkvm/src/scheme/verifier.rs @@ -647,7 +647,7 @@ impl> ZKVMVerifier let (_, rt) = gkr_circuit.verify( num_var_with_rotation, proof.gkr_iop_proof.clone().unwrap(), - &evals, + evals, pi, raw_pi, challenges, diff --git a/gkr_iop/src/gkr.rs b/gkr_iop/src/gkr.rs index b025aa1e4..eea5b5f7f 100644 --- a/gkr_iop/src/gkr.rs +++ b/gkr_iop/src/gkr.rs @@ -121,7 +121,7 @@ impl GKRCircuit { &self, max_num_variables: usize, gkr_proof: GKRProof, - out_evals: &[PointAndEval], + mut evaluations: Vec>, pub_io_evals: &[E], raw_pi: &[Vec], challenges: &[E], @@ -134,7 +134,6 @@ impl GKRCircuit { let GKRProof(sumcheck_proofs) = gkr_proof; let mut challenges = challenges.to_vec(); - let mut evaluations = out_evals.to_vec(); evaluations.resize(self.n_evaluations, PointAndEval::default()); let rt = izip!(&self.layers, sumcheck_proofs).enumerate().try_fold( vec![], From 1c92725d0b685156db47ca37f31d66f3f771a26d Mon Sep 17 00:00:00 2001 From: "sm.wu" Date: Fri, 6 Feb 2026 09:55:26 +0800 Subject: [PATCH 2/2] wip: tower proof, not pass yet --- ceno_recursion/src/tower_verifier/program.rs | 191 ++++++++----------- ceno_recursion/src/zkvm_verifier/verifier.rs | 4 +- 2 files changed, 82 insertions(+), 113 deletions(-) diff --git a/ceno_recursion/src/tower_verifier/program.rs b/ceno_recursion/src/tower_verifier/program.rs index 2bf1e412d..fc1a9f737 100644 --- a/ceno_recursion/src/tower_verifier/program.rs +++ b/ceno_recursion/src/tower_verifier/program.rs @@ -87,44 +87,44 @@ pub fn verify_tower_proof( proof: &TowerProofInputVariable, unipoly_extrapolator: &UniPolyExtrapolator, + // The number of product and lookup specs is fixed by the verifying key, so + // thread them in explicitly to keep the verifier loops static. + num_prod_specs: usize, + num_logup_specs: usize, ) -> ( PointVariable, Array>, Array>, Array>, ) { - let num_prod_spec = prod_out_evals.len(); - let num_logup_spec = logup_out_evals.len(); + let num_prod_spec = Usize::from(num_prod_specs); + let num_logup_spec = Usize::from(num_logup_specs); + let num_specs_usize = num_prod_specs + num_logup_specs; let one: Ext = builder.constant(C::EF::ONE); let zero: Ext = builder.constant(C::EF::ZERO); builder.assert_usize_eq(proof.prod_specs_eval.len(), num_prod_spec.clone()); - iter_zip!(builder, prod_out_evals).for_each(|ptr_vec, builder| { - let ptr = ptr_vec[0]; - let evals = builder.iter_ptr_get(&prod_out_evals, ptr); + for idx in 0..num_prod_specs { + let evals = builder.get(&prod_out_evals, Usize::from(idx)); builder.assert_usize_eq(evals.len(), num_fanin.clone()); - }); + } builder.assert_usize_eq(proof.logup_specs_eval.len(), num_logup_spec.clone()); - iter_zip!(builder, logup_out_evals).for_each(|ptr_vec, builder| { - let ptr = ptr_vec[0]; - let evals = builder.iter_ptr_get(logup_out_evals, ptr); + for idx in 0..num_logup_specs { + let evals = builder.get(logup_out_evals, Usize::from(idx)); builder.assert_usize_eq(evals.len(), RVar::from(4)); - }); + } builder.assert_usize_eq( num_variables.len(), num_prod_spec.clone() + num_logup_spec.clone(), ); let var_zero: Var = builder.constant(C::N::ZERO); - let num_specs: Var = builder.eval(num_prod_spec.get_var() + num_logup_spec.get_var()); - let should_skip: Array> = builder.dyn_array(num_specs); - builder.range(0, num_specs).for_each(|i_vec, builder| { - let i = i_vec[0]; - + let should_skip: Array> = builder.uninit_fixed_array(num_specs_usize); + for idx in 0..num_specs_usize { // all specs should not be skipped initially - builder.set_value(&should_skip, i, var_zero); - }); + builder.set_value(&should_skip, Usize::from(idx), var_zero); + } transcript_observe_label(builder, challenger, b"combine subset evals"); let alpha = challenger.sample_ext(builder); @@ -139,25 +139,19 @@ pub fn verify_tower_proof( builder.cycle_tracker_start("initial sum"); let initial_rt: Array> = builder.dyn_array(log2_num_fanin); transcript_observe_label(builder, challenger, b"product_sum"); - builder - .range(0, initial_rt.len()) - .for_each(|idx_vec, builder| { - let idx = idx_vec[0]; - let c = challenger.sample_ext(builder); - builder.set_value(&initial_rt, idx, c); - }); + for idx in 0..log2_num_fanin { + let c = challenger.sample_ext(builder); + builder.set_value(&initial_rt, Usize::from(idx), c); + } let prod_spec_point_n_eval: Array> = - builder.dyn_array(num_prod_spec.clone()); - - iter_zip!(builder, prod_out_evals, prod_spec_point_n_eval).for_each(|ptr_vec, builder| { - let ptr = ptr_vec[0]; - let evals = builder.iter_ptr_get(&prod_out_evals, ptr); + builder.uninit_fixed_array(num_prod_specs); + for idx in 0..num_prod_specs { + let evals = builder.get(&prod_out_evals, Usize::from(idx)); let e = evaluate_at_point_degree_1(builder, &evals, &initial_rt); - let p_ptr = ptr_vec[1]; - builder.iter_ptr_set( + builder.set( &prod_spec_point_n_eval, - p_ptr, + Usize::from(idx), PointAndEvalVariable { point: PointVariable { fs: initial_rt.clone(), @@ -165,35 +159,23 @@ pub fn verify_tower_proof( eval: e, }, ); - }); + } let logup_spec_p_point_n_eval: Array> = - builder.dyn_array(num_logup_spec.clone()); + builder.uninit_fixed_array(num_logup_specs); let logup_spec_q_point_n_eval: Array> = - builder.dyn_array(num_logup_spec.clone()); - - iter_zip!( - builder, - logup_out_evals, - logup_spec_p_point_n_eval, - logup_spec_q_point_n_eval - ) - .for_each(|ptr_vec, builder| { - let ptr = ptr_vec[0]; - let evals = builder.iter_ptr_get(&prod_out_evals, ptr); - + builder.uninit_fixed_array(num_logup_specs); + for idx in 0..num_logup_specs { + let evals = builder.get(logup_out_evals, Usize::from(idx)); let p_slice = evals.slice(builder, 0, 2); let q_slice = evals.slice(builder, 2, 4); let e1 = evaluate_at_point_degree_1(builder, &p_slice, &initial_rt); let e2 = evaluate_at_point_degree_1(builder, &q_slice, &initial_rt); - let p_ptr = ptr_vec[1]; - let q_ptr = ptr_vec[2]; - - builder.iter_ptr_set( + builder.set( &logup_spec_p_point_n_eval, - p_ptr, + Usize::from(idx), PointAndEvalVariable { point: PointVariable { fs: initial_rt.clone(), @@ -201,9 +183,9 @@ pub fn verify_tower_proof( eval: e1, }, ); - builder.iter_ptr_set( + builder.set( &logup_spec_q_point_n_eval, - q_ptr, + Usize::from(idx), PointAndEvalVariable { point: PointVariable { fs: initial_rt.clone(), @@ -211,27 +193,25 @@ pub fn verify_tower_proof( eval: e2, }, ); - }); + } let initial_claim: Ext = builder.eval(zero + zero); - iter_zip!(builder, prod_spec_point_n_eval).for_each(|ptr_vec, builder| { - let ptr = ptr_vec[0]; - let prod_eval = builder.iter_ptr_get(&prod_spec_point_n_eval, ptr); + for idx in 0..num_prod_specs { + let prod_eval = builder.get(&prod_spec_point_n_eval, Usize::from(idx)); builder.assign(&initial_claim, initial_claim + prod_eval.eval * alpha_acc); builder.assign(&alpha_acc, alpha_acc * alpha); - }); + } - builder - .range(0, num_logup_spec.clone()) - .for_each(|i_vec, builder| { - let p = builder.get(&logup_spec_p_point_n_eval, i_vec[0]); - builder.assign(&initial_claim, initial_claim + p.eval * alpha_acc); - builder.assign(&alpha_acc, alpha_acc * alpha); - let q = builder.get(&logup_spec_q_point_n_eval, i_vec[0]); - builder.assign(&initial_claim, initial_claim + q.eval * alpha_acc); - builder.assign(&alpha_acc, alpha_acc * alpha); - }); + for idx in 0..num_logup_specs { + let lk_idx = Usize::from(idx); + let p = builder.get(&logup_spec_p_point_n_eval, lk_idx.clone()); + builder.assign(&initial_claim, initial_claim + p.eval * alpha_acc); + builder.assign(&alpha_acc, alpha_acc * alpha); + let q = builder.get(&logup_spec_q_point_n_eval, lk_idx); + builder.assign(&initial_claim, initial_claim + q.eval * alpha_acc); + builder.assign(&alpha_acc, alpha_acc * alpha); + } builder.cycle_tracker_end("initial sum"); let curr_pt = initial_rt.clone(); @@ -244,10 +224,9 @@ pub fn verify_tower_proof( eval: initial_claim, }; - let next_layer_evals_output_len: Usize = builder - .eval(Usize::from(1) + num_prod_spec.clone() + Usize::from(2) * num_logup_spec.clone()); + let next_layer_evals_len = 1 + num_prod_specs + 2 * num_logup_specs; let next_layer_evals: Array> = - builder.dyn_array(next_layer_evals_output_len); + builder.dyn_array(next_layer_evals_len); builder.range(0, op_range).for_each(|i_vec, builder| { let round_var = i_vec[0]; @@ -374,49 +353,37 @@ pub fn verify_tower_proof( builder.if_ne(op_range, Usize::from(0)).then(|builder| { // update prod_spec and logup_spec evaluations at next_rt - let product_evals = { - let start: Var = builder.eval(Usize::from(1)); - let end: Var = builder.eval(start + num_prod_spec.clone()); - next_layer_evals.slice(builder, start, end) - }; - let logup_evals = { - let start: Var = builder.eval(Usize::from(1) + num_prod_spec.clone()); - let end: Var = builder.eval(start + Usize::from(2) * num_logup_spec.clone()); - next_layer_evals.slice(builder, start, end) - }; - - builder - .range(0, num_prod_spec.clone()) - .for_each(|i_vec, builder| { - let i = i_vec[0]; - let eval = builder.get(&product_evals, i); - - let point_and_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { - point: next_rt.point.clone(), - eval, - }); - builder.set_value(&prod_spec_point_n_eval, i, point_and_eval); + let product_evals = next_layer_evals.slice(builder, 1, 1 + num_prod_specs); + let logup_start = 1 + num_prod_specs; + let logup_evals = + next_layer_evals.slice(builder, logup_start, logup_start + 2 * num_logup_specs); + + for idx in 0..num_prod_specs { + let eval = builder.get(&product_evals, Usize::from(idx)); + + let point_and_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval, + }); + builder.set_value(&prod_spec_point_n_eval, Usize::from(idx), point_and_eval); + } + for idx in 0..num_logup_specs { + let lk_idx = Usize::from(idx); + let q_idx = Usize::from(num_logup_specs + idx); + let p_eval = builder.get(&logup_evals, lk_idx.clone()); + let q_eval = builder.get(&logup_evals, q_idx); + + let p_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval: p_eval, }); - builder - .range(0, num_logup_spec.clone()) - .for_each(|i_vec, builder| { - let i = i_vec[0]; - let p_idx = i; - let q_idx: Var = builder.eval(num_logup_spec.clone() + i); - let p_eval = builder.get(&logup_evals, p_idx); - let q_eval = builder.get(&logup_evals, q_idx); - - let p_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { - point: next_rt.point.clone(), - eval: p_eval, - }); - let q_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { - point: next_rt.point.clone(), - eval: q_eval, - }); - builder.set_value(&logup_spec_p_point_n_eval, i, p_eval); - builder.set_value(&logup_spec_q_point_n_eval, i, q_eval); + let q_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval: q_eval, }); + builder.set_value(&logup_spec_p_point_n_eval, lk_idx.clone(), p_eval); + builder.set_value(&logup_spec_q_point_n_eval, lk_idx, q_eval); + } }); ( diff --git a/ceno_recursion/src/zkvm_verifier/verifier.rs b/ceno_recursion/src/zkvm_verifier/verifier.rs index 169a26a19..33417be9a 100644 --- a/ceno_recursion/src/zkvm_verifier/verifier.rs +++ b/ceno_recursion/src/zkvm_verifier/verifier.rs @@ -584,6 +584,7 @@ pub fn verify_chip_proof( } let tower_proof = &chip_proof.tower_proof; + let num_rw_records_usize = r_len + w_len; let num_variables: Array> = builder.uninit_fixed_array(num_batched_usize); // Every entry of `num_variables` is identical, so emit straight-line assignments // with a compile-time bound driven by the verifying key. @@ -612,6 +613,8 @@ pub fn verify_chip_proof( num_var_with_rotation.clone(), tower_proof, unipoly_extrapolator, + num_rw_records_usize, + lk_len, ); builder.cycle_tracker_end(format!("verify tower proof for opcode {circuit_name}",).as_str()); @@ -627,7 +630,6 @@ pub fn verify_chip_proof( builder.cycle_tracker_end(format!("check tower proof p {circuit_name}",).as_str()); } - let num_rw_records_usize = r_len + w_len; let num_rw_records: Usize = Usize::from(num_rw_records_usize); builder.assert_usize_eq(record_evals.len(), num_rw_records.clone()); builder.assert_usize_eq(logup_p_evals.len(), lk_counts_per_instance.clone());