Fix(prover): fix issues blocking Rust std program verification#511
Conversation
Codex Code ReviewNo actionable issues found in the PR diff. I reviewed the changed hunks for security (VM/prover semantics, syscall behavior, Rust unsafe/asm), correctness, and significant performance risks, and didn’t find regressions or vulnerabilities introduced by these changes. Residual risk: I did not run the test suite in this review pass. |
ReviewFour targeted, well-described fixes. The root-cause analysis in the PR description is accurate and matches the diffs. What's correct
Issues foundThree low-severity issues, all in new test/example code — the core fixes are clean:
|
|
Benchmark Results for modified programs 🚀
|
|
Benchmark Results for unmodified programs 🚀
|
|
/bench |
Benchmark — fib_iterative_8M (median of 3)Table parallelism: 32 (auto = cores / 3)
Commit: 82ca002 · Baseline: cached · Runner: self-hosted bench |
Summary
print_stringcalls that emitted orphan Print ecalls (Bus 19 imbalance)These four issues combined made it impossible to prove any Rust std program. After this PR,
allocator.elf,commit_sum.elf, andethrex.elfall verify correctly.Changes
SRL extension gating (
prover/src/tables/shift.rs)compute_aux()setis_negative = MSB(in[3])regardless of thesignedflag. For logical right shift (SRL,signed=0), this filled the output with 1s instead of 0s when the input'stop bit was set — producing arithmetic-shift output. The SHIFT trace disagreed with the CPU trace, imbalancing Bus 13.
The spec's SHIFT-C13 constraint (
MSB16[is_negative; in[3]]) is gated bysigned, leavingis_negativeunconstrained for SRL. The fix setsis_negative = self.signed && MSB(in[3]),which is the only value that produces correct SRL output.
CSR instruction decoding (
prover/src/tables/types.rs)DecodeEntry::from(Instruction::CSR)left all ALU flags at zero. This madepad = 1, so CM54's multiplicity was 0 — the CPU never sent PC-update tokens for CSR rows. But MEMW_Runconditionally generated PC rows, creating orphan receivers on Bus 14.
The fix sets
op_add = true, mirroring the existingInstruction::Fencetreatment (no-op asADDI x0, x0, 0). CSR instructions appear in Rust std programs because the toolchaininjects
csrrci x10, mstatus, 0during startup.W-suffix register value truncation (
executor/src/vm/instruction/execution.rs)ArithImmWandArithRegWstored the truncated 32-bit value inLog.src1_val/src2_val:The prover uses src1_val as the register value for the MEMW_R Memory bus chain. When the upper 32 bits were lost, the chain broke for any register holding a 64-bit value accessed by a
W-suffix instruction. This only manifested in programs that put large values in registers (e.g., ethrex's hash computations).
Stray Print ecall removal (syscalls/)
sys_halt() and sys_getenv() called print_string(), emitting Print ecalls (#1) that have no receiver on the Ecall bus. Every Rust std program hit this on every execution, imbalancing Bus
19.