We play CUBE Backgammon too, and knowing how the dice work does not make an opponent’s third double any more welcome. It is especially hard to shrug off a run like that when one of those rolls has just hit your last exposed checker.

It is easy to remember the hit that turned a game around and overlook the uneventful rolls around it. A run of doubles can also seem exceptional when a long game has given it many chances to occur.

Our article on consecutive doubles gives a specific example. Three doubles in three rolls chosen in advance have a chance of 1 in 216. Once you have already seen the first double, the chance of the next two also being doubles is 1 in 36. Both calculations are right; they answer different questions. Watching for a streak throughout a long game gives it many more chances to catch your attention.

That explains one source of suspicion, but it does not establish that any particular app is fair. For CUBE Backgammon, the more useful questions are how the dice are generated and what can be checked afterwards.

From random bytes to six faces

For ordinary games against the computer, CUBE Backgammon starts with random bytes from the device’s cryptographically secure random-number generator. A byte is a number from 0 to 255. We need to convert these numbers into die faces while giving each face the same chance.

There is a small trap in turning those bytes into dice. A byte has 256 possible values, but 256 does not divide evenly by six. Assigning each value to a face using only the remainder after division would give four faces 43 possible values each and the other two only 42.

We discard the four values from 252 to 255 and use the remaining 252. Each face then has exactly 42 possible values. Discarding and trying again is called rejection sampling; it avoids adding a bias while converting a uniform byte stream into six faces.

252 accepted values: 42 for each face
142
242
342
442
542
642

Die face above, number of values below. The four remaining values are discarded.

Two accepted values make a roll. There are six ways to roll a double among the 36 ordered dice pairs, so doubles have a chance of 1 in 6. There is no rule saying they must appear once in each group of six rolls, or that a player who has had several should now receive fewer.

A fixed sequence can still come from randomness

Rather than asking for a completely new random source every turn, an ordinary computer match starts with a seed: a value from which the whole sequence can be reproduced. The app combines its random contribution with the time of your press on Start, then uses SHA-256, a standard cryptographic hash function, to derive the dice stream.

The sequence generator takes that seed as its input. The board position, the difficulty setting and the computer’s need for a particular number are not inputs to it. Choosing a harder opponent changes how it plays its rolls.

Reproducible does not mean hand-picked. Think of shuffling a deck, recording its order, then dealing it. Once shuffled, the order is fixed, but it can still have been chosen randomly. The important questions are how the initial choice was made and whether the sequence was subsequently changed.

Before the first roll, the app also calculates a digital fingerprint of the seed, called a commitment. Revealing the seed later allows that fingerprint to be recomputed. This is one ingredient of a verifiable record, although where and when the fingerprint is made available matters too.

What you can replay after a game

For recorded ordinary computer matches, the Dice statistics panel keeps a recent dice record. After a match is completed or abandoned, you can inspect its seed, fingerprint and ordered rolls, and use Verify to check the record. Guided teaching examples and the fixed dice used for calibration are separate from these ordinary random games.

The replay regenerates the sequence from the revealed seed and compares it with the rolls in the record. It also checks the seed’s fingerprint and the boundaries between games. Changing a recorded die without changing the seed makes that comparison fail.

The example below independently implements the published dice algorithm. You can replay its example seed, change a recorded roll, or enter a seed and roll list from a completed match. It checks the listed prefix of the sequence in your browser; it does not load your match history or send the values to us.

Replay a sequence

Same seed, same rolls. This example displays the first eight rolls from the sample seed.

Example calculated from the seed cube-dice-example.

The first eight rolls of the sequence

  1. 1Roll 1: 1, 4
  2. 2Roll 2: 4, 4
  3. 3Roll 3: 4, 3
  4. 4Roll 4: 3, 3
  5. 5Roll 5: 3, 2
  6. 6Roll 6: 6, 6
  7. 7Roll 7: 5, 5
  8. 8Roll 8: 1, 1
Fingerprint of the last regenerated seedcf29dd9f3513b834311bbc5e1ca1029730bd9f02fc3af98b82697754e5bfb84a

A replay checks consistency with a seed, not how that seed was chosen. Replay seed replaces the list with eight regenerated rolls.

Replaying is a useful check, with a specific limit

A matching replay establishes that a list of rolls is consistent with a seed. By itself, it cannot establish that the program chose that seed honestly in the first place. A program could theoretically search many seeds before choosing one and still produce a perfectly consistent replay.

A stronger public protocol would make the original commitment available before an independent player contribution, retain both contributions and allow someone outside the app to verify the whole exchange. Our current after-game record and in-app Verify button do not provide that complete guarantee. We do not describe them as an independent audit or a public proof that cheating is impossible.

The same distinction applies to the statistics panel. Counting faces, doubles and differences between players can reveal a programming mistake over enough rolls. A short sample looking balanced does not prove fairness, and an unbalanced evening does not prove cheating.

What we check in development

We test the conversion of bytes into faces, including every accepted byte and the rejection of the four unused values. We also compare generated sequences with independently calculated examples, check that saved records replay correctly, and deliberately alter records to make sure verification rejects them.

Those checks address different failure modes: biased conversion, a changed algorithm, a damaged record or a sequence that cannot be reproduced. Statistical checks supplement them, rather than replacing the direct checks of the mechanism.

The same dice can still leave you with very different positions depending on how you move your checkers. CUBE Backgammon’s coach helps you compare those choices during the game and review them afterwards.

The description of CUBE Backgammon’s ordinary match dice and receipt checks was checked against the app’s implementation. The browser replay here is a separate reference implementation, not an audit of the app. The W3C Web Cryptography specification documents the platform random source; libsodium’s random-data documentation explains why uniform conversion needs to avoid modulo bias.

The replay algorithm

For algorithm sha256-rejection-v1, hash the UTF-8 strings seed:0, seed:1, seed:2 and so on with SHA-256, concatenating their digest bytes. Skip bytes 252–255; turn each remaining byte into a face with (byte modulo 6) + 1, then pair consecutive faces. The fingerprint is SHA-256 of the seed itself. The demo accepts up to 4,096 rolls, checks the listed prefix and, if supplied, its fingerprint. It does not check an app receipt’s metadata or game boundaries. It describes ordinary computer matches, not the server protocol for online play.