SNIP 36: How Starknet is Bringing Proof Verification In-Protocol — and What It Unlocks


Zero-knowledge proofs are often described as the endgame for blockchain scaling and privacy. But there is an uncomfortable gap between generating a proof and using it on-chain. Today, verifying a STARK proof inside a Starknet smart contract is not just expensive — it is practically impossible given calldata limits and gas costs. SNIP 36 proposes a protocol-level solution that could change this entirely.

The proposal introduces in-protocol proof verification: rather than forcing contracts to process raw proof data, the Starknet OS itself verifies proofs and exposes the results — called proof facts — as native primitives that any contract can query. This seemingly simple architectural decision has profound consequences. It unlocks two capabilities the ecosystem has wanted for years: infinite horizontal scaling through ZKThreads and genuine transaction-level privacy. Let us break down how it works, what it enables, and what challenges remain.


The Problem: Why On-Chain Proof Verification Does Not Work Today

If you want to verify a STARK proof inside a Starknet smart contract today, you face a hard wall. A typical STARK proof weighs between 50 and 200 KB. Starknet transactions have strict calldata limits, and even if you could somehow fit a proof into a transaction, the computational cost of verifying it — running FRI commitment checks, evaluating AIR constraints, performing Merkle path verification — would blow past any reasonable gas budget.

This is not a Starknet-specific problem. Ethereum L1 has the same issue, which is why rollups use dedicated verifier contracts with special precompiles. But the key insight of SNIP 36 is that Starknet, as a STARK-based L2, already has a proving infrastructure in its DNA. The Starknet OS already verifies proofs as part of its block production pipeline. Why not expose that capability to application developers?

Without in-protocol verification, developers who want to build proof-dependent applications — privacy pools, recursive rollups, verifiable computation marketplaces — are stuck. They either build fragile off-chain verification systems, wait for custom opcodes, or give up and build on chains that have SNARKs as precompiles. SNIP 36 offers a native path forward.


The Solution: Proof / Proof-Facts Separation

The core design principle of SNIP 36 is a clean separation between proof verification (computationally expensive, done by the protocol) and proof fact consumption (cheap, done by smart contracts).

Here is the flow:

┌──────────────┐     ┌─────────────────┐     ┌──────────────────┐
│   Prover     │────>│  Starknet OS    │────>│  Smart Contract  │
│ (off-chain)  │     │ (verifies proof)│     │ (reads facts)    │
└──────────────┘     └─────────────────┘     └──────────────────┘
       │                      │                       │
  Generates proof      Extracts proof facts     Queries fact registry
  + submits via        + stores in protocol     + acts on verified data
    JSON-RPC             state                    (no proof data needed)

Step 1 — Proof Submission. A prover generates a STARK proof off-chain (using SHARP, Stwo, or any compatible prover) and submits it to a Starknet node via a new JSON-RPC endpoint. The proof never touches the contract layer.

Step 2 — Protocol-Level Verification. The Starknet OS — which already runs Cairo programs and produces validity proofs for L1 — verifies the submitted proof as part of block production. If the proof is valid, the OS extracts the public outputs of the proven computation.

Step 3 — Fact Registration. These public outputs are registered as proof facts in protocol state. A proof fact is essentially a hash-indexed record: “computation X with inputs Y produced outputs Z, and this has been verified.”

Step 4 — Contract Consumption. Any smart contract can now query the fact registry. Instead of receiving and parsing a 100 KB proof, the contract simply asks: “Has fact F been verified?” This is a single storage read — cheap, fast, and composable.

The elegance here is that proof verification cost is amortized across the entire block, absorbed into the existing Starknet OS proving cycle. Individual contracts pay only for the storage lookup.


How It Works Technically

The Proving Pipeline

