Skip links

Provable Fairness – Blackjack

Provable Fairness – Blackjack

This blog post explains how the game results are randomly generated on Peergame Blackjack.

In order to create a random order of cards, we first need a random number. We use the hash of two components, Daily Seed and Unique TDID, and Javascript seedrandom library to create a random number. Then, we use Fisher-Yates Shuffle Algorithm to generate the order of cards.

Daily Seed

Daily Seed is a Hashchain of secret keys provided by us:

DayN Seed = Hash(Secret Key)

Day(N-1) Seed = Hash(DayN Seed)

Day2 Seed = Hash(Day3 Seed)

Day1 Seed = Hash(Day2 Seed)

*Daily Seed is disclosed 48 hours after its use.



TDID(Table Deposit ID) is created using the hash of game, round number, and client seed(paymail):

  • TDID = HASH(“game”||”round”||”client seed”)


SHA256("blackjack991889cd19fc45") = "c7527e1791e7af0594606da80aaf5dcade6e0eeb9be7db2a81e34e9db6bd5032"
    • Game: blackjack
    • Round: 9918
    • Client Seed: 89cd19fc45
      • Client Seed is the first 10 alphanumeric characters from the hash of user’s Paymail address
    • TDID: c7527e1791e7af0594606da80aaf5dcade6e0eeb9be7db2a81e34e9db6bd5032

Reference: SHA256 Hash Calculator:


Hash of Daily Seed & TDID + Javascript Seedrandom

Using the hash of these two components, we generate a random number using Javascript seedrandom library:

Random Number = SHA256(Daily Seed || TDID)


  • Daily Seed of Round 9918: 9e1271ea93b65f9e5854b56a994bbf76105d0b94722ba721bb07301c641c2e8e
  • SHA256(Daily Seed || TDID) = “ac1c2506ce00006d41bc6686dbe959d320ce671b5c6cc99b56a19776d84be894”


*Specifically, we use seedrandom release 3.0.5 from PRNG(Pseudo Random Number Generator) library


Random Number + Fisher-Yates Shuffle Algorithm

After generating the random number, we use Fisher-Yates Shuffle Algorithm to generate the order of cards for every round.

var seedrandom = require('seedrandom'); // Using Javascript Library to generate a verifiable Random Number
const deckCount = 4; // 4 card decks. 208 cards total

// Initial Deck: Number order 'A, 2, 3, ..., Q, K', Pattern order 'C, D, H, S'.
// ex)1st card: AC, 2nd card: 2C, 52nd card: KS, 53rd card: AC
static getInitialDeck(deckCount) {
    const deck = [];
    for (let i = 0; i < deckCount; i += 1) {
      for (const pattern of Card.patterns) {
        for (const number of Card.numbers) {          
          deck.push(new Card(pattern, number));

    return deck;

static shuffle(seed, deckCount) {
    return this.fisherYates(seed, this.getInitialDeck(deckCount));

static fisherYates(seed, initialDeck) {
    const shuffledDeck = Object.assign(initialDeck);

    var rng = seedrandom(seed);

    for (let i = initialDeck.length - 1; i > 0; i -= 1) {
      const index = Math.floor(rng() * i);

      // swap
      const tmp = shuffledDeck[index];
      shuffledDeck[index] = shuffledDeck[i];
      shuffledDeck[i] = tmp;
    return shuffledDeck;



Result of card shuffle from the example

  • Card { id: 145, pattern: ‘S’, number: ‘3’, color: ‘B’ },
  • Card { id: 111, pattern: ‘C’, number: ‘8’, color: ‘B’ },
  • Card { id: 18, pattern: ‘D’, number: ‘6’, color: ‘R’ },
  • Card { id: 77, pattern: ‘D’, number: ‘K’, color: ‘R’ },
  • Card { id: 37, pattern: ‘H’, number: ‘Q’, color: ‘R’ }

Using the Fairness Calculator

Peergame provides Fairness Calculator that displays all the information mentioned above neatly into a single table. Simply insert the bet TxID, which can be found on your Game History page, and all the necessary information will automatically fill up.

Using the information given here, anyone can verify the results.