PROOF(7)The Dark Room ManualPROOF(7)

proof(7)

What the proof of a batch states, how it is made, how its setup was done, and how to check it without trusting this site.

Statement

For every slot of the batch that holds a commitment, unless the slot is flagged broken:

  1. the inner ciphertext used is the committed one (its Poseidon hash equals the commitment), so no order can be swapped;
  2. it is opened with the secret key that matches the room key posted for that day, so the plaintext is the only one possible;
  3. the plaintext is a valid order of this slot's owner for this batch, or it takes no part;
  4. the outcome of every slot (dark, matched with its fill, void) is exactly the rule applied to all of them at the prices the contract read.

So the room cannot leave a valid order out, add one, or change a fill, and an unmatched order's outcome reveals nothing but "dark".

Public inputs

the 203 public inputs, in the order the contract passes them
[0]         batch id
[1..2]      room public key of the day (x, y)
[3..10]     price of each of the 8 market slots (0 = does not trade)
[11..74]    commitment of each of the 64 slots (0 = empty or cancelled)
[75..138]   owner of each slot
[139..202]  outcome of each slot: kind | market | side | qty | limit | fill

Proof system

system
Groth16 over BN254; circuit in circom 2.2 (303,043 constraints, 64 order slots, 8 market slots)
verifier
Groth16Verifier, exported from the final key, called by DarkRoom.settle before any balance moves; a settlement costs about 1.8M gas, most of it the 203 public inputs
key
files and hashes in /zk/ceremony.json; verification key in /zk/vkey.json

The prover

one full 64-order batch, measured on the room's machine
device                               proof      in the room (witness + proof + self-check)
GPU, ICICLE CUDA backend (Groth16)   1.3 s      about 2 s; GPU at 99 to 100% during the proof
CPU, same prover                     4.8 s
CPU, snarkjs (Groth16, the fallback) 11.7 s     about 12 s
before (PLONK, 16 orders, CPU)       155 s

The room proves with icicle-snark on ICICLE's CUDA backend: the multi-scalar multiplications (in both groups) and the number-theoretic transforms run on the GPU. The proving key stays loaded in the prover between batches. If the GPU prover fails, the room proves on the CPU with snarkjs instead, logs it loudly, and records it: the settlement emits Proved(batchId, prover, proveMs), and every batch page shows which device made its proof and how long it took. That record is the room's report; the proof itself is checked the same way whichever device made it.

A batch takes up to 64 orders; the room pays the gas of every settlement.

The setup

Groth16 needs a setup specific to the circuit. It is done in two public phases, and it is secure as long as one contributor, in either phase, destroyed the randomness they used.

phase 1
the Perpetual Powers of Tau (80 contributions), file ppot_0080_19, hash in ceremony.json
phase 2, contribution 1
the room's machine, with kernel randomness that was never written to disk
phase 2, contribution 2
a member of the team, on their own machine, with circuits/ceremony.sh contribute
beacon
the randomness of a drand quicknet round announced before it was published, applied with circuits/ceremony.sh finalize
#contributioncontribution hash
1room machinedf057a92 24032dd6 d5fcea61 f378c6d9 a992127f f928a788 89eb499a 058b2681 12686a08 5129bacd 2fb76e1f f8509935 3c26338c 7d9af696 4e62bf67 e03831cd
2teamafc28ccf 575c84d3 ee244c5e c94f479a 3f604f34 65fe6db9 1a62e8ce 2e9a3802 2491151f 7f029ea6 1a7512e4 facdba86 373803d3 1bd98e04 e78305b1 a4a6807c
3drand quicknet round 32830943a46b37e6 4fbb923e dd407f78 2c1e8e39 96d94238 e3ff242a 74fe0449 bf7b4c6e 1f8386a8 e7c84215 563f34e5 a56f8b96 a60e7a5b 131e1161 ec97a72f 5aef8b52

beacon: drand quicknet round 32,830,943, announced 2026-10-06 14:06:33 UTC, before the round existed, published 2026-10-06 14:16:33 UTC; randomness 71f171746867cee99496dcaef9b22f6cac8dd9621f0c276d8a1a14795117e834

final key sha256 ead60da5a954767f84031334bd6cedcfd2e28cd3a7ae4f8419de8c52d0d12c06

Anyone can check the transcript: snarkjs zkey verify main.r1cs ppot_0080_19.ptau main_final.zkey lists every contribution hash and fails if the key does not derive from the circuit and phase 1.

Verify it yourself

# the verification key and the ceremony record
curl -O https://zkdarkpool.xyz/zk/vkey.json
curl -O https://zkdarkpool.xyz/zk/ceremony.json
# on any batch page: "download public.json and proof.json", then
npx snarkjs groth16 verify vkey.json public.json proof.json

Every batch page also verifies the proof in your browser from chain data alone: it rebuilds the 203 inputs from the Settled event, the commitments and the room key, reads the proof from the settle transaction, and runs the verifier locally.

/ search · [ ] previous and next page