Proving systems

Proving systems supported in the o1js-pairing codebase.

PLONK

The o1js-blobstream codebase supports the gnark version of PLONK, used in SP1. Instructions on how to use it are described in other sections.

We provide two versions. The first is a single circuit that runs end to end verifier in ~1,200,000 constraints, roughly 700,000 for PIOP part of PLONK and ~500,00 for computing and proving that multi Miller loop output is an "r-th" residue, based on techniques developed in On proving pairings.

However, Mina programs are bounded by 64k constraints, so the computation is divided into smaller specialized circuits. Those circuits are then interconnected with different recursion techniques introduced in PCD.

The second, and practically usable one, is 24 proofs which are then compressed using a tree approach in the plonk/recursion folder. Concretely, instead of building a recursive chain we build a recursive tree. In the folder, there are 24 specialized circuits that prove specific parts of the verifier. These circuits are leaves of the computational tree, or in other words that is layer0 of our tree. We then introduce two generic compressor circuits.

These circuits are taking 2 by 2 proofs from layer i and by folding them into a new proof we build a layer i + 1. This pattern is repeated until there is one proof left - a root of a tree. The main responsibility of the compressor circuit is making sure that the output of the left subtree is equal to the input of the right subtree. Last but not least, it also makes sure to carry the public inputs of the Groth16 proof all the way to the root.

Finally, the root proof is then handed to a zkapp which checks that whole recursion was carried out correctly and constrains the public inputs. An end-to-end example of this in the context of a rollup is provided in other sections.

Note that the first run of this process is slower, since it builds the circuits for the first time and has no cache.

Groth16

The codebase also contains the infrastructure for Groth16 verification.

Since this was the earliest attempt of implementing a recursive architecture, it contains two kinds of recursive architectures, one of which is kept in the codebase for potential future-use in other use cases or when o1js constraints or tooling change.

We provide two versions. The first is a single circuit that runs end to end verifier in ~700,000 constraints. This circuit first computes multi Miller loop output and then proves that that output is an "r-th" residue, based on techniques developed in "On proving pairings". To run this circuit do the following:

cd contracts
npm install
npm run build
node --max-old-space-size=65536 build/src/groth16/multi_miller.js

The second is 16 proofs which are then compressed using a tree approach in the groth16/recursion folder. It uses the same infrastructure as the PLONK version.

If you look through git history, you will also find a third version. It's an IVC-inspired design. There is a chain of 24 connected circuits where each circuit i does a specific part of verification and verifies circuit i-1. This approach comes with a significant computational overhead because of how o1js currently handles compilation and caching.

Last updated