Decent Dice (Entropy Lab) — 2D rigid-body physics drop simulation running client-side. Decent DiceI built an interactive, browser-based physics entropy simulator called
Decent Dice to explore how chaotic rigid-body dynamics, material contact physics, and timer jitter combine to generate high-entropy raw bitstreams for cryptographic key derivation:
Simulator Link: https://mixoftix.net/workshops/entropy_lab_decent_dice.aspHow the Physics & Entropy Model WorksInstead of pulling directly from a single static PRNG call, the simulator models a 2D square die falling and bouncing under configurable environmental and physical parameters:
- Material & Contact Physics: Models restitution, surface friction, and adhesion across 4 die materials (plastic, wood, metal, rubber) and 6 surface materials (wood, carpet, glass, metal, rubber, felt).
- Environmental & Initial State Space: Incorporates temperature (°C), humidity (%), altitude (km, dynamically adjusting gravity g), drop height (m), initial angular velocity (rad/s), initial top face, and a millisecond Timer / Counter jitter factor routed through selectable noise mixers (trigonometry, xor-xor-mix, mix-mix-xor, tri-mix-xor, xcs-tri-xor).
- 100% Client-Side Execution: Everything executes locally inside the browser—zero data is ever transmitted to a server. Full session parameters can also be exported and re-imported for deterministic replay and auditing.
The Math: Covering the secp256k1 KeyspaceA valid Bitcoin private key lies in the range
[1, n - 1] where
n ≈ 1.1579 × 10^77 (
256 bits of security). To avoid keyspace collapse, the raw entropy source must comfortably exceed 256 bits of Shannon entropy before key derivation:
- Single Die Drop (d6): Yields log2(6) ≈ 2.585 bits of entropy per outcome (requiring at least ⌈256 / 2.585⌉ = 100 independent rolls to reach 256 bits).
- Default Batch Run (16 Sequences × 10 Batch Size = 160 Drops):
— In Dice mode (1–6): 6^160 ≈ 3.17 × 10^124 possible sequences, equal to ~413.6 bits of combinatorial state space.
— In Hex mode (0–f): 16^160 = 2^640 ≈ 4.56 × 10^192 possible sequences, providing 640 bits of raw output space—more than 2.5× the 256-bit secp256k1 scalar field. - Initial Condition Sensitivity: Because rigid-body corner impacts amplify tiny variations in drop height, angular spin, restitution, and timer jitter across multiple bounces, slight perturbations in initial physical parameters diverge into completely different trajectory histories.
Key Derivation & Educational Companion ToolThe output of this simulator should be treated strictly as
raw entropy, not as a raw private key directly. For converting extracted dice sequences into valid elliptic-curve private keys (
secp256k1 /
secp256r1), raw rolls should be passed through a standard Key Derivation Function (such as
PBKDF2-HMAC-SHA512 with a user-supplied salt,
HKDF, or
BIP-39) inside a trusted offline environment.
You can explore how base-6 conversion and salted
PBKDF2-HMAC-SHA512 (200,000 iterations) map raw dice sequences onto valid
secp256k1 scalars in our companion client-side demonstration tool:
Dice to Private Key (Entropy Lab): https://mixoftix.net/workshops/entropy_lab_dice_to_prvkey.aspSample Physics Simulation Telemetry LogEach die drop records the timer-driven parameter offsets, rigid-body trajectory steps (
Time, X, Y, Theta, Vx, Vy, Omega), impact events, and final settled orientation:
================================================
DICE DROP – INITIAL PARAMETERS
================================================
Simulator profile : WEB_JS_64BIT
Label mode : dice
Random mode : weak
Noise mode : trigonometry
Timer (ms) at drop : 188168
Counter at drop : 1711
Noisy factor : 0.910981
Geometric faces --> Labels:
Face 0 --> 4
Face 1 --> 5
Face 2 --> 2
Face 3 --> 3
================================================
Actual noise applied (timer-driven):
Angle offset : -1.402°
Spin offset : 0.507 rad/s
Height offset : 0.0077 m
Restitution offset: -0.0074
Friction offset : -0.0057
Adhesion offset : 0.0051
Altitude offset : -0.45 km
Time offset : 0.798 s
================================================
Initial geometric top face : 0
Initial label on top : 4
Initial label on bottom : 2
Drop height (center) : 1.4077 m
Unified_Math.PI : 3.141592653589793°
Base angle : 3.14°
Initial angle : 178.60°
Initial spin (Omega) : 9.907 rad/s
Dice material : rubber
Surface material : felt
Temperature : 31.0 °C
Humidity : 52.0 %
Altitude : 32753 km
Gravity (g) : 0.2601 m/s²
Simulation time (requested): 23.6 s
Simulation time (effective): 24.40 s
Effective restitution : 0.590
Effective friction : 0.379
Effective adhesion : 0.262
================================================
JS_titles: Time, X, Y, Theta, Vx, Vy, Omega
JS_zoom_out: 0.00000,0.00000,1.40772,3.12703,0.00000,-0.00026,9.90691
JS_zoom_out: 0.05000,0.00000,1.40737,3.62237,0.00000,-0.01327,9.90691
JS_zoom_out: 0.10000,0.00000,1.40638,4.11772,0.00000,-0.02627,9.90691
JS_zoom_out: 0.15000,0.00000,1.40473,4.61306,0.00000,-0.03928,9.90691
JS_zoom_out: 0.20000,0.00000,1.40244,5.10841,0.00000,-0.05229,9.90691
JS_zoom_out: 0.25000,0.00000,1.39949,5.60376,0.00000,-0.06530,9.90691
JS_zoom_out: 0.30000,0.00000,1.39589,6.09910,0.00000,-0.07830,9.90691
.
.
JS_trigger: [settled 100 < 100] / [speed] 0.09598 < 0.2 / [Y] 0.02543 < 0.02550
JS_zoom_XD: 12.23050,-0.99459,0.02541,29.86278,-0.06479,-0.05534,0.21718
JS_impact+: 12.23050,-0.99459,0.02544,29.86278,-0.06476,-0.05527,0.21456
JS_trigger: [settled 101 < 100] / [speed] 0.09587 < 0.2 / [Y] 0.02544 < 0.02550
JS_titles: Time, X, Y, Theta, Vx, Vy, Omega
JS_settled: 12.23050,-0.99459,0.02544,29.86278,-0.06476,-0.05527,0.21456
================================================
RESULT
================================================
Simulation time : 12.23 s
Final theta (radians) : 29.86278230894412
Final geometric top face : 1
Final label on top : 5
Final label on bottom : 3
Final angle : 271.0°
================================================
>>> TOP FACE SHOWS: 5 <<<
================================================
-- Feedback on the physics model, noise-mixing modes, and statistical distribution (
Dice vs.
Hex vs.
Bin output streams) is very welcome!