Skip to content

dl-solarity/zkit

Repository files navigation

npm License: MIT

ZKit - Circom Zero Knowledge Kit

A zero knowledge kit that helps you develop circuits using Circom.

  • Compile and interact with circuits without snarkjs hassle.
  • Generate and verify ZK proofs with a single line of code.
  • Render optimized Solidity verifiers.
  • Forget about native dependencies - everything is in TypeScript.

Installation

To install the package, run:

npm install --save-dev @solarity/zkit

Usage

CircomZKit

ZKit is a configless package, which means you don't need to provide any configuration to use it:

import { CircomZKit } from "@solarity/zkit";

async function main() {
  const zkit = new CircomZKit();
  
  const multiplier = zkit.getCircuit("Multiplier");
  
  // Generates artifacts in the "./zkit-artifacts" directory
  await multiplier.compile();

  // Generates ZK proof
  const proof = await multiplier.generateProof({ a: 2, b: 3});
}

By default, ZKit will look for the circuit file in the ./circuits directory. However, you can change this by providing a custom one:

new CircomZKit({ circuitsDir: "./my-circuits" });

To generate zkey, the power-of-tau file is required. ZKit automatically downloads those files from Hermes to the ${HOME}/.zkit/.ptau directory, so you don't need to re-download them every time you start a new project.

You can also provide a custom path to the directory where the power-of-tau files are stored:

new CircomZKit({ ptauDir: "./my-ptau" });

Important

Note that all the files in the ptauDir directory must have the powers-of-tau-{x}.ptau name format, where {x} is a maximum degree (2x) of constraints a ptau supports.

ZKit may also ask you for the permission to download the power-of-tau files. You can enable this by toggling off the allowDownload option:

new CircomZKit({ allowDownload: false });

CircuitZKit

Once you created a CircuitZKit instance using the getCircuit method, you can manage the underlying circuit using the following methods:

Note

You should first compile the circuit before creating verifiers or generating proofs.

compile()

Compiles the circuit and generates the artifacts in the ./zkit-artifacts or in the provided artifactsDir directory. The default output is r1cs, zkey and vkey files.

await multiplier.compile();

createVerifier()

Creates Solidity verifier contract in the ./contracts/verifiers or in the provided verifiersDir directory.

await multiplier.createVerifier();

generateProof()

Generates a proof for the given inputs.

/// { proof: { pi_a, pi_b, pi_c, protocol, curve }, publicSignals: [6] }
const proof = await multiplier.generateProof({ a: 2, b: 3});

verifyProof()

Verifies the proof.

/// true
const isValidProof = await multiplier.verifyProof(proof);

generateCalldata()

Generates calldata by proof for the Solidity verifier's verifyProof() method.

/// You can use this calldata to call the verifier contract
const calldata = await multiplier.generateCalldata(proof);

Known limitations

  • Currently, ZKit supports only the Groth16 proving system.
  • Zkey generation doesn't allow additional contributions.
  • The compile method may cause issues.