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 10 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?