To understand what SNIP 36 is verifying, it helps to trace how a STARK proof is produced:

  1. Execution Trace. The prover runs a Cairo program and records every computational step in a table — rows are steps, columns are registers. This trace captures the full computation.

  2. AIR Constraints (Algebraic Intermediate Representation). The trace is encoded as polynomial constraints. Boundary constraints fix values at specific rows; transition constraints enforce relationships between consecutive rows (e.g., a[i+1] = a[i] + b[i]). If the program executed correctly, all constraints are satisfied.

  3. FRI Protocol (Fast Reed-Solomon IOP of Proximity). The prover commits to evaluations of the constraint polynomials, then enters the FRI folding process: split the polynomial into even and odd parts, fold with a random challenge, repeat until the polynomial is constant. The verifier spot-checks the folding to confirm the polynomial has low degree — which implies the constraints hold.

  4. STARK Proof. The complete proof bundles the FRI commitments, query responses, and Merkle authentication paths. It is transparent (no trusted setup), relies only on hash function collision resistance, and is quantum-resistant.

SNIP 36 does not change this pipeline. It simply moves the verification step from “impossible inside a contract” to “native OS operation.”

The Virtual OS Layer

A key architectural piece is the Virtual OS — an abstraction layer within the Starknet OS that manages proof lifecycle operations. The Virtual OS:

  • Receives proof submissions from the JSON-RPC layer
  • Dispatches verification to the appropriate verifier (supporting multiple proof systems over time)
  • Manages the fact registry as part of the OS state
  • Ensures facts are available within the same block or a deterministic number of blocks after submission

This is important because it means the proof verification system is extensible. Phase 1 may support only Stwo proofs with a specific program hash format, but the Virtual OS architecture allows future phases to add Groth16 verification, Plonk, or custom circuits without changing the contract-facing API.

JSON-RPC Interface

Provers interact with the system through new JSON-RPC methods:

  • Submit proof: sends the proof blob and associated metadata (program hash, public inputs) to the node
  • Query fact status: checks whether a specific fact has been verified and registered
  • Get fact data: retrieves the public outputs associated with a verified fact

From the smart contract side, fact queries are exposed as system calls — similar to how contracts currently access block timestamps or caller addresses.


What This Unlocks

ZKThreads: Infinite Horizontal Scaling

ZKThreads are Starknet’s answer to the “one sequencer, one execution environment” bottleneck. The idea: application-specific execution environments (think L3s) that run their own logic, produce STARK proofs, and settle back to Starknet.

Without SNIP 36, a ZKThread has no way to trustlessly settle on Starknet. The proof it generates cannot be verified by a Starknet contract. With SNIP 36, the settlement flow becomes:

  1. ZKThread executes transactions in its own environment
  2. ZKThread prover generates a STARK proof of the state transition
  3. Proof is submitted to Starknet via JSON-RPC
  4. Starknet OS verifies and registers the fact
  5. A settlement contract on Starknet reads the fact and updates the ZKThread state root

This creates a fractal scaling architecture: Starknet itself is a validity rollup on Ethereum, and ZKThreads are validity rollups on Starknet. Each layer inherits the security of the layer below. A game running on a ZKThread gets 10,000+ TPS at near-zero cost, while its state is ultimately anchored to Ethereum L1 security.

The key advantage over building separate L3s is shared liquidity and composability. ZKThreads on Starknet share the same token standards, bridge infrastructure, and DeFi protocols. Users do not need to bridge assets across fragmented chains.

Privacy: From “De Facto” to Formally Zero-Knowledge

This is where things get genuinely interesting — and subtle. Starknet already uses zero-knowledge proofs for scaling, but it does not use the zero-knowledge property of those proofs. The proofs verify correct execution (validity), but all transaction data is public. The ZK in “ZK-rollup” is about compression, not confidentiality.

SNIP 36 changes this by enabling contracts to act on proof facts without seeing the underlying data. Consider a private transfer:

  1. Alice wants to send tokens to Bob without revealing the amount or recipient on-chain
  2. A prover generates a STARK proof that: “Starting from balance tree root R1, a valid transfer occurred, resulting in new root R2, and the sender had sufficient balance”
  3. The proof is verified by the Starknet OS; the fact registered is: (program_hash, R1, R2, nullifier)
  4. The smart contract checks the fact, verifies the nullifier has not been used, and updates the state root from R1 to R2
  5. No amount, sender, or recipient appears on-chain

