What’s the first thing that comes to mind when you hear the term “virtual machine?”
If you’re thinking of a computer, you’re not too far from the truth. A virtual machine is essentially a program that can run other programs, usually through a fetch-decode-execute loop of instructions. It’s sort of like a virtual representation of a physical computer.
There’s a lot more I can share about the fundamental role virtual machines play in modern computing infrastructure, but we’re not here to discuss that today. Today, we’re talking about virtual machines in the context of zk-proofs. We’re talking about zkVMs.
Let’s get right into it.
If you’ve been in the zero-knowledge space for a while, you’ve most likely heard of zkEVMs, or zero-knowledge Ethereum Virtual Machines. A zkEVM is a virtual machine that executes Ethereum smart contracts in a way that is compatible with zero-knowledge-proof (zk-proof) computation.
zkEVMs compress any number of Ethereum transactions in a single low-cost and succinct validity proof. This allows for delegating the running of the EVM to powerful nodes with no trust assumptions, while keeping the backbone (validators) on cheap hardware, promoting accessibility and decentralization.
Unfortunately, the Ethereum Virtual Machine was not designed to run in a zk-circuit because back then, very few people even knew what zero-knowledge was. Due to this, several trade-offs must be made when implementing a zkEVM, from choosing not to be Ethereum-equivalent to having gas costs not reflect prover costs (check out Vitalik’s article on types of zkEVMs).
In other words, Ethereum’s limitations change how difficult it is to implement and optimize the validity proofs zkEVMs produce. More importantly, it also requires redoing all the testing, fuzzing, and auditing that are so important for security.
What if there was a convenient and easy way for you to write a high-level program and execute it, as well as get both the output and the proof, without having to know anything about zero-knowledge?
A zkVM, or zero-knowledge virtual machine, is a virtual machine implemented as a circuit for a zk-proof system that guarantees secure and verifiable trustworthiness through zk-proofs. Instead of proving the execution of a specific program, you are proving the execution of a VM.
zkVMs can make implementing zk-proofs significantly less time-consuming and prone to error.
zkVMs aren’t exactly a new concept. The first system to do arbitrary computation inside zero knowledge was TinyRAM, created in 2013, which dealt with random access memory. After this, DSLs, or Domain Specific Languages, emerged. Languages like Circom and Noir created a middle ground between low-level circuits and high-level specialized languages. From there, we got to Cairo-VM and Miden. Cairo-VM, built by Starkware in 2021, had several features, including optimized validity proofs, a modern language similar to Rust for writing provable programs, and a program which allows for efficient execution of Cairo code.
Miden, Polygon’s approach, aimed to be developer-friendly. Developers didn’t have to learn anything about cryptography or zk-proofs to run smart contracts on top of Miden VM, because the zkVM had multi-language support.
Since then, several VMs have emerged, including the RISC Zero zkVM and SP1 by Succinct. We’ll dive into these approaches a little later.
So what are the main differences between zkEVMs and zkVMs?
zkEVMs can be a little complicated, because the Ethereum Virtual Machine has complex specifications. zkEVMs are expensive to develop, maintain and audit, as they are basically another EVM implementation, written as polynomial equations instead of a normal programming language.
zkVMs, on the other hand, are a little more straightforward. They can give all their applications the ability to use zk-proofs in each of their transactions relatively seamlessly. It’s easier to alter and expand the proof system code base, do auditing, and use a wider range of tools (e.g. more programming languages). For more details on the differences between zkEVMs and zkVMs as well as Ethereum scaling and zk-proofs, check out this excellent article.
The Taiko team has been contributing to the PSE’s zkEVM from the Ethereum Foundation. More specifically, we implement each EVM opcode as a manual circuit using the “Halo2-KZG” proof system that Axiom, EZKL and Scroll contribute to as well, sharing the burden of implementation and audits. Then, when a block is submitted, with a list of transactions consisting of EVM instructions, the zkEVM is able to generate a proof by combining the output of all circuits.
Because zk-proofs are highly complex and consist of pretty much implementing Ethereum as a set of polynomial equations, there are risks associated with proving systems, circuit compilers, and the zkEVM code itself. This is why Taiko has implemented a multi-prover system, which involves generating several types of proofs for a single block. Thus, even if one type of proof is somehow compromised, the other proofs ensure the system continues to run securely by detecting the faulty state transition.
Over time, we’ve moved towards a zkVM model. We can also modify a client and run it, generating a zk-proof. We’ve done this by upgrading from using a system comparable to ASICs (that is, writing a client as specialized cryptographic circuits) to using a general purpose CPU, except that the client running on that CPU has already been written, tested and audited.
To ensure Taiko’s robustness, we are constantly diversifying the cryptographic assumptions we rely on. We do this by building a multi-proof system and contributing to several zkVMs (RISC Zero, SP1, Powdr). We keep investing in Halo2-KZG as RISC-Zero and SP1 are STARK-based and Powdr+Halo2 would be SNARK-based (see next section for more details on these zkVMs).
Taiko also uses SGX, or Software Guard Extensions, a set of security-related instruction codes that help enhance privacy and security without revealing the data itself. We modify execution clients based on geth/reth so that they can run in a SGX enclave, with minimal modifications (check out Taiko’s implementation, Raiko). The client then generates a SGX proof (check out this post by Justin Drake for more details).
To learn more about Taiko’s approach to multi-proofs, check out this article by Taiko’s ZK engineer, Cecilia.
RISC Zero has built a general purpose zkVM, which allows developers to prove correct execution of arbitrary Rust code, enabling them to make use of existing tools to build programs. While this makes it a lot more convenient to prove code, it also means the RISC Zero team has to build a circuit that may require more complicated computation to add in new features.
A relatively new player in the zkVM market, SP1 is Succinct’s first-generation zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs. Like RISC Zero zkVM, SP1 does not require developers to learn specialized knowledge. The team recently released SP1 Reth, an open-source performance type-1 zkEVM built with SP1, where they essentially run an Ethereum client within their zkVM.
Powdr is a zkVM compiler stack that helps build zkVMs and similar proof frameworks. Developers can use powdr to perform dynamic executions, as well as define arithmetic constraints, lookups and more. The team targets multiple backends including Halo2-KGZ, eSTARKS, and SuperNova.
Valida is a community-driven STARK-based VM working on code reuse, prover performance and extensibility.
The Nexus zkVM is a modular, extensible, open-source and highly-parellelized zkVM designed to run at a trillion CPU proved cycles per second given enough machine power. The zkVM is written in Rust and is focused on performance and security.
Delphinus Lab is building a zkWASM (zkSNARK virtual machine that supports Web Assembly. a binary instruction format that serves as a compiler for programming languages like C, C++, and Rust). The zkWASM will operate as a trustless layer between applications running on WASM runtime and smart contracts on chain.
Nil Foundation is building zkLLVM, a compiler from high-level programming languages into an input for provable computations protocols verifiable on EVM. Every proof output from zkLLVM is an in-EVM variable one.
CirC is a compiler infrastructure which supports compilation from high-level (stateful, uniform) languages to (state-free, non-uniform, existentially quantified) circuits.
Nova is a high-speed recursive SNARK that achieves IVC, or incrementally verifiable computation. IVC is a powerful cryptographic primitive that allows a prover to produce a proof of correct execution of “long running” sequential computations in an incremental fashion.
zkVMs represent a significant development in the realm of zero-knowledge computing, offering developers a powerful tool to execute programs securely and verifiably. While zkEVMs have paved the way for zero-knowledge computation, zkVMs offer a more flexible and developer-friendly approach.
This article would not have been possible without the incredible ongoing efforts of the zk-proof community. A special thank you to Mamy Ratsimbazafy and Brecht Devos from the Taiko team, as well as to Paul Gafni from RISC Zero.
Explore open positions on our job board.
To stay updated on the latest from Taiko:
Website: https://taiko.xyz
Discord: https://discord.gg/taikoxyz
GitHub: https://github.com/taikoxyz
Twitter: https://twitter.com/taikoxyz
Contribute to Taiko and earn a GitPOAP! You will also be featured as a contributor on our README. Get started with the contributing guide.