How to verify a case opening result
Checking a case opening takes five inputs and about two minutes. You need the hashed server seed you saw before opening, the revealed server seed, your client seed (or, for battles, a block hash), the nonce, and the box's ticket ranges. This guide uses Packdraw's published method as the worked example, because its fairness page shows the full code, then covers how CSGORoll and Skinrave differ.
Step 1: record the commitment before you open
Before opening anything, note the hashed server seed. Packdraw shows it in your account profile and says it is the SHA-512 hash of the server seed. Skinrave shows the active seed in red while it is still hashed. Copy the hash somewhere outside the site, with the date. This is the step people skip, and it is the one that makes the rest meaningful.
Also note your client seed. On Packdraw and CSGORoll you can set it yourself. Pick something you choose, not the default.
Step 2: open, then reveal the seed
Open your box or case. To verify, the site must reveal the server seed. Packdraw says it exposes the unhashed seed after purchase. On Skinrave and CSGORoll's Roll game, the seed is revealed when you change your client seed, which starts a new seed pair.
Find the opening in your history. You need the server seed, client seed and nonce for that specific opening. The nonce is a counter that starts at 0 and goes up by 1 for each opening on the same seed pair, so a five-box multi-open uses five nonces.
Step 3: check the hash matches
Hash the revealed server seed and compare it with what you recorded in step 1. Packdraw uses SHA-512 for this. If the two do not match, stop: the result cannot be trusted, and you should keep your notes and contact support.
Our SHA-256 hash generator covers SHA-256 sites. For SHA-512, use the Node.js snippet below or any local tool.
Step 4: recompute the ticket
Packdraw's fairness page publishes this function. It joins the client seed, server seed and nonce with colons, takes SHA-512 of that string, reads the hex as one large integer, and keeps the remainder after dividing by 1,000,000. Adding 1 gives a ticket from 1 to 1,000,000.
const crypto = require('crypto');
const sha512 = (v) => crypto.createHash('sha512').update(v).digest('hex');
function ticket(clientSeed, serverSeed, nonce) {
const hash = sha512(`${clientSeed}:${serverSeed}:${nonce}`);
return Number((BigInt('0x' + hash) % 1000000n) + 1n);
}
const serverSeed = '4f1c9a7e2b6d8035c1e9f7a4b2d6083e5c7a9f1b3d5e7092c4a6b8d0e2f41357';
console.log(sha512(serverSeed).slice(0, 16)); // compare with the hash you recorded
for (let n = 0; n < 3; n++) console.log(n, ticket('maple-leaf-77', serverSeed, n));
We ran it with those example seeds. The hash starts 39b562dbe6b54d6b, and the three tickets are:
| Nonce | Ticket |
|---|---|
| 0 | 674,184 |
| 1 | 910,929 |
| 2 | 231,914 |
Change the seeds and nonce to your own and run it with Node.js. Each run gives the same output for the same inputs, which is the point.
Step 5: map the ticket to the item
Each item in a box owns a range of tickets that matches its odds. Packdraw says the ranges are visible in the pack details. Take an example $25 box:
| Item value | Odds | Tickets |
|---|---|---|
| $1,000 | 0.4% | 1 to 4,000 |
| $100 | 5% | 4,001 to 54,000 |
| $30 | 20% | 54,001 to 254,000 |
| $12 | 35% | 254,001 to 604,000 |
| $5 | 39.6% | 604,001 to 1,000,000 |
Ticket 674,184 lands in the $5 range, ticket 910,929 too, and ticket 231,914 lands in the $30 range. If the site showed you a different item for one of those openings, the result does not match the published method.
While you have the table open, check two more things. The ranges should cover exactly 1 to 1,000,000 with no gaps or overlaps. And the expected value is easy to compute: 1,000 x 0.004 + 100 x 0.05 + 30 x 0.20 + 12 x 0.35 + 5 x 0.396 = $21.18, so this box returns about 84.7% of its price on average.
Battles: verifying with a block hash
In battles, Packdraw replaces your client seed with the hash of a future block on the EOS blockchain, chosen when the battle starts. Skinrave and CSGORoll do the same. To verify, you need the block number the site committed to, then the hash of that block from a public EOS block explorer. Use that hash in place of the client seed and recompute.
Packdraw's jackpot battles work differently. Each player gets a range of raffle tickets in proportion to their share of the pot. The winning ticket is SHA-256 of the block hash, read as an integer, modulo the total number of tickets, plus 1. The player whose range contains it wins.
Check that the block was in the future when the battle was created. If the block number was chosen after the block existed, the result could have been known in advance.
How other sites differ
CSGORoll. For newer games, CSGORoll generates a server seed per game, publishes its SHA-256 hash, and commits to a future EOS block number before the game starts. It links to a verifier you can run in the browser. For its Roll game, it takes SHA-512 of the seeds and nonce, reads the first five hex characters as a number, skips to the next five if the value is above 10,000, and divides by 100 to get a roll from 0 to 99.99. Older games used a 10-million-long SHA-256 hash chain and older RNG versions, and the page lists which nonces each version covers.
Skinrave. Skinrave publishes code for each game. Battles draw tickets from 0 to 9,999 using the server seed, a future EOS block id, the slot number and the round number. For solo games, change your client seed to reveal the old server seed, then verify with the seeds and nonce from your history.
Why a check fails
- Wrong nonce. Multi-opens use several nonces. Count from the first opening on that seed pair.
- Wrong order of inputs. Packdraw's string is client seed, then server seed, then nonce. Swapping them changes everything.
- A rotated seed. If you changed your client seed between openings, each group uses a different server seed.
- Changed ranges. Box contents and odds can be updated. Screenshot the box page at the time you open.
- A real mismatch. If none of the above explains it, keep the hash you recorded, the revealed seed and your screenshots, and raise it with the site.
For the general method across casino games, see our guide to verifying a provably fair bet.
To see which sites publish a method you can check this way, read provably fair mystery box and case opening sites.
Sources
- Packdraw fairness page: https://packdraw.com/fairness
- CSGORoll provably fair page: https://www.csgoroll.com/info/provably-fair/
- Skinrave fairness page: https://skinrave.gg/en/fairness
- NIST FIPS 180-4, Secure Hash Standard: https://csrc.nist.gov/pubs/fips/180-4/upd1/final
- Node.js crypto documentation: https://nodejs.org/api/crypto.html
Key terms
- Provably fair
- A cryptographic method that lets you confirm a game result was set before your bet and left untouched afterwards.
- Server seed
- The casino's secret random value that, together with your client seed and the nonce, decides each bet result.
- Hashed server seed
- The SHA-256 digest of the casino's secret server seed, published before any bet as proof the seed is locked in.
- Client seed
- The player's own input to every provably fair result, set or edited by you so the casino cannot work out outcomes in advance.
- Nonce
- A bet counter that goes up by one for each wager on the same seed pair, so no two bets share a result.
- Seed rotation
- Swapping the active server seed for a fresh one, which discloses the old seed so you can verify its bets.
- SHA-256
- A cryptographic hash that maps any input to a fixed 256-bit digest; casinos use it to commit to server seeds.
- Mystery box
- A box sold at a fixed price that reveals one item at random from a published list of items and odds.
- Case battle
- A mode where several players open the same cases or boxes and the highest total value usually takes all the items.