libsnark: a C++ library for zkSNARK proofs
Authors
The libsnark library is developed by the SCIPR Lab project and contributors
and is released under the MIT License (see the LICENSE file).
Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file).
Overview
This library implements zkSNARK schemes, which are a cryptographic method
for proving/verifying, in zero knowledge, the integrity of computations.
A computation can be expressed as an NP statement, in forms such as the following:
- “The C program foo, when executed, returns exit code 0 if given the input bar and some additional input qux.”
- “The Boolean circuit foo is satisfiable by some input qux.”
- “The arithmetic circuit foo accepts the partial assignment bar, when extended into some full assignment qux.”
- “The set of constraints foo is satisfiable by the partial assignment bar, when extended into some full assignment qux.”
A prover who knows the witness for the NP statement (i.e., a satisfying input/assignment) can produce a short proof attesting to the truth of the NP statement. This proof can be verified by anyone, and offers the following properties.
- Zero knowledge:
the verifier learns nothing from the proof beside the truth of the statement (i.e., the value qux, in the above examples, remains secret). - Succinctness:
the proof is short and easy to verify. - Non-interactivity:
the proof is a string (i.e. it does not require back-and-forth interaction between the prover and the verifier). - Soundness:
the proof is computationally sound (i.e., it is infeasible to fake a proof of a false NP statement). Such a proof system is also called an argument. - Proof of knowledge:
the proof attests not just that the NP statement is true, but also that the
prover knows why (e.g., knows a valid qux).
These properties are summarized by the zkSNARK acronym, which stands for Zero-Knowledge Succinct Non-interactive ARgument of Knowledge (though zkSNARKs are also knows as
succinct non-interactive computationally-sound zero-knowledge proofs of knowledge).
For formal definitions and theoretical discussions about these, see
[BCCT12], [BCIOP13], and the references therein.
The libsnark library currently provides a C++ implementation of:
- General-purpose proof systems:
- A preprocessing zkSNARK for the NP-complete language “R1CS”
(Rank-1 Constraint Systems), which is a language that is similar to arithmetic
circuit satisfiability. - A preprocessing SNARK for a language of arithmetic circuits, “BACS”
(Bilinear Arithmetic Circuit Satisfiability). This simplifies the writing
of NP statements when the additional flexibility of R1CS is not needed.
Internally, it reduces to R1CS. - A preprocessing SNARK for the language “USCS”
(Unitary-Square Constraint Systems). This abstracts and implements the core
contribution of [DFGK14] - A preprocessing SNARK for a language of Boolean circuits, “TBCS”
(Two-input Boolean Circuit Satisfiability). Internally, it reduces to USCS.
This is much more efficient than going through R1CS. - ADSNARK, a preprocessing SNARKs for proving statements on authenticated
data, as described in [BBFR15]. - Proof-Carrying Data (PCD). This uses recursive composition of SNARKs, as
explained in [BCCT13] and optimized in [BCTV14b].
- A preprocessing zkSNARK for the NP-complete language “R1CS”
- Gadget libraries (gadgetlib1 and gadgetlib2) for constructing R1CS
instances out of modular “gadget” classes. - Examples of applications that use the above proof systems to prove
statements about:
- Several toy examples.
- Execution of TinyRAM machine code, as explained in [BCTV14a] and
[BCGTV13]. (Such machine code can be obtained, e.g., by compiling from C.)
This is easily adapted to any other Random Access Machine that satisfies a
simple load-store interface. - A scalable for TinyRAM using Proof-Carrying Data, as explained in [BCTV14b]
- Zero-knowldge cluster MapReduce, as explained in [CTV15].
The zkSNARK construction implemented by libsnark follows, extends, and
optimizes the approach described in [BCTV14], itself an extension of
[BCGTV13], following the approach of [BCIOP13] and [GGPR13]. An alternative
implementation of the basic approach is the Pinocchio system of [PGHR13].
See these references for discussions of efficiency aspects that arise in
practical use of such constructions, as well as security and trust
considerations.
This scheme is a preprocessing zkSNARK (ppzkSNARK): before proofs can be
created and verified, one needs to first decide on a size/circuit/system
representing the NP statements to be proved, and run a generator algorithm to
create corresponding public parameters (a long proving key and a short
verification key).
Using the library involves the following high-level steps:
- Express the statements to be proved as an R1CS (or any of the other
languages above, such as arithmetic circuits, Boolean circuits, or TinyRAM).
This is done by writing C++ code that constructs an R1CS, and linking this code
together with libsnark - Use libsnark’s generator algorithm to create the public parameters for this
statement (once and for all). - Use libsnark’s prover algorithm to create proofs of tru