Introduction to Zero-Knowledge Proofs

Zero-knowledge proofs (ZK-proofs) are cryptographic protocols that allow one party (the prover) to convince another party (the verifier) that a certain statement is true, without revealing why it is true or any additional information beyond the validity of the statement.

A good zero-knowledge proof system should satisfy the following three properties:

  • Completeness: If the prover knows a valid solution (called the witness) for a given public input, they should be able to generate a proof that convinces an honest verifier.
  • Soundness: If the prover does not know a valid witness, it should be computationally infeasible to create a convincing proof. This prevents cheating.
  • Zero-Knowledge: The verifier learns nothing about the witness beyond the fact that the statement is true. In other words, the proof reveals no private information.

Interactive vs Non-Interactive Proofs

ZK-proofs come in two main forms:

  • Interactive proofs: These involve multiple rounds of communication between the prover and the verifier. The verifier sends random challenges, and the prover responds. This interaction is necessary to establish soundness, but it can be impractical in many real-world applications.

  • Non-interactive proofs: These eliminate the need for back-and-forth communication. Instead, the prover generates a single proof that the verifier can check independently. This is ideal for decentralized systems like blockchains.


SNARKs vs STARKs

Non-interactive proofs are further divided into two major types:

  • zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge): Efficient and compact proofs that support fast verification and small proof sizes. However, they require a trusted setup—a preprocessing step that must be done securely to avoid compromising the system.

  • zk-STARKs (Zero-Knowledge Scalable Transparent Arguments of Knowledge): A more recent alternative that avoids the need for a trusted setup and offers post-quantum security, but generally results in larger proof sizes and slower verification.


Common zk-SNARK Proof Systems

There are multiple zk-SNARK systems with different trade-offs. The two main ones are:

  • Groth16: One of the most widely used zk-SNARK systems. It produces very small proofs (~200 bytes) and is extremely fast to verify. However, it requires a trusted setup that is specific to each circuit.

  • PLONK: A more recent proving system that supports a universal trusted setup, meaning the same setup can be reused across many circuits. It is slightly slower and produces larger proofs than Groth16, but offers greater flexibility and updatability.


Summary

We can summarize the different types of Zero-Knowledge Proofs with this diagram.

graph TB A[Zero Knowledge Proofs] A --> B[Interactive Proofs] A --> C[Non-interactive Proofs] C --> D[zk-SNARKs] C --> E[zk-STARKs] D --> F[Groth16] D --> G[Plonk]

In this tutorial, we will focus on zk-SNARKs, particularly using Groth16, which is currently one of the most practical and widely supported options in tooling like snarkjs and circom. In the next section Getting Started with zk-SNARKs, we’ll walk through how it works, how to define a circuit, how to generate the trusted setup, and how to create and verify proofs.