Skip to main content
All CollectionsGamemodesXP & bonuses
How are bonus cases fair?
How are bonus cases fair?

Information about how bonus cases are provably fair

Enzo avatar
Written by Enzo
Updated over 7 months ago

The result is generated as soon as a customer clicks to open a bonus case. There are 5 variables that are used for this generation:

  • Server seed (A cryptographically secure pseudo-randomly generated string - Example: FmLhRSyET7sLqv77j2CYdFKX5svdBNjuD96GgwKTyklJVsyeN8rxPP5il0cXSy8Lna9N5uiylI25MMa2fv65Q1r4696llhbT)

  • Nonce (A number that is incremented every time the seed is used - Example: 1)

  • Client seed (A user-defined (or random by default) string - Example: wesdioufrhjrwe80u54230ihn5234iuj5340i)

  • Case number (The number of the case, this increments depending on the case tier - Example: 2)

  • Quantity (The number of tickets available in a case, 1 item = 10,000 tickets - Example: 80,000)

For the server seed, this is hashed until the customer re-generates a new one here: https://csgoempire.com/fairness via the ‘Info’ tab:

For the client seed, customers can determine what’s entered here. This can be edited to the customer’s liking here: https://csgoempire.com/fairness via the ‘Info’ tab:

For the case number and quantity, this can be found by clicking on the case type like so:

The result is then given out to the customer using the spinner. The spinner has no say over the actual result, it’s a purely visual way of displaying the pre-generated outcome.

To verify previous results, customers can use the following PHP script:

<?php
/*
* Fill in all five below and click the blue 'eval();' button.
* ------------------ */

$numberOfCase = -1;
$unhashedServerSeed = '';
$nonce = -1;
$clientSeed = '';
$qty = -1;

/* ------------------ */

if ($numberOfCase < 0 || $unhashedServerSeed == '' || $nonce < 0 || $clientSeed == '' || $qty <= 0) {
echo "Fill in details";
return;
}

define('MAX_HEX_SEGMENTS', 6);
define('HEX_SEGMENT_SIZE', 2);
define('BASE_FOR_HEX_CONVERSION', 256);
define('HASH_TYPE', 'sha256');

function calculateDecimalValue(string $preResult): float
{
$decimalValue = 0;
for ($i = 0; $i < MAX_HEX_SEGMENTS; $i++) {
$hexValue = substr($preResult, HEX_SEGMENT_SIZE * $i, HEX_SEGMENT_SIZE);
$decimalValue += hexdec($hexValue) / pow(BASE_FOR_HEX_CONVERSION, $i + 1);
}
return $decimalValue;
}

function getProvablyFairResult(string $init, string $serverSeed, int $qty): array
{
$preResult = hash_hmac(HASH_TYPE, $init, $serverSeed);
$decimalValue = calculateDecimalValue($preResult);
$result = (int) ($decimalValue * $qty) + 1;
return [
'preResult' => $preResult,
'result' => $result,
];
}

$unhashedServerSeed = preg_replace( "/\r|\n/", "", $unhashedServerSeed);
$clientSeed = preg_replace( "/\r|\n/", "", $clientSeed);
$stringToHash = "$clientSeed-$numberOfCase-$nonce";

$result = getProvablyFairResult($stringToHash, $unhashedServerSeed, $qty);

echo "Result: {$result['result']}";

Openings between April 18th 2024 and December 5th, 2023 used this code: https://3v4l.org/ecFuT

Openings between December 5th 2023 and December 9th 2019 used this code: https://3v4l.org/urEYG

Openings before December 9th 2019 used this code: https://3v4l.org/P9Qir

This can be run locally or on any PHP script runner found online. We direct customers to: https://3v4l.org/ for this, but there are plenty of options available like so:

The customer will need to edit the caseNumber, unhashedServerSeed, nonce, clientSeed & qty variables in the script to verify results.

This information can be found here: https://csgoempire.com/fairness under ‘Bonus Cases’.

For example, if we run the following script it matches up with the result logged in my bonus case history for my most recent opening:

<?php
/*
* Fill in all five below and click the blue 'eval();' button.
* ------------------ */

$numberOfCase = 0;
$unhashedServerSeed = 'GJciI6l1Eve92F7VpOxOjEzlMZdHYJZVd5ZWIhHpgCun4I8VCjTGuYvQvbxZDQf9PntbAX1Y2InPNBESUz2Is';
$nonce = 612;
$clientSeed = 'ANjPuIY3o6kDLlkViH6e610JECNNLhXK';
$qty = 80000;

/* ------------------ */

if ($numberOfCase < 0 || $unhashedServerSeed == '' || $nonce < 0 || $clientSeed == '' || $qty <= 0) {
echo "Fill in details";
return;
}

define('MAX_HEX_SEGMENTS', 6);
define('HEX_SEGMENT_SIZE', 2);
define('BASE_FOR_HEX_CONVERSION', 256);
define('HASH_TYPE', 'sha256');

function calculateDecimalValue(string $preResult): float
{
$decimalValue = 0;
for ($i = 0; $i < MAX_HEX_SEGMENTS; $i++) {
$hexValue = substr($preResult, HEX_SEGMENT_SIZE * $i, HEX_SEGMENT_SIZE);
$decimalValue += hexdec($hexValue) / pow(BASE_FOR_HEX_CONVERSION, $i + 1);
}
return $decimalValue;
}

function getProvablyFairResult(string $init, string $serverSeed, int $qty): array
{
$preResult = hash_hmac(HASH_TYPE, $init, $serverSeed);
$decimalValue = calculateDecimalValue($preResult);
$result = (int) ($decimalValue * $qty) + 1;
return [
'preResult' => $preResult,
'result' => $result,
];
}

$unhashedServerSeed = preg_replace( "/\r|\n/", "", $unhashedServerSeed);
$clientSeed = preg_replace( "/\r|\n/", "", $clientSeed);
$stringToHash = "$clientSeed-$numberOfCase-$nonce";

$result = getProvablyFairResult($stringToHash, $unhashedServerSeed, $qty);

echo "Result: {$result['result']}";
echo "Result: {$result['result']}";

By clicking onto the case, I can check that the ticket I got falls into the correct range for the item I received:

This helps prove to the customer that we pre-generated the result 10,949 as the result for this spin when they clicked open. If the provably fair script returned a different result, it would be obvious that we manipulated the result compared to what was given out to the customer.

Did this answer your question?