Zeth Public Release: The First Type 0 zkEVM

ChainCatcher Selection
2023-08-25 18:49:00
Collection
The Ethereum open-source ZK block validator Zeth based on RISC Zero zkVM is publicly released.

Original Title: Announcing Zeth: the first Type Zero zkEVM

Authors: Tim Cartens, Victor Graf, Rami Khalil, Steven Li, Parker Thompson, Wolfgang Welz, Zeth Collaboration

Compiled by: bayemon.eth, ChainCatcher

Today, Zeth, the Ethereum open-source ZK block validator based on RISC Zero zkVM, is publicly released. Zeth completes all the work required to build new blocks in the zkVM without relying on validators or synchronization committees. Zeth has been validated on multiple real blocks on the Ethereum mainnet and has passed all relevant tests in the Ethereum official test suite. Zeth is capable of achieving zkVM-based Rust support and powerful modules including revm, ether, and alloy within 4 weeks. With support for continuity and Bonsai proof services through zkVM, Zeth can generate these proofs in just a few minutes. With Zeth's support for on-chain validation, anyone can validate these proofs on-chain at a low cost. In this article, we will introduce more details, and if you want to dive deeper into the code, please check the source code and visit the RISC Zero developer portal.

Summary

About a year ago, Vitalik elaborated on the different types of zkEVM:

Ethereum was not originally designed with ZK friendliness in mind, so many parts of the Ethereum protocol require significant computation for ZK validation. Type 1 EVM aims to fully replicate Ethereum, so it cannot alleviate these inefficiencies. Currently, proving Ethereum blocks can take hours to complete.

While there have been relevant cases in the history of Ethereum's development, today we are pleased to announce that Ethereum block proofs using RISC Zero's zkVM and Bonsai services can be completed in minutes instead of hours.

Zeth: Verifiable Ethereum Block Generation

Today, we are releasing the open-source ZK block validator Zeth for Ethereum on RISC Zero zkVM.

Zeth can prove that a given Ethereum block is valid without relying on validators or synchronization committees. This is because Zeth completes all the work required to generate new blocks in the zkVM, including:

  • Verifying transaction signatures
  • Validating account and storage states based on the parent block's state root.
  • Applying transactions
  • Paying fees to the block author.
  • Updating the state root
  • Other necessary work for block generation

After generating a new block, Zeth calculates and outputs its hash. By running this process in the zkVM, we obtain a ZK proof that the new block is valid.

By leveraging RISC Zero's zkVM and popular Rust crates (such as revm, ether, and alloy), we wrote the first version of Zeth in less than 4 weeks. With support for continuity and Bonsai proof services through zkVM, proof generation can be completed in just a few minutes. With support for on-chain validation, we can validate these proofs on-chain at a low cost.

Zeth has been validated on multiple real blocks on the Ethereum mainnet and has passed all relevant tests in the Ethereum official test suite.

Since Zeth builds standard Ethereum blocks, it can be regarded as a Type 1 zkEVM. But its significance goes far beyond that: because Zeth is built using standard Rust codebases (the same ones used by popular full nodes like Reth), we prefer to consider it a Type 0 zkEVM: complete protocol compatibility and a large amount of code reuse.

This milestone represents a significant step forward for ZK technology and the Ethereum ecosystem. In this article, we will discuss how we wrote the first version of Zeth in just a few weeks, its performance, how it works, and what this means for ZK projects.

RISC Zero Makes Building zk Rollups, zkEVMs, Lightweight Clients, and Bridges Easier

We built Zeth for two main reasons:

  1. To make it easier for other teams to build their own ZK-driven infrastructure: zk rollups, zkEVMs, ZK lightweight clients, ZK bridges, etc. Zeth provides everything needed to generate ZK proofs for EVM-based block generation. This is a key component for any zkEVM or bridge. Zeth is based on the open-source revm, so project developers can easily modify or use it. Proofs can be validated on-chain (great for bridges and L2) or validated in local applications (great for full nodes and lightweight clients).
  2. To conduct relevant research on EVM performance in Zeth's zkVM, particularly for Ethereum-related tasks. (See analysis of findings below).

zk Rollup vs. zkEVM

As a Type 0 zkEVM, Zeth enables developers to build zk rollups with fully native EVM and Ethereum compatibility. Coupled with Zeth's support for on-chain proof validation, building ZK-driven L2 scaling solutions will become incredibly simple.

