Skip to content

Ginger-lib is a general purpose zk-SNARK library that supports recursive proof composition

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

DanieleDiBenedetto/ginger-lib

 
 

Repository files navigation

ginger-lib: a RUST library for zk-SNARKs

Ginger-lib is a general purpose zk-SNARK library that supports recursive composition of Groth16 arguments.

Originally a fork of the ZEXE project, ginger-lib was created with the goal of being an independent library, i.e. not linked to the Decentralized Private Computation (“DPC”) application or any other specific use case. Designed as a developer toolset for implementing zero-knowledge SNARKs, ginger-lib comes with an increased collection of cryptographic primitives and matching gadgets, that can serve as building blocks for application-tailored statements/circuits.

Ginger in Italian is "Zenzero", and this “Zen zero-knowledge” library was indeed developed to add some more spice to the already hot global zk-SNARK movement!

Overview

Ginger-lib was built with the goal of being easily integrated and used by any project that needs to implement its own, application-tailored zk-SNARK. As such, it provides SNARK core objects and functionalities, and a few closely related ancillary tools.

In particular, its first release comes with a complete set of tools for recursive proof composition as in Ben-Sasson, et al. "Scalable Zero Knowledge via Cycles of Elliptic Curves (2014)". Specifically, it adds to the original ZEXE code the following elements:

  • MNT4-753 and MNT6-753 curves, a re-implementation of Coda's MNT4-MNT6 cycle of pairing friendly elliptic curves for a security level of 128 bit. All curve parameters were re-checked, the pairing engine ported to Rust, the gadget collection extended with all needed recursive argument evaluation components.
  • mixed-domain FFT, to allow efficient conversion between coefficient and point-value polynomial representations in the domains needed to support large circuits.

The library includes also some additional cryptographic primitives, implemented to be efficiently modelled in a SNARK, and in particular:

  • the POSEIDON hash function - thanks to its efficient description as an arithmetic circuit, the POSEIDON hash family is ideal for SNARKs. Our implementations for both the MNT4-753 and MNT6-753 scalar fields use the modular inversion S-Box, apply a security level of 128 bits and are optimized for performance.
  • Schnorr NIZK proof and signature scheme - Schnorr-like non-interactive zero-knowledge (NIZK) proof and the Schnorr signature scheme, using POSEIDON as random oracle and adapted to be efficiently integrated in a SNARK.
  • a SNARK-friendly Verifiable Random Function (VRF), based on our Schnorr and POSEIDON primitives.
  • a SNARK-friendly Merkle Tree, using POSEIDON as its hash function.

Along with the above primitives, ginger-lib comes with the following new gadgets:

  • Groth16 verification gadgets for both the MNT4 and the MNT6 curve. These gadgets are the core components of recursive proof evaluation. They enforce that a Groth16 SNARK, based on one of these two curves, verifies.
  • POSEIDON hash gadget, enforcing that some pre-image hashes to a given fingerprint.
  • Schnorr proof / signature verification gadgets, enforcing that a single-exponent Schnorr NIZK proof or Schnorr signature, that was created by our corresponding primitives, verifies.
  • VRF verification gadget, enforcing that a public key and message, and a VRF-output, are consistent.
  • Merkle Tree gadget, enforcing that the authentication path of a leaf is consistent with a given Merkle root.

Extensive automated tests have been introduced for the added implementations.

Since it was developed to support real-world applications, ginger-lib has a strong focus on performance. Some of the code is already optimized in timing. More specifically, optimizations were performed on the implementation of the POSEIDON hash function: batch hashing/verification was significantly sped up by using a "single inversion + field multiplications" replacement for multiple parallel inversions. The same trick was also used to speed up hashing in Merkle trees. Further performance improvements were obtained by parallelizing the code for multi-core implementation, and by speeding up the implementation of field multiplication.

Continuous performance improvement will be a key goal for all future releases and improvements of the library.

Please note: the library is in development, its core code is still being modified, and it has not yet undergone extensive review or testing. No guarantees are provided about its security and functionality. At this stage, it is not suitable for use in production systems.

Directory structure

The high-level structure of the repository is as follows:

  • algebra: Rust crate that provides all the mathematical "bricks": finite fields, elliptic curves, FFT.
  • primitives: Rust crate that implements all the key cryptographic primitives.
  • proof-systems: Rust crate that implements the Groth16 and GM17 zk-SNARK proving systems.
  • r1cs-core: Rust crate that defines core interfaces for a Rank-1 Constraint System (R1CS).
  • r1cs-std: Rust crate that provides various gadgets used as building blocks of more complex R1CS circuits.
  • r1cs-crypto: Rust crate that provides various cryptographic primitives gadgets.

In addition, there is a bench-utils crate which contains infrastructure for benchmarking. It includes macros for timing code segments. It hasn't been changed from the original ZEXE implementation.

Documentation

Detailed information about the choices made when designing and implementing our primitives and gadgets is available in the doc/ directory. In particular you can find the following documents:

  • PoseidonAndGadgets, it documents the parameters for our POSEIDON hash function and its verification circuit.
  • SchnorrAndGadgets, it explains our length-restricted variant of the Schnorr signature, and its verification circuit.
  • SchnorrVerdictGadget, it describes a slight generalization of the Schnorr verification gadget, a circuit which enforces a boolean input (the "verdict") to encode the validity/non-validity of a given Schnorr signature.

Build guide

The library compiles on the stable toolchain of the Rust compiler. To install the latest version of Rust, first install rustup by following the instructions here, or via your platform's package manager. Once rustup is installed, install the Rust toolchain by invoking:

rustup install stable

After that, use cargo, the standard Rust build tool, to build the library:

git clone https://github.com/.../ginger-lib.git
cd ginger-lib
cargo build --release

This library comes with unit tests for each of the provided crates. Run the tests with:

cargo test --all-features 

Please note: by default, cargo test will execute the tests concurrently on all available cores. Since some tests are resource-intensive, this may abort the tests execution. If this happens, you may want to reduce the number of cores running the tests with the command:

cargo test --all-features --test-threads=<#threads>

Lastly, this library comes with benchmarks for the algebra crate. These benchmarks require the nightly Rust toolchain; to install this, run rustup install nightly. Then, to run benchmarks, run the following command:

cargo +nightly bench --all-features 

Contributing

Contributions are welcomed! Bug fixes and new features can be initiated through GitHub pull requests. To speed the code review process, please adhere to the following guidelines:

  • Follow Horizen repositories' code of conduct
  • Follow Horizen repositories' styling guide
  • Please gpg sign your commits
  • Please make sure you push your pull requests to the development branch

PRs Welcome

License

ginger-lib is licensed under the following license:

Unless you explicitly state otherwise, any contribution submitted for inclusion in ginger-lib by you shall be licensed as above, without any additional terms or conditions.

License MIT

Acknowledgements

The library was developed by Horizen (formerly ZenCash), as part of their effort to implement the Zendoo sidechain system.
The project started by modifying a forked code-base originally developed by the SCIPR Lab researchers for their ZEXE project.
ZEXE had previously borrowed some code from the Zcash/ECC Bellman library.
Some of the objects made available in this repo were adapted by the work performed by O(1) Labs for their Coda project.
Ginger-lib owes deeply to SCIPR Lab's LibSNARK, the real foundation of all practical zk-SNARK development activities.

About

Ginger-lib is a general purpose zk-SNARK library that supports recursive proof composition

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%