Cryptographically-secure random number service for casino games — dice, slots, deck shuffles, provably-fair commit/reveal.
Rust 1.95ChaCha20axum tokio4 shards100k req/test passed
Single-source RNG for our gaming platform. One Rust process with four independent
ChaCha20Rng shards, each seeded from the OS entropy pool
(getrandom, 32 bytes). Round-robin balancing distributes incoming
requests across shards via an atomic counter, so contention scales with shard count.
getrandom (Linux's getrandom(2) syscall — kernel CSPRNG, not /dev/urandom).rand::Rng::gen_range) — no modulo bias, output uniform across the requested interval.
A separate 32-byte server_seed is generated up-front and never sent to clients.
POST /api/commit returns sha256(server_seed) — clients store this hash before the round.
POST /api/reveal returns the original seed and rotates to a fresh one;
the result is sha256(server_seed | client_seed | nonce) — fully reproducible by the player.
Every endpoint except /api/health requires a bearer token:
Authorization: Bearer <RNG_TOKEN>.
| Parameter | Value |
|---|---|
| Concurrent backend connections | 10 |
| Requests per connection | 1,000 |
Random numbers per request (count) | 1,000 |
| Endpoint | POST /api/range |
| Total HTTP requests | 10,000 |
| Total numbers delivered | 10,000,000 |
| Wall time | 4.71 s |
| Errors | 0 |
| Numbers / second | 2,125,035 |
| p99 latency | 6.93 ms |
What this means in game terms (at 2.12 M numbers/s): ~424,000 slot spins/s (5 reels) · ~2.12 M roulette rounds/s (1 number/round) · ~40,000 deck shuffles/s (52-card Fisher-Yates). More than two orders of magnitude above the load any operator below the global top-10 would generate.
10,000 HTTP requests against POST /api/range with 1,000 numbers per request — 10 million numbers total.
Concurrency=10 reflects how a real backend client would batch RNG calls. Loopback, sharded service.
100,000 HTTP requests with 1,000 simultaneous open connections — saturation scenario. Latency here reflects HTTP queue depth (Little's Law: 1,000 inflight ÷ 2,600 rps ≈ 385 ms wait), not RNG cost.
Shard distribution after the stress run was perfectly even — 250,000 calls per shard (round-robin AtomicUsize, no skew). Raw RNG core throughput measured separately at ~4.1M numbers/s on count=4096 batches.
Sample of 8,192,000 full-range i64 values collected via the API and analysed with the
industry-standard ent tool. Expected values for a perfect CSPRNG in parentheses.
| Metric | Value | Ideal | Verdict |
|---|---|---|---|
| Entropy (bits/byte) | 7.999997 | 8.000000 | PASS |
| χ² distribution (bytes) | 268.11 (p=27%) | ~256 ± 22 (p≈50%) | PASS |
| Arithmetic mean (bytes) | 127.4924 | 127.5000 | PASS |
| Monte Carlo π estimate | 3.142322 (err 0.02%) | 3.141593 | PASS |
| Serial correlation | 0.000022 | 0.000000 | PASS |
| Bit entropy (bits/bit) | 1.000000 | 1.000000 | PASS |
Six core NIST tests applied to the same sample. P-values above 0.01 indicate the sequence is statistically indistinguishable from random.
| Test | P-value | Verdict |
|---|---|---|
| Frequency (Monobit) | 0.78381 | PASS |
| Block Frequency (M=128) | 0.53391 | PASS |
| Runs | 0.39613 | PASS |
| Longest Run of Ones (M=10000) | 0.45846 | PASS |
| Cumulative Sums (forward) | 0.96053 | PASS |
| Cumulative Sums (reverse) | 0.81903 | PASS |
Quick chi-square goodness-of-fit on a small sample to verify range generation is unbiased.
| Face | Count | Frequency |
|---|---|---|
| 1 | 8,148 | 16.30 % |
| 2 | 8,400 | 16.80 % |
| 3 | 8,261 | 16.52 % |
| 4 | 8,412 | 16.82 % |
| 5 | 8,337 | 16.67 % |
| 6 | 8,442 | 16.88 % |
χ² = 7.44 with 5 degrees of freedom — well below the 11.07 threshold (95% confidence). Uniform distribution confirmed.
u64 from the next round-robin shard.{min,max,count} — returns count integers in [min,max] (max 4096 per request, unbiased).{count} — array of f64 in [0,1).{deck:[…]} — Fisher-Yates shuffle of the input array.sha256(server_seed) + server_seed_id. Use before each round.{client_seed,nonce} — reveals the seed, computes sha256(seed | client_seed | nonce), rotates to a fresh seed.curl -s -X POST https://rnd.alphapari.com/api/range \
-H "Authorization: Bearer $RNG_TOKEN" \
-H "Content-Type: application/json" \
-d '{"min":1,"max":36,"count":5}'
// response will appear here