###### Random Number Generation

For each bet being checked, we use: client seed, server seed, nonce and cursor as input parameters for the random number generation function.
The function uses the ** HMAC_SHA256 ** cryptographic hash to generate bytes, which are then used as the basis for how we generate reliably random results on our platform.

```
// Random number generation based on following inputs: serverSeed,
// clientSeed, nonce and cursor
function byteGenerator({ serverSeed, clientSeed, nonce, cursor }) {
// Setup cursor variables
let currentRound = Math.floor(cursor / 32);
let currentRoundCursor = cursor;
currentRoundCursor -= currentRound * 32;
// Generate outputs until cursor requirement fullfilled
while (true) {
// HMAC function used to output provided inputs into bytes
const hmac = createHmac('sha256', serverSeed);
hmac.update(`${clientSeed}:${nonce}:${currentRound}`);
const buffer = hmac.digest();
// Update curser for next iteration of loop
while (currentRoundCursor < 32) {
yield Number(buffer[currentRoundCursor]);
currentRoundCursor += 1;
}
currentRoundCursor = 0;
currentRound += 1;
}
}
```

###### Server seed

The server seed is generated by our system in the form of a random string of 32 characters before the start of the game, which you cannot recognize until it is completed. The reason why we do not provide you with a server seed at any time is that in this case the player would be able to calculate the results of the games in advance.

###### Client seed

The client seed is owned by the player and is used to ensure that the player also influences the randomness of the generated results. Without this component of the algorithm, only the server seed will have a complete influence on the result of each bet.
All players are free to edit and change their client side regularly to create a new chain of random upcoming results. This ensures that the player has absolute control over the generation of the result, like cutting a deck in a regular casino.
During registration, your browser creates a client seed to ensure the smooth operation of the site. Although this randomly generated client seed is considered appropriate, we strongly recommend that you choose your own so that your influence is included in randomness.
You can do this in your profile settings.

###### Nonce

Nonce is simply a number that increases by 1 with every new bet you make. Due to the peculiarities of the SHA256 cryptographic function, a completely new result is created each time.
The implementation of nonce ensures that we remain committed to your client and server pair, while at the same time generating new results for every bet made.

###### Cursor

We use 4 bytes of data to generate one game result. Since SHA256 is limited to 32 bytes, we use this cursor implementation to enable us to create more game events without having to change our provable honesty algorithm.
The cursor is iterated only when the game requires more than 8 (32 bytes / 4 bytes) possible results. For example: when we need to use more than 8 cards in a blackjack game.
The cursor starts at 0 and increments by 1 each time 32 bytes are returned by the HMAC_SHA256 function. If we do not need more than 8 random numbers to be generated for game events, the cursor does not increase because there is no need to generate any additional possible game results.

###### Floating point bytes

