-
Notifications
You must be signed in to change notification settings - Fork 281
feat: program commitment (bytecode + program image) #1221
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
quangvdao
wants to merge
45
commits into
a16z:main
Choose a base branch
from
quangvdao:quang/program-image-commitment
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add BytecodeReadRafAddressSumcheckProver/Verifier and BytecodeReadRafCycleSumcheckProver/Verifier - Add BooleanityAddressSumcheckProver/Verifier and BooleanityCycleSumcheckProver/Verifier - Add SumcheckId variants: BytecodeReadRafAddressPhase, BooleanityAddressPhase, BytecodeClaimReductionCyclePhase, BytecodeClaimReduction - Add VirtualPolynomial variants: BytecodeValStage, BytecodeReadRafAddrClaim, BooleanityAddrClaim, BytecodeClaimReductionIntermediate - Update prover: prove_stage6a() and prove_stage6b() - Update verifier: verify_stage6a() and verify_stage6b() - Update JoltProof: stage6a_sumcheck_proof and stage6b_sumcheck_proof - Add bytecode-commitment-progress.md planning doc
- BooleanityAddressSumcheckProver: now has its own state (B, G, F, gamma_powers) - BooleanityCycleSumcheckProver: now has its own state (D, H, eq_r_r, gamma_powers) - BytecodeReadRafAddressSumcheckProver: now has its own state (F, val_polys, int_poly) - BytecodeReadRafCycleSumcheckProver: now has its own state (ra, gruen_eq_polys, bound_val_evals) The into_cycle_prover() method now transfers only the necessary state rather than wrapping an inner shared struct. This makes the separation cleaner and prepares for potential future changes where the two phases might diverge further.
…d modes - BytecodePreprocessing::preprocess() now returns Self (caller wraps in Arc) - JoltSharedPreprocessing::new() takes &BytecodePreprocessing, stores bytecode_size - JoltProverPreprocessing stores Arc<BytecodePreprocessing> + optional commitments - JoltVerifierPreprocessing uses VerifierBytecode<PCS> enum (Full or Committed) - Added TrustedBytecodeCommitments<PCS> for type-safe commitment handling - Updated SDK macros to return (shared, bytecode) tuple - Updated all tests, guest/*, and benchmarks This refactor enables Committed mode where verifier only receives bytecode commitments instead of full O(K) bytecode data. Actual commitment computation is TODO for a future PR.
- Create jolt-core/src/zkvm/tests.rs with E2ETestConfig infrastructure - Port all 15 e2e tests from prover.rs to unified test runner - Add committed bytecode mode tests (ignored until verifier ready) - Wire verifier Stage 6a to branch on BytecodeMode (committed path) - Update read_raf_checking for optional bytecode preprocessing - Update bytecode-commitment-progress.md with status
- Add macro-generated preprocess_<func> and keep verifier preprocessing derived from prover - Update examples and host template to the new 2-call workflow - Fold bytecode preprocessing refactor notes into bytecode-commitment-progress.md (single authoritative doc) - Fix bigint inline assembly gating to avoid host build failures
Expose compute_bytecode_vmp_contribution for external callers (e.g., GPU prover) and remove #[cfg(test)] restriction from set_layout.
Delegate to compute_bytecode_vmp_contribution to eliminate code duplication.
…lding - Initialize bytecode Dory context using main matrix dimensions to support embedding in Stage 8. - Update VMP contribution logic to use correct column count. - Handle trailing dummy rounds in BytecodeClaimReductionProver for batched sumcheck alignment. - Pass max_trace_len to TrustedBytecodeCommitments derivation.
Add committed program-image support in committed bytecode mode via staged scalar claims + a degree-2 claim reduction, and avoid materializing initial RAM in verifier Stage 4. Fix Stage 8 joint opening by aligning Main context dimensions with trusted commitment dimensions.
…sing into ProgramPreprocessing Introduce unified types for program data handling: - ProgramPreprocessing: merges bytecode instructions and program image words - ProgramMetadata: lightweight metadata replacing RAMPreprocessing - TrustedProgramCommitments: unified commitments for bytecode + program image - VerifierProgram: enum for Full/Committed verification modes Remove zkvm/program_image.rs (superseded by program.rs) and update all callsites.
Rename BytecodeMode → ProgramMode since it now controls both bytecode and program image commitment (not just bytecode). Changes: - BytecodeMode enum → ProgramMode in config.rs - bytecode_mode field → program_mode in proof/prover structs - gen_from_elf_with_bytecode_mode → gen_from_elf_with_program_mode - Test names: *_committed_bytecode → *_committed_program Add 14 new committed program mode tests covering: - Small/large traces, different Dory layouts - Various programs (sha2, sha3, merkle-tree, memory-ops, muldiv) - Advice + committed program interaction Two tests ignored pending investigation: - fib_e2e_committed_large_trace (CycleMajor at 2^17) - btreemap_e2e_committed_program (Stage 8 failure) Delete program-image-commitment-progress.md (all TODOs complete).
For CycleMajor layout, bytecode polynomial coefficient indexing uses `lane * T + cycle`. When T differs between commitment time (max_trace_len) and proving time (padded_trace_len), row indices don't align, causing Stage 8 verification to fail. The fix: - Store bytecode_T in TrustedProgramCommitments for VMP indexing - For CycleMajor, commit bytecode with main-matrix dimensions - Ensure padded_trace_len >= bytecode_T in committed mode prover - Pass bytecode_T through streaming RLC context to VMP computation Re-enables previously failing tests: - fib_e2e_committed_large_trace - btreemap_e2e_committed_program
Replace the dense `ProgramIOPolynomial` with sparse evaluation that avoids allocating a large vector for the entire IO region. - Add `eval_io_mle` for sparse evaluation of IO polynomial (inputs, outputs, panic, termination bits) with proper domain embedding - Add `sparse_eval_u64_block` helper for evaluating u64 blocks at offset - Rename `evaluate_public_initial_ram_evaluation` to `eval_initial_ram_mle` - Remove `program_io_polynomial.rs` module This optimization is important when the IO region is large (large max_input_size or max_output_size), as the previous implementation allocated a dense vector of size `io_region.next_power_of_two()`.
Brings in the IO polynomial optimization: - Add eval_io_mle for sparse evaluation of IO polynomial - Rename functions to eval_initial_ram_mle, eval_inputs_mle, sparse_eval_u64_block - Remove program_io_polynomial.rs module
Add missing trait implementation that was causing zklean-extractor compilation to fail in CI.
- Replace fully qualified paths with imports in prover.rs and verifier.rs
- Consolidate scattered imports into main use crate::{...} blocks
- Store bytecode_read_raf_params and booleanity_params in prover state
instead of passing between prove_stage6a and prove_stage6b
ProgramImageClaimReduction prover now parallelizes per-round evaluation across lanes. BytecodeClaimReduction verifier avoids per-chunk allocations by evaluating lane weights via an inner product.
Add tracing::instrument spans to claim reduction methods for profiling. Gate MontU128Challenge import behind cfg(not(feature = "challenge-254-bit")).
Centralize canonical lane offsets and expose a sparse evaluator for the bytecode lane vector. This localizes one-hot/boolean semantics so higher-level protocols can avoid dense scans.
Avoid materializing/binding dense weight chunk polynomials by separating eq(r_bc,cycle) from lane-only weights. Also adds a fast first-round evaluator using sparse one-hot/boolean lane semantics.
Move mid-file `use` statements to top-level import blocks and replace fully qualified paths (3+ segments) with short names via `use` statements.
Refactors BytecodeReadRafCycleSumcheckProver and BooleanityCycleSumcheckProver to derive cycle-phase state directly from Stage 6a openings instead of replaying the address sumcheck. Key changes: - Add `gruen_poly_from_evals_with_q0` helper to construct round polynomials by computing q(0) directly, avoiding need for stage claims - Remove `prev_round_claims` and `prev_round_polys` fields from cycle prover - Compute `bound_val_evals` from accumulator-staged Val claims or direct eval - Add `ActiveLaneValue` enum and `for_each_active_lane_value` for sparse lane iteration in bytecode VMV contribution - Parallelize `compute_bytecode_vmp_contribution` with thread-local accum
Resolved conflicts in RAM module by keeping ProgramMode branching logic for Full vs Committed modes. Preserved separate RAMPreprocessing (metadata) and ProgramImagePreprocessing (data) structs to support committed-mode verification without O(program_size) data.
The analyze function's return type ProgramSummary was not in scope because the imports were placed inside the function body, not at the module level. Using the fully qualified path fixes the compile error.
Add tracing spans to compute_message and ingest_challenge methods in BooleanityCycleSumcheckProver and BytecodeReadRafCycleSumcheckProver.
Match prover pattern: store bytecode_read_raf_params and booleanity_params in JoltVerifier fields between stage 6a and 6b instead of passing as arguments.
Reuse main_sigma_nu() in case available
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This PR introduces Committed Program Mode, extending the bytecode commitment work to also commit to the initial RAM (program image). This enables fully succinct verification independent of both bytecode size and program image size.
This PR supersedes #1213 (bytecode commitment only) by:
BytecodePreprocessingandProgramImagePreprocessinginto a singleProgramPreprocessingtypeTrustedProgramCommitmentsfor both bytecode and program image commitmentsKey Additions (Beyond Bytecode Commitment)
1. Program Image Commitment
New file:
jolt-core/src/zkvm/claim_reductions/program_image.rsClaim reduction sumcheck that binds the program-image contribution to
Val_init(r_address)claims from Stage 4 to a trusted commitment:ProgramImageClaimReductionParams: Stores gamma, opening points, padded lengthProgramImageClaimReductionProver/Verifier: Runs the claim reduction sumcheckCommittedPolynomial::ProgramImageInitopening for Stage 8 batchingRAM module additions (
jolt-core/src/zkvm/ram/mod.rs):prover_accumulate_program_image(): Computes and stages program-image contribution claimsverifier_accumulate_program_image(): Stages opening points without materializing RAM2. Unified Program Preprocessing
New file:
jolt-core/src/zkvm/program.rsConsolidated types for all static program data:
Removed file:
jolt-core/src/zkvm/program_image.rs(folded intoprogram.rs)3. Verifier No Longer Materializes Initial RAM
In committed mode, the verifier:
build_initial_ram_state()(avoids O(program_size) work)verifier_accumulate_program_image()to stage claimsProgramImageClaimReductionVerifierto bind claims to commitmentprogram_image_commitment4. Stage 8 Program Image Integration
File:
jolt-core/src/poly/rlc_polynomial.rsProgramImageInithandling inStreamingRLCContextPreprocessing API Changes
Before (separate types)
After (unified type)
Key Difficulties & Solutions
1. Program Image Padding for Main Sigma Compatibility
Problem: Small program images may have fewer words than Main's
num_columns, making the matrix degenerate.Solution: In committed mode, pad program image to at least
main_num_columns:2. Trace-Dense Embedding for Program Image
Problem: Program image lacks lane variables, so it must be embedded specially in Stage 8.
Solution: Use contiguous block embedding (CycleMajor) or stride-by-K embedding (AddressMajor), mirroring advice polynomial handling.
3. Stage 4 Claim Staging
Problem: Stage 4's
Val_init(r_address)computation requires O(program_size) work for the program-image contribution.Solution: In committed mode, prover stages scalar claims via
prover_accumulate_program_image(), which are later bound to the commitment in Stage 6b via claim reduction.Files Changed (Summary)
New Files
jolt-core/src/zkvm/program.rs- Unified program preprocessingjolt-core/src/zkvm/claim_reductions/program_image.rs- Program image claim reductionDeleted Files
jolt-core/src/zkvm/program_image.rs- Superseded byprogram.rsMajor Changes
jolt-core/src/zkvm/prover.rs- Unified preprocessing, program image accumulationjolt-core/src/zkvm/verifier.rs- Program image verification, claim reductionjolt-core/src/zkvm/ram/mod.rs-prover/verifier_accumulate_program_imagefunctionsjolt-core/src/poly/rlc_polynomial.rs- Stage 8 program image handlingjolt-sdk/macros/src/lib.rs- Updated preprocessing API64 files changed, 6832 insertions(+), 1627 deletions(-)
Testing
All existing tests pass, including:
fib_e2e_committed_bytecode(CycleMajor + AddressMajor)bytecode_mode_detection_full/committedUsage