In conjunction with announcing Espresso, we're excited to release the Jellyfish cryptography library. Jellyfish is a toolkit of various cryptographic primitives—ranging from hash functions to accumulators to zero-knowledge proof systems. It is fully implemented in Rust, allowing for remarkable efficiency and correctness. One particular highlight of Jellyfish is our implementation of the zero-knowledge proof system, PLONK, which we believe is currently the most feature-complete and fastest open-source implementation of PLONK, according to our benchmarks.
While all of the tools in Jellyfish are being used in developing Espresso’s scalable and privacy-enabled blockchain infrastructure as well as our release of Configurable Asset Privacy for Ethereum (CAPE), these tools are fundamental cryptography building blocks for all web3 and blockchain systems. Therefore, we’ve open sourced Jellyfish under the MIT license, a highly permissive free software license. We’re excited to play our part in bolstering the rapidly growing blockchain ecosystem and in supporting the rapid adoption and development of zero-knowledge proofs. We are already seeing significant interest in Jellyfish from projects in the community and we couldn’t be more thrilled to contribute to standardization efforts for zero-knowledge.
Components of the Jellyfish library
Jellyfish implements a number of key cryptographic primitives:
PLONK, a zk-SNARK with universal setup
Hashes, pseudorandom functions (PRFs), and commitments based on Rescue, an arithmetization-friendly cipher which is ideal for zero-knowledge proofs
Merkle tree accumulators
ElGamal public key encryptions
AEAD symmetric encryptions
Jellyfish’s PLONK implementation
The past several years have seen a snowballing of improvements to general-purpose zero-knowledge proof systems. For even full-time researchers in the space, it has been difficult to keep track of all the new constructions like Bulletproofs, Marlin, PLONK, and Supersonic, and their respective benefits and tradeoffs.
Central to Jellyfish is our implementation of PLONK, introduced in 2019 by Ariel Gabizon, Zachary J. Williamson, and Oana Ciobotaru. PLONK has gained a lot of interest in the last couple years because its tradeoffs make it suitable for many privacy-related use cases in blockchains. Though PLONK still requires a trusted setup, it uses a universal and updatable trusted setup procedure. It is “universal” in that a single trusted setup is enough for any program, rather than being limited to a single program. PLONK’s setup scheme is also “updatable” which means that the trusted setup can be continually updated by new parties—as long as a single participant is honest, then the proof system is secure.
Our customized PLONK constraint system contains many key optimizations:
An efficient Rescue hash circuit: a single 3-to-1 hash gadget (over BLS12-381 scalar field) takes 148 PLONK constraints
Implements Plookup and enables efficient lookup gates and range-check gates
Circuits for PLONK verifiers
a PLONK verifier gadget (that verifies a single PLONK proof) takes only ~ 22000 PLONK constraints
Efficient elliptic curve operation circuits
e.g. an elliptic curve addition/doubling circuit only takes 2 PLONK constraints
e.g. a variable-base multi-scalar multiplication gadget with 128 base points and 256-bit scalars uses only ~36000 PLONK constraints, which is 8 times smaller than the size of a naive circuit.
Efficient modular multiplication circuits (i.e. constraining a + b = c % N or a * b = c % N for a parameter N that is different from the size of the circuit field).
e.g., for a 384-bit circuit field, a modular multiplication gadget with 256-bit modulus only takes ~20 PLONK constraints
Circuits for various crypto-primives, e.g., Merkle tree, Schnorr signatures, ElGamal encryptions, PRFs, commitments, etc.
Meanwhile, our implementation of the PLONK proof system:
Integrates Plookup arguments
Enables batch proving, i.e., generating a single (larger) PLONK proof for multiple SNARK instances.
Enables fast batch proof verifications
Supports PLONK proving/verification key merging and circuit merging
one can merge the proving key/verification key/circuit for SNARK instance A with those for SNARK instance B, and obtain a proving key/verification key/circuit for the instance A ⋀ B (i.e. the conjunction of A and B).
Finally, the Jellyfish PLONK implementation is generic in that it supports various prime fields and elliptic curves.
Getting Started with Jellyfish
We’re excited for the community to start exploring, integrating, and contributing to the development of Jellyfish. In the coming weeks, we’ll be publishing additional technical explainers and code samples using Jellyfish. Be sure to join our Discord community, where we have dedicated channels to discuss #cryptography and #development.