The result of the random number generator (byteGenerator) function is a hexadecimal 32-byte hash.
As explained in the cursor implementation, we use 4 bytes of data to generate one game result.
Each set of 4 bytes is used to generate floating point values ranging from 0 to 1
(4 bytes are used instead of one to provide a higher level of accuracy when generating floating point numbers.)
It is with these generated numbers that we get the formal result of the provable honest 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)
);
};
```

###### Floating point numbers in game events

Since the random number generation process is universal for all our games,
It is at this stage of the generation of the game result that a unique procedure is implemented,
allowing you to determine the transfer from a floating point number to game events.
A randomly generated result is multiplied by the possible remaining results of a particular game.
For example: in a game that uses a deck of 52 cards, this can be done by simply multiplying the number by 52.
The result of this equation is then converted to the corresponding game event.
For games where multiple game events are required, this process continues every 4 bytes in the result chain,
which was generated using the described byteGenerator function.

###### Shuffle game events

For games like Keno, Mines, and Video Poker, where the results cannot be duplicated, we use the random shuffling algorithm Fisher Yates .

Game events are the translation of randomly generated numbers into the corresponding game-specific result.
This includes everything from the outcome of a roll of dice to the order of the cards in the deck, or even the location of each bomb in Mines.
The following is a detaiseed explanation of how we translate numbers into events for each specific game on our platform.

###### Blackjack, Hilo & Baccarat

There are 52 unique possible outcomes in the standard deck of cards:

```
// Index of 0 to 51 : ♦2 to ♣A
const CARDS = [
♦2, ♥2, ♠2, ♣2, ♦3, ♥3, ♠3, ♣3, ♦4, ♥4,
♠4, ♣4, ♦5, ♥5, ♠5, ♣5, ♦6, ♥6, ♠6, ♣6,
♦7, ♥7, ♠7, ♣7, ♦8, ♥8, ♠8, ♣8, ♦9, ♥9,
♠9, ♣9, ♦10, ♥10, ♠10, ♣10, ♦J, ♥J, ♠J,
♣J, ♦Q, ♥Q, ♠Q, ♣Q, ♦K, ♥K, ♠K, ♣K, ♦A,
♥A, ♠A, ♣A
];
// Game event translation
const card = CARDS[Math.floor(float * 52)];
```

###### Diamonds

When playing Diamonds, there are 7 possible outcomes in the form of diamonds. To achieve this, we multiply each floating-point number by 7,
and then translate it into the corresponding diamond:

```
// Index of 0 to 6 : green to blue
const GEMS = [ green, purple, yellow, red, light_blue, pink, blue ];
// Game event translation
const gem = GEMS[Math.floor(float * 7)];
```

Then the player receives 5 diamonds.

###### Dice

In our version of the Dice game, we cover the possible throw spread from 00.00 to 100.00,
which has a range of 10,001 possible results.
Translation of game events is performed by multiplying the floating point number by the number of possible results,
and then divide by 100 so that the resulting number matches the limits of our declared range of dice.

```
// Game event translation
const roll = (float * 10001) / 100;
```

###### Limbo

When it comes to Limbo, we use a two-step process.
Firstly, we take the number and multiply it by the maximum possible multiplier and by% of the casino advantage.
Then, to generate a game event using the probability distribution ,
we divide the maximum possible factor by the result of the first step to create a game event in the form of a final coefficient.

```
// Game event translation with houseEdge of 0.99 (1%)
const floatPoint = 1e8 / (float * 1e8) * houseEdge;
// Crash point rounded down to required denominator
const crashPoint = Math.floor(floatPoint * 100) / 100;
```

###### Plinko

For any Plinko game, the generated result is based on which cell the ball will fall into.

`const bucket = Math.floor(float * (pins + 1));`

###### Roulette

Our roulette is taken from the European version of the game, in which the wheel consists of 37 different possible pockets in the range from 0 to 36.
A game event is calculated by multiplying the number by 37, and then transferred to the appropriate pocket:

```
/ Index of 0 to 36
const POCKETS = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36 ];
// Game event translation
const pocket = POCKETS[Math.floor(float * 37)];
```

###### Keno

Traditional Keno games require a selection of 10 possible game events in the form of cells on the game board.
To achieve this, we multiply each floating-point number by the number of unique squares possible.

```
// Index of 0 to 39 : 1 to 40
const SQUARES = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40 ];
const hit = SQUARES[Math.floor(float * 40)];
```

The implementation of a random Fisher-Yates sequence is used to prevent duplication of possible hits.

###### Mines

Mines consists of 24 separate game events in the form of mines on the playing field.
Each number is multiplied by the number of possible unique tiles still remaining on the board.
Cell locations are constructed using the grid position from left to right, from top to bottom.
The implementation of a random Fisher-Yates sequence is used to prevent duplication of possible hits.
Depending on the selected settings, 2 to 24 results of game events are used.

###### Video Poker

Playing Video Poker includes 52 individual game events in the form of cards in the deck.
Each number is multiplied by the number of possible cards remaining in the deck.

```
// Index of 0 to 51 : ♦2 to ♣A
const CARDS = [
♦2, ♥2, ♠2, ♣2, ♦3, ♥3, ♠3, ♣3, ♦4, ♥4,
♠4, ♣4, ♦5, ♥5, ♠5, ♣5, ♦6, ♥6, ♠6, ♣6,
♦7, ♥7, ♠7, ♣7, ♦8, ♥8, ♠8, ♣8, ♦9, ♥9,
♠9, ♣9, ♦10, ♥10, ♠10, ♣10, ♦J, ♥J, ♠J,
♣J, ♦Q, ♥Q, ♠Q, ♣Q, ♦K, ♥K, ♠K, ♣K, ♦A,
♥A, ♠A, ♣A
];
// Game event translation
const card = CARDS[Math.floor(float * 52)];
```

The implementation of a random Fisher-Yates sequence is used to prevent duplication of possible hits.