How our RNG works and how you can verify it yourself
An honest, technical look at the random number generator behind our poker tables, the certification process it passed, and the daily proofs you can audit independently.
By The Ultimate Poker Team
The most important thing an online poker site can do is shuffle cards honestly. If we get that wrong, nothing else matters: not the software, not the promotions, not the rake. Fortunately, “shuffle cards honestly” is a solved problem — there is a well-understood toolkit for doing it, and well-understood ways for outsiders to verify that it is being done.
This post is a technical look at how our RNG works, what certifications it has, and — most importantly — how you can verify our deals were not tampered with after the fact, without trusting us.
It is the longest and most detailed post we will publish on this topic. If you are looking for marketing copy, the security page has a friendlier version. This one is for the readers who want the actual details.
What “random” means in this context
The cards we deal need to satisfy three properties:
- Unpredictable: nobody, including us, should be able to predict the next card before it is dealt.
- Uniform: each remaining card in the deck should be equally likely to be the next one drawn.
- Verifiable after the fact: once a hand has been dealt, the deal should be auditable so that we cannot claim a different shuffle happened than what actually did.
Different RNG designs trade these properties against each other. Online casinos historically have done (1) and (2) well but were weak on (3) — you had to take their word that the deal you saw was the deal that happened. The modern provably-fair approach fixes that.
The pieces of our system
Our RNG is built from three components, in this order:
1. A hardware entropy source
The base layer is a hardware random number generator — specifically, an Intel RDRAND-backed entropy source on our deal servers, supplemented by the Linux kernel’s /dev/urandom pool which mixes in environmental sources (timing jitter, network interrupts, etc.). RDRAND is built on thermal noise inside the CPU and is, as far as anyone has been able to demonstrate, genuinely unpredictable.
Why hardware? Software pseudo-RNGs are deterministic — given the same seed, they produce the same output. If an attacker could learn the seed, they could predict every future card. Hardware RNGs do not have this property; the seed is constantly being refreshed from a physical process.
We do not trust any one source alone. RDRAND is mixed with /dev/urandom, which is itself mixed with hardware timing samples, by feeding everything into a SHA-512 hash. Even if any one source were compromised, the others would still provide entropy. This pattern — multiple independent entropy sources, mixed cryptographically — is the standard for serious deployments.
2. A cryptographic PRNG
The hardware entropy is then used to seed a cryptographic pseudo-random number generator (CSPRNG). We use ChaCha20, which is a stream cipher with extremely well-studied randomness properties. The CSPRNG is what actually drives card draws, because hardware entropy is slow and cryptographic PRNGs can produce a much higher rate of high-quality random output.
The CSPRNG is reseeded from hardware entropy on every hand. So even if there were a flaw in the CSPRNG (there isn’t one known), it could only affect the cards of a single hand — it can’t compound across hands.
3. The Fisher-Yates shuffle
To turn a stream of random bytes into a shuffled deck, we use the Fisher-Yates algorithm. It is the standard way to produce a uniformly random permutation of a list, and the correctness proof is short enough to fit in a stats textbook. We use the modern in-place variant, drawing each random index from the CSPRNG.
Importantly, we do not shuffle the deck once and then deal — we shuffle a fresh deck for every hand. This is the same as a live dealer producing a fresh shuffle for every hand. It eliminates the entire class of attacks that depend on partial information about a previous deal.
Certification
The whole stack is certified by iTech Labs, one of the major independent testing labs in the gaming industry. iTech audited:
- The source code of the shuffle algorithm
- The integration with the hardware RNG
- The statistical properties of millions of generated shuffles
- The deployment configuration on our production servers
- Our key-management and incident-response procedures
The certificate is available on our security page and is updated annually.
iTech’s tests include the standard NIST SP 800-22 randomness test suite (15 separate tests covering things like frequency, runs, autocorrelation, and serial correlation), Diehard, and several others. We pass all of them.
The provably-fair part
Here is where it gets interesting, and where you can actually do something with the information instead of just taking our word for it.
For every hand we deal, we generate a “server seed” and “client seed” before any cards are revealed. The shuffle is determined by:
final_seed = SHA256(server_seed + client_seed + hand_id)
Before the hand starts, we publish SHA256(server_seed) — that is, the hash of our seed, not the seed itself. We cannot change server_seed later, because doing so would change the hash, and we already committed to a hash.
After the hand is over, we publish server_seed (the actual value, not the hash). You can:
- Hash the published
server_seedand verify it matches the pre-committed hash. (Proves we didn’t substitute the seed after the fact.) - Combine
server_seed, yourclient_seed(which is generated client-side and which we cannot influence), andhand_id, and reproduce the exact shuffle yourself. - Confirm that the cards you saw match the cards the algorithm produces.
If our committed hash doesn’t match, or if the cards we dealt don’t match the cards the algorithm produces from the public seeds, we are caught immediately and publicly.
This is called a commit-reveal scheme, and it’s the same primitive used in serious provably-fair casino games. The math is simple — the hash is a one-way function, so we can prove we committed to a particular value without revealing it, and we can later open the commitment by publishing the original value.
Daily deal-log hashes
In addition to per-hand provably-fair seeds, we publish a daily hash of the previous day’s complete deal log. At 00:00 UTC, we compute SHA-256 over the entire log of every hand dealt the previous day and publish that hash on a public location (currently a chain of timestamped tweets and a GitHub repo).
This means that if you record a hand history during the day, and the daily hash later doesn’t include your hand, we are caught. Conversely, if we tried to retroactively change a hand we already dealt, the daily hash would no longer match the original, and that mismatch would be visible to everyone.
This is a belt-and-suspenders measure. The per-hand commit-reveal already protects you. The daily hash makes the protection harder to subvert in subtle ways.
What this does not protect against
Honest disclosure: there are a few things even a perfect RNG cannot defend against.
- Collusion between players. Two players sharing hole cards can win unfairly without ever touching the RNG. We have a separate detection system for this.
- Bot play. Bots play the cards they’re dealt; they don’t need to compromise the RNG. We detect bots via behavioral analysis.
- Operator dishonesty about which hands a player sees. The RNG might be honest, but if we deliberately deal worse cards to certain players, we could rig results that way. The commit-reveal protects against this: the seed is committed before we know who is at the table, so we cannot tailor a shuffle to a player.
If you’re worried about the third one, the commit-reveal verification is your tool. We genuinely cannot rig hands without being detectable, given how the protocol works.
How to actually verify a hand
If you want to do this:
- After a hand completes, go to your hand history and click “Verify shuffle.”
- The page shows: the pre-committed hash, the revealed server seed, the client seed, and the hand ID.
- You can verify locally — either by clicking the in-page “verify” button (which runs the math in your browser using audited open-source code), or by running our open-source CLI tool which performs the same computation independently.
- The result is either “matches” (we dealt what we committed to) or “MISMATCH” (we did not, and you should immediately escalate).
We genuinely encourage you to do this occasionally, especially on big pots. The whole point of provably-fair is that it works because players actually verify, not because the operator promises it works.
Source code and audit
The shuffle code, including the commit-reveal protocol, is open-source and available on our GitHub. The version running in production is built from a public commit hash, which is published on the security page. The build artifact’s checksum is also published.
This means a sufficiently determined auditor can:
- Pull the source code at the commit we claim is running.
- Build it themselves.
- Compute the checksum and confirm it matches what we published.
- Confirm what is running in production matches.
This is not standard in our industry. We think it should be.
Summary
- Our entropy comes from hardware (RDRAND + kernel pool), mixed via SHA-512.
- A ChaCha20 CSPRNG drives the Fisher-Yates shuffle. The deck is shuffled fresh every hand.
- Every hand uses a commit-reveal protocol so you can verify the shuffle yourself.
- Every day’s complete deal log is hashed and publicly published.
- The whole thing is certified by iTech Labs and the source code is open.
If any of this turns out to be wrong, please tell us. We mean that. Our abuse address goes to a real human and we take any plausible report of RNG misbehavior very seriously.
Trust isn’t earned by claiming to be honest. It’s earned by being checkable.