Repository navigation
Conversation
Size the pre-first-squeeze transcript run from every advice phase up to and including the first challenge-bearing phase, not just phase 0, so the valid "advice in an early phase, challenge in a later phase" shape no longer under-sizes the buffer and overruns VK_MPTR. In the quotient VM limb-decomposition and product-add peepholes, re-check that fused opcode coefficients still fit their one-byte constant slots after intervening residue/base emission, falling back to generic ops instead of panicking in the u8::try_from(...).expect(...). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render now returns two extra artifacts for VM output, `quotient_listing` (text) and `quotient_manifest` (JSON). The generated .sol files are unchanged. The manifest records one entry per identity in `partially_evaluate_identities` order: gate name and polynomial index or family, target bucket, y exponent, execution kind (inline prefix, VM bytecode with its byte range, native callback, permutation, lookup or trash block), plus the constant table with VK offsets, the evaluation slot map, and keccak hashes of the program and constants. The listing is decoded from the final program bytes as embedded in the VK. For every VM identity it shows each instruction with symbolic operands and the polynomial rebuilt from the bytes, and it prints the Yul used for inline and native identities. Rendering fails closed if any VM identity's decoded program disagrees with `Expression::evaluate` at random points or symbolically, or if bytes or identities are not covered exactly once. Adds `examples/quotient_listing.rs`, which re-derives the listing from a deployed VK and checks it against a shipped listing and manifest, and docs/reference/QUOTIENT_LISTING.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
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.
Summary
Adds an annotated disassembly listing and a machine-readable identity manifest to the quotient-VM output. The goal is that an audit of the generated contracts alone can see which VM bytes implement which gate polynomial, and can regenerate that view from the deployed VK bytes. The generated
.solfiles are unchanged.RenderedArtifactsgainsquotient_listing: Option<String>(text) andquotient_manifest: Option<String>(JSON). Both are always produced for VM output; on Moonlight this costs about 10 ms of render time.Manifest. It has one entry per identity, in
partially_evaluate_identitiesorder. Each entry gives:It also contains:
All of it comes from the existing
execution_manifest/QuotientIdentitySourcemetadata.Listing. It is decoded from the final program bytes as embedded in the VK, after run compaction and packing.
a_3_next,2^56,r - 0x…), MODARITH7/LIN7/BILIN7/AFFINE_SUM/run opcodes expanded into their terms, and the polynomial rebuilt from the bytes.Validation (fails closed). The new decoder and interpreter (
vm/disasm.rs, all 31 opcodes, written from the Yul operand layouts) evaluates every VM identity at 4 random points and symbolically, and compares againstExpression::evaluateof the gate polynomial. It also checks that every program byte and every identity is covered exactly once. On failurerenderreturnsGeneratorError::Planning { stage: "quotient listing" }. This is a new way for render to fail on a generator bug; valid programs are unaffected.Auditor tool.
cargo run --example quotient_listing -- <Halo2VerifyingKey.sol|runtime.hex> <manifest.json> --listing <listing.txt> --verifier <Halo2Verifier.sol>re-derives the listing from the VK bytes and checks the hashes, the verifier's pins and anchors, and every block against the shipped listing. Exit status: 0 exact match, 2 match after a reported layout shift, 1 failure. The workflow is documented indocs/reference/QUOTIENT_LISTING.mdand referenced fromdocs/audit/REVIEW_PACKET.md.Tests
cargo test --release --lib: 156 passed. Withevm,rust-verifier-traceandHALO2_SOLIDITY_RUN_EVM_TESTS=1: 191 passed.The 12 new unit tests cover:
tests/quotient_listing_tool.rs: an exact round trip, a reported one-word header shift, and rejection of corrupted inputs.Fixture results (listing produced, full coverage, validation passes, and the tool round trip passes on each):
.solbyte identity: the tracked fixture dumps are unchanged, and the Moonlight B64/B8 renders are byte-identical to renders from6b3d2096.Moonlight wrap (Nightfall
fee_12345, B64 and B8)bd482567, whose VK has one extra header word (the quotient certificate). The constants and commitments match word for word; the program matches once its memory pointers are shifted by one word. The tool detects this and passes the production files with exit 2, and--outwrites the blocks in production addresses.Limitations
This branch is based on
6b3d2096, which is not yet onmain(the same base as #10), so it is included here.🤖 Generated with Claude Code