A “ZK coprocessor” (as defined by Axiom) uses SNARKs to prove off-chain computations on on-chain data that would be too expensive to compute natively in a smart contract. There are many interesting non-blockchain use cases that are barely explored. For example, a cloud service provider could prove to its clients that they correctly ran certain computations delegated to their servers. Software registries like npm or crates.io could prove that a binary was compiled from specific source code, reducing the risk of software supply chain attacks. Or a person could prove that their Tool Assisted Speedrunning (TAS) of Super Mario Bros. broke the world record (an idea also described by RISC Zero).
Many of these applications involve programs that are too complex to be converted into circuit DSLs (domain-specific languages) - imagine, for example, rewriting an entire compiler or NES emulator in the Circom language. However, if the program compiles to an instruction set supported by the zkVM, no hand-written circuits or DSL conversions are required: the programmer only needs to write the program in the high-level programming language of their choice, and the zkVM takes care of the rest.
The remaining challenge, then, is the performance of the zkVM prover: it needs to be fast enough to be useful. This is particularly important for blockchain use cases, as prover time affects latency and therefore the user experience.
Verifiable computation has long been touted as the ultimate solution for blockchain scaling, but the technology faces three major barriers to adoption:
Performance:Proofer execution introduces several orders of magnitude higher overhead than native execution.
Complexity:The complexity of SNARKs raises concerns about their security, as they will be responsible for the security of billions of dollars in on-chain assets.
Availability:Domain-specific languages (DSLs) like Circom require expertise that is beyond the reach of most software developers.
The development of zero-knowledge virtual machines (zkVMs) overcomes the third barrier (usability) because zkVMs allow developers to write programs in high-level programming languages such as Rust or Go without requiring any knowledge of the underlying SNARKs to prove their execution. But the increased usability of zkVMs also leads to high performance overhead (8 to 9 orders of magnitude) and complex deployment.
Last year, a Jolt paper introduced a new paradigm for zkVMs that promised to overcome the two challenges of performance overhead and deployment complexity. Jolt has a different theoretical background compared to existing ideas based on STARKs. By leveraging Lasso query parameters and other sumcheck-based techniques, Jolt can prove programs faster than ever before and make it easier than ever to deploy new VM instructions.
Today, we are happy to release an open source implementation of Jolt for the RV32I instruction set, fulfilling the promise made in that Jolt paper.
Fast: Our deployment is over 5x faster than RISC Zero, and 2x faster than the just-released SP1 in preliminary benchmarks.
(Relatively) Simple: The entire codebase is less than 25,000 lines of Rust (less than half of other zkVMs), and a single CPU instruction can be implemented in just 50 lines of code.
Below, we walk through performance benchmarks that show Jolt as the most advanced emerging zkVM. We’ve also provided some guidance for developers interested in developing applications that use Jolt, as well as a roadmap preview for developers interested in contributing to Jolt—we expect Jolt to get even faster and easier to use in the coming months.
The a16z crypto engineering team was founded on a firm belief in the value of open source. Making Jolt an open source public product will accelerate zkVM research, broader SNARK research, and the entire web3 industry. Building cryptography in closed source silos (code that cannot be reviewed by the public) often lends trust to otherwise untrustworthy systems.
1, Performance
ZkVMs have historically incurred an overhead of about 8 orders of magnitude compared to native execution, which has made many applications of verifiable computation unfeasible. The current version of Jolt reduces this overhead to less than 6 orders of magnitude.
While we already have state-of-the-art performance, Jolt's underlying technology (based on the sumcheck protocol) has not received as much attention from engineers as more popular technologies (based on FRI). This suggests that there is more room for Jolt to grow - we have already set some optimizations on the roadmap, and we expect there will be undiscovered opportunities.
Our a16z/zkvm benchmarks benchmark Jolt, SP1, and RISC Zero on a variety of different Rust programs. The results show that relative performance is similar across many of the same RV32 programs. The graph below references a program that does a Sha2 hash chain.
The results of these benchmarks are shown below. The benchmarks were run on an AWS r7g.16xlarge ARM machine with 64 CPU cores and 512 GiB DDR5 RAM. All benchmarks are CPU-only.
Continuous systems using continuations face a trade-off between prover time and proof size - as the proof is split into more "shards" (or "segments"), the prover becomes faster (due to parallelization between shards), but the proof size before recursion is larger. The proof size benchmark is shown below, where the results for SP1 are parameterized by the shard count: SP1(shard_count). RISC Zero has a fixed-size shard, so its shard count grows implicitly with the program cycle count. RISC Zero supports recursion (SP1 and Jolt do not yet), but the benchmarks below are performance checks without recursion. We also do not use "precompilation", so the benchmarks reflect the performance of the core zkVM proof system.
2, How to Build on Jolt
To make Jolt as easy to use as possible, the Jolt SDK (built by a16z crypto engineering partner Noah Citron) provides simple wrappers around Jolt's core functions. All you have to do is add the jolt_sdk::provable attribute to the function you want to prove.
You will then be able to use the build_* functions to create a prover and verifier.
See the full Fibonacci example (and others) in the code repository.
For a deeper dive into the Jolt architecture, the Jolt Book (WIP) is a live-updating document of design choices and codebases not documented in the Jolt article. In the coming weeks, we will be releasing more content for developers interested in building on Jolt or wanting to learn about Jolt's internals.
3 What's Next
While Jolt is an important milestone in the zkVM space, we still have a long way to go. Stepping back, our performance benchmarks show that the Jolt prover (on an M3 Max) proves a program as fast as a 100kHz processor - more than twice the onboard computing power of the Apollo 11 manned lunar mission. For another modest comparison, that's 150 times slower than a TI-84 graphing calculator.
We have a lot of work to do to achieve computer-level performance. We will continue to improve Jolt's performance and usability to provide the best possible developer experience. The following major tasks on the roadmap are of particular interest to us:
Binius: Ben Diamond and Jim Posen recently proposed a multilinear polynomial commitment scheme that is particularly useful for systems like Jolt, where the commitment values are small. Binius, combined with Justin Thaler's small-domain sumcheck algorithm, will significantly improve Jolt's prover performance (we estimate 5-10x).
More Instructions:The Jolt codebase currently implements RV32I, but the Jolt architecture is very flexible. We plan to add the RISC-V "M" extension to provide support for integer multiplication and division, as described in the Jolt paper. In addition, Jolt can easily support the 64-bit variant RV64IM.
Continuations:Currently, Jolt cannot prove computations of arbitrary length due to memory constraints. We will use continuations to split long computations into smaller chunks of computation, each of which can be proved by Jolt. This will reduce memory usage and support additional parallelism when proving a single computation.
Proof Recursion:We further reduce proof size and verification time by combining Jolt with another proof system. For example, a Jolt validator can be implemented using the Circom language to generate constant-size Groth16 proofs that can be efficiently verified on-chain.