Research lab · v2

zkShuffle v2 · mental poker, live in your browser

The trust model our tables actually run: nobody · not our dealer, not the host, not other players · can see your cards during a hand. This page runs the REAL cryptography (not a mock) right here, and lets you try to cheat it.
⚗️ Really on-chain · and really live. This page runs the v2 protocol core client-side on BN254 (the curve the EVM has native precompiles for), and every Schnorr key proof and Chaum–Pedersen decryption-share proof below is verified by a deployed contract · ZkDealerV2 at 0x292E…b67D · through a zero-gas eth_call. You are watching the actual chain accept or reject each proof. Live cash tables and tournaments run the same protocol, same curve, same Fiat–Shamir domains and the same verifier library; there the on-chain checks live in the room's card layer, ZkTableDealer at 0x3fD6…3fe8. Not audited by a third party yet.

How it works, in one hand

Three players (simulated below, each with its own secret key your browser never shares between them): they aggregate a table key, each one shuffles and re-encrypts the deck themselves, then each hole card is decrypted only by its owner using the other players' decryption shares · and each of those shares is proven correct and checked by the contract on-chain. Watch the log: no party other than the owner ever holds a readable card.

The last step of the lab is the post-hoc audit: every player opens their permutation and randomness, the whole chain is recomputed and any tampering is attributed to the exact stage that did it. Press the cheat button and watch it happen. At a live table that audit is the belt, not the braces · see the next section for what actually guards a real hand.

BOARD
Press “Play an honest hand”.

What a real hand proves, and where

  • Verified by the contract, during the hand: every player's Schnorr key proof (a rogue key cannot join and the aggregate table key is formed on-chain); every Chaum–Pedersen decryption share, checked against the committed ciphertext and that seat's per-hand key; and that the shares decrypt to exactly the card being claimed · B − Σd == (card+1)·G. A forged share or a lied-about card reverts, so the coordinator cannot put a card on the felt that the cryptography did not produce. A per-deal bitmask also rejects the same card value appearing twice.
  • Verified by every client, during the hand: the shuffles. Each player's shuffle carries a Wikström zero-knowledge proof that the output deck is a permutation plus re-encryption of the input, with nothing opened afterwards. Every other client fetches the whole transcript and checks all of it (and pins its own stage inside it) before it will hand over a single decryption share, and the deal commits the keccak of that transcript on-chain, so anyone holding it can re-verify the shuffle forever. That is stage R2 of the spec, and it is live · the "at least one honest shuffler" assumption is no longer load-bearing.
  • Enforced on-chain when someone vanishes: a missing decryption share becomes an on-chain accusation naming the exact card. The accused client can answer it within a rescue window, which also delivers the withheld share; only an unanswered accusation forfeits that player's committed chips, pro-rata to the other players in the hand and never to the operator.
  • Not done: the shuffle argument itself is verified by clients and by the coordinator, not inside a contract · the chain holds its commitment, not its verification. There is no third-party audit yet. And undealt cards are never decrypted at all: only the 2k + 5 ciphertexts actually in play are committed, as hashes with the points passed in calldata, which is what keeps the coordinator's gas at roughly 0.086 STT per completed heads-up hand and 0.14–0.16 STT at four players (measured on Somnia at its fixed 6 gwei base fee; a player's own action costs about 0.001 STT).
Play poker Read the docs Source ↗