Sarah Dec 16, 2018

The Advanced Guide to Transparent Card Shuffling on CoinPoker

Until now, online poker rooms have been secretive about their card shuffling software. Players have been unable to verify that these closed systems shuffle the cards in a truly fair manner, and is something CoinPoker’s Transparent Card Shuffler was built to change. Using one-way cryptographic hash functions, CoinPoker’s new card shuffler makes it possible to The Advanced Guide to Transparent Card Shuffling on CoinPoker


Until now, online poker rooms have been secretive about their card shuffling software. Players have been unable to verify that these closed systems shuffle the cards in a truly fair manner, and is something CoinPoker’s Transparent Card Shuffler was built to change.

Using one-way cryptographic hash functions, CoinPoker’s new card shuffler makes it possible to safely disclose information about the shuffling process, and give you the ability to:

Before diving into the technology behind transparent card shuffling, have a look at our brief tutorial to help you test it out for yourself!

How to Use the Validation Tool to Prove Participation

If our transparent card shuffler is totally new to you, we suggest you start by checking out our basic guide with screenshots here.

Step 1: In order to prove the fairness of the hand, you will need to access the one-way hash functions mentioned earlier. You will find these by clicking on the RNG Shuffle Order link in the bottom inside the Hand History Tab.

Step 2: Here you will find a long list of hash sequences. The first section will be for each card in the initial deck order, followed by the encrypted seeds from each player and CoinPoker, and lastly the hashes of each card in final deck order.

Think of the numbers listed under shuffled hashed deck as their position in the deck, and each player hash as their encrypted “shake factor” submitted at the start of the hand.

Step 6: This data is useless without the Validation Tool, which you can access by clicking on the link at the top of the window.

Step 7: The next step is validating the hand, which can mean one of two things depending on whether you would like to:

  1. Verify fairness by proving your participation in the “shaking”
  2. Verify if the actual position of a card in the final deck matches the encrypted position you participated in determining before the shuffle

For Option 1:

Enter the encrypted seeds or “shake factors” as we’ve been calling them into the Validation Tool. These are marked by the blue arrows. The outputs will be the “collective shake factor” or combined hash, and the final deck order.

If they match, then you have successfully verified your participation in the shuffle!

For Option 2:

