Presenting CircomJS
I have been writing ZK circuits in Circom for quite some time, and have pushed the DSL to its limit! Worked with circuits with more than 70 million constraints, and one thing that kept bugging me was the lack of a proper workflow and the need for a reliable build tool! Let me elaborate more on this.
A ZK project development can be divided into 3 phases:
- Writing Circuits: expressing your computation.
- Building the Circuits: exporting artifacts like R1CS, proving key, verification, etc.
- Consuming the builds: generating proofs, verifying proofs, calculating total constraints from R1CS, etc.
Circom as a DSL is amazing in filling the first box, which is writing circuits! But the DX around the build process and consuming the builds is a rough one.
Here is what it takes to generate your first proof (and verify the same) from a Circom file:
- power of tau file:
- find the ideal power of the tau file depending upon your total circuit constraints.
- If you go through the route of generating it rather than downloading it then that is again of a lot more steps. - compiling your Circom file
- creating your input.json { “defining inputs for your circuit” }
- calculating witness { calculating witness for a given input }
- creating your zkey:
Plonk: can be done in a single step
Fflonk: can be done in a single step
Groth16: will take 5 more steps! - exporting verification key
- generating proof
- verifying proof
Hence it is an 8–13 step process depending on whether you are using Plonk, FFlonk, or Groth16. Now here is the thing:
All of this has to be done via shell commands!!! Yes and every time you change your source code you have to repeat all steps from 2.
Welcome to the world of every Circom Developer ever!
Automation & testing?
Every Circom project requires certain automation ( compiling, generating proofs, verifying them, generating verifier smart contracts, etc ) and testing.
The question is how do we do this? So this far most of the teams I have talked with rely on shell scripts!!!! Yes every one of them is writing their shell scripts!
Shell scripts are very low-level! We need the support of Automation & Testing in a high-level programming language, what hardhat and ethers do for Solidity development.
Hola CircomJS
CircomJS aims to solve these problems, it allows you to interact with your circuits in Javascript { Typescript as well }.
Hence you can do the following in Javascript with CircomJS:
- compile circuits { generates R1CS, Witness generation programs, proving keys, verification keys }
- generating witness
- generating proofs
- verifying proofs
- calculating total constraints
- and much more!
Hence, you can script your Circom workflow similarly to how you do it right now with Hardhat and Ethers for solidity.
You can test your circuits in your favorite JS testing frameworks like Jest and Mocha, automate smart contract verifier deployment, generate & verify proofs directly on your server-side applications, and much more!
You have to declare a simple circuit.config.js file at your project root and CircomJS takes care of the rest!
You can get started with the project via our docs!
Upcoming features
CircomJS will be receiving a lot of cool updates soon and we are listing a few of them below:
- Support for C compilation of circuits { witness generation programs }
- Automatic download of ideal power of tau file
- Parallel build of ZK Circuits
- Integration with Ethersjs to deploy smart contract verifiers
- Using SHA-256 to only build circuits when the source code changes
We at ZeFi are open to ideas around the project and would love to interact with the community and see contributions comings their way, feel free to join our telegram group and say hi, also feel free to write to us at contact@zefi.io.