This repository contains an example circom circuit that is used to test the Bitcoin script for a fflonk verifier.
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
.
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
We use circom to compile the circuit.
circom test_circuit.circom --r1cs --wasm --sym
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
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
We can derive the verifying key out of the proving key.
snarkjs zkey export verificationkey circuit.zkey verification_key.json
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
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