Za!
An experimental port of the circom zk-SNARK compiler in Rust with embedded bellman-bn128 prover. I created it as a PoC port of the existing JavaScript compiler to Rust when I was working for iden3.
WARNING: This is a proof-of-concept prototype, and in particular has not received careful code review.
Building
Install rust
curl https://sh.rustup.rs -sSf | sh
Install additional dependencies, you may need to install the clang build-essentials and openssl-dev
Clone the repo
git clone https://github.com/adria0/za.git
Build
cargo build --release
The final binary will be in target/release/za
Usage
Generating trusted setup
za setup --circuit <circut.za> --pk <proving.key> --verifier <verifier.sol> --verifiertype <solidity|json>
circuit.zais an input file with themaincomponent that specifies the circuitproving.keyis a generated output with the key required to generate proofsverifier.solis a generated output with the smartcontract to verify the generated proofs
if you want to do a test, create a file with name circuit.za with the following contents and run the za setup
template T() {
signal private input p;
signal private input q;
signal output r;
r <== p*q;
}
component main = T();
Generating a proof
za prove --input <input.json> --pk <proving.key> --proof <proof.json>
input.jsonis an input file with the required input signals to generate the full witnessproving.keyis an input file with the key required to generate proofsproof.jsonis the input required by the smartcontract to verify the proof
if you want to do a test, create a file with name input.json with the following contents and run the za prove
{ "p" : "2", "q": "3" , "r" : "6"}
then deploy the verifier.sol smartcontract and exec the verifyTx method with the contents of the proof.json
Testing a circuit
In order to test if a circuit is correct is possible to write an embedded test by using the #[test] tag before a template definition (see interop/circomlib/babyjub.circom), to execute the test, run:
za test --circuit <circuit.za>
this will run the tests found in the circuit and all the tests found in the included templates
Golang verification
you can verify the za! generated proofs generated with za! with the https://github.com/arnaucube/go-bellman-verifier tool (thanks @arnaucube)
JavaScript bindings
to compile the JavaScript bindings, go to the binding/js folder and run:
npm inpm run installnpm test
check the test located in binding/js/test/test.js
Differences with circom
There are few differences between this implementation and the official circom:
- Precedence of operators rust-like instead C-like:
DECNUMBER,HEXNUMBER,"(" exp ")"- Unary
-! ***/\\%+-<<>>&^|==!=<><=>=&&||
- Removed
++,--and:? - Matrix access is only accessible with
[x][y](not with[x,y]) - End statement semicolons are mandatory
- Loops/conditionals statements must be inside blocks
{ } - Added
dbg!function to trace variables, signals and components - Do now allow to use component
signal outputs until allsignal inputare set - Signal input/outputs arrays should be evaluable with template parameters
- Stamements tagged with
#[w]are only evaluated in witness generation #[test]tagged templates are used to verify embeeded tests#[]expressions can be comment-scapped by using/*#[]#*/to be compatible with circom circuits.
