> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-security-edits.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Zero-knowledge proofs on TON

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

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.

<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.
</Aside>

## Prerequisites

* [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)

## Initialize a project

<Steps>
  <Step title="Create a new project">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npm create ton@latest ZkSimple && cd ZkSimple
    ```
  </Step>

  <Step title="Install dependencies">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npm install snarkjs @types/snarkjs export-ton-verifier@latest
    ```
  </Step>
</Steps>

## Create the Circom circuit

<Steps>
  <Step title="Create the circuit directory">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    mkdir -p circuits/Multiplier && cd circuits/Multiplier
    ```

    Run the commands from the following steps in the `circuits/Multiplier` directory, or adjust the paths accordingly if running from the project root.
  </Step>

  <Step title="Implement the circuit">
    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.

    ```circom title="./circuits/Multiplier/Multiplier.circom" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    pragma circom 2.2.2;

    template Multiplier() {
      signal input a;
      signal input b;

      signal output c;

      c <== a*b;
    }

    component main = Multiplier();
    ```
  </Step>

  <Step title="Compile the circuit">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    circom Multiplier.circom --r1cs --wasm --sym --prime bls12381
    ```

    The compiler generates the following files:

    * `Multiplier.r1cs` — circuit constraints (R1CS)
    * `Multiplier.sym` — symbolic signal map
    * `Multiplier_js/Multiplier.wasm` — artifact for generating proof
  </Step>

  <Step title="Check the constraints">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    snarkjs r1cs info Multiplier.r1cs
    ```

    ```text title="snarkjs output" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    [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 Labels: 4
    [INFO]  snarkJS: # of Outputs: 1
    ```

    <Aside type="note">
      snarkjs supports the [alt\_bn128](https://eips.ethereum.org/EIPS/eip-196) and [bls12-381](https://electriccoin.co/blog/new-snark-curve/) curves. This guide uses bls12-381 because it is supported by TON.
    </Aside>
  </Step>
</Steps>

## Initialize trusted setup

The trusted setup is a one-time ceremony that generates the proving and verification keys for a circuit. It is 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.

Choose the "power of tau" parameter (`10`) as low as possible, because it affects execution time, but not too low, because the more constraints in the scheme, the higher the parameter required.

<Steps>
  <Step title="Execute the first phase">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
      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"
    ```
  </Step>

  <Step title="Execute the second phase">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
      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"
    ```
  </Step>

  <Step title="Export the verification key">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    snarkjs zkey export verificationkey Multiplier_final.zkey verification_key.json
    ```
  </Step>

  <Step title="Clean up artifacts">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    rm pot10_0000.ptau pot10_0001.ptau pot10_final.ptau Multiplier_0000.zkey
    ```

    Run the commands from the following steps in the project root.
  </Step>
</Steps>

## Export the verifier contract

<Steps>
  <Step title="Export the verifier contract">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npx export-ton-verifier ./circuits/Multiplier/Multiplier_final.zkey ./contracts/verifier_multiplier.tolk
    ```
  </Step>

  <Step title="Generate TypeScript wrappers">
    These TypeScript wrappers enable type-safe interaction with the verifier contract.

    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npx export-ton-verifier import-wrapper ./wrappers/Verifier_tolk.ts --groth16 --force
    ```
  </Step>
</Steps>

## Test and verify the proof

<Aside type="tip">
  Build the contracts and generate the TypeScript wrappers before running tests.
</Aside>

<Steps>
  <Step title="Import dependencies">
    ```ts title="./tests/ZkSimple.spec.ts" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    import * as snarkjs from 'snarkjs';
    import path from 'path';
    import { dictFromInputList, groth16CompressProof } from 'export-ton-verifier';
    import { Verifier } from '../wrappers/Verifier_tolk';
    ```
  </Step>

  <Step title="Implement local verification">
    ```ts title="./tests/ZkSimple.spec.ts" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    it("should verify the proof locally", async () => {
      const wasmPath = path.join(
        __dirname,
        '../circuits/Multiplier/Multiplier_js',
        '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);
      expect(okLocal).toBe(true);
    });
    ```
  </Step>

  <Step title="Implement on-chain verification">
    ```ts title="./tests/ZkSimple.spec.ts" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    it("should verify the proof on-chain", async () => {
      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; subsequent handling of the result depends on the integration.
      await verifier.sendVerify
        deployer.getSender(),
        { pi_a, pi_b, pi_c, pubInputs, value: toNano('0.15') }
      );
    });
    ```
  </Step>
</Steps>

## 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 the snarkjs format. The idea is always the same: generate `proof.json` and `verification_key.json` in the snarkjs format, then perform the verification in TON with the export-ton-verifier.

[The zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/) contains templates for Noname, gnark, and Arkworks. It is possible to generate proofs in any of these stacks, then convert them to the snarkjs format and verify them both locally and on-chain.

<Aside type="tip">
  Two utilities are available that help convert proofs and verification keys in a format compatible with snarkjs: [ark-snarkjs](https://github.com/mysteryon88/ark-snarkjs) and [gnark-to-snarkjs](https://github.com/mysteryon88/gnark-to-snarkjs).
</Aside>

### Rust

Use the Arkworks library to generate the proof and verification key, then convert them into snarkjs format with ark-snarkjs.

<Steps>
  <Step title="Create a new project">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    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
    ```

    <Aside type="note">
      The listed packages are core dependencies for most Arkworks circuits. Depending on the specific circuit implementation, additional packages may be required.
    </Aside>
  </Step>

  <Step title="Implement the circuit">
    Implement the circuit logic using Arkworks primitives, similar to a Circom circuit.

    <Aside type="tip">
      Learn how to write constraints in Arkworks by following the [Arkworks R1CS tutorial](https://github.com/arkworks-rs/r1cs-tutorial).

      [The zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Arkworks/MulCircuit) contains a working example of a simple multiplication circuit.
    </Aside>
  </Step>

  <Step title="Compile, generate proof, perform trusted setup">
    Follow the same workflow as in [the Circom section](#create-the-circom-circuit) and [the trusted setup section](#initialize-trusted-setup), but implement the logic in Rust with Arkworks instead of Circom. The resulting proof and verification key will be in Arkworks format, which can be converted to snarkjs format with ark-snarkjs.
  </Step>

  <Step title="Export the proof and verification key">
    The following script will create the directory and files automatically.

    ```rust title="Rust" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    use ark_snarkjs::{export_proof, export_vk};
    use ark_bls12_381::Bls12_381;

    let _ = export_proof::<Bls12_381, _>(&proof, &public_inputs, "json/proof.json");
    let _ = export_vk::<Bls12_381, _>(
        &params.vk,
        public_inputs.len(),
        "json/verification_key.json",
    );
    ```
  </Step>

  <Step title="Export the verifier contract">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npx export-ton-verifier ./circuits/Arkworks/MulCircuit/json/verification_key.json ./contracts/verifier_ark.tolk
    ```
  </Step>
</Steps>

### Go

Use the gnark library to generate the proof and verification key, then convert them to the snarkjs format with gnark-to-snarkjs.

<Steps>
  <Step title="Create a new project">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    mkdir zk-ton-gnark && cd zk-ton-gnark
    go mod init zk-ton-gnark

    ```

    <Aside type="tip">
      [The gnark repository](https://github.com/Consensys/gnark) contains an example circuit.

      [The zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/tree/main/circuits/Cubic%20%28gnark%29) contains a working example of a simple cubic circuit.
    </Aside>
  </Step>

  <Step title="Install the dependencies">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    go get github.com/consensys/gnark@latest
    go get github.com/mysteryon88/gnark-to-snarkjs@latest
    ```
  </Step>

  <Step title="Export the proof and verification key">
    ```go title="Go" theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    {
      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)
    }
    ```
  </Step>

  <Step title="Export the verifier contract">
    ```bash theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
    npx export-ton-verifier ./circuits/cubic-gnark/verification_key.json ./contracts/verifier_cubic.tolk
    ```
  </Step>
</Steps>

## Useful Links

* [The zk-ton-examples repository](https://github.com/zk-examples/zk-ton-examples/) contains additional examples of zk-SNARK circuits and their integration with TON.
* [The export-ton-verifier repository](https://github.com/mysteryon88/export-ton-verifier) is a library that generates TON-compatible verifier contracts from snarkjs verification keys.
* [The snarkjs repository](https://github.com/iden3/snarkjs) is a JavaScript library for generating and verifying zk-SNARK proofs, as well as performing trusted setup ceremonies.
* [The ark-snarkjs repository](https://github.com/mysteryon88/ark-snarkjs) is a utility that converts Arkworks proofs and verification keys into a format compatible with snarkjs.
* [The gnark-to-snarkjs repository](https://github.com/mysteryon88/gnark-to-snarkjs) is a utility that converts gnark proofs and verification keys into a format compatible with snarkjs.
* [The Noname repository](https://github.com/zksecurity/noname) is a high-level language for writing zk-SNARK circuits, which can be compiled to a format compatible with snarkjs.
* [The gnark repository](https://github.com/Consensys/gnark) is a Go library for writing zk-SNARK circuits and generating proofs.
* [The Arkworks homepage](https://arkworks.rs/) is a Rust ecosystem for zk-SNARKs, providing libraries for writing circuits, generating proofs, and performing trusted setup ceremonies.
