moonbitstack / moonseed · the bench
Two panels, both running this library compiled to wasm. The page gathers the bytes and lays the result out; every number it shows was computed inside that module — the mask, the comparisons and the value itself. Nothing here draws a number in JavaScript.
A draw at or above the bound is thrown away whole, and the next one is taken.
below(bound) reads the bound as a big-endian number and draws as many bytes
as bound - 1 needs. The unused high bits of the first byte are cleared, and
the draw is turned into a number. If that number is below the bound it is the answer;
if it is not, the whole draw is discarded and another takes its place.
What comes back is as wide as the bound, so a bound of b"\x03\xe8" answers
with two bytes, not an Int. A bound that is a power of two never pays for
the loop: the mask already fits.
Below, the pool is filled once from the platform's own source, and every call starts at its front — so pressing twice on the same bound shows the same draws twice.
The tray is empty. Press draw to fill it with the bytes of one call.
—
Sixty-six bytes for a P-521 key, with seven bits shifted out of every draw.
scalar(order) returns a value in [1, order - 1], as wide as the
order. The order of P-521 is 521 bits, which is 66 bytes with seven bits to spare: the
draw is shifted right by seven rather than masked, so a byte at the bottom becomes a
value in the low place, and the answer keeps the order's width.
The two red cells below are the only place a value can reach: the first byte's top seven bits are clear, and the last byte holds what was shifted out.
scalar over a fresh replay. A draw of zeros, or one at or above
the order, is discarded and taken again — the panel shows the answer, not the attempts.
No scalar yet.