---
title: gnark - a fast zero-knowledge proof library
description: gnark is a fast zero-knowledge proof library developed at ConsenSys by Gautam Botrel, Gus Gutoski and Thomas Piellard
image: https://i.imgur.com/iAj7POt.png
---
# Introducing `gnark`: a fast zero-knowledge proof library
<img style="display: block;margin: auto;" width="70%"
src="https://i.imgur.com/FvAjdSF.png">
#### We are proud to introduce `gnark`---a fast, open-source library for zero-knowledge proof protocols written in Go.
### `gnark` at a glance:
* `gnark` offers a high-level API and CLI that makes it easy for developers to write functions and produce zero-knowledge proofs for those functions.
* `gnark` currently supports the [Groth16 zk-SNARK protocol](https://eprint.iacr.org/2016/260). We intend to add support for other protocols in the future.
* `gnark` is faster than [bellman](https://github.com/zkcrypto/bellman/), which is a popular state-of-the-art implementation of Groth16. (See our [benchmarks](#gnark-is-fast) below.)
* The source code for `gnark` is [available on GitHub](https://github.com/consensys/gnark) under the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0.html).
:::warning
:warning: **Warning** :warning:
`gnark` has not been independently audited and is provided "as-is". Use `gnark` at your own risk. `gnark` offers no security guarantees such as constant-time implementation or side-channel attack resistance.
:::
## Zero-knowledge proofs in 2020
A zero-knowledge proof (ZKP) provides cryptographic assurance of **computational integrity** and **privacy**.
Let's unpack those terms:
1. **Computational integrity.** Alice wishes to convince Bob that she executed a program $P$ correctly on input $x$, obtaining output $y=P(x)$. The cost to Bob must be far smaller than the cost of simply executing $P$ himself.
2. **Privacy.** Alice wishes to convince Bob that she knows a secret input $x$ that leads to the output $y=P(x)$ without revealing any information about $x$ to Bob.
These features are well-suited to decentralized finance. For example:
* **Computational integrity** enables incredible advances in scalability---up to thousands of transactions per second!---as exemplified by projects such as [ZK-Rollup](https://medium.com/matter-labs/optimistic-vs-zk-rollup-deep-dive-ea141e71e075) for Ethereum.
* **Privacy** enables confidential, anonymous transactions as exemplified by projects such as [ZCash](https://z.cash/).
You may have heard the term **zk-SNARK** (**z**ero-**k**nowledge **S**uccinct **N**on-interactive **AR**gument of **K**nowledge). It refers to a class of ZKPs that meet certain specific conditions on the costs borne by the parties in a ZKP protocol. For simplicity in this article we prefer the term _zero-knowledge proof (ZKP)_.
ZKP is a very active area of academic research with improvments and new protocols announced week-by-week. For example, according to [this overview article](https://nakamoto.com/cambrian-explosion-of-crypto-proofs/) we saw the following new ZKP protocols in 2019: Libra, Sonic, SuperSonic, PLONK, SLONK, Halo, Marlin, Fractal, Spartan, Succinct Aurora, RedShift, AirAssembly.
There are many good expositions of ZKPs. We recommend [this explainer](https://z.cash/technology/zksnarks/) by the fine people behind ZCash and [this curated list of references](https://zkp.science).
---
<img style="display: block;margin:auto;width:80px;"
src="https://i.imgur.com/tYQ8i9r.png">
## Why `gnark` ?
In our discussions on ZKPs with clients, solutions architects, and applied cryptographers we consistently heard:
1. ZKPs are complicated, hard to understand
2. ZKPs are hard to use
3. ZKPs are too slow
`gnark` aims to address these issues and propose an enterprise-grade library, enabling a **normal development cycle** for ZKPs, with **flexible** integration into complex solutions.
### How to use `gnark`: a simple example
The `gnark` source code includes several examples.
In the `/examples/cubic` directory you'll find an implementation of the very simple example used by [Vitalik Buterin in his ZKP explainer from 2016](https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649). Given some publicly known number $y$, Alice wishes to prove to Bob that she knows a number $x$ satisfying the cubic equation $x^3+x+5=y$.
Here is the contents of `cubic.go`:
```go
package main
import "github.com/consensys/gnark/cs"
func main() {
// create root constraint system
circuit := cs.New()
// declare secret and public inputs
x := circuit.SECRET_INPUT("x")
y := circuit.PUBLIC_INPUT("y")
// specify constraints
// x**3 + x + 5 == y
x3 := circuit.MUL(x, x, x)
circuit.MUSTBE_EQ(y, circuit.ADD(x3, x, 5))
// optional: serialize circuit
circuit.Write("cubic.r1cs")
}
```
`gnark` exposes the conventional ZKP algorithms (**Setup**, **Prove**, **Verify**) through a command-line interface (`gnark setup`, `gnark prove`, `gnark verify`) and through a Go API as follows:
```go
{
//.. circuit definition
r1cs := cs.NewR1CS(circuit)
var pk groth16.ProvingKey
var vk groth16.VerifyingKey
// 1: setup, needs to be run only once per circuit
groth16.Setup(r1cs, &pk, &vk)
// 2: prove
proof, err := groth16.Prove(r1cs, &pk, input)
// 3: verify
err := groth16.Verify(proof, &vk, publicInput)
}
```
:arrow_right: Visit our [GitHub](https://github.com/consensys/gnark) for more details on:
* How to use the CLI and API to generate ZKPs for your own custom functions.
* How to leverage our standard library of ZKPs for common building blocks such as hash functions, Merkle paths, digital signatures, etc.
* How to integrate `gnark` in your project.
## `gnark` is fast!
We compare our work to [bellman](https://github.com/zkcrypto/bellman/), a state-of-the-art implementation of the Groth16 ZKP protocol developed for [ZCash](https://z.cash/) and used in multiple projects such as [Filecoin](https://filecoin.io/), [Matter Labs](https://matter-labs.io/), [ZoKrates](https://zokrates.github.io/).
It is difficult to fairly and accurately compare benchmarks among libraries. Some implementations may excel in conditions where others may not: target (web assembly, embedded, ...) or available instruction set, CPUs and RAM may have significant impact.
Nonetheless, it appears that `gnark` is faster than state-of-the-art.
Here are our measurements for the **Prover**, using BLS12-381 curve. These benchmarks ran on a `c5d.metal` AWS instance (96 vCPUS, 192GB RAM):
| nb constraints | $10^3$|$10^4$|$4\times 10^4$|$10^5$|$10^6$|$10^7$|
| -------- | --------|--------| -------- | -------- |-------- |-------- |
| bellman (ms/op)|103|183|450|807|5445|60045|
| `gnark` (ms/op) |11|67|252|520|4674|56883|
| improvement |==-89.3%==|==-63.4%==|==-44.0%==|==-35.6%==|==-14.2%==|==-5.3%==|
Observe that `gnark`'s advantage over bellman degrades for very large circuits. We have identified the elliptic curve multi-exponentiation algorithm as the cause of this degredation. In the above benchmarks, for programs of 1M constraints or more `gnark` outpaces bellman using only 30% of available CPUs! :exploding_head: We intend to improve our multi-exponentiation algorithm to make better use of CPUs, which should widen the advantage of `gnark` over bellman for very large circuits.
Here are some measurements on a consumer laptop (2016 MBP, 8 cores, 16GB RAM), for 40k constraints (~size of ZCash's spend circuit):
| $4\times 10^4$ constraints | Prove |Verify|
| -------- | --------|--------|
| bellman (ms/op)|2021|3.69|
| gnark (ms/op) |1648|3.04|
| improvement |==-18.5%==|==-17.6%==|
---
<img style="float:right;width:20%" src="https://i.imgur.com/d7nrZ5M.png">
Some of these performance improvements come from `goff`, a blazingly fast field arithmetics library we built in Go. For more information check out our [announcement article](https://hackmd.io/@zkteam/goff) on `goff`.
---
## Why write in Go?
`gnark` users write their ZKP functions in plain Go. In contrast to other ZKP libraries, we chose to not develop our own language and compiler. Here's why:
* Go is a mature and widely used language with a robust toolchain.
* Developers can **debug**, **document**, **test** and **benchmark** their circuits as they would with any other Go program.
* Circuits can be versioned, unit-tested and used in standard continious-delivery workflows.
* IDE integration (we use VSCode) and all these features come for free and are stable accross platforms.
Moreover, `gnark` exposes its APIs like any conventional cryptographic library (think `aes.encrypt([]byte)`). Complex solutions need this flexibility --- gRPC/REST APIs, serialization protocols, monitoring, logging, are all few lines of code away!
## What's next?
We released `gnark` in `0.1.0-alpha`, and are in the process of refactoring and cleaning up the code base. **Expect significant changes** as we add new ZKP schemes and complete our preliminary work on security / threat model. Future work includes:
- documentation and tutorials
- extensive testing
- refining developer experience
- new components in `gnark` standard library (aka gadgets)
- easier integration (gRPC APIs , Solidity verifier export, ...)
- security audit
- new constructs (PLONK , ...)
- further optimizations
:+1: [Issues](https://github.com/consensys/gnark/issues), new features suggestions and PRs are welcome.
---
<img style="float:left;width:90px;margin-right:20px;"
src="https://i.imgur.com/tYQ8i9r.png"> *`gnark` was written by [Gautam Botrel](https://www.linkedin.com/in/gautam-botrel/), [Gus Gutoski](https://www.linkedin.com/in/ggutoski/), and [Thomas Piellard](https://www.linkedin.com/in/thomas-piellard-53b881129/).*
*We’re a research team at [ConsenSys](https://consensys.net/). If you are interested in our work (fast finite field arithmetic, elliptic curve pairings, zero-knowledge proofs), [give us a shout](mailto:zkteam@consensys.net).*