Verify the dice
Everything runs in your browser. Nothing is sent anywhere. You can save this page and use it offline.
How the dice work
- Key. Before the game the app takes 32 random bytes from the phone's cryptographic generator. This is the secret key of the game.
- Fingerprint. Before the first roll the app shows SHA-256 of the key — a sealed envelope. Finding another key with the same fingerprint is practically impossible, so the rolls cannot be changed afterwards.
- Roll number i (from 0, the opening roll included) = HMAC-SHA256(key,
narde-v1|phrase|i). Bytes 252–255 are skipped; every other byte b gives a dieb mod 6 + 1, so all six faces are exactly equally likely. The first two dice are the roll. If a block has fewer than two usable bytes (chance ≈ 10−55), the next one is…|i|1. - After the game the key is revealed. Its SHA-256 must equal the fingerprint, and the rolls computed from it must equal the roll log in the app. The computer's level never touches the dice.
Check without our site
You do not have to trust this page. The algorithm uses only standard SHA-256 and HMAC, available in every programming language.
Python (any computer, nothing to install):
import hashlib, hmac
key = bytes.fromhex("PASTE THE KEY")
phrase = "PASTE THE PHRASE"
print(hashlib.sha256(key).hexdigest()) # must equal the fingerprint
for i in range(60):
mac = hmac.new(key, f"narde-v1|{phrase}|{i}".encode(), hashlib.sha256).digest()
print(i, [b % 6 + 1 for b in mac if b < 252][:2])
CyberChef — an open tool by GCHQ that runs in the browser: gchq.github.io/CyberChef.
Add the operation HMAC, key type Hex, paste the key, function SHA256; type narde-v1|phrase|0 as input. Read the result two hex digits at a time: skip fc, fd, fe, ff; convert the rest to a number, take the remainder after dividing by 6 and add 1.
Test example
Key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, phrase test:
fingerprint 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd roll 0: HMAC c0a03654… → c0 = 192 → 192 mod 6 + 1 = 1; a0 = 160 → 5 → 1-5 roll 1: HMAC 1b6b74e5… → 1b = 27 → 4; 6b = 107 → 6 → 4-6 roll 2: HMAC 32c986d4… → 32 = 50 → 3; c9 = 201 → 4 → 3-4
The same example is checked by the app's automated tests, so the app, this page and the Python script always agree.