Choose one of the dealt cards (these will have both a hash on the left and the encrypted hash function on the right. Enter the hash inside the function of the right in the Card Validation section. The output should be the hash listed to the left in CoinPoker, as well as the correct card value.

Step 8: Have fun exploring undealt card and proving your participation in online poker’s first decentralized RNG system!

The Advanced Explanation: How CoinPoker’s Transparent RNG Works

Imagine the deck of unshuffled cards as follows: 2c, Qd, Kh

In reality, there would be a permutation of 52 cards, but to get an idea of how this process works, we will limit the number to three. Using this deck order, CoinPoker will create the initial deck and share it with all players at the table in the following steps.

Step 1

CoinPoker runs its RNG using a secret value, which we will refer to as a seed. This value only exists temporarily and is simply used to get the process started.

Step 2

CoinPoker uses this random seed to generate a salt value; random data that acts as a password or passphrase for one-way cryptographic functions. This is combined with a card to create a hash for each card in the deck. Using the three cards mentioned earlier, the formula would look a little like this:

  • Hash(2c + salt1) = aa
  • Hash(Qd + salt2) = bb
  • Hash(Kh + salt3) = cc

Note: The hashes aa, bb, and cc are simplified for the sake of representation. In reality, they are 256-bit strings and a little trickier to work with; at least for humans.

Step 3

CoinPoker shuffles the hashed deck from Step 2 using the random seed from Step 1.

  • Unshuffled deck in hashes was: aa (2c), bb (Qd), cc (Kh)
  • Shuffled deck (initial deck) in hashes is now: bb (Qd), cc (Kh), aa (2c)

Step 4

CoinPoker sends this hashed deck (as a vector including all the card hashes in the initial deck order) to each player.

The purpose of using the hashes is to make it possible to reveal certain cards from the deck and allow players to verify them, without exposing others that should be kept hidden (i.e. mucked hands). Now all the players have in their possession the list of hashes that reveals initial deck order.

The next steps cover how the initial deck is transformed into the final deck using input from players, which is combined with CoinPoker’s input to form a collective input (a.k.a. aggregate seed). Again, these are referred to as seeds.

Step 5

Again, for the sake of simplifying the complexity of this process, imagine that there are two players at the table. Let’s call them Alice and Bob.

Step 6

Alice and Bob now need to calculate a hash of their seed to send to CoinPoker. The formula will look a little like this:

  • Hash(Alice’s_seed) = XX
  • Hash(Bob’s_seed)  = YY

Step 7

CoinPoker generates a new seed, so not the one from Step 1. This random seed is used to create a hash: Hash(CoinPoker’s_seed) = ZZ

Step 8

The player hash seeds, as well as CoinPoker’s, are then compiled into a list of commitment seeds: [XX, YY, ZZ].

Step 9

CoinPoker sends a vector of commitment seeds to Alice and Bob.

Step 10

After receiving the commitment seeds, Alice and Bob send their real seed from Step 5. This is the seed that was used to create the hashes. So Hash(Alice’s_seed) = XX and Hash(Bob’s_seed) = YY.

Step 11 

The real seeds are then used to create an aggregate seed. This new seed takes into account all player seeds as well as CoinPoker’s resulting in a value that the entire table has contributed to.

Hash(Alice’s_seed + Bob’s_seed + CoinPoker’s_seed) = aggregated_seed

Step 12

CoinPoker uses the aggregate seed to shuffle the initial deck. The hash for the final deck is then distributed to all places. Note that this is the final deck used until the hand is completed.

Initial Deck: Qd, Kh, 2c →  RNG with aggregated_seed → Final Deck: Kh, 2c, Qd
              (Hashescc, aa, bb)

How the RNG Verification Tool Works

One of the key advantages of using cryptographic hash functions is that we are able to safely disclose information about the shuffle, which can later be used to prove if the shuffle was fair. We call this the RNG Validation Tool, and we’ll continue the steps to help you understand how it works.

Note that neither Bob or Alice know each other’s real seeds, and only have access to their own real seed. What they do have access to are all the seed hashes of other players and CoinPoker (remember Steps 8 and 9).

After the hand is played, players receive the real seeds of all participants, which they can use to verify their participation in the final deck shuffle, as well as the randomness of the cards.

Steps 13-18: Verifying Player Impact on the Shuffled Deck

Step 13

First, players need to take each real seed and use it to verify if the hash value they have is correct. They do this by plugging in the real seed into the hash formula, checking if the outcome matches the actual value they received.

If Hash(Alice’s_seed) actually equals XX then it is verified as correct

Step 14

Once all the real seeds from players and CoinPoker are used to verify the hashes,  players can also check if the aggregated_seed is correct by plugging in the missing values into a hash function:

Hash(alice_seed + bob_seed + server_seed) = aggregated_seed

Step 15

Now that the aggregated seed is verified as correct by each player, Alice or Bob can reverse the RNG function. By plugging in the final deck hash and aggregate seed to compute the initial deck, players can check if it results in the same initial deck order that they received in Step 4.

Step 16

 If the result matches the initial deck hash order, then the player has successfully proven that they participated in shuffling the final deck.

Proving participation is just the start. Players can also verify the randomness of the cards in the final deck. This can be done for all community cards and hands revealed by other players (so no Mucked hands), but for the sake of explaining we will show you how you can verify the fairness of the first two cards:

Step 17

Once the hand is over, players receive (in addition to all the real seeds) the salts and values of the first two cards dealt. Note that card values  and salts were used in the Hash function from Step 2:

Hash(Kh+salt3) = cc

Step 18

Now that Alice and Bob have values for all the variables in the hash function, they can reverse it to confirm if the Kh was the actual first card in the final deck shuffle received in Step 12.

If Hash(Kh+salt3) results in cc, then the player confirms that the final deck hash cc is correct. This can be done for any revealed cards on the table.

In the case of undealt cards or mucked hands, players will not receive a card value or salt. They will have access to the hashes, but won’t be able to use this method to reveal them.

Expert Explanation and the 1,000,000 CHP Bug Bounty

While the above explanation may be advanced enough for your average poker player, it would only cover the tip of the iceberg for cryptography enthusiasts. Below are links to the original protocol document, as well as the open source code on GitHub:

In the spirit of transparency, we are also offering 1,000,000 CHP to anyone who can prove the transparent card shuffling system faulty. For more details on bounty conditions and how to claim, view our official Bug Bounty page here.