Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions contract-dev/privacy-zk/groth16-examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
title: "How to verify Groth16 examples on TON"
sidebarTitle: "Groth16 examples"
description: "Run Groth16 verifier examples on TON with Circom, Noname, Gnark, and Arkworks."
---

import { Aside } from '/snippets/aside.jsx';

Run one of the Groth16 verifier examples from [`zk-examples/zk-ton-examples`](https://github.com/zk-examples/zk-ton-examples) and confirm the proof both locally and on-chain in TON.
For the underlying export flow, see [Zero-knowledge proofs on TON](/contract-dev/zero-knowledge).

## Objective

Run one of these upstream circuits on TON:

- `Multiplier` from Circom
- `Sudoku` from Noname
- `cubic-gnark` from Gnark
- `MulCircuit` from Arkworks

## Prerequisites

- [Node.js](https://nodejs.org/en/download/) 18 or later LTS
- [Blueprint](/contract-dev/blueprint/overview)
- One proving stack: [Circom](https://docs.circom.io/getting-started/installation/#installing-circom), [Noname](https://github.com/zksecurity/noname), [Go](https://go.dev/dl/), or [Rust](https://www.rust-lang.org/tools/install)

## Clone the examples repository

```bash
git clone https://github.com/zk-examples/zk-ton-examples.git
cd zk-ton-examples
npm install
```

## Choose an example

| Example | Stack | Circuit | What the proof exposes publicly | Tolk test |
| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------------------- |
| `Multiplier` | Circom | [`circuits/Multiplier`](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Multiplier) | `c = a * b` | `npx blueprint test Verifier_multiplier_tolk` |
| `Sudoku` | Noname | [`circuits/Sudoku`](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Sudoku) | A partially filled grid | `npx blueprint test Verifier_sudoku_tolk` |
| `cubic-gnark` | Gnark | [`circuits/cubic-gnark`](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/cubic-gnark) | `y = x^3 + x + 5` | `npx blueprint test Verifier_cubic_tolk` |
| `MulCircuit` | Arkworks | [`circuits/Arkworks/MulCircuit`](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Arkworks/MulCircuit) | `z = x * y` | `npx blueprint test Verifier_ark_tolk` |

<Aside type="tip">
This page follows the upstream Tolk verifier tests and runs locally in the Blueprint sandbox, not on TON mainnet.
</Aside>
Comment on lines +44 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Environment warning uses tip instead of safety callout

Lines 44–46 use <Aside type="tip"> to state that the page runs locally in the Blueprint sandbox and not on TON mainnet. Given that later examples include a sendVerify call with a non-trivial TON amount, environment separation between sandbox, testnet, and mainnet is a safety concern rather than a mere tip. The style guide calls for using caution or danger callouts whenever there is potential funds movement or chain impact, and requires explicitly naming testnet and mainnet to prevent confusion.

Suggested change
<Aside type="tip">
This page follows the upstream Tolk verifier tests and runs locally in the Blueprint sandbox, not on TON mainnet.
</Aside>
<Aside type="caution" title="Run in sandbox or testnet">
These examples follow the upstream Tolk verifier tests and run in the Blueprint sandbox by default. When adapting them to TON Testnet or TON Mainnet, start on TON Testnet with small amounts; transfers on mainnet are irreversible.
</Aside>

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!


## Run the `Multiplier` example

Select `Multiplier` for the smallest end-to-end Groth16 verifier flow in the repository.
The proof is generated at test time from `Multiplier.wasm` and `Multiplier_final.zkey`.
Comment on lines +50 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Subjective “smallest” marketing-style claim for Multiplier

Line 50 describes the Multiplier example as “the smallest end-to-end Groth16 verifier flow in the repository,” which is a comparative, marketing-style claim without concrete metrics. The style guide prohibits subjective intensity language like “smallest” when not backed by measurable criteria such as constraints, gas, or code size. As written, this description may become inaccurate if other examples change or new ones are added, and it does not help readers understand what is actually different about the example.

Suggested change
Select `Multiplier` for the smallest end-to-end Groth16 verifier flow in the repository.
The proof is generated at test time from `Multiplier.wasm` and `Multiplier_final.zkey`.
Select `Multiplier` for a minimal end-to-end Groth16 verifier flow with two private inputs and one public output.
The proof is generated at test time from `Multiplier.wasm` and `Multiplier_final.zkey`.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!


```bash
cd circuits/Multiplier
circom Multiplier.circom --r1cs --wasm --sym --prime bls12381
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"
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"
snarkjs zkey export verificationkey Multiplier_final.zkey verification_key.json
cd ../..
npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.tolk --tolk
npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force --groth16
npx blueprint test Verifier_multiplier_tolk
Comment on lines +53 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Missing safety label on trusted-setup example randomness

Lines 53–65 show a full Groth16 trusted-setup sequence for Multiplier, including snarkjs powersoftau and zkey contribute commands that hard-code "some random text" as entropy. The block appears as a ready-to-run bash snippet without any “Not runnable” or safety note, despite the randomness being intentionally weak and unsuitable for real setups. The style guide requires that partial or context-dependent snippets be labeled as not runnable and that examples involving secrets or entropy call out the need for high-entropy values, so readers do not reuse insecure patterns in production.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!

```

Expected output

```text
PASS tests/Verifier_multiplier_tolk.spec.ts
```

The checked-in upstream Tolk snapshot records `Verify = 88768` gas and code size `4353 bits / 11 cells`.

## Run the `Sudoku` example

Select `Sudoku` for a larger verification key and many public inputs.
The current `Sudoku` source checks rows, columns, and diagonals. It does not check 3x3 boxes (subgrids).

Comment on lines +78 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Time-relative “current” in Sudoku description

Line 79 refers to “The current Sudoku source” when describing what the circuit checks. The style guide discourages time-relative qualifiers like “current”, “new”, or “soon” because they stale quickly and become misleading as upstream code evolves. In this case, the behavior being documented (rows, columns, diagonals; not 3×3 boxes) can be stated directly without implying a temporal state that may later change.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!

```bash
cd circuits/Sudoku
noname check
noname run --backend r1cs-bls12-381 --private-inputs '<SOLUTION_JSON>' --public-inputs '<GRID_JSON>'
snarkjs powersoftau new bls12-381 14 pot14_0000.ptau -v
Comment on lines +81 to +85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Ambiguous quoting for JSON placeholders in noname run

Line 84 uses --private-inputs '<SOLUTION_JSON>' --public-inputs '<GRID_JSON>' in a bash snippet, wrapping the <ANGLE_CASE> placeholders in single quotes. The style guide requires copy-pasteable commands to minimize quoting ambiguities, especially when placeholders stand for JSON objects or values that may themselves need quoting. Keeping the surrounding single quotes increases the chance that readers paste literal angle-bracketed strings or mis-nest quotes when inserting JSON.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!

snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau --name="First contribution" -v -e="some random text"
snarkjs powersoftau prepare phase2 pot14_0001.ptau pot14_final.ptau -v
snarkjs groth16 setup Sudoku.r1cs pot14_final.ptau Sudoku_0000.zkey
snarkjs zkey contribute Sudoku_0000.zkey Sudoku_final.zkey --name="1st Contributor" -v -e="some random text"
snarkjs zkey export verificationkey Sudoku_final.zkey verification_key.json
snarkjs groth16 prove Sudoku_final.zkey Sudoku.wtns proof.json public.json
cd ../..
npx export-ton-verifier ./circuits/Sudoku/Sudoku_final.zkey ./contracts/verifier_sudoku.tolk --tolk
npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force --groth16
npx blueprint test Verifier_sudoku_tolk
```

Define placeholders

- `<SOLUTION_JSON>` — JSON object with the private solved grid in the format expected by `circuits/Sudoku/src/main.no`
- `<GRID_JSON>` — JSON object with the public partially filled grid in the format expected by `circuits/Sudoku/src/main.no`

Expected output

```text
PASS tests/Verifier_sudoku_tolk.spec.ts
```

The checked-in upstream Tolk snapshot records `Verify = 850815` gas and code size `44471 bits / 75 cells`.

## Run the `cubic-gnark` example

Select `cubic-gnark` when the proving stack is Go.
The upstream `main.go` proves the public relation `y = x^3 + x + 5` and exports `proof.json` plus `verification_key.json` in `snarkjs` format.

```bash
cd circuits/cubic-gnark
go run main.go
cd ../..
npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts/verifier_cubic.tolk --tolk
npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force --groth16
npx blueprint test Verifier_cubic_tolk
```

Expected output

```text
PASS tests/Verifier_cubic_tolk.spec.ts
```

The checked-in upstream Tolk snapshot records `Verify = 88768` gas and code size `4353 bits / 11 cells`.

## Run the `MulCircuit` example

Select `MulCircuit` when the proving stack is Rust.
The upstream `main.rs` proves a multiplication circuit over `Bls12_381` and exports `json/proof.json` plus `json/verification_key.json`.

```bash
cd circuits/Arkworks/MulCircuit
cargo run
cd ../../..
npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.json ./contracts/verifier_ark.tolk --tolk
npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force --groth16
npx blueprint test Verifier_ark_tolk
```

Expected output

```text
PASS tests/Verifier_ark_tolk.spec.ts
```

The checked-in upstream Tolk snapshot records `Verify = 88768` gas and code size `4353 bits / 11 cells`.

## Verify

Run-time verification succeeds when all of the following are true:

- `snarkjs.groth16.verify(...)` returns `true`
- The contract `getVerify` method returns `true`
- `npx blueprint test ...` exits with code `0`
Comment on lines +157 to +161
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Missing canonical reference link for snarkjs.groth16.verify

Line 159 lists snarkjs.groth16.verify(...) as a bullet without linking to any canonical reference or upstream documentation. The style rules specify that the first meaningful mention of an important API or constant should link to its official docs or internal reference anchor to support quick lookups and avoid duplicating behavior explanations across pages. Without such a link, readers must search manually for the function’s semantics and options.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!


Not runnable. Partial snippet from the upstream Tolk tests:

```ts
const okLocal = await snarkjs.groth16.verify(verificationKey, publicSignals, proof);
expect(okLocal).toBe(true);

const { pi_a, pi_b, pi_c, pubInputs } = await groth16CompressProof(proof, publicSignals);

expect(await verifier.getVerify({ pi_a, pi_b, pi_c, pubInputs })).toBe(true);

const verifyResult = await verifier.sendVerify(deployer.getSender(), {
pi_a,
pi_b,
pi_c,
pubInputs,
value: toNano('0.15'),
});
```

## Troubleshoot

- If `npx blueprint test ...` fails because `../wrappers/Verifier` is missing, rerun `npx export-ton-verifier import-wrapper ./wrappers/Verifier.ts --force --groth16`.
- If `npx blueprint test ...` fails because the Tolk contract is missing, rerun the matching `npx export-ton-verifier ... --tolk` command for that example.
- If `snarkjs.groth16.verify(...)` returns `false`, confirm that the proof, public signals, and verification key come from the same circuit build.
- If `export-ton-verifier` rejects the input file, confirm that the example uses Groth16 over `bls12-381`.

## See also

- [Zero-knowledge proofs on TON](/contract-dev/zero-knowledge)
- [`zk-examples/zk-ton-examples`](https://github.com/zk-examples/zk-ton-examples)
- [`mysteryon88/export-ton-verifier`](https://github.com/mysteryon88/export-ton-verifier)
3 changes: 2 additions & 1 deletion contract-dev/zero-knowledge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ This guide shows how to create, compile, and test a simple [Circom](https://docs
<Aside>
This guide is also applicable to circuits written in the [Noname](https://github.com/zksecurity/noname) language, since the [`export-ton-verifier`](https://github.com/mysteryon88/export-ton-verifier) library integrates with `snarkjs`, which in turn integrates with the Noname language.

Other examples can be found [here](https://github.com/zk-examples/zk-ton-examples/).
For repo-backed examples covering Circom, Noname, Gnark, and Arkworks, see [Groth16 verification examples](/contract-dev/privacy-zk/groth16-examples).
The upstream source repository is [`zk-examples/zk-ton-examples`](https://github.com/zk-examples/zk-ton-examples/).
</Aside>
Comment on lines 10 to 15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] Stub sentence around external examples repository

Lines 13–14 mention “For repo-backed examples…” and then add “The upstream source repository is …” as a trailing sentence whose only job is to label the repository. The revised text removes the banned “here” link but still violates the style rule against standalone stub sentences and redundant meta commentary around links. The link to zk-examples/zk-ton-examples can be integrated directly into a single descriptive sentence that explains its purpose without a separate explanatory fragment.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!


## Prerequisites
Expand Down
10 changes: 8 additions & 2 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -459,13 +459,19 @@
"contract-dev/signing",
"contract-dev/contract-sharding",
"contract-dev/security",
{
"group": "ZK proofs",
"pages": [
"contract-dev/zero-knowledge",
"contract-dev/privacy-zk/groth16-examples"
]
Comment on lines +463 to +467
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] ZK navigation group lacks how-to labeling and ordering clarity

Lines 463–467 introduce a "ZK proofs" subgroup in the contract-dev navigation containing "contract-dev/zero-knowledge" and "contract-dev/privacy-zk/groth16-examples". Both target procedural, task-focused flows rather than pure explanations, but the group label is generic and does not convey that it contains how-to content. The style guide requires grouping and ordering content as Explanation → How-to → Reference and using labels that reflect document type to aid discovery; keeping a non-type label here makes it harder for readers to distinguish conceptual ZK docs from step-by-step guides.

Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!

},
"contract-dev/gas",
"contract-dev/on-chain-jetton-processing",
"contract-dev/using-on-chain-libraries",
"contract-dev/random",
"contract-dev/upgrades",
"contract-dev/vanity",
"contract-dev/zero-knowledge"
"contract-dev/vanity"
]
},
{
Expand Down
6 changes: 6 additions & 0 deletions resources/dictionaries/custom.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ Goldschlag
Golev
Grafana
grammY
Gnark
gnark
Groth
Groth16
GTon
Gunicorn
gusarich
Expand Down Expand Up @@ -468,6 +472,7 @@ multicast
Multicasting
multichain
Multichain
MulCircuit
multiplatform
Multiplatform
multiset
Expand Down Expand Up @@ -683,6 +688,7 @@ subexpressions
subfolder
subfolders
subgraph
subgrids
subinterval
subnet
subnets
Expand Down
Loading