feat(verifier-ray): implement comptime vanishing polynomial check#3249
feat(verifier-ray): implement comptime vanishing polynomial check#3249ivokub wants to merge 40 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a comptime-driven vanishing-quotient verification path to verifier-ray, backed by Go codegen that extracts compiled *global.Verifier metadata from prover-ray systems and generates compact Zig vanishing.System fixtures plus prover-generated honest/invalid scenarios.
Changes:
- Introduces
verifier-ray/src/query/vanishing.zigto verify the PLONK quotient identity using comptime system metadata (modules/buckets/expressions/cancellations). - Adds
verifier-ray/codegensupport to extract and render vanishing-system data fromprover-ray’s compiledglobal.Verifieractions; generatestestdata/generated/vanishing.zigfixtures and adds Zig tests for scenario coverage. - Updates verifier runtime transcript inputs to absorb oracle commitments (vs raw oracle column vectors) and regenerates golden/runtime trace fixtures accordingly; removes prior
vortexstubs.
Reviewed changes
Copilot reviewed 35 out of 39 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| prover-ray/wiop/compilers/global/global.go | Exposes Verifier/VerifierBucket fields needed for extraction by verifier-ray codegen. |
| verifier-ray/Makefile | Adjusts test target wiring (notably test-zig) and target declarations. |
| verifier-ray/README.md | Updates high-level docs to reflect new codegen + vanishing flow and commands. |
| verifier-ray/build.zig | Adds test_vanishing module wiring for generated vanishing.zig fixtures. |
| verifier-ray/src/runtime.zig | Switches round messages to absorb oracle commitments and public values via a ColumnMessage union. |
| verifier-ray/src/query/vanishing.zig | New comptime vanishing quotient verifier (modules/buckets/expr evaluation + cancellation). |
| verifier-ray/src/field/koalabear_ext.zig | Adds powComptime for fixed-exponent fast paths. |
| verifier-ray/src/lib.zig | Exposes new query.vanishing module and removes vortex exports. |
| verifier-ray/src/vortex/verifier.zig | Removes placeholder vortex verifier stub. |
| verifier-ray/src/vortex/smt.zig | Removes placeholder SMT stub. |
| verifier-ray/src/vortex/ringsis.zig | Removes placeholder RingSIS stub. |
| verifier-ray/src/vortex/reed_solomon.zig | Removes placeholder Reed-Solomon stub. |
| verifier-ray/test/all.zig | Replaces removed vortex test import with vanishing tests. |
| verifier-ray/test/golden_test.zig | Updates runtime trace replay to new ColumnMessage structure and adds visibility tag check. |
| verifier-ray/test/transcript_test.zig | Updates runtime absorb test to use oracle commitments + public columns. |
| verifier-ray/test/vanishing_test.zig | New tests validating honest/invalid vanishing scenarios and dynamic module size validation. |
| verifier-ray/test/vortex_test.zig | Removes vortex “unsupported” placeholder test. |
| verifier-ray/testdata/README.md | Updates testdata layout/docs (generated fixtures + binary inputs). |
| verifier-ray/testdata/generated/vectors.zig | Regenerated fixtures reflecting commitment absorption + new trace encoding. |
| verifier-ray/testdata/generated/vanishing.zig | New generated vanishing systems + scenario proof views for Zig tests. |
| verifier-ray/testdata/generate/main.go | Extends generator to emit vanishing fixtures and adapt runtime trace generation to commitments. |
| verifier-ray/testdata/generate/go.mod | Uses local replaces for prover-ray and verifier-ray/codegen. |
| verifier-ray/testdata/generate/go.sum | Updates sums consistent with module dependency changes. |
| verifier-ray/codegen/go.mod | New Go module for verifier-ray codegen (depends on local prover-ray). |
| verifier-ray/codegen/go.sum | New dependency sums for the codegen module. |
| verifier-ray/codegen/vanishing.go | New extraction logic: build compact vanishing system from compiled global.Verifier actions. |
| verifier-ray/codegen/vanishing_zig.go | New Zig renderer (template-based) for vanishing system data. |
| verifier-ray/codegen/vanishing_test.go | New Go tests for vanishing system extraction/rendering invariants. |
| verifier-ray/codegen/cmd/ray-zig-codegen/main.go | Removes old stub CLI entrypoint. |
| verifier-ray/codegen/internal/generator/generator.go | Removes old stub generator implementation. |
| verifier-ray/codegen/internal/generator/generator_test.go | Removes tests for the deleted stub generator. |
| verifier-ray/codegen/internal/generator/writer.go | Removes stub generator writer helper. |
| verifier-ray/codegen/internal/generator/options.go | Removes stub generator options. |
| verifier-ray/codegen/internal/generator/emitters.go | Removes placeholder file for stub generator. |
| verifier-ray/docs/system-codegen.md | New documentation for compiled-system extraction and comptime verifier data rationale. |
| verifier-ray/docs/vanishing-pcs-integration-notes.md | New notes tracking assumptions to revisit once PCS/FRI is integrated. |
| verifier-ray/testdata/field/.gitkeep | Removes empty-dir placeholder. |
| verifier-ray/testdata/transcript/.gitkeep | Removes empty-dir placeholder. |
| verifier-ray/testdata/vortex/.gitkeep | Removes empty-dir placeholder. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4e07c4b. Configure here.
| if (input.quotient_claims.len != system.total_quotient_claims) return error.InvalidClaimCount; | ||
| if (input.module_sizes.len < system.dynamic_module_count) return error.MissingDynamicModuleSize; | ||
|
|
||
| var rt = runtime.Runtime.initWithRoundCount(3); |
There was a problem hiding this comment.
(the scope of this issue is beyond PCS. The PCS-related part is the one mentioned in the Vanishing PCS Integration Notes.)
The verify() function hardcodes a 3-round Fiat-Shamir runtime and absorbs exactly two messages before sampling coins:
var rt = runtime.Runtime.initWithRoundCount(3);
// absorb initial_round → sample merge_coins
rt.advanceRoundWithMessage(0, merge_message, &merge_coins);
// absorb quotient_round → sample eval_coins
rt.advanceRoundWithMessage(1, eval_message, &eval_coins);
Looking at the canonical pipeline in pipeline_test.go, there are always several pre-rounds before global in any real pipeline use:
rangecheck → lookuptologderivsum → logderivativesum → localvanishing → global
But look at what the prover does in [global.go:43-44]:
// initial_round r0: user witness round
// prior round r1, i.e. lookuptologderivsum
// prior round r2
// ...
quotientRound := sys.NewRound() // appended AFTER all existing rounds
evalRound := sys.NewRound() // appended after quotientRound
The prover's mergeCoin is derived after absorbing all prior rounds (from r0 + r1 + r2). The Zig verifier absorbs only initial_round (r0) before sampling, so it gets a different mergeCoin and evalCoin.
There was a problem hiding this comment.
You're completely right -- I was thinking about how to approach the issue. In the current prover side vanishing scenarios all cases have the fixed three rounds, but I essentially took a shortcut for now until I was able to figure out how to test in case we have more rounds.
I'll see if on the prover side they already have some more scenarios which would allow me to have a compatibility test as well.
I think another issue is that currently the round advancing is done in the vanishing verifier, but imo it should be in the higher-level proof verifier step and we should only pass on the coins (as you had in your PR).
There was a problem hiding this comment.
Oh, there are already wioptest.RangeCheckCompilerScenarios(), wioptest.LookupScenarios() etc. I could use. I'll also include these test scenarios as well and will try to fix that we may have more rounds.
And perhaps we can just provide the initialized runtime as an argument to vanishing query verifier.
There was a problem hiding this comment.
round advancement at the higher level makes sense to me. There are coins not only in the vanishing rounds, but also in the LookupToLogDerivSum round.
I think the clean split would be:
- higher-level driver owns:
Runtime, round advancement, and coin distribution - sub-verifiers own: the math check, given pre-sampled coins
There was a problem hiding this comment.
Partially resolved the issue -- now we consider all rounds compiled by the prover, not hardcoded to three. I also added all fixtures from the prover. There seems to be a bug where for edge cases (column size 1) the logderivativesum compiler doesn't emit any vanishing polynomial checks. I'm trying to confirm if this is expected (I think not, imo the system becomes unsound this way).
What I still haven't resolved is to move the coin generation to a higher level -- I already have all the tools required (particularly knowing the coin count needed for every round), but I just need to figure out the structuring -- I think I need to implement something in high-level verify which does the coin sampling and passes it on into vanishing query check. But now I still want to have the testing localized.
|
Closing -- proceeded by #3271 |

