This repository contains an example circom circuit that is used to test the Bitcoin script for a fflonk verifier.

Dependencies

We use circom, snarkjs, and circomlib.

  • follow instructions here to install circom and snarkjs.
  • circomlib has been included as a git submodule. One can do git submodule update --init --remote --recursive.

Instructions

Step 1: obtain the setup parameters

We use the KZG setup ceremony that Polygon Hermez has done. More information can be found here.

wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_21.ptau

Step 2: compile the circuit

We use circom to compile the circuit.

circom test_circuit.circom --r1cs --wasm --sym

Step 3: perform the witness generation

Then, we use the witness generator that circom creates to compute the witness.

cd test_circuit_js
node generate_witness.js test_circuit.wasm ../input.json ../witness.wtns
cd ../

You can test if the witness is correct.

snarkjs wtns check test_circuit.r1cs witness.wtns

Step 4: preprocess the keys

Now, we use snarkjs to preprocess the keys, which creates the proving key file circuit.zkey

snarkjs fflonk setup test_circuit.r1cs powersOfTau28_hez_final_21.ptau circuit.zkey

Step 5: export the verification key

We can derive the verifying key out of the proving key.

snarkjs zkey export verificationkey circuit.zkey verification_key.json

Step 6: create the proof

We can now run the proof generation.

snarkjs fflonk prove circuit.zkey witness.wtns proof.json public.json

For testing purposes, however, it is more common to use fixed randomness.

USE_FIXED_RANDOMNESS=1 snarkjs fflonk prove circuit.zkey witness.wtns proof.json public.json

And if one wants to save the console output to a file, use |& tee a.txt.

To check if the verifier will accept this proof, do:

snarkjs fflonk verify verification_key.json public.json proof.json

Step 7: export the Solidity verifier contract

A very convenient feature of snarkjs is that it can generate a highly efficient and fully preprocessed Solidity smart contract that exactly represents the verifier.

snarkjs zkey export solidityverifier circuit.zkey verifier.sol