Existing ZK rollups and zkEVM circuits are designed as monolithic systems, making upgrades impossible without a high-level understanding of ZK cryptography. In contrast, the zkVM-based Zeth approach allows any developer to customize and modify it according to their needs.

Zeth is open-source based on revm, making it relatively easy to adjust to support other zkEVMs and EVM-compatible chains. Therefore, Zeth will respond relatively quickly to future EIP updates. Additionally, Zeth provides modular functionality, allowing developers to build their own block construction logic within it.

We hope that Zeth's efforts will democratize zk rollups and zkEVMs, considering that zk-driven L2 solutions previously required years of research and over $100 million in funding, which is an expense that most projects cannot afford.

Lightweight Clients and Bridges

Undoubtedly, the introduction of the beacon chain is a boon for lightweight clients and bridges. These technologies are built on Ethereum's now-mature PoS model, allowing lightweight clients and bridges to easily validate recent blocks without needing to reconstruct them, as long as everyone adheres to the rules.

Of course, the entire point of staking is to provide economic incentives for nodes that follow the rules. However, the threat of slashing imposed on nodes does not completely prevent malicious behavior—external incentives can tilt the "scales" of interest permanently towards wrongdoing—making it challenging to design a lightweight client or bridge that can correctly handle these malicious behaviors.

With tools like Zeth, the risk of node malfeasance is greatly reduced. Lightweight clients can integrate with Zeth by simply adding a few call interfaces to the zkVM; on-chain applications like bridges can integrate with Zeth using our on-chain proof validation contracts.

In the near future, we can envision lightweight clients and bridges using ZK proofs to determine whether a given block is valid. This approach will significantly reduce risk while not substantially increasing the cost of validating blocks.

This is particularly important for application chains, modular ecosystems, and new chains, as they do not yet have the same level of security provided by Ethereum's large full node community.

A Good Foundation Simplifies Project Development Processes

Zeth is based on RISC Zero zkVM, powered by the RISC-V instruction set architecture, providing developers with a familiar programming experience. But our zkVM is not just a RISC-V core. We also equip it with accelerated circuits for common cryptographic tasks like hashing and signature verification.

This hybrid approach (combining a general-purpose CPU core with accelerated circuits) gives us the best of both worlds:

  • Support for mainstream programming languages.
  • No compromise on the performance of critical cryptographic operations.

Thus, we were able to quickly build Zeth using existing Rust packages from revm, ether, and alloy. By reusing existing modules, we completed the first version of Zeth in less than 4 weeks. Such speed is unattainable in less mature ecosystems.

In terms of performance, Zeth leverages our accelerator circuits used for ECDSA signature verification and continuity—this is a new feature of our ZK framework that allows for rapid proof generation of large computations using GPU clusters working in parallel (using nVidia CUDA or Apple Metal). Continuations are easy to use: this feature is transparently provided to all guest programs running in the zkVM, meaning it works seamlessly without any modifications to the code.

With our zkVM, we can quickly generate ZK proofs of Ethereum block validity in minutes instead of hours.

Performance

We will introduce the performance of the Zeth block generator. Zeth is still a new product, so this data may change; however, we hope to provide some concrete data as a baseline for future work.

When it comes to performance, several factors need to be considered:

  • The computational resources required to generate proofs.
  • The "wall time" required to generate proofs (i.e., how long users have to wait to obtain the proof).
  • The total cost of generating proofs (in dollars).

Continuity

Zeth's zkVM can adjust performance by using continuations. Therefore, we need to pause and discuss how "continuations" work.

Our zkVM implements a standard RISC-V processor. Thus, execution is done in cycles. (In our circuits, most RISC-V instructions require only 1 cycle to execute, though there are exceptions). Simple programs typically require hundreds of thousands of cycles to execute, but more complex programs may require billions of cycles.

In a typical ZK system, these execution cycles aggregate into a proof; as the number of cycles increases, the time and memory required to generate the proof also increase. But our zkVM does not follow these conventions; earlier this year, we pioneered a new continuity feature that improves the shortcomings of traditional proof generation modes.

In terms of continuity, the proof process is divided into three stages:

We perform the necessary computations in a non-proof simulator. During this process, we count the number of loops executed so far. At configurable time intervals, we take snapshots of the program's state. This effectively segments the execution process into multiple segments. Each segment is small, typically representing 1 million cycles or fewer.

These segments are assigned to a group of proof generation workers. They generate ZK proofs for their given program segments. Importantly, they can complete this work in parallel. As long as there are enough workers, all segments can be proven in the time it takes to prove one segment. Because the segments are small, the required time is usually short (a few seconds).

When generating segmented proofs, they will eventually be rolled up. Each "rollup" operation takes a pair of consecutive segmented proofs and generates a new proof for the combination of those segments. For example, if segment 1 proves that the program transitioned from state A to state B, and segment 2 proves that the program transitioned from state B to state C, then the rollup proves that the program transitioned from state A to state C. If there are enough workers, this can be completed in log(N) time, where N is the number of segments.

As we delve into these numbers, we will see the actual effects of these stages.

How Difficult is it to Build an Ethereum Block?

First, let's look at the complexity of building an Ethereum block. In the table below, we select some real-world Ethereum blocks and reconstruct them using Zeth in the zkVM.

For example, block 17606771 produced 2131 segments. Each segment represents up to 2^20 execution cycles, so the entire computation could require up to 2,234,515,456 execution cycles.

In general, we see that a typical Ethereum block requires 200-400 million cycles to build, but sometimes as much as 9.5 billion cycles. (Initially, we were surprised to find that these differences were not reflected in the Gas of the transactions. But upon further reflection, it made sense: the Gas system was designed with conventional execution in mind, not ZK proofs).

With continuity, managing this scale becomes straightforward. Based on this data, a peer-to-peer network with 10,000 nodes running zkVM validators is sufficient to achieve maximum parallel validation performance for the largest blocks, which is just a small fraction of the 700,000 validators currently on Ethereum.

How Long Does it Take to Generate Proofs?

To gather some basic performance data, we launched a Bonsai test instance with 64 GPU workers. We then asked it to use Zeth to prove block 17735424 (182 transactions, 3242 segments, or approximately 3.4B cycles).

To generate the proof, the zkVM must first split the execution into multiple segments. In the screenshot below, the Executor task captures this process, which ran for 10 minutes. (Most of this time was spent doing AWS-related tasks, like writing to network storage). On a local machine, the same task completed in under 6 minutes. We hope to significantly reduce this time in the coming year.

The executor ultimately divided the execution into 3242 segments. For only 64 GPUs, this is a significant segmentation. Therefore, each worker node must generate 50 segmented proofs. As shown in the figure, this took 35 minutes. If we had 50 times as many worker nodes, it would only take 42 seconds.

After the segmented proofs are completed, the rollup begins. Since there are 3242 segments, we need to perform log_2(3242) = 12 rounds of the rollup process. In the early stages of the rollup, the workload exceeds that of the workers; thus, the first stage took 1 minute, the second stage took 35 seconds, the third stage took 25 seconds, and so on. By the seventh stage, the time stabilized at just over 5 seconds. Similarly, if we had more workers, each stage would only take 5 seconds.

Once the rollup is complete, the results are finalized, which takes another minute.

Thus, in a scenario with insufficient cluster scale, we were able to generate proofs in about 50 minutes (with an effective speed of 1.1 MHz). If the cluster scale is appropriate, we estimate that the proof generation speed would be faster:

In a fully parallel scenario, the proof steps can be completed in 42 + 12 * 5 + 60 seconds or 2 minutes and 42 seconds.

If we conservatively round up and include the executor time, the total time would be approximately between 9 and 12 minutes (with an effective speed of 4.7 MHz - 6.3 MHz).

As we continue to improve the executor and proof framework, we are optimistic that this time will be significantly reduced in the coming year.

Resource Consumption for Generating Proofs

The test cluster mentioned above was deployed on AWS. It consists of 64 g5.xlarge proof nodes and 1 m5zn.xlarge execution node. According to Amazon, each g5.xlarge node has:

  • 1 GPU with 24 GiB of GPU memory
  • 4 vCPUs with 16 GiB of memory

At the time of writing, the on-demand price for these instances is $1.006/hour, and the reserved instance discounted price is $0.402/hour. Meanwhile, Amazon's specifications show that our m5zn.xlarge node has:

  • 4 vCPUs with 16 GB of memory

At the time of writing, the on-demand price for this instance is $0.3303/hour.

We can use these numbers to roughly estimate the proof cost for block 17735424 described above.

Recall that we deployed 64 proof nodes, and under this deployment, generating the proof took 50 minutes (end-to-end). Ignoring idle worker time, the cost for 64 proof nodes plus one execution node for 50 minutes is 50/60 * (64 * 0.402 + 0.3303) = $21.72. This is an overestimate because it assumes we are paying for idle workers. If we disregard the cost of idle workers (for example, by shutting them down or having them do other work), the cost is approximately $19.61.

  • This block has 182 transactions, which means $0.11 per transaction.
  • The total value of the transactions is 1.125045057 Eth, approximately $2137.59. Thus, for every $1 spent on proof, $109.01 of user funds is obtained.
  • The rewards paid for this block amount to 0.117623263003047027 Eth (excluding transaction fees). At the time of writing, this is approximately $223.48. Therefore, our proof cost is about 8.7% of the block reward.
  • The transaction fees total 0.03277635 Eth, or $62.28, which is more than three times our proof cost.

It is worth noting that these dollar estimates are independent of the scale of the cluster! What matters is the number of segments. This is because the cost of one machine completing two jobs sequentially is the same as the cost of two machines completing one job in parallel. Therefore, while a larger cluster will generate proofs faster, the cost will not be higher.

There are several ways to further reduce costs. In addition to continuing to improve the performance of the zkVM, we might also add a Keccak accelerator, and we can look for cheaper instances. Importantly, given that we are using lower-spec machines (and our zkVM supports nVidia Cuda and Apple Metal), this work can be easily accomplished through a peer-to-peer network composed of ordinary consumer PCs and Macs.

On-Chain Validation

As mentioned above, we verified Zeth's proofs on Sepolia using the RISC Zero Groth16 verifier. This is a relatively new part of the RISC Zero protocol stack, released earlier this month. It works by using Bonsai to convert the native STARK proofs of the zkVM into equivalent SNARK proofs, which are then submitted to the on-chain SNARK verifier.

If we consider the transaction inputs as UTF-8 data, we can see that this proof corresponds to block 17735424.

Using Bonsai, the conversion from STARK to SNARK takes about 40 seconds. Validating the SNARK on-chain consumed 245,129 gas (approximately $5.90 at the time of writing).

Of course, one advantage of the zkVM is that it can merge multiple proofs into one. With this capability, an entire set of proofs can be validated on-chain without using any additional gas. This way, the cost of on-chain validation can be distributed across the entire set of proofs, reducing fees for everyone.

What This Means for Ethereum

As mentioned earlier, Ethereum was not designed with ZK friendliness in mind. As shown by the case of zkEVMs, there are many things that can be done differently, especially regarding opcodes, digital signatures, and hash functions.

While these changes do improve performance, we are still able to achieve stable performance without using these modifications. When Vitalik wrote about the different types of zkEVM last year, proving the validity of an Ethereum block took several hours; now, we can complete it in minutes. ZK performance is rapidly improving, and we have reason to believe that this trend will continue in the coming years.

Appendix: How Zeth Works

This section is prepared for developers.

Roughly speaking, Zeth constructs blocks in the same way as a full node: we start with the parent block, a list of transactions, and the block author, then perform a significant amount of computation (verifying signatures, running transactions, updating global state, etc.), and finally return the hash of the new block.

But unlike a full node, we complete this work in the zkVM. This means we obtain a ZK proof that the block with a given hash is valid.

Of course, this is not without challenges. In this section, we will introduce these challenges and how we addressed them.

Cryptography

The first challenge is cryptography. Constructing an Ethereum block requires a lot of work, primarily hashing (Keccak-256) and signature verification (ECDSA with secp256k1).

Our zkVM has accelerated support for elliptic curves, so ECDSA signature verification is not difficult.

But when it comes to hashing, we are not so lucky. Our zkVM provides accelerated support for Sha2-256 but does not support Keccak-256 (as of the time of writing). Therefore, we currently only use the Keccak implementation from the sha3 Rust crate. Through profiling, we know this requires a significant number of cycles. This is not an optimal solution, but our zkVM can handle it, and we can loop back and add a Keccak accelerator later.

Accounts and Storage: Performance and Security

