Circuit-specific keys. Starts after Phase 1 freezes and uses the frozen output as input. Snarkjs handles the MPC; this dashboard indexes the rounds.
Phase 2 ends with a public random beacon — a Bitcoin block hash. We pre-announce
the block height when Phase 1 freezes; mining proceeds independently; then
we derive a final transform from SHA-256(block_header) and apply it to
each tier's final zkey.
Phase 2 is mechanically similar to Phase 1 but shorter: it specializes the universal SRS to Onym's specific circuit layout. We use the standard snarkjs tooling (because its transcript format is widely audited), wrap it in a pinned Docker image, and ingest each round back into this coordinator so the whole thing shows up in one place.
Participation is open, but slots are scheduled rather than FIFO — each round takes 20-40 minutes of compute per tier.
Starting from the Phase 1 SRS $\sigma = \{\tau^i G\}_{i \le 2^d}$ and the circuit's R1CS $(\mathbf{A}, \mathbf{B}, \mathbf{C})$, snarkjs computes:
Each round $j$ re-randomizes $\delta^{(j)} = \delta^{(j-1)} \cdot \delta_j$ and contributes to the $\delta$-suffixed terms.
The snarkjs handoff runs inside a pinned-digest Docker image so every
contributor gets the same binary, with no accidental dependency drift
between rounds. Source is at docker/phase2-helper/.
docker pull ghcr.io/rinat-enikeev/ceremony-phase2-helper:latest
docker run --rm \
-v "$(pwd):/work" \
ghcr.io/rinat-enikeev/ceremony-phase2-helper:latest \
contribute \
--input /work/input.zkey \
--output /work/output.zkey \
--tier small \
--name "my handle"
The image ships a stripped ceremony_tool (for Phase 1 SRS
export), snarkjs pinned to a specific version, and a thin
shell wrapper that writes an attestation receipt alongside the zkey.
No Phase 2 rounds have been indexed yet. Check back after Phase 1 freezes.