This is intended as introductory material, and aims for accessibility and conceptual intuition over precision and rigor.
For a more precise approach, we recommend Proofs, Arguments, and Zero-Knowledge and the SNARGs Book. For something in between, we recommend the ZK Whiteboard Sessions and the ZK MOOC.
Verifiable computation refers to the ability to offload some computational task to a third party, while maintaining verifiability of the results. In some sense, all computation is verifiable: anyone can simply re-run the original computation to check the results. But recent advances in computer science have shown that it’s possible to verify a computation using less resources than it took to run the original computation. This is called succinct verifiable computation.
A pivotal moment for succinct verifiable computation came in 1992, with the proof of the PCP Theorem. The PCP Theorem shows that any proof can be rewritten in such a way that can be checked without reading the entire proof. At first glance, it’s rather hard to believe that succinct verifiable computation is possible. How could one possibly verify the correctness of a computation without re-doing the computation? And indeed, there is a caveat. Succinct verifiable computation will always have some margin of error — some possibility that a faulty computation will pass verification. Fortunately, we can tune down this margin of error to be negligible.
In 1992, this was a theoretical result that couldn’t really be applied in practice. But over the course of the next couple decades, the techniques for succinct verifiable computation have become more and more efficient. In 2013, the first application of succinct verifiable computation was deployed in the real world (ZCash). At that stage, building applications that leverage this technology was extremely difficult. Building verifiable applications was something that was accessible to cryptographers who were willing to write assembly code.
Today, tools like the RISC Zero zkVM have made it possible for regular software developers to build verifiable applications and deploy them on the blockchain of their choice. The tooling has matured to the point that you can build and deploy an end-to-end prototype in a weekend, using your own laptop. And when you’re ready to go to production, you can outsource the computation to Bonsai, the proving service for RISC Zero’s zkVM. And as icing on the cake, there’s a ready-to-use verifier, already deployed on a number of leading blockchains.
To sum up: the era of verifiable computation has arrived. It’s fast, affordable, and the software development experience is ergonomic. After 2+ years since our initial 0.1 release, zkVM 1.0 has arrived, complete with end-to-end tooling for building and deploying verifiable applications.
You’re probably thinking — OK, but why should I care?
Keep reading to find out.
In traditional web applications, most of the computational work is delegated to Amazon Web Services. In hardware, computation gets delegated to GPUs, FPGAs, and ASICs. For blockchains and blockchain applications, verifiable computation is a pre-requisite for delegating computation.
When talking about delegating computation in any of these contexts, we can say that we offload work from the main processor to a coprocessor.
Let’s dig in a bit deeper to the idea of coprocessors for blockchains.
Recall that a blockchain is a computer, and a smart contract is a computer program. Generally, a blockchain is a very slow, very expensive computer, which imposes severe limits in what's possible using smart contracts.
Enter: Verifiable computation.
Verifiable computation offers a mechanism for offloading computation from the blockchain to another computation environment, which simultaneouosly reduces costs and increases capabilities for blockchain applications.
In an on-chain game, the complex game logic can be moved off-chain. In an identity application, the signature verification can be moved off-chain. The list goes on.
The list above highlights the basic idea of a coprocessor in the context of blockchain applications: an application developer delegates their app logic to some verifiable, off-chain computational environment, in order to scale their application without impacting their on-chain footprint.
This not only enables applications to scale, it fundamentally changes what's possible on-chain. Previously, on-chain applications were subject to limits on data sizes and computational intensity. Delegating computation enables blockchain applications to trascend these limitations entirely.
Beyond the benefits at the application level, the same techniques can be used to offload the computational work of the blockchain itself. Read about "ZK rollups" or "validiums" to learn more.
In practical applications of verifiable computation, SNARKs are generally the tool-of-choice: Succinct, Non-interactive ARguments of knowledge. Let’s unpack some of the terminology, and then discuss some of the engineering tradeoffs in designing SNARK protocols.
We’ve already touched on the term succinct — this refers to the property that verification is more efficient than the original computation. Non-interactive means that the “Prover” and the “Verifier” don’t need to interact in real time. One party can generate a SNARK that “proves” the output of some computation, and another party can verify that SNARK, with no direct communication required, aside for sharing the SNARK itself. Argument of knowledge roughly translates to “proof of computation. For more precise definitions, check out Proofs, Arguments, and Zero-Knowledge or the SNARGs Book.
So, we can summarize:
And amazingly, the Verifier can check the validity of the SNARK in milliseconds — regardless of the complexity of the original computation!
When designing SNARK protocols, there are a number of competing costs that one aims to minimize:
In the context of blockchain applications, the Verifier is a smart contract living on-chain, which means that we need the SNARK to be small and the verification algorithm to be lightweight. The Prover is the computationally intense component here. Depending on the application, the Prover might be running on a mobile device, a laptop, a supercomputer, or a hardware cluster.
Systems like RISC Zero, ZK Sync, and Polygon zkEVM rely on a multi-layer proof system in order to get the best of all worlds. At RISC Zero, most layers of the proof system utilize a hash-based SNARK, which offers fast proving, and a SNARK size of roughly 200 kB. The last step uses an elliptic-curve-based SNARK, which is slower but offers a SNARK size on the order of 100 bytes.
These tiny SNARKs are small enough to post & verify on-chain, enabling blockchain applications to utilize SNARKs as a replacement for expensive on-chain computation.
In this part, we present a framework for building SNARKs, in terms of four components:
Note that you can utilize verifiable computation in your applications without understanding anything in this section. If you're more interested in building than theory, you can skip to Part 5.
Arithmetization is the process of translating a statement like, “A known algorithm was run for 10000 steps, and the final output was 0” into a more formal language that’s conducive to SNARK protocols.
The “language” is defined in terms of instances and witnesses. Given some computation, the witness is an encoding of the execution trace — i.e., a complete record of the state of the machine at each step of the computation. And the instance is an encoding of the rules that define the correctness of the computation. So, checking that the witness satisfies the the constraints is logically equivalent to checking the correctness of the computation.
Circling back to the statement we started with…
A known algorithm was run for 10000 steps, and the final output was 0.
Once we choose an arithmetization scheme, we can translate the computational algorithm, the number of steps, and the asserted output into an instance. And if the Prover has actually run the algorithm as asserted, they will have a witness that satisfies the instance.
Common arithmetization schemes include R1CS, Plonkish, and AIR.
Now, the Prover need a technique to prove that the witness satisfies the instance.
Enter: Interactive Oracle Proofs.
Interactive oracle proofs (IOP) are a technique for proving that a witness satisfies an instance.
In a (polynomial) IOP protocol, a Prover and Verifier exchange a number of messages, where each message from the Prover is in the form of a “polynomial oracle” (which the Verify can "query") and each message from the Verifier is drawn from a “random oracle.”
As the names suggest, polynomial oracles and random oracles are idealized abstractions. In real SNARK constructions, polynomial commitment schemes are used in place of polynomial oracles and hash functions are used in place of random oracles.
IOPs are useful because they provide a clean mathematical framework for analyzing properties like completeness, soundness, and zero-knowledge, which we’ll discuss later on.
As mentioned in the previous section, Interactive Oracle Proofs include two tools that don't exist in the real world: random oracles and polynomial oracles.
To bring the math to the real world, we replace the random oracle with a cryptographic hash function, and we replace the polynomial oracle with a polynomial commitment scheme.
So, now we can give a high-level view for how we build SNARKs in the random oracle model.
Fortunately, tooling for verifiable computing has evolved to a point where developers don't need to work directly with concepts like arithmetization or IOPs.
Today, developers can write applications in a high-level language like Rust, and then generate SNARKs by running their applications inside a "zkVM" (zero-knowledge virtual machine).
To get started, check out the RISC Zero developer docs or head straight to the Foundry Template.
Find me in the RISC Zero Discord.