The contract never sees the proof. It never sees the private inputs. It only sees the verified statement that a valid transition occurred.


Privacy Patterns Enabled by SNIP 36

With in-protocol proof verification, several privacy patterns become practical on Starknet:

Private Transfers (Commitment-Nullifier Pattern)

The classic pattern from Zcash and Tornado Cash, adapted for Starknet:

  • Users deposit into a commitment pool: commitment = H(secret || value || recipient)
  • Commitments are stored in an on-chain Merkle tree
  • To withdraw, the user provides a nullifier N = H(secret, domain_separator) and a proof that N corresponds to a valid commitment in the tree
  • The proof is verified by the OS; the contract only sees the nullifier and the Merkle root
  • Double-spending is prevented because the nullifier is deterministic — same secret always produces the same N

Anonymous Voting

  • Each eligible voter generates a proof: “I hold a valid credential AND I am voting for option X AND I have not voted before”
  • The proof fact exposes: (election_id, vote_option, nullifier) — but not the voter identity
  • The contract tallies votes without knowing who voted for what

ZK-KYC (Selective Disclosure)

  • A user proves: “A licensed KYC provider has verified that I am over 18 and reside in the EU”
  • The proof fact exposes: (provider_hash, claim_age_over_18: true, claim_eu_resident: true)
  • The DeFi protocol can enforce compliance without ever seeing the user’s passport, address, or identity

Threat Model Considerations

Not all privacy is equal. It is worth being explicit about what SNIP 36 does and does not provide:

ThreatSNIP 36 ProtectionLimitations
On-chain observers see transaction dataPrivate inputs hidden; only proof facts are publicMetadata (timing, gas, contract interactions) still visible
Sequencer sees transaction contentsSequencer sees the proof submission, not the private inputsSequencer knows who submitted (IP, account)
MEV extractors front-run based on tx dataPrivate inputs not available for front-runningProof submission itself may leak intent
State analysis links accounts over timeNullifiers prevent linking deposits to withdrawalsSmall anonymity sets reduce privacy; timing analysis persists
Regulatory compliance requires identityZK-KYC allows selective disclosure proofsRequires trusted credential issuers; not a protocol-level solution

A critical factor is anonymity set size. A privacy pool with 10 participants offers far less protection than one with 10,000. This is a social coordination problem, not a cryptographic one — SNIP 36 provides the tools, but the ecosystem must build pools large enough to be meaningful.

This connects to the Q4 2025 Starknet community poll, where privacy was voted the #1 priority for the network. The demand is clear; SNIP 36 is the infrastructure that makes it buildable.


The DX Challenge

Here is the honest assessment: SNIP 36 is necessary infrastructure, but it is not sufficient for a privacy or scaling explosion. There is a significant gap between “the protocol can verify proofs” and “developers can easily build proof-dependent applications.”

Prover complexity. Generating a STARK proof requires running a specialized prover (Stwo, SHARP). Most application developers do not have experience with proof generation, trace construction, or AIR constraint design. The tooling for “write a Cairo program, generate a proof, submit it” needs to be as smooth as “write a Solidity contract, deploy it.”

Circuit design. Privacy applications require carefully designed circuits. The commitment-nullifier pattern sounds simple in theory, but getting the constraint system right — ensuring soundness, handling edge cases, avoiding information leaks — is expert-level work. We need audited, reusable circuit libraries.

Client-side proving. For genuine privacy, the proof should be generated on the user’s device (otherwise the prover sees the private inputs). Client-side STARK proving is computationally intensive. WebAssembly provers exist but are slow. Hardware acceleration and optimized proof systems (like Stwo’s circle STARKs) are improving this, but we are not yet at “prove in 2 seconds on a phone.”

SDK and abstraction layers. What developers actually need is something like:

