Provably Fair

Bytes to Floats

The output of the Random Number Generator (byteGenerator) function is a hexadecimal 32-byte hash. As explained under the cursor implementation, we use 4 bytes of data to generate a single game result. Each set of 4 bytes are used to generate floats between 0 and 1 (4 bytes are used instead of one to ensure a higher level of precision when generating the float.) It is with these generated floats that we derive the formal output of the provable fair algorithm before it is translated into game events.

// Convert the hash output from the rng byteGenerator to floats
function generateFloats ({ serverSeed, clientSeed, nonce, cursor, count }) {
  // Random number generator function
  const rng = byteGenerator({ serverSeed, clientSeed, nonce, cursor });
  // Declare bytes as empty array
  const bytes = [];

  // Populate bytes array with sets of 4 from RNG output
  while (bytes.length < count * 4) {
    bytes.push(rng.next().value);
  }

  // Return bytes as floats using lodash reduce function
  return _.chunk(bytes, 4).map(bytesChunk =>
    bytesChunk.reduce((result, value, i) => {
      const divider = 256 ** (i + 1);
      const partialResult = value / divider;
      return result + partialResult;
    }, 0)
  );
};

Floats to Game Events

Where the process of generating random outputs is universal for all our games, it's at this point in the game outcome generation where a unique procedure is implemented to determine the translation from floats to game events.

The randomly float generated is multiplied by the possible remaining outcomes of the particular game being played. For example: In a game that uses a 52 card deck, this would simply be done by multiplying the float by 52. The result of this equation is then translated into a corresponding game event. For games where multiple game events are required, this process continues through each corresponding 4 bytes in the result chain that was generated using the described byteGenerator function.

Shuffle of Game Events

For games such as Keno, Mines and Video Poker, where outcomes cannot be duplicated, we then utilise the Fisher-Yates shuffle algorithm. This procedure influences the conversion process from floats to game events because each time a game event is translated, the amount of possible remaining game event possibilities has been reduced for any remaining steps in the result chain.

As an example, in video poker, there is at first 52 cards available in the complete deck, and therefore the first game event is translated by multiplying the float by 52. Once this card has been dealt, there is only 51 remaining cards in the deck, and therefore the second card translation is done by multiplying the second float generated by 51. This continues in the same fashion until all the game events required have been generated.

With regards to Mines and Keno, this is simply a matter of implementing the same process as explained with video poker but changing that to tiles or locations on the board or grid, ensuring that each game event generated, hasn’t already been done so beforehand in the chain of results.