The secure generation of parameters for zk-SNARKs is a crucial step in the trustworthiness of the resulting proof system.
The trusted setup is done in two steps. The first step, also known as "phase 1", does not depend on the program and is called Powers of Tau. The second step is called "phase 2" and is circuit-specific, so it should be done separately for each different program. The Ethereum community runs a phase 1 setup called Perpetual Powers of Tau, whose output we will use. Therefore, we only need to run phase 2 of the setup.
The security of the ceremony relies entirely on the fact that at least one participant needs to securely delete their "toxic waste" for the resulting parameters to be generated honestly. Opening the ceremony to a large number of participants reduces the probability that the resulting parameters are dishonest. Once the ceremony is finalized, we can generate a verifier smart contract by using the keys we obtained through the trusted setup ceremony. At this point, we can safely deploy the contract and verify proofs on-chain.
We will use the challenge file challenge_0087
(see this page of the Powers Of Tau repo).
It was downloaded from:
https://pse-trusted-setup-ppot.s3.eu-central-1.amazonaws.com/challenge_0087
Its blake2b
hash is:
3ee2b349a7381bbcceefc4ddb3b2360f52d61cdad9829665f0cc078baf8622bf32149804dda4fae932b770f03c07a8a48fc1a4dcea18fe3582bfbd95bd380e3f
We will use the hash of block 23440000 on the Ethereum mainnet, which will be mined around Thu Sep 25 2025 12:39:26 UTC. We chose this particular block height as:
It is no less than one day in future relative to the date that we will announce it.
It is rounded to a multiple of 1000.
We then interpret the hash as a 32-byte array and use it as an input to the delay function.
We will use Argon2 as our Delay Function — we will perform 2048 iterations of Argon2d with
memory cost of 16GiB. The implementation of our delay function is available in the
delay_function.rs
file.
We assume that:
- Argon2 is a pre-image resistant hash function
- An Ethereum block hash is considered final after roughly 6 minutes.
- No adversary is able to perform our Delay Function within 6 minute window and influence the block hash.
The block hash is:
TO BE FILLED IN
The Delay Function output is:
TO BE FILLED IN
We will use the phase2-bn254 project (rev dd6b96657d16c1a2b81fd23e540581c356284ec6
).
cargo run --release --bin beacon_constrained ./challenge_0087 ./response 28 1024 <TO BE FILLED IN> 10
(note that this will also apply another 2¹⁰ SHA-256 iterations to the given Delay Function output)
The response file blake2b hash is:
TO BE FILLED IN
Its URL is:
TO BE FILLED IN
Next we will generate the radix files — we need to obtain the phase1radix2m11
file that is
suitable for circuits of up to 2¹¹ constraints:
cargo run --release --bin prepare_phase2 ./response 28 1024
For the phase 2 we will use the zokrates
binary v0.8.8
.
First we will initialize the phase 2 of the ceremony:
zokrates mpc init -i circuit.out -o mpc.params -r phase1radix2m11
Each participant must run the following for the <previous participant>.params
file:
zokrates mpc contribute -i <previous participant>.params -o <current participant>.params -e <entropy>
We will use our Delay Function on a new pre-announced Ethereum block (at least a day in advance) to obtain a new random beacon value to apply to the final contribution:
zokrates mpc beacon -i <final participant>.params -o final.param -h <TO BE FILLED IN> -n 10
(note that this will also apply another 2¹⁰ SHA-256 iterations to the given Delay Function output)
Once the ceremony is finalized, we can export the keys and use them to generate proofs and verify them:
zokrates mpc export -i final.param