// Pseudocode — what the DX should look like
let proof = prove("private_transfer", {
    sender_secret: alice_secret,
    amount: 100,
    recipient: bob_pubkey,
    merkle_tree: current_tree
});
await submitProof(proof);

We are not there yet. Getting there requires SDKs, templates, documentation, and — critically — audited reference implementations that developers can fork and customize.


What Is Next: Phases and Limitations

SNIP 36 is designed for incremental rollout:

Phase 1 (Current Proposal)

  • Support for Stwo proofs (StarkWare’s next-generation prover based on circle STARKs over the Mersenne31 field)
  • Fixed set of supported program hashes — not arbitrary Cairo programs, but a curated list
  • Fact registry accessible via system calls
  • JSON-RPC submission interface

Key limitations in Phase 1:

  • No support for arbitrary proof systems (Groth16, Plonk, etc.)
  • Limited builtin support — Keccak builtins, needed for Ethereum compatibility, are not yet available
  • Proof submission is not permissionless in the fullest sense; supported programs must be whitelisted
  • No native proof aggregation (proofs are verified individually, not batched)

SHARP Integration Path

SHARP (Shared Prover) is StarkWare’s existing proving service that aggregates multiple programs into a single proof for L1 verification. The natural evolution is for SNIP 36 facts to be included in SHARP batches, meaning:

  • An application submits a proof to Starknet
  • The Starknet OS verifies it and registers the fact
  • The fact (and its verification) is included in the next SHARP batch
  • The batch proof is verified on Ethereum L1

This creates a recursive verification chain: the application proof is verified by Starknet, and Starknet’s proof (including the application proof verification) is verified by Ethereum. Security cascades upward.

Future Phases

  • Keccak builtins: enabling verification of Ethereum-compatible proofs and bridging use cases
  • Arbitrary program support: any Cairo program can be proven and verified, not just whitelisted ones
  • Proof aggregation: multiple application proofs batched into a single verification for cost efficiency
  • Cross-chain fact sharing: proof facts on Starknet that can be consumed by Ethereum L1 contracts via the existing messaging bridge

Conclusion

SNIP 36 is not a flashy consumer feature. It is plumbing — but it is the kind of plumbing that determines what can be built on top. By moving proof verification into the protocol layer and exposing results as lightweight, queryable facts, Starknet transforms from a network that uses zero-knowledge proofs into one that offers them as a primitive.

The proof/proof-facts separation is the key design insight. It respects the computational reality (proof verification is expensive) while providing the abstraction developers need (fact queries are cheap). It is the same pattern that made rollups viable in the first place: push the hard work off the critical path, and let the application layer consume only the results.

What excites me most is the composability potential. Once proof facts are native protocol objects, they can be referenced by any contract, combined with other facts, and used as building blocks for applications we have not yet imagined. A DeFi protocol that requires ZK-KYC facts. A gaming platform that settles ZKThread state transitions. A governance system where votes are private but tallies are verifiable. These are not hypothetical — they are architectural possibilities that become practical the moment SNIP 36 goes live.

The challenges are real: developer tooling is immature, client-side proving is slow, and anonymity sets start at zero. But the foundation is sound. Starknet is betting that making proof verification a first-class protocol feature — not an afterthought, not a precompile hack — is the right long-term architecture. Given that the community voted privacy as its top priority, that bet looks well-placed.

The infrastructure is being laid. Now we need the applications.


Further Reading

For deeper dives into the concepts discussed in this article, see the wiki:

  • STARKs vs SNARKs — the two proof families, their tradeoffs, and the convergence trend
  • FRI Protocol — how the core verification mechanism of STARKs works (coming soon)
  • Execution Trace & AIR — the pipeline from program execution to polynomial constraints (coming soon)
  • Privacy Patterns — commitment-nullifier schemes, anonymous voting, ZK-KYC in depth (coming soon)
  • Commitment Schemes — Pedersen, Poseidon, and why homomorphic commitments matter (coming soon)
  • Nullifiers — preventing double-spend in private systems (coming soon)
  • Merkle Trees — inclusion proofs, sparse trees, and hash choices for ZK (coming soon)