Summary
Adds prover-ray compatibility coverage for verifier-ray vanishing quotient checks. The branch extracts compiled
global.Verifieractions from prover-ray systems, code-generates Zigvanishing.Systemdata, and verifies prover-generated honest/invalid scenarios in Zig.Approach
System.Rounds[*].VerifierActionsand consume only*global.Verifieractions.vanishing.Systemso generated metadata is compiled into a dedicated verifier program instead of interpreted as a runtime DAG.CheckInput.module_sizes.verifier-ray/testdata/generated/and keep scenario systems and proof inputs side by side.Notes
PCS/FRI verification is intentionally not included yet. Witness and quotient evaluations are trusted fixture inputs for this compatibility layer; follow-up integration notes are tracked in
verifier-ray/docs/vanishing-pcs-integration-notes.md.Validation
make generate-testdatamake test-zigmake test-codegenmake fmt-zigmake fmt-codegenmake fmt-testdata-generateCloses #3192. I also cleaned up some of the previous stubs when initializing the project (i.e. vortex)
Checklist
PR.
Note
Medium Risk
New quotient verification logic and Fiat-Shamir round/coin ordering must stay aligned with prover-ray; witness and quotient evaluations remain trusted in fixtures until PCS is wired.
Overview
Adds prover-ray compatibility for the PLONK global vanishing quotient check in Zig: compiled
global.Verifiermetadata is extracted in Go, emitted as comptimevanishing.Systemdata, and checked byvanishing.verifyagainst prover-generated fixtures (honest and invalid scenarios).prover-ray exports
global.Verifier/VerifierBucketfields so codegen can read module size, witness/quotient claims, buckets, and expression trees. verifier-ray addscodegen(BuildVanishingSystem, Zig templates),src/query/vanishing.zig(comptime expression eval, cancellation, merge-coin aggregation, quotient identity), andpowComptimefor static domain sizes. The runtime now absorbs oracle commitments (Poseidon digests) instead of raw oracle column assignments; public columns/cells unchanged.testdata/generate runs the full compiler pipeline on
wioptestscenarios, writestestdata/generated/vanishing.zig, and refreshes transcript vectors for commitment-shaped rounds. Stub ray-zig-codegen and vortex placeholders are removed; docs cover codegen and PCS follow-ups. Makefile/README adjust testdata regeneration and zkc input byte order.Reviewed by Cursor Bugbot for commit baa15d3. Bugbot is set up for automated code reviews on this repo. Configure here.