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