Writing My First ZK Circuit with Circom

The crypto market is down bad right now 📉. But honestly? The bear market is my favourite time to learn. No FOMO, no Twitter noise. Just me, my laptop, and a very long reading list.

I have been talking about zero-knowledge proofs for a while now (see my earlier posts on the STARK prover). This time I actually wrote one from scratch instead of just reading about it.

Why Circom?

I started with Circom because it targets Solidity developers and the tooling around it (snarkjs) is well-documented. There are other options like Noir or Halo2, but Circom felt the most approachable as a starting point.

The mental model that finally clicked for me: a ZK circuit is like a function where you prove you know the inputs that produce a given output, without revealing those inputs. The verifier learns nothing about your private inputs — only that they satisfy the constraints.

My First Circuit

I started with the classic example: prove that you know two numbers a and b that multiply together to give a public value c. Sounds simple, but seeing it work end-to-end made everything concrete.

pragma circom 2.0.0;

template Multiply() {
    signal input a;
    signal input b;
    signal output c;

    c <== a * b;
}

component main = Multiply();

After compiling with Circom, running through snarkjs to generate the proving and verification keys, and finally deploying the Solidity verifier contract on a testnet — it worked. The verifier confirmed my proof without knowing what a and b were.

It’s honestly a bit magical the first time you see it. 🤯

What Tripped Me Up

The hardest part was understanding the difference between signals and variables in Circom. Signals are constrained (they form part of your circuit), variables are not. If you mix them up, you get subtle bugs that compile fine but produce incorrect proofs.

Also, the trusted setup phase with snarkjs requires downloading some relatively large files (the Powers of Tau ceremony output). The documentation does warn you but I still sat there wondering why my internet was being hammered.

What’s Next

I want to build something actually useful with this — probably a simple private voting circuit. Also planning to explore Noir from Aztec, which has a Rust-like syntax and might feel more natural given my background with Rust.

ZK is hard, but it’s the kind of hard that feels worth it.

References

How I learn Rust

From my observation, Rust is a really popular language in not only blockchain but also areas such as gaming where high performance is required. Many of my favourite projects are written in Rust, and it is frustrating when I can’t understand the language… 🥲 This is also my main driving force to study Rust.

I came across few resources on the Rust official site. Making sure that I subscribe to official updates and newsletters. Another source I follow is the Rust in Blockchain site, they also occasionally update their blog which is very helpful to catch up with blockchain-related Rust projects.

Rust - Most Loved Language!

✅ Speed ✅ Safety ✅ Come with Cargo Manager ✅ Come with Error Messages ✅ Efficient C Binding ✅ Treads without Data Races

I am currently going through Easy Rust’s tutorials. It is fantastic so far! I love how David Macleod explains Rust in a very detailed way. I am sure you will like it as well! His tutorials are available on Youtube. If you prefer reading, you can check out his book here.

My planning after the Easy Rust tutorials:

fn main() {
    println!("Hello World!");
}

P.S. The best way to learn is to get your hands dirty.

Learn how to write a STARK prover from scratch in Python

Starkware is one of the projects that are always on my watch list. Today, I finally have some spare time to go over one of their stark 101 tutorials to write a stark prover from scratch.

The tutorial is a great material to understand the proving mechanism, in which the verifier is succinct logarithmically using a small amount of computation and the prover is proving in a quasi-linear to achieve efficiency on both sides. In other terms, it is scalable. As the amount of verification scales in a log-squared manner, the computation required does grow but it grows very slowly.

Starkware’s team encourage us to rewrite another set of exercises for stark verifier, or maybe rewrite it using a different recurrence rule, or try a different computational statement to see if it can optimize performance better.

If you would also want to give this tutorial a try. I would recommend first read this article where it explains the mathematical primer. It helps you to pick up the math quicker.

After that, you can explore the course material at the STARK 101 course page and start playing with the jupyter notebooks.

Videos are available here.