Skip to content

[precompile] part2 integrate keccak precompile into e2e flow #980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: master
Choose a base branch
from

Conversation

hero78119
Copy link
Collaborator

@hero78119 hero78119 commented Jul 6, 2025

gkr-iop circuit

This PR complete keccak precompile circuit construction, and try to separate clearly: for zkvm related circuit are construct in "keccak" opcode, while precompile only handle dedicate logic. For witness assignment also same principle, phase 1 witness are also assign separately for better modulariztion

circuit builder

lookup keccak circuit switch to new circuit builder and not depends on layer_constrain_system dependency.

e2e integration

keccak opcode are integrated into prover flow. It can be invoke via guest program: cargo run --package ceno_zkvm --release --bin e2e -- --platform=ceno --hints=1,6 examples/target/riscv32im-ceno-zkvm-elf/release/examples/ceno_rt_keccak

fixed RC processing

In this PR RC was refactor to use witness first, because I realized the design of expanding fixed poly (and commitment) according to num_instance is very complex because fixed poly in our codebase are assume immutable everywhere. Mutability involve quite of change which also seems unnessesary. In particular, fixed poly immutable should be common sense. Thus, I will try to figure out how to deal with RC (and fixed poly) properly later

Next steps (in next PR)

Integrate gkr-iop verifier into verifler flow

benchmark

cargo bench --features jemalloc --bench keccak --package ceno_zkvm -- --baseline baseline
mode # instructions # cycles proof size (mb) median time (ms) speedup (↑ better) proof size ratio (↓ better)
(baseline) w/o precompile 1,755,337 7,021,352 1.95 3.5385 1.00× (baseline) 1.00× (baseline)
precompile 732 2,932 4.51 2.18 1.62× 2.31×

on fibonacci against master remain no change

cargo bench --features jemalloc --bench fibonacci --package ceno_zkvm -- --baseline baseline
Benchmark Median Time (s) Median Change (%)
fibonacci_max_steps_1048576 2.1139 +0.5573% (No change in performance detected)
fibonacci_max_steps_2097152 3.6055 +1.6858% (Change within noise threshold)

@hero78119 hero78119 marked this pull request as draft July 6, 2025 15:06
@hero78119 hero78119 force-pushed the feat/gkr_iop_integration branch 2 times, most recently from f81759d to 3f77797 Compare July 7, 2025 09:58
@hero78119 hero78119 force-pushed the feat/gkr_iop_integration branch from a4bdf61 to 45e98d8 Compare July 8, 2025 10:09
@hero78119 hero78119 force-pushed the feat/gkr_iop_integration branch from 766666e to 9dd5207 Compare July 9, 2025 09:00
@hero78119 hero78119 marked this pull request as ready for review July 10, 2025 15:42
@hero78119 hero78119 requested a review from spherel July 10, 2025 15:50
@@ -879,8 +881,7 @@ pub fn verify<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + serde::Ser
transcript,
zkvm_proof.has_halt(&verifier.vk),
)?;
// print verification statistics like proof size and hash count
tracing::info!("e2e proof stat: {}", zkvm_proof);
Copy link
Collaborator Author

@hero78119 hero78119 Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was move to proof ready before verify, so even verify failed we still can see proof size data

Copy link
Member

@spherel spherel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First round finished. I will rebase my PR firstly and see if I have other questions.

@@ -115,12 +96,10 @@ impl<E: ExtensionField> MockProver<E> {
&layer.expr_names,
&layer.out_eq_and_eval_exprs
) {
if !expect.is_equal(&got) {
if expect != got {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a case that expect and got are equal, but one is saved as FieldType::Base(..) but the other is saved as FieldType::Ext(..)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes you are right and I verified it's syntatic equal.

I added this commit, moving is_equal into PartialEq trait definition

Comment on lines +89 to +92
Some(Expression::StructuralWitIn(id, ..)) => Expression::WitIn(offset_eq_id + *id),
invalid => panic!("invalid eq format {:?}", invalid),
};
zero_check_exprs.push(eq_expr * zero_check_expr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to change it from Expression::WitIn(..) to Expression::StructuralWitIn(..)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean reverse? what it actually do here is convert StructuralWitIn to WitIn, because gkr-iop backend only recognize Witin

Comment on lines +137 to +141
num_instances.push((
index,
num_instance >> vk.get_cs().rotation_vars().unwrap_or(0),
));
num_instances_with_rotation.push((index, num_instance))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why compute num_instances from num_instance >> vk.get_cs().rotation_vars().unwrap_or(0),))?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because what rmm.num_instances() return is height, or number of rows. With rotation, the relation between number of rows and real instance are got rotation factor. So to derive real num instances, we need to divide rotation size, thus we do right shit toward rotation num_vars

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants