Open-sourcing the Axiom ZK Circuits

Announcing the open-sourcing of the Axiom ZK circuits, describing our ZK circuit framework and libraries on top of halo2, and inviting community contributions.

Axiom is a ZK coprocessor for Ethereum which provides smart contracts trustless access to historic on-chain data and arbitrary expressive compute. A core component of Axiom is our ZK circuits, which allow us to prove to Ethereum that we correctly read and processed historic data to deliver query results on-chain. To write these, we created a framework on top of the Halo2 proof system to implement the necessary ZK circuits in an efficient and developer-friendly way.

Today, we are announcing that we have open-sourced all of our ZK circuit code at github.com/axiom-crypto under a permissive MIT license. This includes:

  • halo2-base: A flexible framework to build ZK circuits on top of halo2 using a simple vertical custom gate, optimized lookup arguments, and configurable circuit shape. This framework dramatically simplifies the process of writing circuits in Halo2.
  • halo2-ecc: A library of elliptic curve cryptography primitives written on top of halo2-base. This supports configurable base curves including BN254 and Secp256k1 and operations including big integers, finite field arithmetic, elliptic curve addition and scalar multiplication, ECDSA signature verification, and the optimal Ate pairing.
  • axiom-eth: A library for Ethereum data structures written on top of halo2-base. This supports parsing RLP serialization, proving Merkle-Patricia trie inclusions, and using these to provide block header, account, and storage proofs.

Our libraries use the Privacy and Scaling Explorations (PSE) fork of halo2 to use the KZG commitment scheme. In addition, we adapted two crucial pieces of open-source code written by PSE as part of the zkEVM project.

  • zkevm-keccak: A library to verify execution of the Keccak hash function in ZK. This was originally written for the Keccak circuit in zkEVM.
  • snark-verifier: A library for aggregation and EVM verfication of halo2 proofs. This supports verification (with deferred pairing) of halo2 proofs with KZG backend as well as generation of Yul code for on-chain pairing check and verification. This was originally written by PSE for the zkEVM, and we have replaced the elliptic curve circuit backend with halo2-ecc to optimize performance.

Axiom would not have been been possible without these crucial open-source pieces, and we believe that ZK technology is strongest and most secure when developed in an open, transparent, and community-driven way. In that spirit, we are excited to continue developing in the open by providing our circuit libraries for usage for other purposes. We welcome contributions and PRs at github.com/axiom-crypto and will share more about our open-source community plans in the coming weeks.

This post will introduce the reasons we chose halo2, our framework and libraries on top of halo2, and the work yet to come in developing the halo2 ecosystem.

The halo2 proof system

The halo2 proof system and library was developed by the Electric Coin Company and deployed in production for ZCash NU5. It combines the PLONKish arithmetization on the frontend with a flexible choice of polynomial commitment scheme on the backend and has strong security foundations stemming from a formal security proof and security audit. We chose halo2 for features including:

  • Frontend support for lookup tables and custom gates.
  • Flexibility in customizing circuit layout.
  • Careful and secure implementation by the Electric Coin Company.

We built Axiom in the Privacy and Scaling Explorations (PSE) fork of halo2 available on GitHub. This adds support for:

  • Modular polynomial commitments on the backend, including KZG commitments on BN254.
  • Use of randomness in witness values to support the most general RAP arithmetization.
  • Ecosystem support for EVM verification with the KZG backend.

Together, these features enable us to build circuits in a flexible frontend arithmetization which can be verified in different backends, either within ZK or in the EVM. Another factor influencing our choice was the growing ecosystem around halo2. We are excited to see and contribute to a diverse set of open-source initiatives adding support for: FRI backend and verification, the Goldilocks field, IPA-based recursion, and hardware acceleration.

KZG polynomial commitment and universal trusted setup

We chose to use the PSE fork of halo2 with the KZG commitment scheme on the BN254 curve. This enables on-chain verification in the EVM using the ecPairing precompile introduced by EIP-197. As a result, all of our circuits depend on a one-time trusted setup. This trusted setup is universal, meaning it can be run once and reused for any ZK circuit. We use the trusted setup generated by the perpetual powers-of-tau ceremony used in production by Semaphore and Hermez. For the benefit of the community, we have converted the parameters from this trusted setup into a format usable in halo2. For more details on our usage of trusted setup parameters, you can see our explainer in our docs.

halo2-base: Axiom's halo2 framework

Because halo2 has an extremely flexible and powerful frontend, it can be complex for developers to configure and use directly. To simplify this process, we wrote halo2-base, an opinionated framework implementing a simpler API which is faster to develop in while maintaining much of the original flexibility of halo2. We made several design choices:

  • Simple vertical gate: All circuits in halo2-base are implemented with a simple vertical gate implementing the relation a + b * c = d on 4 consecutive cells. We found this simple configuration to be quite performant compared to more complex custom gates.
  • Automated gate placement and configurable circuit shape: The halo2-base library places the simple gates automatically. Developers can specify their desired number of rows and columns while keeping a roughly fixed total number of cells, and we will configure a circuit with the same functionality accordingly. This allows developers to trade off faster proving speed (fewer rows, more columns) and cheaper verification (fewer columns, more rows). For a rough mental model behind these cost tradeoffs, see Cost Modeling.
  • Shared lookups: We offer lookups into a fixed table containing the constants {0, 1, ..., 2^k - 1}. Crucially for performance, we only enable these lookups from a special set of lookup columns to which we copy all cells to be looked up.

In the remainder of halo2-base, we implement basic primitives in terms of which all other circuits can be implemented. This includes operations like:

  • Arithmetic operations: addition, division, multiplication, equality checks
  • Vector operations: dot products, linear combinations, indexing into arrays
  • Range operations: inequality checks, binary decomposition, range checks

Circuits for these basic operations are exposed via a simple API which does not require interacting with the raw halo2 API.

halo2-ecc: ZK circuits for elliptic curve cryptography

As a first use case of halo2-base, we implemented halo2-ecc, a configurable library of elliptic curve cryptography primitives used heavily for recursion and aggregation in Axiom. Our library supports curves over non-native coordinate fields like BN254 and Secp256k1 and implements primitives including:

  • Big integer arithmetic: Our method combines ideas from the Chinese Remainder Theorem used in Aztec's implementation and overflow limb techniques from circom-ecdsa.
  • Finite field arithmetic: We support prime field operations and certain extension fields of degree 2 and 12 which are designed to support BN254 and BLS12-381. Our design is inspired by techniques from our prior work in circom-ecdsa and circom-pairing, but with optimizations and parameter choices tuned to the new Plonkish arithmetization.
  • Elliptic curve operations: We support standard elliptic curve operations over short Weierstrass curves over all supported finite fields, including field extensions. This includes:
    • Elliptic curve addition and doubling
    • Scalar and multi-scalar multiplication (MSM). We optimize for ZK proving performance, using windowed methods and Pippenger’s algorithm as appropriate.
    • ECDSA signature verification
    • Optimal Ate pairing for the BN254 curve.

These implementations are inspired by techniques from our prior work for circom-pairing, but optimized for the new Plonkish setting and with all primitives built on top of halo2-base. A few representative benchmarks on halo2-ecc proving performance (on M2 Max) include:

  • Proving ECDSA on Secp256k1 in 2s.
  • Proving optimal Ate pairing on BN254 in 9.5s.
  • Proving a length 100 MSM on BN254 in 27.8s.

More comprehensive and reproducible benchmarks are available at our GitHub, including different column configurations and runtimes for both M2 Max and AWS instances.

axiom-eth: ZK circuits for Ethereum data structures

To prove verified reads from on-chain historic data, we built axiom-eth, a library with support for the data structures underlying Ethereum. Our library is built on top of halo2-base and the zkevm-keccak library from the zkEVM. It supports the following operations in ZK:

  • Parsing RLP serialization: Ethereum data is serialized in the Recursive Length Prefix (RLP) format. We support parsing of individual fields in RLP-serialized fields and arrays.
  • Merkle-Patricia trie inclusion: All Ethereum data is committed to in 16-ary Merkle-Patricia tries whose roots are in the block header. We support inclusion proofs into trie roots, which are used to prove inclusion into the account and storage tries.
  • Ethereum block header, account, and storage proofs: We enable proving fields in the block header, account information, and local account storage relative to a trusted block hash. This includes:
    • Parsing block header fields in a block.
    • Proving the balance, nonce, storageRoot, and codeHash for an account.
    • Verifying lookups into an account's local storage mapping.

We use chains of block header proofs to maintain the cache of block headers in AxiomV0, and the account and storage proofs are fundamental building blocks for queries into Axiom. To enable richer queries into Axiom, we use batching and aggregation on top of proofs about individual pieces of on-chain Ethereum data. In addition, we verify the final proofs on-chain in the EVM. We do this by using the snark-verifier SDK for aggregation and on-chain verification of halo2 circuits and checking against the block hash cache in the AxiomV0 smart contract. In the coming weeks, we will explain how this works and how it enables core Axiom functionality.

What's next?

With this open-source release, we are excited to build these ZK circuits and libraries in collaboration with the community. We have benefited greatly from the work of collaborators at ZCash / Electric Coin Company, Privacy and Scaling Explorations, and Scroll in building our circuits, and we hope to give back with our libraries by enabling new applications and contributors on halo2. Finally, we are open to PRs and contributions at github.com/axiom-crypto!

If you are a smart contract developer and would like to build on Axiom, we are looking for early integration partners! To discuss possible applications or learn more:

If you'd like to join us in empowering smart contract developers with ZK:

  • We are hiring developers to tackle the hard technical problems necessary to develop, scale, and optimize Axiom. Check out our jobs page here or reach out directly at jobs@intrinsictech.xyz.
  • If you want to get straight to the code, check out our Github repos. We are open to extensions or contributions!

To stay in touch about Axiom, join our community on Twitter, Telegram, or Discord.