ZK/SEC Research notes from zkSecurity
All posts
tools · zk

Verifying Cairo proofs on Ethereum

We have been working with StarkWare on building the EVM adapter, and are pleased to announce that we have recently successfully verified Cairo proofs on the Ethereum mainnet! We are furthering the work of Andrew Milson and Aditya Bisht who have reached this milestone before us, and we believe that this is a big step forward towards making StarkWare’s technology more accessible to the open-source community.

In this post, we’d like to share some background into how Cairo programs are verified on Ethereum, and perhaps motivate some of our readers to try out our code.

image

StarkWare’s SHARP

As an L2, Starknet needs to post proofs of numerous transactions posted on its network to L1. Most of the transactions just invoke a function of a Cairo program, and proving that means proving the execution of the invoked Cairo program. This results in a pretty large proof (for reference, a simple fibonacci program proving that its 10th step is 144 is 166kb!) that needs to be uploaded to L1, which also scales linearly for each proof.

In order to reduce this overhead, StarkWare uses SHARP (Shared Prover) to aggregate multiple transactions (i.e. multiple executions of multiple Cairo programs) into a single proof. As the following diagram shows (from the documentation), SHARP refers to the entire backend stack that takes as input Cairo jobs (i.e. Cairo programs and corresponding function calls) creates a single proof of execution of all of them, and submits the proof to L1, where a SHARP verifier is deployed.

SHARP

Bootloader

Internally, SHARP uses a Cairo program called the bootloader to create a single aggregated proof (the code is public here, although you’ll find that it’s missing some python files necessary for processing hints when you try to run it).

The short version of how the bootloader program works is that it loads the bytecode of the Cairo programs that it’s proving in-memory and executes them. The difference between this and a normal execution of a Cairo program is that the bytecode of a Cairo program is normally included in the public part of the memory, but the bootloader program keeps them private. Instead, it computes the hash of the bytecode and makes it public, allowing anyone to verify it separately. This way, you can reduce the cost of proving Cairo program execution, as you can remove the constraints needed to make each program public.

Another interesting point is that the bootloader also supports recursive proving. In other words, you can provide as input not only Cairo programs, but also Cairo proofs. More specifically, the bootloader program can be seen as having an outer program and an inner program (named “simple bootloader”), whose execution can be verified in the outer program. This recursive functionality allows SHARP to incrementally create proofs of Cairo program executions instead of proving many at once, which means they can prove transactions as they are received, and they can prove them on relatively slower devices.

Adapting Cairo proofs for Ethereum

This single proof is not yet suitable for L1, however, because the size of the proof increases based on the number of programs being proved and can also fluctuate based on the types of programs being proved, potentially exceeding Ethereum’s gas price limit.

To solve this problem, the SHARP verifier on Ethereum splits the Cairo proof into multiple components (Merkle tree, FRI, Memory Page, Main) and uploads each proofs separately. This document and our own STARK book provide a good overview of how the verifier works.

Introducing stark-evm-adapter

And this is where our work enters!

stark-evm-adapter is a library for parsing a Cairo proof to be compatible with the SHARP verifier on Ethereum. We also included an example demo that showcases the e2e flow of creating a Cairo proof and verifying it on-chain given a Cairo program and an input.

Some key differentiators:

  • Unlike previous work that used the ministark prover to create a Cairo proof, our code uses the StarkWare's Stone prover to create a Cairo proof.
  • Showcases StarkWare’s functionality of the bootloader program (compressing multiple proofs of multiple programs into one), which is essential for efficient proof verification.
  • Distribute a Rust library that 3rd dapp/services can easily adopt into their own code.

You can either integrate this library into your system or modify our example to prove your own Cairo programs.

What’s next?

The library can be used as of now, but we are still working on some details before officially releasing it. We are also planning to integrate this library into our definitive Stone CLI in the near future, so stay tuned for more updates!

Keep reading
Recommended

Unveiling the Magic Behind Starknet: A Deep Dive into New Specifications

In our deep dive into Starknet's cryptographic components, we tackled the challenge of missing comprehensive specifications by reverse-engineering and publishing draft specs. Readers can explore our work on key protocols like Starknet Channels and STARK Verifier, with an open invitation to join us in refining these efforts. Curious to see what we've pieced together? Check out our drafts and get involved!

David Wong · November 15, 2024

Partnership with StarkWare

We're teaming up with StarkWare to enhance Ethereum's scalability using an exciting tool called the EVM adapter. This innovative open-source project takes proofs from the Stone Prover and makes them verifiable on Ethereum, showcasing the power of Cairo bootloader programs for Layer 2 scaling. By diving into our collaboration, you'll get a glimpse of StarkNet's ability to streamline transactions efficiently and how our joint efforts are driving this tech forward. Plus, our Stark Book offers a deeper technical dive for the curious minds!

ZK/SEC · April 05, 2024

Stone CLI: Making Cairo programming more accessible

We're excited to introduce the Stone CLI, our new tool designed to simplify the process of proving and verifying Cairo programs. Working alongside the StarkWare team, we've streamlined the toolchain for developers, making it easier to compile, run, and prove these programs with less hassle. You'll get the scoop on how to seamlessly use the Stone CLI across various verifiers, serialize proofs, and even create Ethereum-compliant proofs using the bootloader. Dive in to see how we're making life easier for both beginners and seasoned Cairo enthusiasts!

Jason Park · November 10, 2024
More to explore

ZNARKs: SNARKs for The Integers

Hey there! Interested in learning about SNARKs that work beyond finite fields? We’ve been diving into $\mathbb{Z}$NARKs, which are SNARKs tailored for computations involving integers. Our latest post unpacks this intriguing area, showing how we can construct efficient proof systems for integer-based computations. You'll discover nifty tricks like range checks without bit decomposition and mixed field emulation, plus how these techniques can simplify RSA computations. Intrigued by the idea of using randomness for more reliable proofs or exploring an intellectual curiosity like $\mathbb{Q}$-circuits? This post covers it all, including a peek into the future of polynomial commitments. Dive in and explore with us!

Mathias Hall-Andersen · November 11, 2024

Public report of auditing Penumbra's circuits

We conducted an audit of Penumbra's main circuits and found eight issues, including the critical "double spend" and "double vote" bugs, which the Penumbra team promptly fixed. Our findings highlight Penumbra's robust documentation and code testing. Readers will get insights into how Penumbra uses zero-knowledge proofs for privacy, its decentralized exchange features, and its governance model. The post also provides detailed pseudocode for various cryptographic protocols, emphasizing how Penumbra ensures secure and private transactions. It's a deep dive into the technical details for those intrigued by privacy-focused blockchain technologies.

ZK/SEC · August 24, 2023

Halo2's Elegant Transcript As Proof

In this blog post, we explore a clever design in Zcash's halo2 implementation for securing the Fiat-Shamir transformation. By using a mutable transcript, the process ensures that values are automatically absorbed, reducing potential bugs. You'll find explanations of the distinct roles of `write` and `read` functions for points and scalars, highlighting how this abstraction makes the prover-verifier interaction seamless and secure. If you're curious about the inner workings of cryptographic protocols, this is a fascinating read.

David Wong · September 30, 2025