Skip to main content
How are case openings fair?

Information about how case openings are provably fair

Enzo avatar
Written by Enzo
Updated over 11 months ago

The result is generated as soon as a customer clicks to open a 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)

  • 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 four below and click the blue 'eval();' button.
* ------------------ */

$unhashedServerSeed = '';
$nonce = -1;
$clientSeed = '';
$ticketQuantity = -1;

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

if ($unhashedServerSeed == '' || $nonce < 0 || $clientSeed == '' || $ticketQuantity <= 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);
$nrand = strlen($clientSeed);
$stringToHash = "$clientSeed-$nrand-$nonce";

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

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

Openings before April 18th 2024 used this code: https://3v4l.org/CQLj9

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 unhashedServerSeed, nonce, clientSeed & qty variables in the script to verify results.

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

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

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

$unhashedServerSeed = '0ECovoExJzCTJuCKxzvJ3urgDKmOU61hkvkDOUASeE8R4eySoOdDnswdmXAsVuMFnVYZxT6BEYjMvVNa9i5HBofCY1n';
$nonce = 30;
$clientSeed = 'test';
$ticketQuantity = 100000;

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

if ($unhashedServerSeed == '' || $nonce < 0 || $clientSeed == '' || $ticketQuantity <= 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);
$nrand = strlen($clientSeed);
$stringToHash = "$clientSeed-$nrand-$nonce";

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

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 87,664 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?