Skip to content

feat(prover): Add Memory-mapped private input#508

Closed
ColoCarletti wants to merge 9 commits into
mainfrom
feat/private-input-memory-mapped
Closed

feat(prover): Add Memory-mapped private input#508
ColoCarletti wants to merge 9 commits into
mainfrom
feat/private-input-memory-mapped

Conversation

@ColoCarletti

Copy link
Copy Markdown
Collaborator
  • Implement memory-mapped private input (pre-loaded at 0xFF000000) replacing the old GetPrivateInputs ecall that was invisible to the prover

    • Fix three bugs that blocked proving Rust std programs and the ethrex empty block

    New feature: Memory-mapped private input

    The old GetPrivateInputs ecall copied bytes into guest memory without emitting Log entries — the prover never saw those writes, so verification always failed for any program reading
    private input.

    Now, private input is pre-loaded at 0xFF000000 as part of the initial memory image. The guest reads it via normal RISC-V loads. The PAGE table commits to the init values, so the Memory
    bus balances naturally.

    • New API: prove_with_input(elf_bytes, private_input)
    • VmProof includes private_input: Vec<u8> so the verifier can reconstruct PAGE commitments
    • GetPrivateInputs ecall (4) removed entirely
    • Guest-side get_private_input() rewritten as read_volatile from 0xFF000000
    • Removed stray print_string calls in sys_halt() and sys_getenv() that were orphan senders on the Ecall bus

    Bug fix 1: SRL extension mis-gating (Bus 13 — Shift)

    shift::compute_aux() set is_negative = MSB(in[3]) regardless of the signed flag. For logical right shift (SRL, signed=0), this produced wrong output when the input's top bit was
    set — the SHIFT table stored arithmetic-shift output instead of logical-shift output.

    Fix: let is_negative = self.signed && (self.in_halves[3] >> 15) & 1 == 1;

    The spec explicitly permits is_negative to be unconstrained when signed=0 (SHIFT-C13's MSB16 lookup is gated by signed).

    Bug fix 2: CSR instructions missing PC update (Bus 14 — Memw)

    DecodeEntry::from(Instruction::CSR) left all ALU flags at false, making pad=1 and CM54's multiplicity 0. The CPU didn't send PC-update tokens for CSR rows, but MEMW_R generated
    them unconditionally — creating orphan receivers.

    Fix: entry.op_add = true; — mirrors the existing Instruction::Fence pattern (no-op as ADDI x0, x0, 0).

    CSR instructions appear in Rust std programs because the toolchain injects csrrci x10, mstatus, 0 during startup.

    Bug fix 3: W-suffix instructions truncate register values in Log (Bus 16 — Memory)

    Instruction::ArithImmW and Instruction::ArithRegW stored the truncated 32-bit value in Log.src1_val/src2_val instead of the raw 64-bit register value:

    // Before (bug):
    let op1 = registers.read(src)? as i32;   // truncates to 32 bits
    src1_val: op1 as u64,                     // hi32 lost
    
    // After (fix):
    let raw_src = registers.read(src)?;       // full 64 bits
    let op1 = raw_src as i32;                // truncate for ALU only
    src1_val: raw_src,                        // full value in Log
    
    The prover uses src1_val as the register's value for the MEMW_R memory chain. When hi32 was lost, the chain broke for any register holding a 64-bit value accessed by a W-suffix
    instruction (ADDIW, SRLIW, SLLW, etc.). This only manifested in ethrex because its hash computations put large values in a0/a1.

@ColoCarletti

Copy link
Copy Markdown
Collaborator Author

/bench

@github-actions

github-actions Bot commented Apr 17, 2026

Copy link
Copy Markdown

Benchmark — fib_iterative_8M (median of 3)

Table parallelism: 32 (auto = cores / 3)

Metric main PR Δ
Peak heap 68340 MB 69168 MB +828 MB (+1.2%) ⚪
Prove time 33.922s 33.913s -0.009s (+-0.0%) ⚪

✅ No significant change.

⚠️ Baseline heap spread: 5.8% (66969 MB / 68340 MB / 70933 MB) — comparison may be less reliable

Commit: 9559d16 · Baseline: cached · Runner: self-hosted bench

@github-actions

github-actions Bot commented Apr 17, 2026

Copy link
Copy Markdown

Benchmark Results for modified programs 🚀

Command Mean [ms] Min [ms] Max [ms] Relative
head hashmap 108.3 ± 3.2 105.0 114.0 1.00
Command Mean [ms] Min [ms] Max [ms] Relative
head keccak 105.9 ± 6.3 97.6 122.0 1.00
Command Mean [ms] Min [ms] Max [ms] Relative
head syscall_commit 77.3 ± 0.9 76.2 78.6 1.00

@ColoCarletti

Copy link
Copy Markdown
Collaborator Author

/bench

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.

1 participant