Circomkit
A simple-to-use & opinionated circuit development & testing toolkit.
Circomkit is still being developed, although at its current state you should really be able to easily play with circuits and write their tests, and most commands should be seamless to work especially with bn128 curve!
Installation
Circomkit is an NPM package, which you can install via:
yarn add circomkit # yarn
npm install circomkit # NPM
You will also need Circom, which can be installed following the instructions here.
Usage
Create an empty project, and install Circomkit. Then, you can setup the environment by simply executing:
npx circomkit init
This command creates the following:
- An example Multiplier circuit, under
circuitsfolder. - A circuit configuration file called
circuits.json, with an example Multiplier circuit configuration. - An example input JSON file for Multiplier, under
inputs/multiplierfolder. - A test using Mocha, under
testsfolder. - A Mocha configuration file.
Although Circomkit initializes with a Mocha test, uses Chai in the background so you could use anything that supports Chai. You should check out circomkit-examples repo as an example!
Circomkit Configuration
Everything used by Circomkit can be optionally overridden by providing the selected fields in its constructor. Circomkit CLI does this automatically by checking out circomkit.json and overriding the defaults with that. You can print the active configuration via the following command:
npx circomkit config
You can edit any of the fields there to fit your needs.
Circuit Configuration
A circuit config within circuits.json looks like below, where the key is the circuit name to be used in commands, and the value is an object that describes the filename, template name, public signals and template parameters:
sudoku_9x9: {
file: 'sudoku',
template: 'Sudoku',
pubs: ['puzzle'],
params: [3], // sqrt(9)
},
You can omit pubs and params options, they default to [].
Command Line Interface
Actions that require a circuit name can be called as follows:
# Compile the circuit
npx circomkit compile circuit
# Create the main component
npx circomkit instantiate circuit
# Create a Solidity verifier contract
npx circomkit contract circuit
# Clean circuit artifacts
npx circomkit clean circuit
# Circuit-specific setup
npx circomkit setup circuit [ptau-path]
Circuit-specific setup optionally takes the path to a PTAU file as argument. If not provided, it will automatically decide the PTAU to use with respect to constraint count, and download it for you! This feature only works for bn128 curve.
Some actions such as generating a witness, generating a proof and verifying a proof require JSON inputs to provide the signal values. For that, we specifically create our input files under the inputs folder, and under the target circuit name there. For example, an input named foo for some circuit named bar would be at inputs/bar/foo.json.
# Generate a witness
npx circomkit witness circuit input
# Generate a proof
npx circomkit prove circuit input
# Verify a proof with public signals
npx circomkit verify circuit input
# Export Solidity calldata to console
npx circomkit calldata circuit input
Circuit Testing
TODO TODO
File Structure
Circomkit with its default configuration follows an opinionated file structure, abstracting away the pathing and orientation behind the scenes. All of these can be customized by overriding the respective settings in circomkit.json.
An example structure is shown below. Suppose there is a generic circuit for a Sudoku solution knowledge proof written under circuits folder. When instantiated, a main component for a 9x9 board is created under circuits/main. The solution along with it's puzzle is stored as a JSON object under inputs/sudoku_9x9. You can see the respective artifacts under build directory. In particular, we see groth16 prefix on some files, indicating that Groth16 protocol was used to create them.
circomkit
├── circuits.json
├── circomkit.json
│
├── circuits
│ ├── main
│ │ └── sudoku_9x9.circom
│ └── sudoku.circom
│
├── inputs
│ └── sudoku_9x9
│ └── my_solution.json
│
├── ptau
│ └── powersOfTau28_hez_final_12.ptau
│
└── build
└── sudoku_9x9
│── sudoku_9x9_js
│ │── generate_witness.js
│ │── witness_calculator.js
│ └── sudoku_9x9.wasm
│
│── my_solution
│ │── proof.json
│ │── public.json
│ └── witness.wtns
│
│── sudoku_9x9.r1cs
│── sudoku_9x9.sym
│
│── groth16_pkey.zkey
│── groth16_vkey.json
└── groth16_verifier.sol
Testing
Run all tests via:
yarn test
You can also use the CLI in the repo by yarn cli as if you are using npx circomkit. This is useful for hands-on testing stuff.
Styling
Circomkit uses Google TypeScript Style Guide.
# check the formatting
yarn format
# lint everything
yarn lint
# do both at once
yarn style