A zkSNARK toolkit to work with circom zkSNARKs DSL in plonk proof system. Based on zkutil and bellman_ce.
- install circom into $PATH
- install snarkit2 into $PATH: npm install -g snarkit2
- Proof Generation
- Verification key generation
- Proof verification
- Solidity verifier generation
- Local key setup for developement
- Proof Aggregation
The script test_poseidon_plonk.sh gives an end-to-end example using plonkit to setup circuits / generate proving keys and validation keys / prove circuits / validate proof in Solidity.
You can also follow the step-by-step commands below.
# Getting help
> plonkit --help
plonkit 
A zkSNARK toolkit to work with circom zkSNARKs DSL in plonk proof system
USAGE:
    plonkit <SUBCOMMAND>
FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
SUBCOMMANDS:
    analyse                              Analyse the circuit and output some stats
    check-aggregation                    Check proofs aggregation
    dump-lagrange                        Dump "SRS in lagrange form" from a "SRS in monomial form"
    export-recursive-verification-key    Export Recursive verifying key
    export-verification-key              Export verifying key
    generate-verifier                    Generate verifier smart contract
    help                                 Prints this message or the help of the given subcommand(s)
    prove                                Generate a SNARK proof
    recursive-prove                      Aggregate multiple proofs
    recursive-verify                     Verify recursive proof
    setup                                Trusted locally set up Plonk universal srs in monomial form
    verify                               Verify a SNARK proof
# Getting help for a subcommand
> plonkit prove --help
plonkit-prove 
Generate a SNARK proof
USAGE:
    plonkit prove [OPTIONS] --srs_monomial_form <srs-monomial-form>
FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
OPTIONS:
    -c, --circuit <circuit>                        Circuit R1CS or JSON file [default: circuit.r1cs|circuit.json]
    -p, --proof <proof>                            Output file for proof BIN [default: proof.bin]
    -l, --srs_lagrange_form <srs-lagrange-form>    Source file for Plonk universal setup srs in lagrange form
    -m, --srs_monomial_form <srs-monomial-form>    Source file for Plonk universal setup srs in monomial form
    -w, --witness <witness>                        Witness JSON file [default: witness.json]
# Suppose we have circuit file and a sample inputs, plus a plonk universal setup SRS (the '.key' file)
# The key file can either be downloaded from a finished third party setup or generated locally (development only)
> ls
circuit.circom  input.json  setup_2^20.key
# generate witness for this circuit
# another option here is use the snarkjs/circom cli like contrib/process_circom_circuit.sh
> snarkit2 check . --witness_type bin --backend wasm
# Generate a snark proof using the universal setup monomial-form SRS
> plonkit prove --srs_monomial_form setup_2^20.key --circuit circuit.r1cs --witness witness.wtns --proof proof.bin
Loading circuit...
Proving...
Proof saved to proof.bin
Proof json saved to proof.json
Public input json saved to public.json
# Export verification key
> plonkit export-verification-key --srs_monomial_form setup_2^20.key --circuit circuit.r1cs --vk vk.bin
Verification key saved to vk.bin
# Generate verifier smart contract, which can be used to verify public.json & proof.json
> plonkit generate-verifier --verification_key vk.bin --sol verifier.sol
Contract saved to saved to verifier.sol
# Verify the proof
> plonkit verify --proof proof.bin --verification_key vk.bin
Proof is correct
# Here's a list of files that we have after this
> ls
circuit.circom  circuit.r1cs  circuit.sym  circuit.wasm  input.json  proof.bin  proof.json  public.json  setup_2^20.key  verifier.sol  vk.bin  witness.wtnsIf you want to set up a SRS locally for testing, you can make use of setup subcommand:
plonkit-setup 
Trusted locally set up Plonk universal srs in monomial form
USAGE:
    plonkit setup --power <power> --srs_monomial_form <srs-monomial-form>
FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
OPTIONS:
    -p, --power <power>                            Power_of_two exponent
    -m, --srs_monomial_form <srs-monomial-form>    Output file for Plonk universal setup srs in monomial form
You may also want to manually edit and lower down plonk::SETUP_MIN_POW2 in the codes to fast generate a relatively small-sized SRS.
Moreover, you can make use of the analyse subcommand to print out the statistics of a circuit (num of inputs, num of constraints, num of gates...):
plonkit-analyse 
Analyse the circuit and output some stats
USAGE:
    plonkit analyse [OPTIONS]
FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
OPTIONS:
    -c, --circuit <circuit>    Circuit R1CS or JSON file [default: circuit.r1cs|circuit.json]
    -o, --output <output>      Output file [default: analyse.json]
Plonkit also supports Proof Aggregation. You can aggregate multiple proofs into one, see test_poseidon_plonk_recursive.sh for a workflow example.
Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInstall plonkit globally
cargo install --git https://github.com/fluidex/plonkit
# Make sure `~/.cargo/bin` is in $PATH (should be added automatically during Rust installation)Or alternatively you can compile and run it instead:
git clone https://github.com/fluidex/plonkit
cd plonkit
cargo run --release -- prove --help