feat: add PCS assist Dory opening formulas#1601
Conversation
289808a to
627edbd
Compare
aa8e52f to
fd5609e
Compare
|
Stack maintenance — rebased onto #1600 and retargeted this PR's base to 📚 Stack A: #1596 → #1597 → #1598 → #1599 → #1600 → #1601 (this PR) → #1602 → #1603 #1596 and #1597 are shared by both stacks; each PR targets the one before it. Conflict resolution
|
|
Claude code review session started: https://claude.ai/code/session_01AU8AYnvPCA7UnbdxegABgM |
moodlezoup
left a comment
There was a problem hiding this comment.
Reviewed the Dory PCS-assist additions. The formula/relation tree under dory_assist/ is the bulk of the diff but isn't wired into live verification yet (only the no-op NoPcsAssist exists), so I focused on the code that compiles and runs: the dory scheme/streaming/types changes and the stage-8 opening path.
Main thing to look at: the clear DoryScheme::verify no longer rejects ZK-artifact proofs, and with the zk dory feature always on this lets a ZK-shaped proof pass PCS::verify while ignoring the claimed evaluation — a binding gap in the stage-8 clear path. Details inline. Also two new verifier files (pcs_assist.rs, stage8/final_openings.rs) are orphan modules that never get compiled, and a combine_hints row-count divergence from core that's latent for now.
The reduce-round transcript replay, fold-factor coordinate math, one-hot commitment fast paths, the repr(transparent) transmutes, and the streaming bounds checks all read correctly against the upstream dory implementation.
Generated by Claude Code
| } | ||
|
|
||
| dory::verify::<ArkFr, InnerBN254, G1Routines, G2Routines, _>( | ||
| dory::verify::<ArkFr, InnerBN254, JoltG1Routines, JoltG2Routines, _>( |
There was a problem hiding this comment.
This drops the guard that rejected proofs carrying ZK artifacts (e2/y_com/sigma1_proof/sigma2_proof/scalar_product_proof) on the clear path. dory is built with zk enabled unconditionally (root Cargo.toml), so the #[cfg(feature = "zk")] branch in verify_evaluation_proof is always live: when those fields are Some, it takes e2 from the proof and the caller-supplied eval is never used (only the (None, None) arm binds e2 = g2_0^eval). It then only checks the sigma proofs, i.e. that y_com/e2 open to some value — not that that value equals eval.
stage8_clear calls PCS::verify(&joint_commitment, point, joint_claim, &proof.joint_opening_proof, …). A prover who submits a ZK-shaped joint_opening_proof gets Ok(()) regardless of joint_claim, severing the binding between the sumcheck-derived claim and the committed witness. The clear stage-8 path is internally reachable in this crate, so the binding is unsound here even though jolt-verifier isn't the production verifier yet.
types.rs already has has_transparent_opening_artifacts() — restore the rejection (call it and bail otherwise) on the clear path. verify_zk is fine since it requires y_com.is_some() and dory rejects mixed shapes.
Generated by Claude Code
| let num_rows = hints | ||
| .iter() | ||
| .map(|hint| hint.row_commitments.len()) | ||
| .max() |
There was a problem hiding this comment.
The comment says this resizes "to the global max" like core, but it uses the per-call batch max (hints.iter().map(len).max()), whereas jolt-core/src/poly/commitment/dory/commitment_scheme.rs:311 uses DoryGlobals::get_max_num_rows(). These agree only when the batch happens to contain a hint at the global row count. If combine_hints is ever called on a subset whose local max is smaller than 2^nu, the combined hint is shorter than the matrix shape open/dory::prove derive from point.len(). Latent today (the live prover still uses the core impl), but worth aligning before this crate replaces it — either resize to the global max or document why the batch always contains the max-width hint.
Generated by Claude Code
| @@ -0,0 +1,100 @@ | |||
| //! Generic PCS-assist verifier boundary. | |||
There was a problem hiding this comment.
This file isn't declared anywhere — lib.rs lists only compat, config, error, preprocessing, proof, stages, verifier, and there's no #[path]/build.rs pulling it in. As an orphan module it's excluded from compilation, so the PcsProofAssist trait, NoPcsAssist impl, and the input structs get no cargo build/clippy/test coverage and can silently rot. If it's intended scaffolding for a later stack PR, either add pub mod pcs_assist; now so CI checks it, or hold the file until the consumer lands. (Same applies to crates/jolt-verifier/src/stages/stage8/final_openings.rs, which stage8/mod.rs doesn't declare.)
Generated by Claude Code
| @@ -0,0 +1,595 @@ | |||
| #[cfg(feature = "field-inline")] | |||
There was a problem hiding this comment.
stage8/mod.rs declares only inputs, outputs, verify — there's no mod final_openings;, so these 595 lines (and their #[cfg(test)] module) are never compiled. None of stage8_final_opening_* are referenced from stage8/verify.rs. Add the mod declaration so it's type-checked/linted, or defer the file until it's wired into the verify flow.
Generated by Claude Code
6d77405 to
fd2a7a3
Compare
Squashed feat + adapt-to-stack during rebase onto restacked parent.
dfaf326 to
8af0b23
Compare
Part of the draft Jolt prover stack.
Base:
prover-stack/05-hyperkzg-zkHead:
prover-stack/06-pcs-assist-dory-openingsAdds Dory PCS-assist opening formulas, verifier protocol hooks, and the Dory assist protocol spec.
Validation before submission:
cargo fmt -q -- --checkcargo metadata --no-deps --format-version 1gh stack pushsimulation against a temporary bare remotehandoffs/, oldSTACK.md,stack/, and old stack workflow