v2.8 · RNG PRE-SUBMISSION PACKAGE v1.2
RAIN RNG · PRE-SUBMISSION PACKAGE v1.2 · DOCUMENT

DOCS/LAB-READINESS — GLI-19 §3 POINT BY POINT

Source sdk-v2/docs/LAB-READINESS.md · commit 96368332 · GLI CSR §2.2: Readiness · ← package index · raw on GitHub ↗

RAIN RNG v2.1 — test-lab readiness (GLI-19 chapter 3, RNG)

An honest point-by-point map of the GLI-19 "Interactive Gaming Systems" RNG requirements (chapter 3 in GLI-19 v3.0; the same substance appears in GLI-11 §3 and most jurisdictional RNG standards) to what this SDK does, what only a lab can attest, and what is the operator's problem, not ours. Section numbers below follow GLI-19 v3.0 headings by topic; check the exact numbering against the lab's edition — we describe requirements, not clause IDs.

Status summary: the design satisfies every RNG requirement we know how to satisfy in software; none of it is certified. Nothing in this repo has been evaluated by GLI, BMM, iTech Labs, eCOGRA or any regulator. The submission package is in lab/ (lab/README.md index, mapped to GLI CSR v2.0 §2.2): RNG description in GLI-19 §3 vocabulary (lab/RNG-DESCRIPTION.md), statistical report with raw logs (lab/REPORT-STATISTICAL.md, lab/results/), collection tools, scaling inventory, reproducible build + fingerprints, runtime KATs/self-verification in rng-node, process documents. The before/after checklist is docs/LAB-SUBMISSION-REQUIREMENTS.md §7 (HAVE 13 · PARTIAL 5 · MISSING 2 — pen-test and external audit).

