🎯 Goal

Learn how zero-knowledge proofs (ZKPs) enable users to prove something is true without revealing why or how. We’ll build an intuition for zkSNARKs and explore tools like Semaphore, Circom, and SnarkJS to create private voting, anonymous signals, and more.


🧠 1. What are Zero-Knowledge Proofs?

β€œI know a secret, and I can prove itβ€”without revealing it.”

πŸ”’ Use Cases

  • Prove membership in a group (e.g., voting, whistleblowing)
  • Prove you know a password without showing it
  • Authenticate without identity
  • Verify correctness of computations anonymously

πŸ” 2. zkSNARK vs zkSTARK

Feature zkSNARK zkSTARK
Proof size Very small Larger
Trusted setup βœ… Required (except Halo) ❌ None
Performance Fast generation & verify Slower generation
Libraries snarkjs, circom starkware, cairo, zkwasm

We’ll use zkSNARKs with Circom in this lesson for simplicity.


πŸ›  3. Toolchain: Circom + SnarkJS + Semaphore

πŸ“¦ Install with NodeJS + Rust

npm install -g snarkjs
cargo install --locked circom

Or build Circom from source:

git clone https://github.com/iden3/circom.git
cd circom
cargo build --release

Test:

circom --help
snarkjs --help

πŸ§ͺ 4. Create a Simple ZK Circuit

πŸ“ circuit.circom

pragma circom 2.0.0;

template IsEven() {
    signal input in;
    signal output out;

    out <== in % 2 === 0;
}

component main = IsEven();

Compile the circuit:

circom circuit.circom --r1cs --wasm --sym

This generates:

  • circuit.r1cs
  • circuit.wasm
  • circuit.sym

πŸ§ͺ 5. Trusted Setup (Phase 1 & 2)

1. Powers of Tau ceremony:

snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="Cypherpunk"

2. Generate proving/verifying keys:

snarkjs groth16 setup circuit.r1cs pot12_0001.ptau circuit_final.zkey
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

πŸ§ͺ 6. Create a Proof

Input file: input.json

{ "in": 42 }

Generate witness:

node circuit_js/generate_witness.js circuit_js/circuit.wasm input.json witness.wtns

Create proof:

snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json

βœ… 7. Verify the Proof

snarkjs groth16 verify verification_key.json public.json proof.json

If valid:

OK!

🧩 8. Bonus: Anonymous Signals with Semaphore

Prove group membership without revealing your identity

πŸ“¦ Install:

npm install -g @semaphore-protocol/cli

Create identity:

semaphore identity create myid

Generate signal:

semaphore proof \
  --identity-path myid.json \
  --group 'cypherpunk-club' \
  --external-nullifier 'vote2025' \
  --signal 'YES'

This generates a ZK proof that:

  • You’re a group member
  • You voted “YES”
  • You didn’t vote twice
  • Nobody knows which member you are

πŸ“ 9. Journal & Git Commit

✍️ Reflect on ZK Proofs

echo "Bonus 4: Learned how zero-knowledge proofs work using Circom and SnarkJS. Built a basic even-number circuit, generated ZK proofs, and verified them. Used Semaphore for anonymous signaling." >> notes/bonus4_zk_snarks.md

πŸ“¦ Git Commit

git add .
git commit -S -m "Bonus 4 – Zero-Knowledge Proofs with Circom, SnarkJS, Semaphore"

βœ… Bonus 4 Checklist

  • Installed Circom and SnarkJS
  • Created a basic ZK circuit
  • Ran trusted setup
  • Generated and verified a zkSNARK proof
  • Used Semaphore to generate an anonymous signal
  • Wrote a journal and signed Git commit

🧭 Up Next Bonus Options

  • Bonus 5: Privacy-Centric Smart Contracts (Aztec, Noir, DarkFi)
  • Bonus X: Encrypted Routing with I2P + Garlic Routing
  • Bonus X: Post-Quantum Crypto Tooling

πŸ“Œ Notes

  • ZKPs are foundational to the next-gen privacy layer for Web3, DAOs, voting, reputation, and more
  • Trusted setup can be removed with newer systems (Halo2, STARKs)
  • Semaphore is useful for anonymous credentials, identity mixers, DAO governance