--- 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$. You'll [find here](https://github.com/consensys/gnark#examplescubic) a code walkthrough, but here is what this circuit definition looks like: ```go // CubicCircuit defines a simple circuit // x**3 + x + 5 == y type CubicCircuit struct { // struct tags on a variable is optional // default uses variable name and secret visibility. X frontend.Variable `gnark:"x"` Y frontend.Variable `gnark:",public"` } // Define declares the circuit constraints // x**3 + x + 5 == y func (circuit *CubicCircuit) Define(curveID gurvy.ID, cs *frontend.ConstraintSystem) error { x3 := cs.Mul(circuit.X, circuit.X, circuit.X) cs.AssertIsEqual(circuit.Y, cs.Add(x3, circuit.X, 5)) return nil } ``` `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: #### APIs ```go pk, vk := groth16.Setup(r1cs) proof, err := groth16.Prove(r1cs, pk, solution) err := groth16.Verify(proof, vk, solution) ``` #### Command line interface ```bash cd examples/cubic go run cubic.go gnark setup circuit.r1cs gnark prove circuit.r1cs --pk circuit.pk --input input.json gnark verify circuit.proof --vk circuit.vk --input input.json ``` :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**. These benchmarks ran on a AWS c5a.24xlarge instance, with hyperthreading disabled. The same circuit is benchmarked using `gnark`, `bellman` (bls381, ZCash), `bellman_ce` (bn256, matterlabs). ### BN256 | nb constraints | 100000|32000000|64000000| | -------- | --------| -------- | -------- | | bellman_ce (s/op)|0.43|106|214.8| | gnark (s/op) |0.16|33.9|63.4| | speedup |x2.6|x3.1|x3.4| On large circuits, that's **over 1M constraints per second**. ### BLS381 | nb constraints | 100000|32000000|64000000| | -------- | --------| -------- | -------- | | bellman (s/op)|0.6|158|316.8| | gnark (s/op) |0.23|47.6|90.7| | speedup |x2.7|x3.3|x3.5| --- <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.3.0`. **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).*