-
Notifications
You must be signed in to change notification settings - Fork 70
feat(Groth16): add working examples of Groth16 verification #1964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
delovoyhomie
wants to merge
7
commits into
main
Choose a base branch
from
Groth16-examples
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4fdbf36
feat(Contract dev > ZK): add working examples of Groth16 verification
delovoyhomie 99d0726
`docs: switch Groth16 examples page to Tolk-only verifier flow`
delovoyhomie 96d888c
docs: refine TON Groth16 examples page and ZK navigation
delovoyhomie 1ca7f8c
Merge branch 'main' into Groth16-examples
delovoyhomie aed69b3
docs: fix Groth16 example commands
delovoyhomie dd30a16
docs: address Groth16 review feedback
delovoyhomie becd79a
Merge origin/main into Groth16-examples
delovoyhomie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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." | ||
|
novusnota marked this conversation as resolved.
|
||
| --- | ||
|
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 | ||
|
delovoyhomie marked this conversation as resolved.
|
||
| ``` | ||
|
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). | ||
|
|
||
|
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` | ||
|
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'), | ||
| }); | ||
|
novusnota marked this conversation as resolved.
|
||
| ``` | ||
|
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) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.