Zero-Knowledge Proofs
A zero-knowledge proof lets one party convince another that a statement is true while revealing nothing beyond its truth. Not a summary, not a redacted version — nothing. You can prove you know a password without transmitting it, that you're over 18 without revealing your birthdate, or that a million transactions executed correctly without anyone re-running them.
The last of those is why the field went from cryptographic curiosity to production infrastructure. Succinct proofs are small and fast to verify regardless of how much computation they attest to, which means a blockchain can verify a proof of a million transactions in milliseconds. That property drives validity rollups, and it's increasingly used outside blockchains entirely — verifiable computation, private identity, and proving that a specific ML model produced a specific output.
TL;DR
- Three properties: completeness (true statements can be proven), soundness (false ones can't), zero-knowledge (nothing else leaks).
- Succinctness is the practical breakthrough: verification cost is independent of the computation's size.
- SNARKs — small proofs, fast verification, often a trusted setup, not quantum-resistant.
- STARKs — larger proofs, no trusted setup, quantum-resistant, transparent.
- A trusted setup produces toxic waste; if retained, forged proofs become possible. Multi-party ceremonies mitigate this.
- Computation must be expressed as an arithmetic circuit — no loops with data-dependent bounds, no branching for free.
- Proving is expensive, verification is cheap. The asymmetry is the whole point.
- Not all ZK applications are private: most rollups use ZK for succinctness, and their data is public.
Quick Example
A ZK circuit for the classic private membership proof — "I'm in this set, and I haven't claimed before" — written in Circom:
The verifier learns: the prover knows a secret in the tree, and this nullifier is now spent. It learns nothing about which leaf. That's the entire mechanism behind private voting, anonymous airdrops, and privacy pools.
Core Concepts
The three properties
The simulation definition is the rigorous one and worth internalizing: a proof is zero-knowledge if a verifier who doesn't have the secret could produce an identical-looking transcript on their own. If they could have faked it, watching the real one taught them nothing.
The classic intuition
Interactive proofs like this are the foundation. The Fiat-Shamir transform makes them non-interactive by replacing the verifier's random challenges with a hash of the transcript, which is what makes proofs postable to a blockchain.
Arithmetic circuits
A ZK system doesn't prove statements about programs. It proves statements about systems of polynomial constraints, so any computation must first be flattened into one.
This is why writing ZK circuits is unlike ordinary programming:
- Loops must have compile-time bounds. The circuit is fixed-size; it can't depend on data.
- Branches cost both sides. There is no jump — you compute both paths and select.
- Comparisons are expensive.
a < brequires bit decomposition; a multiplication is one constraint. - Hash choice dominates. SHA-256 costs tens of thousands of constraints; ZK-friendly hashes (Poseidon, Rescue) cost hundreds.
A common beginner mistake is porting an algorithm directly and producing a circuit with a hundred million constraints that takes hours to prove.
SNARKs vs. STARKs
The families are converging: modern SNARK systems (PLONK, Halo2, Nova) use universal or no trusted setups, and STARK proofs are often wrapped in a SNARK for cheap on-chain verification. The choice is increasingly about proving system maturity and tooling rather than a hard tradeoff.
Trusted setups
Some SNARK systems need a one-time ceremony generating public parameters from secret randomness. That randomness — the toxic waste — must be destroyed. Anyone who retains it can forge proofs of false statements.
Multi-party ceremonies mitigate the risk: many participants each contribute randomness, and the setup is secure if at least one destroyed their contribution. Ethereum's KZG ceremony for EIP-4844 had over 140,000 participants, which makes the assumption about as weak as an assumption gets. Still, "no setup required" is a real advantage of transparent systems, and it's why STARKs are favored where trust minimization is paramount.
What They're Actually Used For
Scaling — the dominant use today
Validity rollups prove that a batch of transactions executed correctly. Ethereum verifies one small proof instead of re-executing thousands of transactions.
Worth stating clearly: this use is about succinctness, not privacy. zkSync and Starknet transactions are fully public. The "zero-knowledge" property is incidental to the reason they're used.
Privacy
- Private transactions — prove a transfer is valid (inputs exist, amounts balance, you own them) without revealing sender, recipient, or amount. Zcash's shielded pools, Aztec, and privacy pools work this way.
- Private voting — prove eligibility and that you voted once, without linking your identity to your ballot.
- Anonymous credentials — prove you're over 18, a citizen, or an accredited investor, without disclosing the underlying document.
The compliance tension is genuine and unresolved: the same primitive that protects legitimate financial privacy also frustrates sanctions enforcement. "Privacy pools" that let honest users prove non-membership in a set of illicit deposits are the leading technical proposal for threading it.
Identity and verifiable credentials
Selective disclosure is the natural fit: an issuer signs a credential once, and the holder proves individual claims from it without revealing the rest, and without the verifier contacting the issuer. This works entirely without a blockchain and is arguably the largest non-crypto application area.
Verifiable computation
Prove that an off-chain computation was performed correctly — a machine learning inference, a data query, a game state transition. zkML proves a specific model produced a specific output, which is a real answer to "did the service actually run the model it claimed?" These are early but no longer theoretical.
Building With ZK
The toolchain
zkVMs are the significant recent shift: instead of hand-writing constraints, you compile normal Rust to a provable virtual machine. The proving overhead is higher than a hand-optimized circuit, and the developer productivity difference is enormous — the same tradeoff as a compiler versus hand-written assembly, and it's likely to resolve the same way.
The proving pipeline
The asymmetry is the entire economic model. Proving is deliberately expensive because it happens once, by one party, off-chain; verification is cheap because it happens everywhere, repeatedly.
Best Practices
Count constraints early and often
Constraint count determines proving time, memory, and cost. Measure it at every stage rather than discovering at the end that your circuit needs 200 GB of RAM. A useful discipline: set a constraint budget before writing the circuit.
Use ZK-friendly primitives
Poseidon instead of SHA-256, Merkle trees instead of iterating a list, and field-native arithmetic instead of emulated bit operations. Switching a hash function alone routinely cuts constraint counts by two orders of magnitude.
Constrain everything — under-constraining is the bug class
A circuit that fails to constrain a signal lets a malicious prover choose it freely, producing valid proofs of false statements. This is the ZK equivalent of missing access control: silent, catastrophic, and the most common serious circuit vulnerability.
Distinguish public from private inputs deliberately
Every public input is revealed to everyone, forever. Every private input must nonetheless be constrained. Mislabeling a signal either leaks data or opens a soundness hole, and reviewing this list explicitly is a cheap, high-value check.
Use nullifiers to prevent replay
Any anonymous action needs a deterministic, unlinkable marker so it can't be repeated. Derive it from the secret so the same secret always yields the same nullifier, and record spent nullifiers publicly.
Don't build the cryptography yourself
Use established proving systems and audited circuit libraries (circomlib and equivalents). Novel constructions require research-level review, and the failure mode — a soundness break — is total and undetectable from outside.
Have circuits audited by ZK specialists
A general smart contract audit will not find under-constrained signals or a soundness gap in a proving system. This is a specialist skill with a small pool of practitioners; budget time accordingly.
Common Mistakes
Assuming ZK means private
Leaving a signal unconstrained
The <-- versus <== distinction in Circom is exactly this trap, and it has produced real vulnerabilities in deployed circuits.
Using a general-purpose hash inside a circuit
Data-dependent control flow
Reusing a nullifier scheme across contexts
Ignoring proving cost in the product design
FAQ
Do I need to understand the math to use ZK?
Not to build applications. Circuit DSLs and zkVMs abstract the cryptography much as a compiler abstracts assembly; you need to understand constraints, public versus private inputs, and proving cost. You do need the math to design a new proving system or audit one — and you need to know enough to recognize that you shouldn't be doing either casually.
How long does proving actually take?
Anywhere from milliseconds to hours, roughly proportional to constraint count. A small membership proof might take under a second in a browser. A zkEVM block proof takes minutes on specialized hardware, which is why proving is a service with dedicated GPU clusters. Assume proving is the bottleneck in any design and measure it early on the hardware users will actually have.
SNARK or STARK?
Whichever your target platform and tooling support, in practice. SNARKs give tiny proofs and cheap on-chain verification, at the cost of a setup ceremony (for older systems) and no post-quantum security. STARKs need no setup and are quantum-resistant, with larger proofs. The distinction is blurring — modern SNARKs have universal or transparent setups, and STARKs are often wrapped in SNARKs for cheap verification.
Is ZK only useful for blockchains?
No, though blockchains funded most of the engineering. Zero-knowledge identity and selective disclosure work entirely off-chain. Verifiable computation lets you outsource work and check the result cheaply. zkML proves a model produced a given output. Private set intersection and private analytics let organizations compute over shared data without pooling it. The blockchain applications are the most visible, not the only ones.
Are ZK proofs quantum-resistant?
STARKs are — they rely only on hash functions. Pairing-based SNARKs (Groth16, PLONK with KZG) are not, since a quantum computer breaking discrete log would break their soundness. Note this affects forging new proofs; it doesn't retroactively reveal information that was never transmitted. Lattice-based and hash-based SNARK constructions are active research.
What is a zkVM and should I use one?
A zkVM proves the execution of a general program — you write Rust or compile to RISC-V and get a proof of correct execution without writing constraints. Use one when developer time matters more than proving cost, which is most applications outside high-volume rollups. Hand-written circuits remain far more efficient and are worth it when the same circuit is proven millions of times.
Related Topics
- Layer 2 Scaling — Validity rollups, the largest deployment of ZK today
- Blockchain Fundamentals — Merkle trees and hashing, the building blocks
- Ethereum & the EVM — Where proofs are verified on-chain
- Encryption — Cryptographic primitives underneath
- Smart Contract Security — Verifier contracts as an attack surface
- Rust — The language of most modern ZK tooling
- Authentication — Selective disclosure and credential use cases