# The Keywright

URL: https://nader.io/projects/keywright/

Five dice decide the anatomy of one key. The anatomy decides the door. There are 7,776 doors, all of them real in the way that a thing you have not checked is real. Nobody gets to choose which one you get.

[Rolled with superandom](<https://github.com/ncserny/superandom>) · [Why the weather didn't make the cut](<https://nader.io/posts/randomness-doesnt-come-from-the-weather/>) · [The serious demo](<https://nader.io/projects/superandom>)

## The cast

cast 0

 or press Space

## Registry entry

unfiled

The ledger is waiting.  
No key has been cast.  
The door, presumably, is fine.

no key yet  
the blank is on the bench

## The ledger

0 distinct of 7,776

empty

## Entropy bench

cold

The dice are not rolled by `Math.random()`. Every face comes from `superandom.randomInt(1, 7)`, drawn from a pool your own hand fills and then XOR-folded with a fresh `crypto.getRandomValues()` mask. Move the mouse and watch the estimate climb.

0 of 256 credited bits

| Source | Events | Credited |
| --- | --- | --- |

Waiting for the library.

## What this is

A toy on top of a real library. Each cast takes five draws, and each die is a rejection-sampled `randomInt` rather than a `% 6`, because the modulo shortcut is biased whenever the range doesn't divide the source's cardinality. Over 7,776 outcomes that bias would be entirely invisible to you and entirely present in the ledger, which is the whole reason the library does it properly.

The entropy your hand contributes does not make the dice fairer. It cannot: the output is already platform-grade from the first millisecond. What it buys is an independent source and a receipt saying where the numbers came from. That argument is [written up here](<https://nader.io/posts/randomness-doesnt-come-from-the-weather/>), and the library is [on GitHub](<https://github.com/ncserny/superandom>).
