--- 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).*