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
195 changes: 195 additions & 0 deletions contract-dev/privacy-zk/groth16-examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
title: "How to verify Groth16 examples on TON"
sidebarTitle: "Groth16 examples"
description: "Run Groth16 verifier examples on TON with Circom, Noname, Gnark, and Arkworks."
Comment thread
novusnota marked this conversation as resolved.
Comment thread
novusnota marked this conversation as resolved.
---
Comment thread
novusnota marked this conversation as resolved.

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/techniques/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="caution"
title="Run locally first"
>
This page follows the upstream Tolk verifier tests and runs in the Blueprint sandbox by default, not on TON Mainnet. When adapting the examples to TON Testnet or TON Mainnet, start on TON Testnet with small amounts. The trusted-setup commands are for local tests; production circuits need a dedicated multi-party ceremony with fresh high-entropy contributions.
</Aside>

## Run the `Multiplier` example

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_js/Multiplier.wasm` and `Multiplier_final.zkey`.

```bash
cd circuits/Multiplier
circom Multiplier.circom --r1cs --wasm --sym --prime bls12381
PTAU_ENTROPY="$(openssl rand -hex 32)"
ZKEY_ENTROPY="$(openssl rand -hex 32)"
npx snarkjs powersoftau new bls12-381 10 pot10_0000.ptau -v
npx snarkjs powersoftau contribute pot10_0000.ptau pot10_0001.ptau --name="First contribution" -v -e="$PTAU_ENTROPY"
npx snarkjs powersoftau prepare phase2 pot10_0001.ptau pot10_final.ptau -v
npx snarkjs groth16 setup Multiplier.r1cs pot10_final.ptau Multiplier_0000.zkey
npx snarkjs zkey contribute Multiplier_0000.zkey Multiplier_final.zkey --name="1st Contributor" -v -e="$ZKEY_ENTROPY"
npx 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 --contract-name multiplierVerifier
npx blueprint test Verifier_multiplier_tolk
Comment thread
delovoyhomie marked this conversation as resolved.
```
Comment thread
novusnota marked this conversation as resolved.

Expected output

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

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

## Run the `Sudoku` example

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

Comment thread
delovoyhomie marked this conversation as resolved.
```bash
cd circuits/Sudoku
noname check
noname run --backend r1cs-bls12-381 --private-inputs "$SOLUTION_JSON" --public-inputs "$GRID_JSON"
PTAU_ENTROPY="$(openssl rand -hex 32)"
ZKEY_ENTROPY="$(openssl rand -hex 32)"
npx snarkjs powersoftau new bls12-381 14 pot14_0000.ptau -v
npx snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau --name="First contribution" -v -e="$PTAU_ENTROPY"
npx snarkjs powersoftau prepare phase2 pot14_0001.ptau pot14_final.ptau -v
npx snarkjs groth16 setup Sudoku.r1cs pot14_final.ptau Sudoku_0000.zkey
npx snarkjs zkey contribute Sudoku_0000.zkey Sudoku_final.zkey --name="1st Contributor" -v -e="$ZKEY_ENTROPY"
npx snarkjs zkey export verificationkey Sudoku_final.zkey verification_key.json
npx 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 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 = 858163` gas and code size `46975 bits / 78 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 --contract-name Cubic
npx blueprint test Verifier_cubic_tolk
```

Expected output

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

The checked-in upstream Tolk snapshot records `Verify = 88655` gas and code size `5805 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 --contract-name arkVerifier
npx blueprint test Verifier_ark_tolk
```

Expected output

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

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

## Verify

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

- [`snarkjs.groth16.verify(...)`](https://github.com/iden3/snarkjs#7-verify-the-proof) returns `true`
- The contract `getVerify` method returns `true`
- `npx blueprint test ...` exits with code `0`
Comment thread
delovoyhomie marked this conversation as resolved.

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'),
});
Comment thread
novusnota marked this conversation as resolved.
```
Comment thread
novusnota marked this conversation as resolved.

## Troubleshoot

- 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/techniques/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)
2 changes: 1 addition & 1 deletion contract-dev/techniques/zero-knowledge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Create, compile, and test a simple [Circom](https://docs.circom.io/) scheme and
<Aside type="tip">
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.

[The zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/) contains additional examples.
For repo-backed examples from [zk-ton-examples](https://github.com/zk-examples/zk-ton-examples/) covering Circom, Noname, Gnark, and Arkworks, see [Groth16 verification examples](/contract-dev/privacy-zk/groth16-examples).
</Aside>

## Prerequisites
Expand Down
8 changes: 7 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,13 @@
"contract-dev/techniques/random",
"contract-dev/techniques/upgrades",
"contract-dev/techniques/vanity",
"contract-dev/techniques/zero-knowledge"
{
"group": "ZK proof how-tos",
"pages": [
"contract-dev/techniques/zero-knowledge",
"contract-dev/privacy-zk/groth16-examples"
]
}
]
},
{
Expand Down
4 changes: 4 additions & 0 deletions resources/dictionaries/custom.txt
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,13 @@ gitbook
Gitpod
globals
gnark
Gnark
Goldschlag
Golev
Grafana
grammY
Groth
Groth16
GTon
Gunicorn
gusarich
Expand Down Expand Up @@ -471,6 +473,7 @@ multicast
Multicasting
multichain
Multichain
MulCircuit
multiplatform
Multiplatform
multiset
Expand Down Expand Up @@ -688,6 +691,7 @@ subexpressions
subfolder
subfolders
subgraph
subgrids
subinterval
subnet
subnets
Expand Down