Skip to content

Comments

zk step provers (risc0 + zisk)#353

Draft
mpernambuco wants to merge 4 commits intomainfrom
perna/risc0-tweaks
Draft

zk step provers (risc0 + zisk)#353
mpernambuco wants to merge 4 commits intomainfrom
perna/risc0-tweaks

Conversation

@mpernambuco
Copy link
Collaborator

@mpernambuco mpernambuco commented Feb 6, 2026

  • ZK step verification pipeline, from proof generation through on-chain Groth16
    verification.
  • Initial ZisK prover integration.

Verification layers

Each layer builds on the one below it. The commands show the full
pipeline from recording a step to verifying it on Ethereum.

The same three values — hash_before, mcycle_count, hash_after — flow
through every layer:

Layer 1 — Replay (emulator)

Record a step log. The emulator automatically replays and verifies
the step log before returning:

cartesi-machine --log-step=mcycle_count,tep.log

The step log embeds hash_before, mcycle_count, and hash_after in its
header. Standalone verification is available via the library API
(machine:verify_step).

Layer 2 — ZK Proof (RISC0 STARK)

The replay runs inside RISC Zero's zkVM, producing a receipt:

cartesi-risc0-cli prove hash_before step.log mcycle_count hash_after receipt.bin
cartesi-risc0-cli verify receipt.bin hash_before mcycle_count hash_after

Layer 3 — Compact Proof (Groth16)

The STARK receipt is compressed into a 256-byte Groth16 seal and a
96-byte ABI-encoded journal, small enough to verify on-chain:

cartesi-risc0-cli prove-groth16 hash_before step.log mcycle_count hash_after seal.bin journal.bin
cartesi-risc0-cli verify-groth16 seal.bin journal.bin hash_before mcycle_count hash_after

Layer 4 — On-chain (Solidity)

CartesiStepVerifier receives the Groth16 seal and journal, verifies
the proof via the RISC Zero Verifier Router, and decodes the step
transition values:

contract CartesiStepVerifier {
    IRiscZeroVerifier public immutable verifier;

    function verifyStep(bytes calldata seal, bytes calldata journal)
        external view
        returns (bytes32 rootHashBefore, uint64 mcycleCount, bytes32 rootHashAfter)
    {
        verifier.verify(seal, ImageID.CARTESI_STEP_VERIFIER_ID, sha256(journal));
        (rootHashBefore, mcycleCount, rootHashAfter) = abi.decode(journal, (bytes32, uint64, bytes32));
    }
}

The ImageID constant is auto-generated from the reproducible guest
build (make -C risc0/solidity image-id). The Foundry test deploys
this contract against a Sepolia fork and exercises valid proofs,
tampered journals, and wrong Image IDs.

Emulator changes

  • Step log now embeds a 72-byte header (root_hash_before, mcycle_count,
    root_hash_after) before the page data and sibling hashes

RISC0

  • Upgraded to risc0-zkvm v3 (3.0.5)
  • Groth16 proving and verification (256-byte seal + 96-byte journal)
  • Reproducible guest builds via Docker (canonical Image ID across platforms)
  • CUDA GPU acceleration support (compile-time feature flag)
  • CLI tool (cartesi-risc0-cli) for prove, verify, Groth16, and artifact export
  • Foundry integration test against the RISC Zero Verifier Router on Sepolia
  • Boundless remote proving workflow (decentralized proving marketplace)
  • Runtime guest ELF override for non-Docker environments

RISC0 GPU Benchmark

STARK proving on an RTX 5090 (32 GB VRAM), RISC0 v3.0.5 with CUDA.

Step logs attached step-logs-benchmark.zip

To reproduce:

  mcycles   prove     verify   step log   receipt
  -------   --------  -------  --------   -------
        1     3.4 s    0.2 s      19 KB    789 KB
      100     5.2 s    0.2 s      35 KB    1.1 MB
  100,000   1m 40 s    2.7 s     153 KB     27 MB
1,000,000  14m 26 s   22.9 s     161 KB    230 MB

  # Build host with CUDA (requires rzup toolchain + NVIDIA GPU)
  make -C risc0 RISC0_FEATURES=cuda

  # If the build machine cannot run Docker (e.g. GPU containers),
  # build the guest elsewhere and pass it at runtime:
  #   make -C risc0 export-artifacts   (on a Docker-capable machine)
  #   cartesi-risc0-cli --guest-elf risc0/artifacts/cartesi-risc0-guest-step-prover.bin ...

  # Prove
  cartesi-risc0-cli prove \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    step-1.log 1 \
    f32e9c3d21f00fe5bcd85d381890568bc83dfedd9089153428722b426c98b01a \
    receipt-1.bin

  cartesi-risc0-cli prove \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    step-100.log 100 \
    9dd5dc81f0d49a8b5348c55b003fed5ca9fae35c7f88541ce93bf70280a3865e \
    receipt-100.bin

  cartesi-risc0-cli prove \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    step-100000.log 100000 \
    6dd4c569985af96b2bdfdefd614d046889fffe393593b503c9cae0a4b5ef6272 \
    receipt-100000.bin

  cartesi-risc0-cli prove \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    step-1000000.log 1000000 \
    b74578832e9b4168c790e59eab95549bea9c8a845cba5f7088e63fd92d6842a3 \
    receipt-1000000.bin

  # Verify
  cartesi-risc0-cli verify receipt-1.bin \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    1 \
    f32e9c3d21f00fe5bcd85d381890568bc83dfedd9089153428722b426c98b01a

  cartesi-risc0-cli verify receipt-100.bin \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    100 \
    9dd5dc81f0d49a8b5348c55b003fed5ca9fae35c7f88541ce93bf70280a3865e

  cartesi-risc0-cli verify receipt-100000.bin \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    100000 \
    6dd4c569985af96b2bdfdefd614d046889fffe393593b503c9cae0a4b5ef6272

  cartesi-risc0-cli verify receipt-1000000.bin \
    ee41a238926648eec0f6fadf2bf7d749b3554dab08d96930ac602ebf1a5f47d9 \
    1000000 \
    b74578832e9b4168c790e59eab95549bea9c8a845cba5f7088e63fd92d6842a3
	

ZisK

Adds initial ZisK prover integration targeting riscv64ima. The ZisK
guest shares the same C++ replay code and step log format as RISC0.
Building requires LLVM 20 and the ZisK toolchain (cargo-zisk, ziskemu).
All 285 step logs pass the ZisK emulator. Constraint verification and
proof generation are supported via cargo-zisk. On-chain verification
depends on the FFLONK pipeline under development by the ZisK team.

@mpernambuco mpernambuco changed the title Perna/risc0 tweaks zk step provers (risc0 + zisk) Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant