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:
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:
The third step is to create a “witness” (private) and pass the actual assignment of values of the Circuit and generate the “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:
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?
This should fail, right? It fails as you can see in the output below:
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!







Recent Comments