Skip to content

feat(verifier): replace panics with error returns#1321

Merged
kunxian-xia merged 6 commits into
masterfrom
feat/verifier-crypto-contract
Apr 23, 2026
Merged

feat(verifier): replace panics with error returns#1321
kunxian-xia merged 6 commits into
masterfrom
feat/verifier-crypto-contract

Conversation

@kunxian-xia
Copy link
Copy Markdown
Collaborator

@kunxian-xia kunxian-xia commented Apr 22, 2026

Problem

A malformed proof could cause the verifier process to crash — any unwrap / expect / unchecked indexing / assert! on proof-derived data is a liveness / DoS risk (a crafted proof kills the process instead of being cleanly rejected).

Changes

  • Panic cleanup. Convert every assert! / assert_eq! / unwrap / expect / unchecked indexing on proof-derived data to ZKVMError returns across verify_proofs_halt, verify_proof_validity, verify_chip_proof, TowerVerify::verify, and EccVerifier::verify_ecc_proof. A malformed proof is now rejected cleanly in all paths.
  • Document the verifier's semantic contract. New sections in CLAUDE.md and docs/src/technical-overview.md ("What the verifier guarantees") state the two program-level facts a valid Ceno proof attests to: execution starts at vk.entry_pc and the terminal shard invokes the halt ecall. The exit code is deliberately not a verifier guarantee — public_values.exit_code is bound by the halt-ecall chip to register a0, but the guest program defines its own exit-code semantics, so a non-zero value may be a legitimate application signal. Callers that want "exited successfully" compare exit_code == 0 themselves.
  • CLAUDE.md additionally flags prefix proofs (expect-halt = false) as a dev/bench affordance, not a production surface. This caveat is contributor-facing and is kept out of the user-facing mdbook.

Test plan

  • cargo check --workspace --all-targets
  • cargo make clippy (workspace, -D warnings)
  • cargo test -p ceno_zkvm --lib (152 passed)
  • cargo test -p ceno_zkvm --lib scheme:: (18 passed)

kunxian-xia and others added 2 commits April 22, 2026 17:02
…de-zero invariant

- Convert all assert!/assert_eq!/unwrap/expect/unchecked indexing on
  proof-derived data in the verifier to ZKVMError returns, so a
  malformed proof is cleanly rejected instead of crashing the process.
  Covers verify_proofs_halt, verify_proof_validity, verify_chip_proof,
  TowerVerify::verify, and EccVerifier::verify_ecc_proof.
- Add an unconditional public_values.exit_code == 0 check per shard,
  making "program exited successfully" an explicit verifier-level
  invariant. On halting shards it is backed by the halt-ecall chip's
  binding to the a0 register argument; on non-halting shards the
  verifier enforces it directly so the field cannot carry forged bytes.
- Document the verifier's two-statement semantic contract (start at
  the verifying-key entry PC, exit with code zero) in CLAUDE.md and in
  a new "What the verifier guarantees" section at the top of
  docs/src/technical-overview.md. Flag prefix proofs as a dev/bench
  affordance, not a production verification surface.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…t/verifier-crypto-contract

# Conflicts:
#	ceno_zkvm/src/scheme/verifier.rs
@kunxian-xia kunxian-xia changed the title feat(verifier): replace panics with error returns and enforce exit code to 0 feat(verifier): replace panics with error returns Apr 22, 2026
Copy link
Copy Markdown
Collaborator

@hero78119 hero78119 left a comment

Choose a reason for hiding this comment

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

LGTM!

kunxian-xia and others added 4 commits April 22, 2026 22:26
The verifier binds public_values.exit_code to register a0 at the halt
site via the halt-ecall chip, but does not require any specific value.
Guest programs can legitimately halt with non-zero exit codes; callers
that want "exited successfully" compare exit_code == 0 themselves.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Prefix / dev-only modes belong in CLAUDE.md (contributor-facing), not
in the user-facing mdbook. Also tightens the Halt bullet to the
production semantic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…t/verifier-crypto-contract

Conflict in ceno_zkvm/src/scheme/verifier.rs: master's PR #1223 introduced
validate_mem_state covering both heap and hint continuation against the new
mem_state_verifier; took master's version since it subsumes this branch's
heap-only check and already returns ZKVMError rather than panicking, which
matches this branch's verifier-error contract.
@kunxian-xia kunxian-xia added this pull request to the merge queue Apr 23, 2026
Merged via the queue into master with commit 60fc10b Apr 23, 2026
6 checks passed
@kunxian-xia kunxian-xia deleted the feat/verifier-crypto-contract branch April 23, 2026 06:34
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.

2 participants