# GLI-19 §3 topic (paraphrased) What RAIN does Status
3.1 Scope / applicability — RNG applies to any outcome that affects a wager RAIN provides r per round (256 bits) and the draw layer drbg(r, gameId); every game outcome derives from it and nothing else (the engines take no other randomness — the slot example uses one cursor) ✅ by construction; lab confirms per game
3.2 Statistical randomness — RNG output must pass recognised statistical tests (chi-square, equidistribution, gap, poker, coupon, permutation, runs, spectral, serial correlation…) at 99 % confidence Output is HMAC_DRBG (SP 800-90A) or ChaCha20 over a 256-bit key; both are standard, cryptographically strong PRFs. Pre-certification evidence shipped (self-run, 2026-09-13/14): Dieharder 3.31.1 full battery on an unbounded stream (-g 200, never rewinds): chacha20 90 PASSED / 5 WEAK / 0 FAILED (61 of 80 test/ntuple combinations; rgb_lagged_sum 14–32 not run — ≈ 200 GB), hmac-drbg partial (0 FAILED on the tests run); NIST STS 2.1.2 1000 × 10⁶ bits all 15 tests: both mechanisms 188/188 lines inside the confidence interval, all uniformity P ≥ 10⁻⁴; TestU01 SmallCrush 15/15 both mechanisms (Crush/BigCrush not run — data volume); scaled outcomes 10⁸ per game (chacha20) / 2 × 10⁷ (hmac-drbg) + 3 adversarial-player modes: every total-distribution χ² passes at 99 % — lab/REPORT-STATISTICAL.md, raw logs in lab/results/. Two earlier Dieharder file-input runs that rewound are quarantined as invalid (report §8) 🧪 lab repeats with its own suite on data from lab/tools/collect-raw.mjs / collect-outcomes.mjs (deterministic by seed)
3.3 Unpredictability — it must be computationally infeasible to predict the next output from previous ones draw(i) is a PRF output under a key derived from r; r itself needs both parties' unrevealed secrets; secrets are 256-bit, from Web Crypto / OS CSPRNG (randomBytes32) or wallet-derived material ✅ design; lab reviews source (no third-party crypto; ~400 lines)
3.4 Non-repeating cycle / period — the RNG period must be sufficiently long that cycles cannot be exploited Each round has a fresh 256-bit r; within a round the counter i addresses up to 2^53 (HMAC) / 2^32 (ChaCha) independent draws; chains are consumed once and rotate at 90 % (65,536 default) ✅
3.5 Seeding / background cycling / re-seeding — seeds must be unpredictable; RNG may not be seeded from a fixed value; reseeding must not weaken output Reseed per round, never per session (builder point c): r_k differs for every k and depends on fresh reveals from both chains; the session seed alone predicts nothing. No time-based or fixed seeds. Background cycling is unnecessary and undesirable: outputs are demand-driven by index, and there is no hidden state whose cycle timing could leak ✅ design (GLI's "background cycling" expectation is satisfied by the per-round reseed argument — expect to explain this)
3.6 Scaling / mapping — mapping raw output to the game range must be unbiased; modulo bias is prohibited unless negligible intBelow(i, n): rejection sampling on 32-bit words, exactly uniform for any n ≤ 2^32; float = 53-bit uniform; shuffle = Fisher–Yates with intBelow. Legacy outcomeMod (uint256(r) % N) kept for byte-identity with on-chain verifiers, bias < N/2^256 (negligible under any standard) ✅
3.7 Independence / no correlation between draws or between players Draw i and draw j are different PRF evaluations; different games under one r are domain-separated (`HMAC(r, "RAIN-RNG-v2.1 "+gameId)`); different players have different sessions, seeds and chains
3.8 RNG state / secrets protection — seeds and state must not be observable or modifiable by unauthorised parties Unrevealed chain elements are the only secrets; each party holds only its own; B's are in the RAIN node (rng-node store, in memory + WAL/Postgres). No HSM integration yet ⚠️ partial: operational controls (key storage, access) are the operator's deployment; the reference node is not hardened
3.9 Game outcome must not be altered after generation; no "near-miss"/outcome selection from multiple draws r_k is fixed once hRev_k is revealed; the operator server derives it deterministically; a house cannot re-roll (one reveal per k, enforced by chain + cursor); the player can replay the exact draw sequence ✅ for RAIN; the operator's engine must consume the cursor deterministically (lab checks the engine)
3.10 Persistence / recovery — after a failure the RNG must not repeat or replay outcomes Chains cannot be rewound (k monotone); house persists the client commitment before revealing; rng-node replays the same hRev_k for a duplicate (k, decision, pRev) and refuses a different one (crash test in rng-node/test/crash.test.mjs) ✅ design; operator must run a durable store
3.11 Documentation of the RNG for the lab — algorithm, seeding, scaling, source code lab/RNG-DESCRIPTION.md (GLI-19 §3 order, §3.3.2 a/b/c, proofs), lab/SCALING-INVENTORY.md, lab/BUILD.md + lab/FINGERPRINTS.json; docs/RNG.md; source in packages/rng-core/src, packages/rng-py/rain_rng; KATs: NIST CAVP HMAC_DRBG (32), FIPS 180-4, RFC 4231, RFC 8439 — also executed at runtime by rng-node (startup, daily, /selftest; output inhibited on failure) ✅
3.12 Multiple implementations must be equivalent TS and Python mirrors share generated vectors (drbg-vectors.json, 12 streams × 7 indices, intBelow, shuffle, ceremony); on-chain Solidity verifiers match the TS ceremony (npm run test:live) ✅
3.13 Hardware RNG requirements Not applicable — software RNG; entropy for secrets from the OS CSPRNG (documented) n/a
3.14 RNG for live/multi-player events (shared outcome) Not covered by rng-session; the Live Crash design (per-round chains, interleaved ticks) exists in the channel protocol only ➖ out of scope for v2.1

What the lab will actually test, and what we can give them

  1. Source review — sha256.ts, drbg.ts, keccak.ts, rng.ts (TS), rain_rng/*.py. Zero dependencies, so there is nothing else to review.
  2. Known-answer verification — run npm test -w @rain/rng-core and python3 -m pytest packages/rng-py; add the lab's own CAVP files (the .rsp parser used to embed ours is in the repo history of scripts/).
  3. Statistical suite — node lab/tools/collect-raw.mjs --bits 32e9 --mechanism chacha|hmac --seed 0x… --workers 4 --out raw.bin (production ceremony + drbg(); deterministic by seed; --out - streams for dieharder -g 200 / TestU01) and node lab/tools/collect-outcomes.mjs --game dice|roulette|coin|slot-reel|card-shuffle … for scaled data. Our own runs: lab/REPORT-STATISTICAL.md.
  4. Scaling — intBelow source is 6 lines; the lab can verify the rejection bound.
  5. Game-level — the operator's engine under drbg(r, gameId).cursor(): RAIN does not certify game math, RTP, paytables, reel strips, or how many draws a feature consumes. examples/slot-spin-endpoint/paytable.mjs is a mock.

Known gaps (honest)

  • No certification, no crypto audit, no pen-test. Statistical suites have been run by us (lab/REPORT-STATISTICAL.md) but not by an independent lab.
  • Reference node not hardened (no HSM, no rate limiting beyond what a reverse proxy adds, secrets in process memory).
  • Time-to-reveal is a liveness property, not a safety one: a stalled node cannot bias, but it can stall; the escrow protocol (@rain/channels) turns stalls into faults, rng-session does not.
  • Same-entity A and B (operator runs both) removes the "two independent parties" argument unless commitments are published (RngAnchor.sol / transparency log). Say so in the submission.
  • Player-side verification depends on a client that verifies. A malicious or lazy client that trusts the server has no protection — this is inherent to any provably-fair scheme.
  • 32-bit compat path exists (seed32Compat, deprecated, warns). Labs should confirm it is not reachable in production builds.

← Back to the package index · Rendered 2026-09-14 09:34 UTC from the repository copy; the markdown in the zip / repo is the document of record.