BlackMind
Research
Applied cryptographyMental pokerVerifiable shufflesBlockchains

On-Chain Bayer–Groth Shuffle Verification for Dealerless Texas Hold'em

memepoker: nine-handed Texas Hold'em on Solana with no dealer, no server and no house. The players' own clients shuffle and deal to each other with mental-poker cryptography, and Solana programs verify every key, shuffle and card reveal on chain before a card moves — the first system to check a transparent Bayer–Groth shuffle argument natively inside Solana programs.

Jovonni L. PharrGeorgia Cyber Warfare Range / BlackMindNovember 7, 2026v0.0.1
Showdown at a nine-seat memepoker table. The hand is dealerless: the deck was shuffled and dealt by the players' own clients with mental-poker cryptography, and every key, shuffle and reveal was verified on chain before a card could move.
Fig. 1Showdown at a nine-seat memepoker table. The hand is dealerless: the deck was shuffled and dealt by the players' own clients with mental-poker cryptography, and every key, shuffle and reveal was verified on chain before a card could move.

In brief

memepoker is a nine-seat Texas Hold'em game on Solana with no dealer, no server and no house — the players' own clients shuffle and deal to each other with mental-poker cryptography, and Solana programs check every key, shuffle and card reveal on chain before play continues. The engineering problem is fitting that verification inside Solana's tight limits: a transparent Bayer–Groth shuffle argument, re-cast as nine resumable checks over a 290-byte scratch state and run on native curve syscalls, verifies a full 52-card shuffle in a single transaction of about one million compute units — to our knowledge the first time such an argument has been checked natively inside Solana programs. Around it sits a validity-first enforcement layer (piggybacked timeouts, slashable SOL bonds, whistleblower and fraud proofs) and a public 'verify this hand' tool that rebuilds any finished hand from chain data alone, trusting the data but never the node that serves it.

Key results

  • First on-chain transparent shuffle: a Bayer–Groth argument with no trusted setup and no SNARK wrapper, verified natively inside Solana programs — one full 52-card shuffle in a single transaction of 1,016,627 compute units.
  • Verification re-cast as nine independent checks over a 290-byte scratch state, resumable across transactions to fit Solana's 1.2M-compute-unit and 32-KiB limits.
  • A 32-bit-limb scalar arithmetic makes one scalar multiplication 3.9× cheaper (5,711 → 1,473 compute units); one buffered sha256 per Fiat–Shamir challenge costs 7,229 CU instead of 151,576 in software.
  • A complete six-player hand costs 90 cryptographic transactions / 7.9M CU in the benchmark profile, and 126 transactions / 12.6M CU in the deployed inline-account profile.
  • Deck privacy against any coalition short of all-but-one, deal soundness, and stall accountability are stated as theorems with proof sketches, then stress-tested by 1,000+ named attack tests plus coverage-guided and stateful fuzzing.
  • Anyone can re-verify a finished hand from chain data alone; the program commits a step count and digest at settlement, so a lying RPC node can make verification fail but never pass.

Abstract