In Ethereum, accounts and storage are tracked by a global Merkle Patricia Trie (MPT).

According to Etherscan, at the time of writing, this tree contains the states of nearly 250,000,000 unique Ethereum addresses. Overall, this is not a large amount of data, but it is enough to make us cautious about how it is stored and used. In particular, the performance of the MPT is crucial.

But performance is not the only factor; we must also consider security.

The Zeth block generator runs in the zkVM as a client. This means it cannot directly access the Ethereum p2p network or other RPC providers. Instead, it must rely on independent programs running outside the zkVM to provide the data.

When analyzing the security of ZK applications, we must assume that external programs are malicious and may provide malicious data. To prevent this, ZK applications must verify that the data provided to them is valid.

For the Zeth block generator, this means verifying the states of all relevant accounts and storage (i.e., the accounts and storage required to run the given list of transactions).

Fortunately, EIP-1186 provides such a mechanism, defining a standard way to prove the state of a given account (and its storage) through Merkle inclusion.

In principle, Zeth's block generator can verify account and storage states by validating a set of EIP-1186 inclusion proofs. But this method is not ideal.

Instead, it is better to use the data from the EIP-1186 inclusion proofs to construct a partial MPT. This is an MPT that only contains nodes relevant to the given list of transactions; unrelated branches are represented only by their corresponding hash values. You can think of the partial MPT as a "union" of Merkle inclusion proofs; or, if you prefer, as a Merkle subset proof.

The process of verifying a partial MPT is essentially the same as verifying a standard EIP-1186 proof: compute the root hash and then compare it with the state root of the parent block. If they match, the integrity of the accounts and storage can be trusted.

Once the partial MPT is verified, transactions can be applied, and the partial MPT can be updated. The new state root can be obtained by calculating the new root hash of the partial MPT.

  1. Before running the Zeth block generator, we first run the list of transactions in a sandbox to determine which accounts and storage are relevant. (This process also allows us to identify the oldest relevant predecessor block, which is necessary for supporting blockhash() queries).
  2. We obtain EIP-1186 inclusion proofs for each relevant account and storage. (We will also obtain the relevant predecessor blocks).
  3. We use these inclusion proofs to construct a partial MPT containing all relevant data.
  4. We start the zkVM, allowing it to run the Zeth block generator and provide the partial MPT and other inputs (parent block, transaction list, etc.).

In the zkVM, the Zeth block generator:

  1. Verifies that the root of the partial MPT matches the state root of the parent block.
  2. Verifies the hash chain of predecessor blocks up to the parent block.
  3. Applies transactions.
  4. Updates the partial MPT.
  5. Uses the new root hash of the partial MPT as the state root of the new block.

Once the Zeth block generator completes, it outputs the hash of the new block.

This hash includes a commitment to the parent block, thus also including the state root of the parent block (used to verify the original partial MPT). This means that a malicious validator cannot provide invalid data for accounts and storage without providing an invalid parent block.

In other words: if the parent block is valid, then the new block generated by Zeth is also valid.

Therefore, if someone gives you a new block and a ZK proof generated by Zeth, you can check the validity of that block by verifying the following three points:

  1. Ensure the ZK proof is valid and comes from Zeth. For off-chain applications, this can be checked using functions provided by the zkVM Rust crate. For on-chain applications, our on-chain proof verifier can be used.
  2. Ensure the ZK proof submitted the hash of the new block.
  3. Ensure the parent block has the expected hash value.

If all of these checks pass, then the new block is valid.

Limitations and Future Improvements

The goal of our project is to study the performance of block construction. To this end, we decided to limit the scope to merged blocks.

Additionally, while Zeth is capable of proving that a given block is valid, it currently cannot prove consensus (i.e., that the block is indeed included in the canonical chain). This may change in the future, possibly by adding checks for validator or synchronization committee signatures in the zkVM.

Finally, Zeth is new software. While we have conducted some tests (including the Ethereum test suite and various real-world blocks), Zeth may still contain some bugs. At the time of writing, it should be considered experimental software.

ChainCatcher reminds readers to view blockchain rationally, enhance risk awareness, and be cautious of various virtual token issuances and speculations. All content on this site is solely market information or related party opinions, and does not constitute any form of investment advice. If you find sensitive information in the content, please click "Report", and we will handle it promptly.
ChainCatcher Building the Web3 world with innovators