Zero-Knowledge Proofs
Originsβ
The concept of Zero-Knowledge Proofs (ZKPs) was first invented by Shafi Goldwasser, Silvio Micali and Charles Rackoff in their seminal paper, The Knowledge Complexity of Interactive-Proof Systems in the 1980s.
Despite being considered as a theoretical breakthrough, even the cryptography community labeled the scheme as impossible in practice when the idea was born. Thanks to many breakthroughs made in the recent years, especially the contribution made by many web3 projects like ZCash and Aztec, we have seen a Mooreβs Law style improvement on the performance of zero-knowledge proof systems.
What is a Zero-Knowledge Proof System?β
A zero-knowledge proof system is a protocol by which someone (the prover) can prove the correctness of a statement to someone else (the verifier) without disclosing any additional information. It consists of the following elements and satisfies the following properties.
Elements of Zero-Knowledge Proof Systemsβ
- Statement: The statement whose truth we want to prove.
- Public Input: The information available to both the prover and the verifier.
- Witness: The information known only by the prover which is enough to prove the statement. The prover wants to keep this information secret from the verifier.
- Proof: A piece of information derived by the prover from the statement, public input, and witness that can be verified against the statement and the public input to test the truth of the claim.
Properties of Zero-Knowledge Proof Systemsβ
Generally, zero-knowledge proof systems must satisfy the following 3 crucial properties:
- Completeness: An honest prover can convince the verifier about any statement he/she knows.
- Soundness: A computationally bounded prover cannot forfeit a proof that can convince an honest verifier.
- Zero-Knowledge: The proof doesnβt leak any information other than the truth of the statement itself.
Exampleβ
To better illustrate a ZKP system, let us run a simple example in the finite field .
- Statement: is a square in
- Public input: .
- Witness: , since in .
The protocol consists of the following steps:
- The prover chooses a random non-zero and sends to the verifier.
- The verifier chooses and sends it to the prover.
- The prover sends the verifier the proof .
- The verifier accepts the proof if .
Then they repeat the protocol above for different values of until the verifier is convinced.
Let us check that the above protocol satisfies the desired properties:
- Completeness: It is clear, since .
- Soundness: A dishonest prover might try to trick the verifier by sending a in step 1 which is not a square. In that case the verifier would reject the proof in half the cases, when they choose . If is a square but is not, the verifier would reject the proof when . A dishonest prover has a probability to trick the protocol on each iteration, so this probability can be made negligible by iterating enough times.
- Zero-knowledge: If , the prover does not use at any point in the proof, it cannot be leaked. If , the only place where the prover uses is in , from which the verifier cannot extract without the knowledge of . As long as the prover does not repeat the above protocol with the same for different 's, the protocol remains zero-knowledge.
Succint Non-Interactive Arguments of Knowledge (SNARKs)β
A particularly important type of ZKP systems are SNARKs. They are zero-knowledge proof systems which satisfy the following extra properties:
Argument of knowledge: The prover wants to prove knowledge of the witness itself. In the example above, the statement would be "I know a square root of in ". One can show the protocol above also proves this stronger statement, thus making it an argument of knowledge.
Succinctness: The proof size is constant or logarithmic compared with the circuit size (i.e. the amount of computations) of the statement. The protocol above is also succint, since the proof is just a number in .
Non-Interactive: Proof generation and proof verification happen in two consecutive rounds: first the prover runs a function to generate a proof and then the verifier runs a function to verify it. The protocol above is interactive, i.e., it does not satisfy this property because of the continuous communication between prover and verifier.
Setupβ
SNARKs need an extra element to be properly defined
- Setup: A set of proving and verifying keys necessary to execute the and functions, respectively.
In pairing-based proving systems such as Groth16, the setup consists of a set of elliptic curve points, generated from a randomly sampled seed, more commonly known as the toxic waste. Knowledge of this seed allow an attacker to fabricate valid ZKPs for false statements, so it is of paramount importance that the generation of the keys is safely executed, i.e., that nobody knows the toxic waste employed to generate them. This is usually done in a multi-party computation known as Trusted Setup.
The simple definition of a SNARKβ
Once all the elements are fixed, a SNARK is defined as a pair of functions
- prove(Setup, Public Input, Witness) -> Proof: Generates a proof for the knowledge of the witness using the public input and witness.
- verify(Setup, Public Input, Proof) -> bool: Verifies the proof against the public input.
ZKPs in MantaPayβ
MantaPay, Manta Network's private payment system, uses ZKPs to ensure that transfers are executed according to a structured protocol, called circuit, while keeping sensitive information (for example, how much money you send or who you send it to) private.
Instead of directly publishing those details on-chain, which would ensure that the protocol has been properly executed but leak all private data, the sensitive bits of information act as witnesses in a ZKP system, namely the SNARK Groth16. Then the Ledger runs the function on the resulting ZKP against the public inputs and, if it passes, posts the transaction.
This ZKP can be summarized as I executed my transaction following the protocol but much more is going under the hood:
- The amount of asset sent from my account is equal to the amount of asset received in the other account.
- I own the asset I am sending.
- I haven't spent the asset I am sending yet.
- The transfer I made is auditable using my viewing key.
The three circuitsβ
MantaPay has three zk-powered circuits:
- ToPrivate: Privatizes an asset, realizing it as a zkAsset and depositing it in the private Shielded Pool. zkAssets can then be used in private transfers.
- PrivateTransfer: Sends a zkAsset to a zkAddress privately.
- ToPublic: Reclaims a zkAsset to get the equivalent amount of Asset in your public wallet.