Powers of Tau

How do I perform the Powers of Tau ceremony?

Universal Setup

In both PlonK and Groth16, there is a universal trusted setup stage known as the Powers of Tau ceremony. In order to utilize a Circom-bourne zkSNARK, you will need to consider how your trusted setup was constructed in order to ensure security and integrity in your cryptosystem.

This preparatory phase can be completed independent of the circuit - completing the trusted setup before completing the circuit, and vice versa, is inconsequential.

New Ceremony

A powers of tau ceremony can be run yourself. This may be convenient for testing purposes, but a powers of tau ceremony's security comes from multiple parties making commitments. Therefore, you should not put anything into production using your own ceremony. The following shows the process used in developing BattleZips V1:

#!/bin/sh
set -e

# --------------------------------------------------------------------------------
# Phase 1
# ... non-circuit-specific stuff

# if zk/ptau does not exist, make folder
[ -d zk/ptau ] || mkdir zk/ptau

# Starts Powers Of Tau ceremony, creating the file pot15_0000.ptau
# If you run into circuit size errors, you need a larger powers of tau ceremony
yarn snarkjs powersoftau new bn128 15 zk/ptau/pot15_0000.ptau -v

# Contribute entropy from the system to the powers of tau ceremony 
yarn snarkjs powersoftau contribute zk/ptau/pot15_0000.ptau zk/ptau/pot15_0001.ptau \
    --name="First contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs powersoftau contribute zk/ptau/pot15_0001.ptau zk/ptau/pot15_0002.ptau \
    --name="Second contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs powersoftau contribute zk/ptau/pot15_0002.ptau zk/ptau/pot15_0003.ptau \
    --name="Third contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"

# Verify the contributions were properly applied
yarn snarkjs powersoftau verify zk/ptau/pot15_0003.ptau

# Apply random beacon to finalised this phase of the setup.
# For more information about random beacons see here: https://eprint.iacr.org/2017/1050.pdf
# For the purposes, the beacon is essentially a delayed hash function evaluated on 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
# (in practice this value will be some form of high entropy and publicly available data of your choice)
yarn snarkjs powersoftau beacon zk/ptau/pot15_0003.ptau zk/ptau/pot15_beacon.ptau \
    0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon"

# Prepare phase 2...
# Under the hood, the prepare phase2 command calculates the encrypted evaluation of the Lagrange polynomials at tau for
# tau, alpha*tau and beta*tau. It takes the beacon ptau file we generated in the previous step, and outputs a final pta
# file which will be used to generate the circuit proving and verification keys.
yarn snarkjs powersoftau prepare phase2 zk/ptau/pot15_beacon.ptau zk/ptau/pot15_final.ptau -v

# Verify the final ptau file. Creates the file pot15_final.ptau
yarn snarkjs powersoftau verify zk/ptau/pot15_final.ptau

Hermez Ceremonies (Safe & Quick)

For development purposes, you can generate your own circuits. However, in production, you should use an existing ceremony for maximal trust. You can find .ptau files for each circuit size here. For larger circuits, you will also save a lot of time downloading a pre-computed ceremony rather than computing it yourself. BattleZips has more than 16384 constraints but less than 32768 constraints, so in our case we download powersOfTau28_hez_final_15.ptau and rename it to "pot15_final.ptau"

@TODO: Add your own commitment to the Hermez ceremony

Groth16 Circuit-Specific Trusted Setup

If your proofs use Groth-16, there is an additional circuit-specific setup phase that you must do. Just like the above Powers of Tau ceremony, commitment to this trusted setup must be done by many parties to derive any semblance of true security. See Theory > Groth16 for more information.

This step is not run at the same time as the universal setup of the pot_xx.ptau file- it is run separately, only once you have the rank-one constraint system auto-generated by Circom.

The following bash script demonstrates the application of the trusted setup to the BattleZips circuits:

yarn snarkjs groth16 setup zk/board.r1cs zk/ptau/pot15_final.ptau zk/zkey/board_final.zkey
yarn snarkjs groth16 setup zk/shot.r1cs zk/ptau/pot15_final.ptau zk/zkey/shot_final.zkey

# # Generate reference zkey
yarn snarkjs zkey new zk/board.r1cs zk/ptau/pot15_final.ptau zk/zkey/board_0000.zkey
yarn snarkjs zkey new zk/shot.r1cs zk/ptau/pot15_final.ptau zk/zkey/shot_0000.zkey

# # Ceremony just like before but for zkey this time
yarn snarkjs zkey contribute zk/zkey/board_0000.zkey zk/zkey/board_0001.zkey \
    --name="First board contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs zkey contribute zk/zkey/shot_0000.zkey zk/zkey/shot_0001.zkey \
    --name="First shot contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs zkey contribute zk/zkey/board_0001.zkey zk/zkey/board_0002.zkey \
    --name="Second board contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs zkey contribute zk/zkey/shot_0001.zkey zk/zkey/shot_0002.zkey \
    --name="Second shot contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs zkey contribute zk/zkey/board_0002.zkey zk/zkey/board_0003.zkey \
    --name="Third board contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"
yarn snarkjs zkey contribute zk/zkey/shot_0002.zkey zk/zkey/shot_0003.zkey \
    --name="Third shot contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)"

# #  Verify zkey
yarn snarkjs zkey verify zk/board.r1cs zk/ptau/pot15_final.ptau zk/zkey/board_0003.zkey
yarn snarkjs zkey verify zk/shot.r1cs zk/ptau/pot15_final.ptau zk/zkey/shot_0003.zkey

# # Apply random beacon as before
yarn snarkjs zkey beacon zk/zkey/board_0003.zkey zk/zkey/board_final.zkey \
    0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Board FinalBeacon phase2"

yarn snarkjs zkey beacon zk/zkey/shot_0003.zkey zk/zkey/shot_final.zkey \
    0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Shot Final Beacon phase2"

Upon successful generation of the x_final.zkey files, we have the artifacts needed to proceed with usage of our Circom circuit to generate zero knowledge proofs.

Last updated