Zero-Knowledge Proofs and Tornado Cash: A Technical Deep Dive -by Jay Makwana


Imagine you’re at a party and someone claims they know the password to the WiFi. Instead of just telling everyone the password (which would defeat the purpose), they prove they know it by successfully connecting their phone. They’ve proven their knowledge without revealing the actual secret. This is essentially what zero-knowledge proofs do in cryptography — and it’s exactly how Tornado Cash revolutionized blockchain privacy.
The Magic Behind Zero-Knowledge Proofs
Zero-knowledge proofs sound like something out of a sci-fi movie, but they’re actually elegant mathematical constructs that solve a fundamental problem: How do you prove you know something without revealing what you know?
Think of it like this classic analogy: You want to prove you can distinguish between two identical-looking balls (one red, one blue) without revealing which is which. A verifier holds both balls behind their back, shows you one, then hides it again. They ask, “Did I switch the balls?” If you really can tell them apart, you’ll be right every time. If you’re just guessing, you’ll be wrong about half the time. After enough rounds, the verifier becomes convinced you can distinguish them, but they never learn which ball is which color.
Round 1: Show Ball A → Hide → Show Ball B → "You switched!" ✓
Round 2: Show Ball B → Hide → Show Ball A → "You switched!" ✓
Round 3: Show Ball A → Hide → Show Ball A → "No switch!" ✓
...and so on
For a proof system to be truly zero-knowledge, it needs three properties:
🎯 Completeness: If you’re telling the truth and both parties play fair, the verifier will believe you.
🛡️ Soundness: If you’re lying, you can’t fool an honest verifier (except with tiny probability).
🔒 Zero-Knowledge: If you’re telling the truth, the verifier learns nothing except that fact.
Meet zk-SNARKs: The Crypto World’s Swiss Army Knife
Tornado Cash didn’t use just any zero-knowledge proof — it used zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge). Let’s break down why these are special:
Succinct: The proofs are tiny and super fast to verify
Non-interactive: No back-and-forth needed — just one proof does it all
Arguments of Knowledge: You must actually know the secret, not just know it exists
Think of zk-SNARKs as the difference between a long, tedious court case with multiple witnesses and evidence (traditional proofs) versus a single, undeniable DNA test (zk-SNARKs). Both prove guilt, but one is way more efficient.
How Tornado Cash Worked: The Technical Magic
The Big Picture
Tornado Cash was like a digital mixing bowl. You’d throw your “marked” coins in one side, and later withdraw “clean” coins from the other side. But here’s the genius part — it used math to prove you deserved those coins without revealing which specific coins you originally deposited.
Alice deposits 1 ETH → [MIXING POOL] → Bob withdraws 1 ETH
Carol deposits 1 ETH → [MIXING POOL] → Alice withdraws 1 ETH
Dave deposits 1 ETH → [MIXING POOL] → Carol withdraws 1 ETH
The blockchain sees the deposits and withdrawals, but it can’t link them together. It’s like a magical vending machine that remembers you paid, but forgets your face.
The Merkle Tree: Your Digital Receipt System
When you deposited money into Tornado Cash, here’s what happened behind the scenes:
You generated a secret recipe — two random ingredients called
nullifier
andsecret
You baked a commitment —
commitment = hash(nullifier + secret)
The system filed your receipt — added your commitment to a giant tree of all deposits
ROOT
/ \
BRANCH1 BRANCH2
/ \ / \
LEAF1 LEAF2 LEAF3 LEAF4
↑ ↑ ↑ ↑
Alice Bob Carol Dave
(commits) (commits) (commits) (commits)
This Merkle tree is like a giant filing cabinet where your deposit receipt gets stored. The beautiful thing? Everyone can see the filing cabinet, but they can’t tell which folder is yours.
The Withdrawal Dance: Proving Without Revealing
When you wanted to withdraw, you had to perform a cryptographic dance with three moves:
Move 1: “I have a valid receipt” — Prove your commitment exists in the tree Move 2: “I know the secret recipe” — Show you know the nullifier and secret Move 3: “I haven’t used this before” — Prove this nullifier hasn’t been spent
Withdrawal Process:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Generate │ │ Create ZK │ │ Submit to │
│ ZK Proof │ -> │ Proof that │ -> │ Smart │
│ (off-chain) │ │ verifies all │ │ Contract │
│ │ │ conditions │ │ (on-chain) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
The Circuit: Where the Magic Happens
The zk-SNARK circuit was like a bouncer at an exclusive club. It checked multiple conditions simultaneously:
// Simplified circuit logic (not actual code, but the idea)
function tornadoCircuit(publicInputs, privateInputs) {
// Public stuff everyone can see
const { merkleRoot, nullifierHash, recipient } = publicInputs;
// Secret stuff only you know
const { nullifier, secret, merklePath } = privateInputs;
// Prove you know the secret recipe
const commitment = hash(nullifier, secret);
// Prove your receipt is in the filing cabinet
const computedRoot = verifyMerklePath(commitment, merklePath);
assert(computedRoot === merkleRoot);
// Prove you haven't used this receipt before
const computedNullifierHash = hash(nullifier);
assert(computedNullifierHash === nullifierHash);
return "Valid proof! You can withdraw.";
}
The Cryptographic Toolbox
Poseidon: The Hash Function That Plays Nice
Traditional hash functions like SHA-256 are like trying to fit a square peg in a round hole when it comes to zero-knowledge circuits. Tornado Cash used Poseidon, a hash function designed specifically for zk-SNARKs.
SHA-256 in ZK circuit: 20,000+ constraints 😵
Poseidon in ZK circuit: ~150 constraints 😎
It’s like the difference between using a sledgehammer and a precision screwdriver — both get the job done, but one is way more elegant.
Groth16: The Proof System
Groth16 was the specific zk-SNARK construction Tornado Cash used. Think of it as a highly optimized proof factory:
Input: Your private information + public parameters Output: A tiny proof (just 3 numbers!) that convinces everyone
Proof Generation:
Private Inputs (Big) → [Groth16 Factory] → Proof (Tiny)
~1MB ~200 bytes
The Smart Contract: Where It All Comes Together
The Tornado Cash smart contract was surprisingly simple for something so powerful:
contract TornadoCash {
// Keep track of used nullifiers (prevent double-spending)
mapping(bytes32 => bool) public nullifierHashes;
// Store the commitment tree root history
bytes32[ROOT_HISTORY_SIZE] public roots;
function deposit(bytes32 _commitment) external payable {
// Add your commitment to the tree
// Update the tree root
// Accept your ETH
}
function withdraw(
bytes calldata _proof,
bytes32 _root,
bytes32 _nullifierHash,
address payable _recipient,
uint256 _fee
) external {
// Verify the ZK proof
// Check nullifier hasn't been used
// Send ETH to recipient
// Mark nullifier as used
}
}
The User Experience: What It Actually Felt Like
Using Tornado Cash was like going to a high-tech bank:
Deposit Phase: “Here’s my 1 ETH and my secret commitment”
Waiting Period: “I’ll come back later from a different address”
Proof Generation: “Let me create my mathematical proof…” (takes 2–3 minutes)
Withdrawal: “Here’s my proof, give me my 1 ETH”
User Journey:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Deposit │ │ Wait │ │ Generate │ │ Withdraw │
│ 1 ETH │ -> │ (optional │ -> │ ZK Proof │ -> │ 1 ETH │
│ Address A │ │ time delay) │ │ (2-3 mins) │ │ Address B │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Security Considerations: The Good, The Bad, The Ugly
The Good: Mathematical Guarantees
The cryptography was solid. If you generated your secrets properly and the setup was honest, your privacy was mathematically guaranteed.
The Bad: Trusted Setup
Groth16 required a “trusted setup ceremony” — like needing a group of people to create a master key and then destroy it. If they cheated, the whole system could be compromised.
Trusted Setup Process:
Person 1: Creates part of key → Destroys their part
Person 2: Adds to key → Destroys their part
Person 3: Adds to key → Destroys their part
...
Final Key: Only usable if ALL participants were honest
The Ugly: Metadata Leakage
While your transaction amounts and addresses were private, other information could leak:
Timing: When you deposit vs. withdraw
Gas prices: How much you paid for transactions
Patterns: If you always withdraw exactly 24 hours after depositing
Performance and Practicality
The Numbers That Mattered
Proof Generation: 2–3 minutes on average laptop
Proof Size: ~200 bytes (tiny!)
Verification: ~270,000 gas (~$10–50 depending on gas prices)
Anonymity Set: Stronger with more users in the pool
Real-World Constraints
Generating proofs was computationally intensive. Your laptop would basically turn into a mini heater for a few minutes while crunching through the math. But once generated, verification was lightning fast.
Beyond Tornado Cash: The Legacy Lives On
Even though Tornado Cash faced regulatory challenges, its technical innovations influenced the entire blockchain privacy ecosystem:
Universal zk-SNARKs (PLONK)
New systems that don’t need trusted setup for every circuit — like having a universal key that works for any lock.
Recursive Proofs
Proofs that can prove other proofs, creating incredibly efficient blockchain systems.
Programmable Privacy
Extending the concept beyond simple mixing to private smart contracts and applications.
The Human Impact: Why This Matters
Privacy isn’t just about hiding illegal activity. It’s about:
Financial Privacy: Not wanting everyone to see your salary
Safety: Protecting activists in oppressive regimes
Business: Keeping competitive information private
Personal: Maintaining basic human dignity in digital transactions
Tornado Cash showed that strong privacy is technically possible on public blockchains. That’s a powerful concept that extends far beyond cryptocurrency.
Wrapping Up: The Future of Private Blockchains
Tornado Cash was like the first airplane — it proved the concept was possible, even if the implementation wasn’t perfect. The technical innovations it introduced continue to inspire new privacy-preserving protocols.
The core insight remains powerful: you can prove you have the right to do something without revealing everything about yourself. In a world where digital privacy is increasingly rare, that’s not just a technical achievement — it’s a fundamental building block for digital freedom.
Whether you’re a developer building the next privacy protocol or just someone curious about how this magic works, understanding these concepts helps us build a more private, secure digital future.
Want to dive deeper? The original Tornado Cash circuits are open source, and studying them is one of the best ways to understand practical zk-SNARK applications. Just remember — with great cryptographic power comes great responsibility.
Subscribe to my newsletter
Read articles from Jay Makwana directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
