— On-Chain Verification —

WHAT IT WOULD ACTUALLY TAKE

AttestedVerifier is a trust bridge, not a cryptographic verifier -- this is the real gap between what exists and what trustless on-chain verification requires.

The two verifiers that exist today

UnimplementedStarkVerifier reverts, always — honest about doing nothing. AttestedVerifier accepts a proof once a trusted party attests off-chain that zkvm verify passed. That moves trust from "the EVM checked the math" to "you trust this one key" — legitimate for testing the rest of the system today, but it must never be described as trustless. See the Threat Model page for the full trust boundary.

The five pieces a real verifier needs, in order

1

Recompute Fiat-Shamir randomness

Re-derive every random challenge by hashing the same transcript the prover used. This project uses Blake3_256, which has no EVM precompile -- an on-chain verifier would need Keccak256 instead, which Winterfell already supports switching to.

2

Merkle authentication

Re-hash each authentication path up to the committed root. With 32 queries (this AIR's default), each log2(trace_length × blowup_factor) nodes deep, this is the bulk of verification gas cost.

3

FRI verification

Check the low-degree proof in rounds -- fold, check query-consistency via more Merkle paths, verify the final remainder polynomial. Algorithmically the most intricate part to port; every step needs the exact field arithmetic the prover used.

4

Field arithmetic

Winterfell's 128-bit prime field has no native EVM support -- every add/sub/mul must be hand-rolled Solidity/Yul, reduced mod that specific prime, matching the prover bit-for-bit.

5

Out-of-domain constraint check

Evaluate the AIR's transition constraints (VmAir::evaluate_transition, ported to Solidity) at the out-of-domain point. This is the step that actually encodes "was this the right AIR" -- it has to be hand-regenerated any time the AIR changes.

Why this isn't a small addition

Every real production STARK-on-Ethereum verifier — Starknet's, RISC Zero's, SP1's — is thousands of lines of specialized Solidity/Yul, built by teams with dedicated cryptography engineers, re-audited whenever the AIR or hash choice changes. Doing it correctly but insecurely doesn't fail loudly — it produces a verifier that silently accepts invalid proofs, strictly worse than AttestedVerifier's explicit trust assumption. That's why UnimplementedStarkVerifier reverts instead of stubbing something "close enough."

The path production systems actually take: wrap it in a SNARK

Because verifying a STARK directly on the EVM is so gas-heavy, most production systems instead run the STARK verifier itself as a program, prove that verifier's execution with a SNARK that has a small, fixed, cheap-to-verify proof and a real EVM precompile for the underlying pairing curve, and put only that small SNARK-verification call on-chain. STARK for cheap, fast, transparent-setup proving of the actual computation; a thin SNARK wrapper only for the part that has to run on Ethereum. This is "recursion" in practice — see the Recursion page for what that would specifically require for this AIR.

What would actually be worth building next, in order

  1. Switch the hasher from Blake3_256 to a Keccak/SHA3-family hasher — real, scoped, testable today.
  2. A native Rust reference verifier mimicking exactly what an on-chain verifier would do, as a test, before writing any Solidity/Yul.
  3. Only after that: a from-scratch Solidity/Yul verifier, or a SNARK-wrapping approach.

None of this is started. AttestedVerifier is the honest stand-in until it is.