From 36cf1a82d3996510f7a71af5797ba1ddd962c2f4 Mon Sep 17 00:00:00 2001 From: mysteryon88 Date: Fri, 21 Nov 2025 12:07:50 +0300 Subject: [PATCH 1/5] docs: ZK-proof guide (Circom, Gnark, Noname, Arkworks + Groth16) for TON --- contract-dev/zero-knowledge.mdx | 314 ++++++++++++++++++ docs.json | 31 +- resources/dictionaries/custom.txt | 27 +- .../dictionaries/two-letter-words-ban.txt | 2 - 4 files changed, 346 insertions(+), 28 deletions(-) create mode 100644 contract-dev/zero-knowledge.mdx diff --git a/contract-dev/zero-knowledge.mdx b/contract-dev/zero-knowledge.mdx new file mode 100644 index 000000000..3055cfe36 --- /dev/null +++ b/contract-dev/zero-knowledge.mdx @@ -0,0 +1,314 @@ +--- +title: "Zero-knowledge proofs on TON" +sidebarTitle: "Zero-knowledge proofs" +--- + +## Introduction + +This guide shows how to create, compile, and test a simple Circom scheme and verify a **ZK-proof** in the **TON** blockchain using the **zk-SNARK Groth16** protocol. This approach is a starting point for more complex cases and integrations. The examples are based on a minimal multiplication scheme. + +You can read more about Circom and zero-knowledge proofs [here](https://docs.circom.io/). + +> This guide is also applicable to circuits written in the [Noname](https://github.com/zksecurity/noname) language, since the `export-ton-verifier` library integrates with `snarkjs`, which in turn integrates with the Noname language. +> +> You can find examples in the [zk-ton-examples](https://github.com/zk-examples/zk-ton-examples/) repository. + +## What you will learn + +- Basic workflow with zero-knowledge proofs in TON. +- Setting up the environment for ZK in TON. +- Creating and compiling the Circom scheme. +- Performing a simplified trusted setup (Groth16). +- Exporting the verifier for FunC, Tolk, and Tact. +- Local and on-chain proof verification. + +## Prerequisites + +- **Node.js** and **npm** installed +- **circom** and **snarkjs** installed (see installation instructions below) +- Basic TON knowledge and Blueprint tool + +## Project setup + +1. Create a new project using Blueprint: + +```bash +npm create ton@latest ZkSimple +cd ZkSimple +``` + +2. Install libraries for working with ZK proofs: + +```bash +npm install snarkjs @types/snarkjs +``` + +3. Install the verifier export utility for TON: + +```bash +npm install export-ton-verifier@latest +``` + +This utility exports verifier contracts for FunC, Tolk, and Tact. + +## Create the Circom circuit + +Create the directory `circuits/Multiplier` and the file `Multiplier.circom`: + +```bash +mkdir -p circuits/Multiplier +cd circuits/Multiplier +``` + +```circom +pragma circom 2.2.2; + +template Multiplier() { + signal input a; + signal input b; + + signal output c; + + c <== a*b; +} + +component main = Multiplier(); +``` + +This circuit proves knowledge of two numbers `a` and `b`, whose product is equal to the public output `c`, without revealing `a` and `b` themselves. + +### Compile + +Run in `circuits/Multiplier`: + +```bash +circom Multiplier.circom --r1cs --wasm --sym --prime bls12381 +``` + +After compilation, the following files will appear: + +- `Multiplier.r1cs` — circuit constraints (R1CS) +- `Multiplier.sym` — symbolic signal map +- `Multiplier.wasm` — artifact for generating proof + +Check constraints: + +```bash +snarkjs r1cs info Multiplier.r1cs +``` + +Output example: + +``` +[INFO] snarkJS: Curve: bls12-381 +[INFO] snarkJS: # of Wires: 4 +[INFO] snarkJS: # of Constraints: 1 +[INFO] snarkJS: # of Private Inputs: 2 +[INFO] snarkJS: # of Public Inputs: 0 +[INFO] snarkJS: # of Outputs: 1 +``` + +> `snarkjs` supports the **altbn-128** and **bls12-381** curves. Altbn-128 is available in Ethereum, but **bls12-381** is used for TON, so it is the one chosen in this guide. + +## Trusted setup (Groth16) + +The **trusted setup** is a one-time ceremony that generates the proving and verification keys for your circuit. It's called "trusted" because if the setup parameters are compromised, proofs could be forged. For production use, you should 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. Parameter (`10`) affects execution time; its selection depends on the size of the scheme - the more constraints, the higher the parameter required. + +```bash +# first phase +snarkjs powersoftau new bls12-381 10 pot10_0000.ptau -v +snarkjs powersoftau contribute pot10_0000.ptau pot10_0001.ptau --name="First contribution" -v -e="some random text" + +# second phase (depends on the compiled scheme) +snarkjs powersoftau prepare phase2 pot10_0001.ptau pot10_final.ptau -v +snarkjs groth16 setup Multiplier.r1cs pot10_final.ptau Multiplier_0000.zkey +snarkjs zkey contribute Multiplier_0000.zkey Multiplier_final.zkey --name="1st Contributor" -v -e="some random text" + +# export verification key +snarkjs zkey export verificationkey Multiplier_final.zkey verification_key.json +``` + +Clear up unnecessary artifacts: + +```sh +rm pot10_0000.ptau pot10_0001.ptau pot10_final.ptau Multiplier_0000.zkey +``` + +## Export the verifier contract + +```bash +# export FunC contract (default) +npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.fc + +# export Tolk contract +npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.tolk --tolk + +# export Tact contract +npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.tact --tact +``` + +For FunC and Tolk you will also need to generate wrappers manually: + +```bash +npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force +``` + +This command generates a TypeScript wrapper file that provides type-safe methods to interact with your verifier contract. + +## Testing and verification + +In `tests/ZkSimple.spec.ts`: + +```ts +import * as snarkjs from 'snarkjs'; +import path from 'path'; +import { dictFromInputList, groth16CompressProof } from 'export-ton-verifier'; + +// for Tact (After running `npx blueprint build --all`) +import { Verifier } from '../build/Verifier_tact/tact_Verifier'; + +// for FunC and Tolk +import { Verifier } from '../wrappers/Verifier'; +``` + +Local verification: + +```ts +const wasmPath = path.join(__dirname, '../circuits/Multiplier', 'Multiplier.wasm'); +const zkeyPath = path.join(__dirname, '../circuits/Multiplier', 'Multiplier_final.zkey'); +const verificationKey = require('../circuits/Multiplier/verification_key.json'); + +const input = { a: '342', b: '1245' }; + +const { proof, publicSignals } = await snarkjs.groth16.fullProve(input, wasmPath, zkeyPath); +const okLocal = await snarkjs.groth16.verify(verificationKey, publicSignals, proof); +``` + +On-chain verification: + +```ts +const { pi_a, pi_b, pi_c, pubInputs } = await groth16CompressProof(proof, publicSignals); + +// Quick check via get-method: verifies the proof locally without changing blockchain state. +expect(await verifier.getVerify({ pi_a, pi_b, pi_c, pubInputs })).toBe(true); + +// Send the proof to the contract in a message +// The contract will run verification; handling the result/flow is up to the developer using this template. +await verifier.sendVerify(deployer.getSender(), { pi_a, pi_b, pi_c, pubInputs, value: toNano('0.15') }); +``` + +> **Note:** Make sure you've built the contracts before running tests. For Tact contracts, run `npx blueprint build --all` first. For FunC/Tolk, ensure the wrappers are generated. + +## Other Languages + +In this tutorial we followed the path **Circom → snarkjs → export-ton-verifier → TON**. +But 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](https://github.com/zk-examples/zk-ton-examples/) — there are already templates for **Noname**, **gnark**, and **arkworks**: you can generate a proof in any of these stacks, then convert it into snarkjs format and verify it both locally and on-chain in the same way. + +> I maintain two utilities that help convert proofs and verification keys into a format compatible with **snarkjs**: +> +> - [ark-snarkjs](https://github.com/mysteryon88/ark-snarkjs): use for exporting from **arkworks** +> - [gnark-to-snarkjs](https://github.com/mysteryon88/gnark-to-snarkjs): use for exporting from **gnark** + +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 the **arkworks** library to generate the proof and verification key, then convert them into snarkjs format with **ark-snarkjs**. + +1. Set up an Arkworks project. +2. Add **ark-snarkjs** as a dependency: + +```sh +cargo add ark-snarkjs +``` + +3. Export the proof and verification key to JSON. Simply specify the file path: + +```rust +use ark_snarkjs::{export_proof, export_vk}; +use ark_bls12_381::{Bls12_381, Fr}; + +let _ = export_proof::(&proof, &public_inputs, "json/proof.json"); +let _ = export_vk::( + ¶ms.vk, + public_inputs.len(), + "json/verification_key.json", +); +``` + +The directory and files will be created automatically. + +4. Export the verifier contract: + +```sh +# FunC contract +npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.json ./contracts/verifier_ark.fc + +# Tact contract +npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.json ./contracts/verifier_ark.tact --tact + +# Tolk contract +npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.json ./contracts/verifier_ark.tolk --tolk +``` + +### Gnark (Go) + +Use the **gnark** library to generate the proof and verification key, then convert them into snarkjs format with **gnark-to-snarkjs**. + +1. Set up a Gnark project. +2. Add **gnark-to-snarkjs** as a dependency: + +```sh +go get github.com/mysteryon88/gnark-to-snarkjs@latest +``` + +3. Export the proof and verification key: + +```go +{ + proof_out, _ := os.Create("proof.json") + defer proof_out.Close() + _ = gnarktosnarkjs.ExportProof(proof, []string{"35"}, proof_out) +} +{ + out, _ := os.Create("verification_key.json") + defer out.Close() + _ = gnarktosnarkjs.ExportVerifyingKey(vk, out) +} +``` + +4. Export the verifier contract: + +```sh +# Tact contract +npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.tact --tact + +# FunC contract +npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.fc + +# Tolk contract +npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.tolk --tolk +``` + +## Conclusion + +You have built a minimal example: **circuit → trusted setup → verifier export → verification in TON**. +From here, you can easily extend this workflow to support more complex circuits and real-world applications. + +## Useful Links + +- Example repository: [zk-ton-examples](https://github.com/zk-examples/zk-ton-examples/) +- Verifier export library: [export-ton-verifier](https://github.com/mysteryon88/export-ton-verifier) +- Additional utilities: + - [ark-snarkjs](https://github.com/mysteryon88/ark-snarkjs) + - [gnark-to-snarkjs](https://github.com/mysteryon88/gnark-to-snarkjs) +- Using ZK proofs in Tact: [docs.tact](https://docs.tact-lang.org/cookbook/zk-proofs/) +- Circom: [docs.circom.io](https://docs.circom.io/) +- Noname: [zksecurity/noname](https://github.com/zksecurity/noname) +- Gnark: [Consensys/gnark](https://github.com/Consensys/gnark) +- Arkworks: [arkworks.rs](https://arkworks.rs/) +- SnarkJS: [iden3/snarkjs](https://github.com/iden3/snarkjs) diff --git a/docs.json b/docs.json index f641014a5..130b43a51 100644 --- a/docs.json +++ b/docs.json @@ -150,9 +150,7 @@ "ecosystem/tma/telegram-ui/platform-and-palette", { "group": "Reference", - "pages": [ - "ecosystem/tma/telegram-ui/reference/avatar" - ] + "pages": ["ecosystem/tma/telegram-ui/reference/avatar"] } ] }, @@ -207,20 +205,14 @@ }, { "group": "Staking", - "pages": [ - "ecosystem/staking/overview" - ] + "pages": ["ecosystem/staking/overview"] }, "ecosystem/analytics" ] }, { "group": "Payment processing", - "pages": [ - "payments/overview", - "payments/toncoin", - "payments/jettons" - ] + "pages": ["payments/overview", "payments/toncoin", "payments/jettons"] }, { "group": "Standard contracts", @@ -237,10 +229,7 @@ "standard/wallets/v4", { "group": "V5", - "pages": [ - "standard/wallets/v5", - "standard/wallets/v5-api" - ] + "pages": ["standard/wallets/v5", "standard/wallets/v5-api"] }, { "group": "Highload Wallets", @@ -258,9 +247,7 @@ }, { "group": "Highload Wallet v2", - "pages": [ - "standard/wallets/highload/v2/specification" - ] + "pages": ["standard/wallets/highload/v2/specification"] } ] }, @@ -360,7 +347,8 @@ "contract-dev/using-onchain-libraries", "contract-dev/random", "contract-dev/upgrades", - "contract-dev/vanity" + "contract-dev/vanity", + "contract-dev/zero-knowledge" ] }, { @@ -444,10 +432,7 @@ { "group": "Libraries", "expanded": true, - "pages": [ - "languages/func/stdlib", - "languages/func/libraries" - ] + "pages": ["languages/func/stdlib", "languages/func/libraries"] }, "languages/func/changelog", "languages/func/known-issues" diff --git a/resources/dictionaries/custom.txt b/resources/dictionaries/custom.txt index 9bb11f739..1c97d371d 100644 --- a/resources/dictionaries/custom.txt +++ b/resources/dictionaries/custom.txt @@ -28,6 +28,12 @@ allowlists altcoin Altcoin altcoins + +altbn +Altbn +altcoin +Altcoin +altcoins AMM* Andr andrei @@ -44,6 +50,8 @@ APIs APY arith arity +arkworks +arkworks.rs asin asm asms @@ -83,6 +91,7 @@ blockquote blockquotes Blockscout BLS +bls bmTON BoC BoCs @@ -160,6 +169,7 @@ configs Configs configurator Configurator +Consensys consortiums constructivization constructivized @@ -287,10 +297,12 @@ Gilmanova gitbook Gitpod globals +gnark Goldschlag Golev Grafana grammY +Groth GTon Gunicorn gusarich @@ -307,14 +319,15 @@ hashmap Hashmap Hashmaps Hasse -Héctor Hetzner highload Highload Hipo Homotopy hostname +Héctor iconUrl +iden ident IHR Imedashvili @@ -479,6 +492,8 @@ NFTs Nginx Niels Nikolay +Noname +noname nonexist NOPs nota @@ -592,7 +607,6 @@ RPCs ruleset runbooks runtimes -Sánchez sandboxing satoshi savelist @@ -636,6 +650,7 @@ skillset skywardboundd smartcont Snarkjs +snarkjs Solana Soulbound Spellbook @@ -683,6 +698,7 @@ SVM swappable systemd Syverson +Sánchez tagless Tal Talpas @@ -809,12 +825,17 @@ workchain workchains Xia XMM -XMPL XMODEM +XMPL XORing Yolo Yung Zakrevskis Zellic zerostate +zk +ZK +zk-proof ZK-proof +zk-SNARK +zksecurity diff --git a/resources/dictionaries/two-letter-words-ban.txt b/resources/dictionaries/two-letter-words-ban.txt index 9130b6a93..2c4756d49 100644 --- a/resources/dictionaries/two-letter-words-ban.txt +++ b/resources/dictionaries/two-letter-words-ban.txt @@ -2421,9 +2421,7 @@ !Zj !ZJ !zJ -!zk !Zk -!ZK !zK !zl !Zl From b6c5650f80e96d18bc4e19d65e7b4ee8e9beb335 Mon Sep 17 00:00:00 2001 From: mysteryon88 Date: Fri, 21 Nov 2025 12:10:38 +0300 Subject: [PATCH 2/5] fix empty string --- resources/dictionaries/custom.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/dictionaries/custom.txt b/resources/dictionaries/custom.txt index 1c97d371d..97ca33444 100644 --- a/resources/dictionaries/custom.txt +++ b/resources/dictionaries/custom.txt @@ -28,7 +28,6 @@ allowlists altcoin Altcoin altcoins - altbn Altbn altcoin From 120ea98041a227c5d5bacc1dff6a3d235deec8c2 Mon Sep 17 00:00:00 2001 From: mysteryon88 Date: Fri, 21 Nov 2025 17:33:07 +0300 Subject: [PATCH 3/5] fixes AI review results and comments --- contract-dev/zero-knowledge.mdx | 77 ++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/contract-dev/zero-knowledge.mdx b/contract-dev/zero-knowledge.mdx index 3055cfe36..cbb5cf739 100644 --- a/contract-dev/zero-knowledge.mdx +++ b/contract-dev/zero-knowledge.mdx @@ -3,17 +3,21 @@ title: "Zero-knowledge proofs on TON" sidebarTitle: "Zero-knowledge proofs" --- +import { Aside } from '/snippets/aside.jsx'; + ## Introduction This guide shows how to create, compile, and test a simple Circom scheme and verify a **ZK-proof** in the **TON** blockchain using the **zk-SNARK Groth16** protocol. This approach is a starting point for more complex cases and integrations. The examples are based on a minimal multiplication scheme. -You can read more about Circom and zero-knowledge proofs [here](https://docs.circom.io/). +Read more about Circom and zero-knowledge proofs in the [Circom documentation](https://docs.circom.io/). + + -## What you will learn +## What this guide covers - Basic workflow with zero-knowledge proofs in TON. - Setting up the environment for ZK in TON. @@ -25,7 +29,7 @@ You can read more about Circom and zero-knowledge proofs [here](https://docs.cir ## Prerequisites - **Node.js** and **npm** installed -- **circom** and **snarkjs** installed (see installation instructions below) +- **circom** and **snarkjs** installed - Basic TON knowledge and Blueprint tool ## Project setup @@ -108,11 +112,13 @@ Output example: [INFO] snarkJS: # of Outputs: 1 ``` -> `snarkjs` supports the **altbn-128** and **bls12-381** curves. Altbn-128 is available in Ethereum, but **bls12-381** is used for TON, so it is the one chosen in this guide. + ## Trusted setup (Groth16) -The **trusted setup** is a one-time ceremony that generates the proving and verification keys for your circuit. It's called "trusted" because if the setup parameters are compromised, proofs could be forged. For production use, you should participate in a multi-party trusted setup ceremony. For local development and testing, a simplified single-party setup is sufficient. +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. Parameter (`10`) affects execution time; its selection depends on the size of the scheme - the more constraints, the higher the parameter required. @@ -149,13 +155,13 @@ npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/ npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.tact --tact ``` -For FunC and Tolk you will also need to generate wrappers manually: +For FunC and Tolk, wrappers must be generated manually: ```bash npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force ``` -This command generates a TypeScript wrapper file that provides type-safe methods to interact with your verifier contract. +This command generates a TypeScript wrapper file that provides type-safe methods to interact with the verifier contract. ## Testing and verification @@ -199,19 +205,23 @@ expect(await verifier.getVerify({ pi_a, pi_b, pi_c, pubInputs })).toBe(true); await verifier.sendVerify(deployer.getSender(), { pi_a, pi_b, pi_c, pubInputs, value: toNano('0.15') }); ``` -> **Note:** Make sure you've built the contracts before running tests. For Tact contracts, run `npx blueprint build --all` first. For FunC/Tolk, ensure the wrappers are generated. + ## Other Languages -In this tutorial we followed the path **Circom → snarkjs → export-ton-verifier → TON**. -But the same workflow applies to other stacks — the key requirement is to obtain a `proof` and a `verification key` in **snarkjs** format. +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](https://github.com/zk-examples/zk-ton-examples/) — there are already templates for **Noname**, **gnark**, and **arkworks**: you can generate a proof in any of these stacks, then convert it into snarkjs format and verify it both locally and on-chain in the same way. +In the example repository — [zk-ton-examples](https://github.com/zk-examples/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. -> I maintain two utilities that help convert proofs and verification keys into a format compatible with **snarkjs**: -> -> - [ark-snarkjs](https://github.com/mysteryon88/ark-snarkjs): use for exporting from **arkworks** -> - [gnark-to-snarkjs](https://github.com/mysteryon88/gnark-to-snarkjs): use for exporting from **gnark** + 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. @@ -219,14 +229,22 @@ The idea is always the same: generate `proof.json` and `verification_key.json` i Use the **arkworks** library to generate the proof and verification key, then convert them into snarkjs format with **ark-snarkjs**. -1. Set up an Arkworks project. -2. Add **ark-snarkjs** as a dependency: +1. Set up an Arkworks project: ```sh -cargo add ark-snarkjs +cargo init +cargo add ark-bls12-381 ark-ff ark-groth16 ark-r1cs-std ark-relations ark-snark ark-snarkjs ark-std rand@0.8.5 ``` -3. Export the proof and verification key to JSON. Simply specify the file path: + + +2. Write the circuit in Rust. Implement the circuit logic using arkworks primitives, similar to how a Circom circuit would be written. Learn how to write constraints in arkworks by following the [arkworks R1CS tutorial](https://github.com/arkworks-rs/r1cs-tutorial). A working example of a simple multiplication circuit can be found in the [zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Arkworks/MulCircuit). + +3. Compile, generate proof, and perform trusted setup following the same workflow as in the Circom section above. + +4. Export the proof and verification key to JSON using **ark-snarkjs**: ```rust use ark_snarkjs::{export_proof, export_vk}; @@ -242,7 +260,7 @@ let _ = export_vk::( The directory and files will be created automatically. -4. Export the verifier contract: +5. Export the verifier contract: ```sh # FunC contract @@ -259,7 +277,8 @@ npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.jso Use the **gnark** library to generate the proof and verification key, then convert them into snarkjs format with **gnark-to-snarkjs**. -1. Set up a Gnark project. +1. Set up a Gnark project. You can find an example circuit in the [gnark repository](https://github.com/Consensys/gnark?tab=readme-ov-file#example). A working example of a cubic circuit can be found in the [zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Cubic%20(gnark)). + 2. Add **gnark-to-snarkjs** as a dependency: ```sh @@ -285,19 +304,19 @@ go get github.com/mysteryon88/gnark-to-snarkjs@latest ```sh # Tact contract -npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.tact --tact +npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts/verifier_cubic.tact --tact # FunC contract -npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.fc +npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts/verifier_cubic.fc # Tolk contract -npx export-ton-verifier "./circuits/Cubic (gnark)/verification_key.json" ./contracts/verifier_cubic.tolk --tolk +npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts/verifier_cubic.tolk --tolk ``` ## Conclusion -You have built a minimal example: **circuit → trusted setup → verifier export → verification in TON**. -From here, you can easily extend this workflow to support more complex circuits and real-world applications. +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 From bd7921f6ca3850c02242e772d9183de3da973bd1 Mon Sep 17 00:00:00 2001 From: mysteryon88 Date: Fri, 21 Nov 2025 17:49:27 +0300 Subject: [PATCH 4/5] fix npm remark --- contract-dev/zero-knowledge.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contract-dev/zero-knowledge.mdx b/contract-dev/zero-knowledge.mdx index cbb5cf739..cad532da3 100644 --- a/contract-dev/zero-knowledge.mdx +++ b/contract-dev/zero-knowledge.mdx @@ -211,7 +211,7 @@ await verifier.sendVerify(deployer.getSender(), { pi_a, pi_b, pi_c, pubInputs, v ## Other Languages -This tutorial follows the path **Circom → snarkjs → export-ton-verifier → TON**. +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](https://github.com/zk-examples/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. @@ -242,9 +242,9 @@ cargo add ark-bls12-381 ark-ff ark-groth16 ark-r1cs-std ark-relations ark-snark 2. Write the circuit in Rust. Implement the circuit logic using arkworks primitives, similar to how a Circom circuit would be written. Learn how to write constraints in arkworks by following the [arkworks R1CS tutorial](https://github.com/arkworks-rs/r1cs-tutorial). A working example of a simple multiplication circuit can be found in the [zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Arkworks/MulCircuit). -3. Compile, generate proof, and perform trusted setup following the same workflow as in the Circom section above. +2. Compile, generate proof, and perform trusted setup following the same workflow as in the Circom section above. -4. Export the proof and verification key to JSON using **ark-snarkjs**: +2. Export the proof and verification key to JSON using **ark-snarkjs**: ```rust use ark_snarkjs::{export_proof, export_vk}; @@ -277,9 +277,9 @@ npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.jso Use the **gnark** library to generate the proof and verification key, then convert them into snarkjs format with **gnark-to-snarkjs**. -1. Set up a Gnark project. You can find an example circuit in the [gnark repository](https://github.com/Consensys/gnark?tab=readme-ov-file#example). A working example of a cubic circuit can be found in the [zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Cubic%20(gnark)). +1. Set up a Gnark project. You can find an example circuit in the [gnark repository](https://github.com/Consensys/gnark?tab=readme-ov-file#example). A working example of a cubic circuit can be found in the [zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Cubic%20%28gnark%29). -2. Add **gnark-to-snarkjs** as a dependency: +1. Add **gnark-to-snarkjs** as a dependency: ```sh go get github.com/mysteryon88/gnark-to-snarkjs@latest From 816ee2df0b809de4a6c82a1e153054b2dbd66b23 Mon Sep 17 00:00:00 2001 From: mysteryon88 Date: Mon, 1 Dec 2025 21:18:12 +0300 Subject: [PATCH 5/5] ZK proof guide cleanup --- contract-dev/zero-knowledge.mdx | 67 +++++++++++++-------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/contract-dev/zero-knowledge.mdx b/contract-dev/zero-knowledge.mdx index cad532da3..46eed4419 100644 --- a/contract-dev/zero-knowledge.mdx +++ b/contract-dev/zero-knowledge.mdx @@ -5,53 +5,39 @@ sidebarTitle: "Zero-knowledge proofs" import { Aside } from '/snippets/aside.jsx'; -## Introduction - -This guide shows how to create, compile, and test a simple Circom scheme and verify a **ZK-proof** in the **TON** blockchain using the **zk-SNARK Groth16** protocol. This approach is a starting point for more complex cases and integrations. The examples are based on a minimal multiplication scheme. - -Read more about Circom and zero-knowledge proofs in the [Circom documentation](https://docs.circom.io/). +This guide shows how to create, compile, and test a simple [Circom](https://docs.circom.io/) scheme and verify a [ZK-proof](https://en.wikipedia.org/wiki/Zero-knowledge_proof) using the [zk-SNARK](https://en.wikipedia.org/wiki/Non-interactive_zero-knowledge_proof) [Groth16](https://eprint.iacr.org/2016/260.pdf) protocol. -## What this guide covers - -- Basic workflow with zero-knowledge proofs in TON. -- Setting up the environment for ZK in TON. -- Creating and compiling the Circom scheme. -- Performing a simplified trusted setup (Groth16). -- Exporting the verifier for FunC, Tolk, and Tact. -- Local and on-chain proof verification. - ## Prerequisites -- **Node.js** and **npm** installed -- **circom** and **snarkjs** installed -- Basic TON knowledge and Blueprint tool +- [Node.js](https://nodejs.org) 18 or a later LTS. +- [`circom`](https://docs.circom.io/getting-started/installation/#installing-circom) +- [`snarkjs`](https://docs.circom.io/getting-started/installation/#installing-snarkjs) +- [Blueprint](/contract-dev/blueprint/overview) ## Project setup 1. Create a new project using Blueprint: -```bash -npm create ton@latest ZkSimple -cd ZkSimple -``` - -2. Install libraries for working with ZK proofs: - -```bash -npm install snarkjs @types/snarkjs -``` + ```bash + npm create ton@latest ZkSimple + cd ZkSimple + ``` +1. Install libraries for working with ZK proofs: -3. Install the verifier export utility for TON: + ```bash + npm install snarkjs @types/snarkjs + ``` +1. Install the verifier export utility for TON: -```bash -npm install export-ton-verifier@latest -``` + ```bash + npm install export-ton-verifier@latest + ``` This utility exports verifier contracts for FunC, Tolk, and Tact. @@ -113,14 +99,16 @@ Output example: ``` -## Trusted setup (Groth16) +## 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. +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. -For local tests, perform a simplified trusted setup ceremony. Parameter (`10`) affects execution time; its selection depends on the size of the scheme - the more constraints, the higher the parameter required. +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. ```bash # first phase @@ -315,8 +303,7 @@ npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts ## 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. +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 @@ -330,4 +317,4 @@ This workflow can be extended to support more complex circuits and real-world ap - Noname: [zksecurity/noname](https://github.com/zksecurity/noname) - Gnark: [Consensys/gnark](https://github.com/Consensys/gnark) - Arkworks: [arkworks.rs](https://arkworks.rs/) -- SnarkJS: [iden3/snarkjs](https://github.com/iden3/snarkjs) +- SnarkJS: [iden3/snarkjs](https://github.com/iden3/snarkjs) \ No newline at end of file