100 challenges to build the ZK mental model from sigma protocols up to zkVMs — Python and Rust throughout, no hand-waving.
A ZK course that teaches you the math and the tooling together. Start from completeness-soundness-ZK, derive Schnorr from scratch, understand Pedersen / KZG commitments, compile to R1CS, walk through Groth16 and PLONK, then STARKs, folding schemes, and zkVMs. Five capstones spanning a NIZK-of-preimage, a confidential payment, a zk-rollup proof-of-reserves, a Semaphore-style membership proof, and a full zkVM workflow — submit any three to earn your certificate.
Built by Lakshya
We grant free access case-by-case — students, career-switchers, builders on a tight budget. Sign in to send us a note.
Sign in to applyComplete all modules, then submit the required number of capstone projects. Each must earn a passing rating from an admin reviewer.
Prove knowledge of x such that SHA-256(x) = y without revealing x. Use Circom + Groth16 (easiest) or axiom-circuit + Halo2 (modern). Submit: the circuit source, a trusted-setup ceremony artefact (or reference to one), one generated proof + verification key, and a verification run showing 'proof valid.' Include a benchmark: constraint count, prover time, verifier time, proof size.
Build a Bitcoin-style UTXO transfer where amounts are hidden (Pedersen-committed) and conservation (sum of inputs = sum of outputs) is enforced via a Bulletproof range proof proving each output amount is in [0, 2^64]. Deliver: Rust or Python code, a test transaction, and the proof bytes. Publish the proof size (expected ~700 bytes per output with Bulletproofs) and the verification time.
Prove 'I am one of the N members of this set' without revealing which. Implement a zk-circuit that proves knowledge of a leaf + Merkle path in a 20-level tree (1M member capacity). Submit: circuit, proof generation script, and a demo where the proof binds a signal (e.g., a message) via a nullifier. This is the Semaphore primitive used in Worldcoin-style anonymous credentials.
Build a proof-of-reserves system where an exchange commits to the sum of all customer balances and proves to each customer 'your balance is included in this total' without revealing other customers' balances. Use a Merkle tree of balances + sum checks. Submit: prover + verifier code, a test run with 1000 synthetic accounts totalling a known sum, and a short design note explaining liabilities and why this does NOT prove solvency on its own.
Use RISC Zero (or SP1) to compile a non-trivial Rust program — a Fibonacci sequence verifier, or a simple SHA-256 preimage checker — into a ZK proof of its execution. Submit: the Rust program, the generated proof, and the verifier output. Bonus: measure cycle count and prover time, and compare against a hand-written circuit's size.
The clearest intro to how R1CS becomes a polynomial identity. Read before Module 4.