We present memepoker, a nine-handed Texas Hold'em system on Solana in which there is no dealer, no server and no house: the players' own clients shuffle and deal the cards to each other cryptographically, and Solana programs verify every cryptographic step before the game is allowed to proceed. Cards are ElGamal ciphertexts over Ristretto255 under a joint key that is the sum of per-hand player keys, each registered with a Schnorr proof of knowledge. Every player shuffles the deck in turn and proves the shuffle with a transparent Bayer–Groth argument, so no trusted setup is involved; cards are opened by threshold decryption with Chaum–Pedersen proofs for every share; and a single Fiat–Shamir transcript format, bound to program, cluster, table, hand, seat and phase, is shared byte for byte by the Rust client, the WebAssembly client and the on-chain verifier. The verifier runs natively on Solana's curve25519 and sha256 syscalls with a 32-bit-limb scalar arithmetic that cuts scalar multiplication from 5,711 to 1,473 compute units, and it splits the argument into nine independent checks over a 290-byte scratch state so verification can be resumed across transactions. Measured on the compiled verifier in a benchmark harness with the fewest accounts per transaction, one 52-card shuffle round is eight transactions (seven chunk uploads and one verification transaction at 1,016,627 compute units, under the 1.2M per-step budget we set ourselves), a decryption share verifies in about 16,000 compute units, and a complete six-player hand needs 90 cryptographic transactions and 7.9M compute units. The deployed poker program, which passes every account inline, splits verification over three transactions: a round is 14 transactions and about 1.44M compute units, and a six-player hand at most 126 cryptographic transactions and 12.6M compute units. Around the cryptography we build a validity-first enforcement layer: timeouts that any player can resolve by piggybacking on their own move under a virtual clock, SOL-only seat bonds with slashing, whistleblower proofs against key sharing, a second, independently written verifier that backs re-verification fraud proofs, and permanent table freezes on invariant violations. We state the security definitions and give theorems with proof sketches for deck privacy against any coalition that excludes one honest player, soundness of the dealt cards, accountability of every stall, and the fee and chip invariants. We also describe the red-team methodology behind them: more than a thousand named attack tests, per-instruction mutation batteries, coverage-guided and stateful fuzzing, and misbehaving-client runs on a local fork of the chain. Finally, any third party can verify a finished hand: an independent verifier, running natively or in the browser, re-derives the hand from plain chain data and re-checks every key, shuffle and share proof, the privacy of every hole card, the announced cards and the payouts. It trusts the chain's data but not the RPC node that serves it. The program publishes a count and a digest of every step of the hand when it settles, so a node that omits transactions can make verification fail but never pass. To our knowledge this is the first system to verify a transparent shuffle argument (Bayer–Groth) natively inside Solana programs.

More figures

  • Dealing approaches for a card game on a public chain and the guarantees each gives. Commit–reveal and on-chain randomness make the deck public once it is used; a server, enclave or committee can hold or reconstruct it; a SNARK-wrapped shuffle needs a trusted setup; optimistic checking needs a watcher and a window. Mental poker with a transparent shuffle argument verified on chain is the only path that gives all five at once.
    Fig. 1Dealing approaches for a card game on a public chain and the guarantees each gives. Commit–reveal and on-chain randomness make the deck public once it is used; a server, enclave or committee can hold or reconstruct it; a SNARK-wrapped shuffle needs a trusted setup; optimistic checking needs a watcher and a window. Mental poker with a transparent shuffle argument verified on chain is the only path that gives all five at once.
  • System architecture. Each seat's client performs every cryptographic duty and submits signed transactions with proofs; the mp_poker program verifies them on chain through the curve and hash syscalls. An independent hand verifier rebuilds a finished hand from JSON-RPC data alone and trusts the node only to return authentic data.
    Fig. 2System architecture. Each seat's client performs every cryptographic duty and submits signed transactions with proofs; the mp_poker program verifies them on chain through the curve and hash syscalls. An independent hand verifier rebuilds a finished hand from JSON-RPC data alone and trusts the node only to return authentic data.
  • The shuffle chain. Starting from the public trivial deck, each seat permutes and re-encrypts every card with fresh randomness and proves it with a Bayer–Groth argument; the program verifies each round on chain before it becomes the next round's input and stores its commitment.
    Fig. 3The shuffle chain. Starting from the public trivial deck, each seat permutes and re-encrypts every card with fresh randomness and proves it with a Bayer–Groth argument; the program verifies each round on chain before it becomes the next round's input and stores its commitment.
  • The hand protocol as a sequence of Solana transactions, from start_hand to settlement. Shuffle rounds run in seat order; decryption shares for the hole cards and the board come from every seat, folded or not.
    Fig. 4The hand protocol as a sequence of Solana transactions, from start_hand to settlement. Shuffle rounds run in seat order; decryption shares for the hole cards and the board come from every seat, folded or not.
  • A full nine-seat table at preflop. memepoker runs as a native 3D client (a Rust app on NEO, the lab's Bevy fork) with real chip physics, and the same game compiles to WebAssembly for the browser and WebXR.
    Fig. 5A full nine-seat table at preflop. memepoker runs as a native 3D client (a Rust app on NEO, the lab's Bevy fork) with real chip physics, and the same game compiles to WebAssembly for the browser and WebXR.
  • The view from your own seat, over your avatar's shoulder: your two hole cards and the Fold / Call / Raise action bar. Your wallet is your seat.
    Fig. 6The view from your own seat, over your avatar's shoulder: your two hole cards and the Fold / Call / Raise action bar. Your wallet is your seat.