zk-SNARK Groth16 protocol.
Prerequisites
Project setup
-
Create a new project using Blueprint:
-
Install libraries for working with ZK-proofs:
-
Install the verifier export utility for TON:
Create the Circom circuit
Create the directorycircuits/Multiplier and the file Multiplier.circom:
a and b, whose product is equal to the public output c, without revealing a and b themselves.
Compile
Run incircuits/Multiplier:
Multiplier.r1cs— circuit constraints (R1CS)Multiplier.sym— symbolic signal mapMultiplier.wasm— artifact for generating proof
Trusted setup (Groth16)
The trusted setup is a one-time ceremony that generates the proving and verification keys for a circuit. It’s called “trusted” because if the setup parameters are compromised, proofs could be forged. For production use, participate in a multi-party trusted setup ceremony. For local development and testing, a simplified single-party setup is sufficient. For local tests, perform a simplified trusted setup ceremony.
The “power of tau” parameter (10) has to be chosen
- as low as possible, because it affects execution time;
- high enough, because the more constraints in the scheme, the higher the parameter required.
Export the verifier contract
Return to the Blueprint project root before running these commands if you are still incircuits/Multiplier:
./wrappers/:
Verifier_tolk for Tolk and Verifier_func for FunC.
Testing and verification
Intests/ZkSimple.spec.ts:
Other Languages
This tutorial follows the path Circom →snarkjs → export-ton-verifier → TON.
The same workflow applies to other stacks — the key requirement is to obtain a proof and a verification key in snarkjs format.
In the example repository — zk-ton-examples — there are already templates for noname, gnark, and arkworks: proofs can be generated in any of these stacks, then converted into snarkjs format and verified both locally and on-chain in the same way.
The idea is always the same: generate proof.json and verification_key.json in snarkjs format, then use export-ton-verifier and perform verification in TON.
Arkworks (Rust)
Use thearkworks library to generate the proof and verification key, then convert them into snarkjs format with ark-snarkjs.
- Set up an Arkworks project:
-
Write the circuit in Rust. Implement the circuit logic using
arkworksprimitives, similar to how a Circom circuit would be written. Learn how to write constraints inarkworksby following the Arkworks R1CS tutorial. A working example of a simple multiplication circuit can be found in thezk-ton-examplesrepository. - Compile, generate proof, and perform trusted setup following the same workflow as in the Circom section above.
-
Export the proof and verification key to JSON using
ark-snarkjs:
- Export the verifier contract:
gnark (Go)
Use the gnark library to generate the proof and verification key, then convert them into snarkjs format with gnark-to-snarkjs.
-
Set up a
gnarkproject. You can find an example circuit in thegnarkrepository. A working example of a cubic circuit can be found in thezk-ton-examplesrepository. -
Add
gnark-to-snarkjsas a dependency:
- Export the proof and verification key:
- Export the verifier contract:
Conclusion
This guide demonstrates a minimal example: circuit → trusted setup → verifier export → verification in TON. This workflow can be extended to support more complex circuits and real-world applications.Useful Links
- Example repository:
zk-ton-examples - Verifier export library:
export-ton-verifier - Additional utilities:
- Using ZK-proofs in Tact: docs.tact
- Circom: docs.circom.io
- Noname:
zksecurity/noname gnark:consensys/gnark- Arkworks:
arkworks - SnarkJS:
iden3/snarkjs