HMAC is the keyed hash that turns your seeds into an item when you open a box on a provably fair site. Picture a wax seal that only closes when you press a secret ring into it. Anyone can see the seal and confirm it is intact, but only the ring that made it could have made that exact shape, and no one can forge a matching seal without the ring. HMAC works the same way. It mixes a secret key with a message and stamps out a fingerprint that could only have come from that exact pair. On a provably fair pull, the site's server seed is the secret ring and your client seed and play count are the message, so the roll that decides your item is a stamp neither side can fake.
Why a plain hash is not enough
A plain hash like SHA-256 takes any input and returns a fixed-length fingerprint. It is one way, so you cannot run it backward, and it is deterministic, so the same input always gives the same output. That is enough to commit to a server seed up front: the site hashes its secret and shows you the fingerprint, and later you check the revealed seed still produces it. If you want the full picture of that commit-and-reveal step, the what is a server seed guide walks through it.
But a plain hash has no secret in it. If a result were just SHA-256 of your client seed and a play count, anyone who knew those two public values could compute the outcome, and nothing would tie the result to the site's committed secret. You need a hash that folds in a private key, so the fingerprint proves the holder of that key produced it. That is exactly what HMAC adds.
What HMAC actually is
HMAC stands for hash-based message authentication code. It is a standard way, defined in RFC 2104, to build a keyed fingerprint on top of an ordinary hash function. You give it two things, a secret key and a message, and it returns a hash that depends on both:
- The key is the secret. Whoever holds it can produce a valid stamp, and no one without it can.
- The message is the public data you are stamping.
Under the hood, HMAC does not just glue the key and message together and hash them once. It mixes the key into the data, hashes that, then mixes the key in a second way and hashes again. That two-pass design is what makes it hard to forge, and it is why every serious provably fair system reaches for HMAC rather than a bare hash. The common form on box sites is HMAC-SHA256, which uses SHA-256 as the inner hash and returns 64 hexadecimal characters. Some sites use HMAC-SHA512 instead, which is the same idea with a longer output. The choice between them is a detail the SHA-256 vs SHA-512 guide covers, and it does not change how the stamp is used.
How HMAC decides your pull
On a provably fair box opening, three inputs go into the stamp:
- The server seed, the site's secret, committed as a hash before you play. This is usually the HMAC key.
- Your client seed, a value tied to your account that you can change whenever you want.
- The nonce, a play count that ticks up by one each time you open, so every pull in a sequence is different. The what is a nonce guide explains why that counter matters.
The site combines your client seed and the nonce into the message, runs HMAC with the server seed as the key, and gets a hex fingerprint. That fingerprint is not your item yet. The site takes a slice of it, reads that slice as a number, and scales the number into a roll that maps to an item. Same key, same message, same fingerprint, same roll, every single time. That determinism is the whole point: it is what lets you recompute the result later and confirm nothing moved.
A worked example
Here is the general flow with real values, reusing the same example from the server seed guide so the numbers line up:
server seed (the HMAC key, revealed after):
8f2a1c9e4b7d0a63f5e8c2b1a4d7906e3c8b5f2a1e9d4c7b0a6f3e2d1c8b5a49
client seed: player-chosen-seed
nonce (play count): 42
message = "player-chosen-seed:42"
HMAC-SHA256(key = server seed, message)
= 7f7c47d46f21aa75eebcad01075ecec0f30e7e3b093969e75ca4a1e0b6aa286d
take the first 8 hex characters: 7f7c47d4
read them as a number: 2,138,851,284
scale into a 0 to 100 roll: 49.7990
Read it top to bottom: two public inputs and one secret key go in, HMAC produces the long fingerprint, a slice of that fingerprint becomes a number, and the number becomes a roll that lands on an item. Change any one input by a single character and the fingerprint changes completely, so the roll changes too. There is no step in the middle where a person picks the result. The math does, and the same inputs always produce the same output.
Turning the fingerprint into a roll
The HMAC output is 64 hex characters, which is far more than a roll needs, so the site uses only a slice of it. In the example it takes the first 8 characters, 7f7c47d4. Hex is base sixteen, so those 8 characters read as a single whole number, 2,138,851,284. That number is large but bounded: 8 hex characters can only ever land between zero and 4,294,967,295, which is 16 to the eighth power minus one. Dividing the number by that ceiling gives a fraction between zero and one, and multiplying by 100 stretches it onto a 0 to 100 scale, which is where the 49.7990 roll comes from.
Different sites slice and scale differently. Some read the first 5 or 13 hex characters instead of 8, some divide by a power of two, and some map the number straight onto a ticket range so it lands on a specific item rather than a percentage. What stays constant is that the slice is taken from a fixed position in a fingerprint that is itself fixed by the inputs. Nothing in this step is random or chosen. It is arithmetic on a value that HMAC already pinned down, which is why two people running the same numbers always reach the same item.
Why the key is what makes it fair
The reason HMAC anchors fairness is that the key is committed before your part of the message exists. The site generates its server seed, hashes it, and shows you that hash up front. Only then do you set or receive your client seed and start opening. So at the moment the site locked in its secret, it could not have known your client seed, and therefore could not have aimed a specific roll at you.
It cuts the other way too. You cannot forge a favorable roll, because you do not hold the key. Without the exact server seed, you cannot produce the HMAC fingerprint that a given roll came from, and a plain hash of the public parts would not match what the site committed to. Two independent inputs, one of them a secret key fixed in advance, is what makes the outcome something both sides are bound to and neither can steer. This is also why any tool claiming to predict a future pull is a scam: the roll cannot be computed until the server seed is revealed, and that only happens after you have already played.
Different sites, the same shape
The example above shows the most common arrangement, the server seed as the key and your client seed plus nonce as the message, joined with a colon. The exact recipe is not identical everywhere, and the differences are small but real. Some sites join the seeds with a hyphen instead of a colon, and some place the client seed before the server seed. A few use the combined string of game, seeds, and nonce as the HMAC key with an empty message, rather than putting the message where you might expect it. Others swap SHA-256 for SHA-512, or take a longer slice of the fingerprint before converting it to a number.
These are the kinds of per-platform details that a verifier has to get exactly right, because a colon where a site used a hyphen produces a completely different roll and a false mismatch. The shape is always the same though: a keyed hash over committed inputs, sliced into a number, mapped to an item. Once you understand that shape, every site's variation is just a different label on the same machine. The full walkthrough of how the pieces fit together lives in the what is provably fair guide.
Check it yourself
You do not have to take any of this on faith. Once the server seed is revealed, you can run the exact HMAC computation on your own device and compare it to what the site showed you. The verifier below does that. Paste in the revealed server seed, your client seed, and the play count, and it recomputes the fingerprint, slices it, and maps it to the roll, without sending anything you type anywhere.
Step 1Where did you play?
Using Ripster box / upgrade: HMAC-SHA256 over clientSeed:noncedetails
HMAC-SHA256 keyed with the server seed over clientSeed:nonce. The first 8 hex characters become a 32-bit integer, divided by 2^32 and multiplied by 100 for a roll in [0, 100). Items are sorted by item ID and selected by cumulative probability: the first item whose cumulative probability is at least the roll wins.
Where to find your numbers on Ripster.gg:
- Before rolling, copy the Server Seed Hash from the Provably Fair modal (also recorded per roll in Account History).
- After the roll, open the Provably Fair modal to copy the Server Seed, Client Seed and Nonce.
- Change your Client Seed anytime in Account Settings; doing so reveals the current Server Seed so all past rolls become verifiable.
Source: Ripster.gg's own fairness page
Step 2Paste your numbers
Runs entirely on your device via your browser's built-in cryptography. Don't take our word for it: open DevTools → Network, click the button, and watch: zero requests.
Runs entirely in your browser. Nothing you paste is sent anywhere.
If the recomputed roll matches the one you were given, the result came from the inputs that were committed before your pull, and nothing was changed after the fact.
The short version
HMAC is a keyed hash. It folds a secret key into a message and stamps out a fingerprint that only that exact pair could produce. On a provably fair pull, the server seed is the key, your client seed and play count are the message, and the fingerprint is sliced into a number that decides your item. Because the key was committed before your seed existed and you never hold it, neither side can forge or steer the roll, and anyone can recompute it to confirm. That is the whole reason the box opening can be checked instead of trusted.