Implementing Zero-Knowledge Proof in Golang

Written by on November 17, 2025 in Golang with 0 Comments

Zero-Knowledge Proofs (ZKP) are a fascinating area within Cryptography. These allow one party, called the “Prover”, to convince another party, called the “Verifier”, that some statement is true without revealing the underlying information.

There are two basic types of ZKPs: Interactive and non-interactive. The former requires a series of messages to be exchanged between the Prover and Verifier, but in the latter, the Prover sends only a single message to the Verifier. In both cases, the Verifier is convinced through the message protocol.

In this article, I will show how to implement a simple non-interactive proof in Golang. The reason I chose Golang is because it has a good ZKP library called “gnark”, an implementation of zk-SNARK. There is even a nice gnark playground where we can compile and run circuits in the browser.

Here is how we can install gnark:

>> go get github.com/consensys/gnark@latest

Let us now walk through the code. The example is to prove that a person is more than 18 years old without revealing the actual age. We use “Circuits” in ZKP to model the statement we want to prove. In Golang, we use a “struct” for this purpose. The constraints are implemented as “code” assertions:

Circuit for Proving Age

Circuit for Proving Age

In this example, the “AgeCircuit” contains a “private” field called “CurrentAge” (for simplicity, I am not using the date of birth) and three public fields – “Aadhar”, “MinimumAge” (as required by the verifier) and “IsAboveAgeThreshold” which asserts that the person is “above the require threshold”. Note that “Aadhar” field is not needed, but I have included it so that the Verifier can know that my claim is linked to my “Aadhar”.

The next step is to compile the circuit into a constraint system and generate the “Proving” and “Verifying” keys:

Generating Keys

Generating Keys

The third step is to create a “witness” (private) and pass the actual assignment of values of the Circuit and generate the “Proof”:

Generating Proof

Generating Proof

Notice that generating proof requires the “ProvingKey”, which should not be shared publicly.

Now that the proof has been generated, what should the prover share with the verifier? Obviously, we need to share the “Proof” and the “VerificationKey”. We also need to share the “public” components of the “witness”. Verifying the shared proof is then pretty straightforward:

Verifying the Proof

Verifying the Proof

Essentially, the following are the steps:

1) Define the circuit and corresponding assertions

2) Compile the circuit and generate keys

3) Generate proof using instantiated circuit

4) Verify the proof

Just to make this example interesting, let us try to create a “false” claim. What if the person is less than 18 years of age, but we claim he is over 18?

Creating False Claim

Creating False Claim

This should fail, right? It fails as you can see in the output below:

Program Output

Program Output

The messages clearly show that the valid proof succeeds as expected, whereas the false claim fails.

In summary, the Golang program using “gnark” library is quite succinct and expressive at the same time. It is a good start to exploring more complex zero-knowledge proof problems.

You can download the main program here.

Have a great week!

Tags: , ,

About the Author

About the Author: .

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Leave a Reply

Your email address will not be published. Required fields are marked *

Top