Audit Verdict
The repo is the credential. You don't have to trust us — every finding ships as code. Run npm test to re-run the full audit: 20 verification steps, 40M simulated rounds, 5,100 live bets re-verified.
Keno Audit Overview
This audit independently validates the Keno game operated by Duel.com across five domains: deterministic outcome generation, entropy integrity, live-to-verifier parity, RTP mathematical accuracy, and fairness integrity testing. We placed 5,100 real bets across 102 seed pairs and independently verified every single outcome using our own implementation of the algorithm.
What Was Audited
- The RNG algorithm is deterministic and verifiable
- Server seeds are cryptographically committed via SHA-256 before play
- Client seed is browser-generated and players can customize it
- Nonces increment correctly and are never reused
- Drawn numbers are computed via HMAC-SHA256 backward Fisher-Yates with bias-free rejection sampling
- Draw outcomes are reproducible from server seed, client seed, and nonce
- Payout logic matches the published multiplier tables for all 40 configurations
- Theoretical RTP is 99.9% across all configurations at the base bet tier (0.1% house edge; scales to 1.0% on larger bets — see 4.6b)
- Bet amount does not influence the RNG or draw outcome
- Players can independently verify every bet
What Audit Covers
| Area | Description |
|---|---|
| Commit-Reveal System | SHA-256 server seed hashing, pre-bet commitment, reveal on rotation |
| Client Seed Origin | Player-controlled seed, browser-generated — server commits before your seed is known |
| Seed Handling | Client seed control, nonce lifecycle, seed pair rotation |
| RNG Analysis | HMAC-SHA256 backward Fisher-Yates verification, rejection sampling, bias analysis |
| Payout Logic | Multiplier table accuracy, house edge verification, bet-size invariance (Phase D) |
| Live Parity | Independent draw recomputation vs live game results |
| RTP Validation | Anti-circularity proof, simulated RTP (40M rounds), cherry-pick detection (Pass 2) |
| Fairness Integrity | Standard integrity matrix — 15 tests across commit-reveal, determinism, payout, isolation, and parameter enforcement |
What Audit Guarantees
- Outcomes are deterministic and reproducible from the recorded inputs
- Live game results match independent recomputation for the verified sample (5,100 / 5,100)
- Draw distribution follows the hypergeometric model for all 40 configurations
- RTP is proven analytically: hypergeometric P(hits) × multiplier = 99.9% for all 40 configurations
- Client seed is a genuine, browser-generated input that materially influences results
- The house edge is a flat 0.1% across all 40 configurations at the base bet tier (the tier all captured bets fall in)
- All 15 standard fairness integrity tests addressed at audit time — 14 pass, 1 N/A (single-step game)
What Audit Excludes
- Infrastructure or server security
- Wallet, payments, or operational systems outside game logic
- Rakeback layer — 99.9% is the certified RTP; rakeback is operator-side
- Cross-account sampling
- Max win cap enforcement — not embedded in game logic
References
Keno — Game Rules7 sections▶
Keno is a draw-based lottery game: pick 1–10 numbers on a 40-number grid, choose a risk level, and watch 10 numbers get drawn. The more of your picks that hit, the bigger the payout.
Keno is a draw-based lottery game. Before the round you pick between 1 and 10 numbers from a 40-number grid (your 'picks') and choose a risk level — Classic, Low, Medium, or High — which shapes the payout curve. The platform then draws 10 numbers from the same grid using a backward Fisher-Yates shuffle seeded with HMAC-SHA256. Your payout depends on how many of your picks land in those 10 drawn numbers: more hits means a bigger multiplier, and higher risk levels shift more of the reward toward rare full-hit outcomes.
1. Choose picks — Select between 1 and 10 numbers from the 40-number grid.
2. Choose risk level — Select Classic, Low, Medium, or High. Higher risk shifts payout weight toward rare large hits.
3. Enter bet amount — Choose how much to wager.
4. Draw — The platform draws 10 numbers via the backward Fisher-Yates shuffle.
5. Outcome — Payout = bet amount × multiplier for your hit count.
The win condition in Keno depends on how many of your picks match the 10 drawn numbers.
| Outcome | Condition | Example (HIGH picks=10) |
|---|---|---|
| Jackpot (all hits) | All picks match drawn numbers | 10/10 hits → 1200× — ~1 in 847 million chance |
| Win (partial hits) | Several picks match drawn | 6/10 hits → 13.1× |
| Loss (no hits) | No picks match drawn | 0/10 hits → 0× |
The core mechanic of Keno is the tradeoff between pick count, risk level, and payout shape.
- Pick count controls hit probability — more picks means more chances to match, but multipliers scale accordingly to maintain 99.9% RTP
- Risk level controls payout shape — Classic has moderate variance; High concentrates value at rare full-hit outcomes with 0× on low hit counts
- RTP is constant — all 40 configurations have the same theoretical RTP (99.9%) regardless of picks or risk
| Parameter | Value | Notes |
|---|---|---|
| Grid Size | 40 (numbers 1–40) | Fixed; all draws from this pool |
| Numbers Drawn | 10 per round | Fixed; drawn via backward Fisher-Yates |
| Player Picks | 1–10 | Player selects; determines hit probability |
| Risk Levels | Classic, Low, Medium, High | Affects multiplier table, not drawn numbers |
| House Edge | 0.1% flat | Within the base tier, the same 0.1% edge applies to all 40 configs |
| Theoretical RTP | 99.9% | Verified across all 40 configurations |
| Configurations | 40 | 10 pick counts × 4 risk levels |
| RNG Algorithm | HMAC-SHA256 | Backward Fisher-Yates with bias-free rejection sampling; key = hex-decoded server seed |
Every Keno bet uses three cryptographic inputs to generate the draw result.
| Seed Type | Format | Example | Purpose |
|---|---|---|---|
| Server Seed | 64-char hex (32 bytes) | 94eee14e882d4332… | Casino-provided randomness |
| Client Seed | Alphanumeric string | dAn1wtkuDAXxQOKP | Player-contributed entropy |
| Nonce | Integer (0–49) | 7 | Ensures uniqueness per bet within epoch |
Payouts in Keno are determined by the hit count, pick count, and risk level. The multiplier is calibrated so that the expected return is exactly 99.9% across all 40 configurations.
win_amount = bet_amount × multiplier_table[risk][picks][hits]| Picks | Risk | Max Multiplier (all hits) | Zero-Hit Multiplier | RTP |
|---|---|---|---|---|
| 1 | Classic | 3.996× | 0× | 99.9% |
| 1 | Low | 1.866× | 0.71× | 99.9% |
| 10 | Classic | 200× | 0× | 99.9% |
| 10 | High | 1200× | 0× | 99.9% |
Why Provably Fair Matters▶
Traditional online casinos require players to trust that games are fair. Provably fair systems eliminate this trust requirement by allowing players to mathematically verify that outcomes were not manipulated. In a Provably Fair system:
- The casino commits to a result before the player bets
- The player contributes randomness that the casino cannot predict
- Anyone can verify the outcome after the fact
High-Level Overview8 sections▶
Checklist Reference
Based on the ProvablyFair.org Audit Execution Checklist, here are the tests covered under this audit document.
1. Commit-Reveal System & Seed Handling
| Test | Description |
|---|---|
| Server seed commit exists before play | SHA-256 hash shown to player before betting |
| Server seed reveal matches commit | SHA-256(hexDecode(revealed)) = committed hash |
| Client seed control | Player can set/change client seed via rotation UI |
| Nonce increments correctly | Starts at 0, +1 per bet, resets at epoch boundary |
| Full determinism | Same inputs → same result |
2. Randomness & Entropy Model
| Test | Description |
|---|---|
| RNG depends only on seeds + nonce | No external inputs (drand absent from Keno) |
| No mixed entropy sources | No timestamps, Math.random, etc. |
| Unbiased mapping | Bias-free rejection sampling with maxFair ceiling eliminates modulo bias for all ranges (2–40) |
| No state leakage | RNG isolated per round — each shuffle step uses unique cursor |
3. Verifier ↔︎ Live Parity
| Test | Description |
|---|---|
| Live outcomes match verifier | 5,100 / 5,100 draws recomputed with 0 SET mismatches |
| Multi-phase verification | Phases A (32 configs), B (picks=1), C (picks=10), D (stake equivalence) |
| Bet-size invariance | $10 bets produce same draws as $0.01 bets |
4. Game Logic & RTP Validation
| Test | Description |
|---|---|
| Anti-circularity proof | Hypergeometric P(hits) × committed multiplier = 99.9% — independent probabilities, committed table |
| House edge audit | Flat 0.1% confirmed across all 40 configs at the base bet tier (scaling 0.1%→1.0% by bet size — see 4.6b) |
| Payout rules correctness | Win amount matches multiplier × bet within 1e-8 |
| Simulated RTP convergence | 40M rounds converge on theoretical 99.9% |
| Cherry-pick detection | 57/1,666 flags ≤ 80 threshold — no evidence of seed pre-selection |
5. Fairness Integrity & Player Verification
| Test | Description |
|---|---|
| Player can reproduce results offline | Using seeds + nonce + backward Fisher-Yates |
| Verifier logic matches live logic | Same HMAC-SHA256 backward Fisher-Yates algorithm |
| Verifier publicly accessible | ProvablyFair.org verifier — no login required |
| No reliance on private APIs | Fully client-side verification |
| 20 verification steps | Commit-reveal, determinism, payout, distribution, anti-manipulation |
To get an overview of how the process works, here is a high-level breakdown:
1. Player Bets — Selects pick count (1–10), risk level, and bet amount
2. Seeds Combined — HMAC-SHA256(hexDecode(serverSeed), clientSeed:nonce:cursor) for each shuffle step
3. RNG Output — Backward Fisher-Yates: 39 iterations from i=39 downto 1, each step swaps positions[i] with a bias-free random index
4. Draw Result — positions[0..9] + 1 = the 10 drawn numbers (1-indexed SET)
5. Hit Count — Count of player's picks appearing in drawn set
6. Multiplier Lookup — hits maps to multiplier via kenoConfig[risk][picks][hits]
7. Payout Result — win_amount = bet_amount × payout_multiplier
Provably fair gambling systems use cryptographic primitives to guarantee the integrity of outcomes. The model relies on three components: a server seed committed via hash before play, a player-controlled client seed, and an incrementing nonce. These inputs are combined using HMAC-SHA256 to produce deterministic, verifiable results. This section documents the global provably fair architecture used by almost all casinos and all relevant games.
The Commit-Reveal model is integral to ensuring fairness and transparency in online gambling. This model involves several key phases:
Commit Phase:
Before any bets are placed, the casino generates a random server seed. To prove its authenticity and prevent later manipulation, only the SHA-256 hash of the hex-decoded seed is sent to the player. This ensures that while the player cannot know the seed initially, they can verify it later.
Bet Phase:
The player places their bet. The server computes the drawn numbers using HMAC-SHA256 with the server seed (hex-decoded) as the HMAC key and the client seed, nonce, and cursor as the message. The same server seed and client seed pair are used for every bet in the epoch; the player can rotate the seed pair at any time to end the epoch.
Reveal Phase:
After the player rotates to a new seed pair, the server reveals the plaintext server seed from the completed epoch. The player can now independently verify SHA-256(hexDecode(serverSeed)) = committedHash.
Verify Phase:
Anyone can recompute every bet's drawn numbers from the revealed server seed, client seed, and nonce using the published backward Fisher-Yates algorithm.
The player's client seed is generated by the browser and submitted to the server via the seed rotation UI. Players can set their own client seed at any time. This ensures:
- The casino cannot predict the full RNG input
- Players contribute entropy that they control
- Results depend on both parties' inputs
Nonce Lifecycle
The nonce is a counter that increments with each bet within an epoch:
- Starts at 0 for each new server seed
- Increments by exactly 1 per bet
- Never reused within the same seed epoch
- Resets to 0 when the player rotates to a new server seed
Seed Epoch: (serverSeed, clientSeed)
Bet 1: nonce = 0 → Draw A
Bet 2: nonce = 1 → Draw B
Bet 3: nonce = 2 → Draw C
...
Bet N: nonce = N−1 → Draw Z
[Player rotates seed — epoch complete]
Next bet: nonce = 0 → Draw X (new seed pair)Determinism Guarantee
Given identical inputs, the output is always identical:
HMAC-SHA256(hexDecode(serverSeed), clientSeed:nonce:cursor) → Always same hash
Same hash per step → Always same swap index in Fisher-Yates
Same swaps across all 39 steps → Always same drawn SET
Same drawn SET + same picks → Always same hit count
Same hit count + same config → Always same payoutTechnical Glossary7 categories▶
| Term | Definition |
|---|---|
| Provably Fair | A cryptographic system that allows players to mathematically verify that game outcomes were not altered. Relies on commit-reveal schemes and deterministic algorithms. |
| Commit-Reveal Protocol | A two-phase process in which the casino commits to a result (by showing its hash) before the player bets, then reveals the actual value after the bet. |
| Determinism | The property that identical inputs always produce identical outputs. Same server seed, client seed, and nonce must always generate the same drawn number set. |
| Client Seed Origin | The method by which the client seed is generated. Full Pass: browser-generated default + player customizable seed. Conditional Pass: server-assigned default + player customizable seed. Hard Fail: player cannot set own seed. |
| Term | Definition |
|---|---|
| Server Seed | A random 32-byte value generated by Duel.com, transmitted as a 64-character hex string. Hashed and shown to players before betting, revealed after epoch rotation. |
| Client Seed | A random value controlled by the player, generated by the browser. Players can change it at any time via the seed rotation UI. |
| Nonce | A sequential counter that increments per bet within an epoch. Starts at 0 and resets to 0 when the player rotates to a new server seed. |
| Hashed Server Seed | SHA-256(hexDecode(serverSeed)) — the commitment hash shown before betting. After rotation, players verify the revealed seed produces this hash. |
| Cursor | Index used in the HMAC message during the backward Fisher-Yates shuffle. cursor = gridSize − 1 − i, starting at 0 for the first step (i=39). Each cursor value produces one shuffle step. |
| Epoch | A sequence of consecutive bets sharing the same server seed and client seed pair. Ends when the player rotates to a new seed pair. This audit covered 102 bet-bearing epochs. |
| Term | Definition |
|---|---|
| HMAC-SHA256 | Hash-based Message Authentication Code using SHA-256. Duel Keno uses HMAC-SHA256 with the hex-decoded server seed as key and clientSeed:nonce:cursor as message. Multiple calls per bet (one per shuffle step). |
| SHA-256 | Secure Hash Algorithm 256-bit. Used for server seed commitment: SHA-256(hexDecode(serverSeed)) = serverSeedHashed. |
| Hex Decoding | Converting a 64-character hex string to 32 raw bytes. Critical for the HMAC key — using the hex string as UTF-8 produces wrong outputs. |
| Backward Fisher-Yates Shuffle | A variant of the Fisher-Yates algorithm that iterates from index 39 down to 1, swapping each position with a random lower index. Produces a uniformly random permutation of the 40-number grid. |
| Term | Definition |
|---|---|
| Verifier | A tool that independently calculates drawn number sets using provided seeds and nonce. The ProvablyFair.org verifier is built from the audit codebase. |
| Parity | Degree of matching between verifier and live game results. 100% parity = every draw SET matches. This audit: 5,100/5,100 exact match. |
| Anti-Circularity | Proof that the win probabilities derive from first principles, not the casino's own claims: independently-derived hypergeometric P(hits) applied to the committed multiplier table = 99.9%. |
| Rejection Sampling | Bias elimination technique used in the shuffle. A maxFair ceiling discards values that would cause modulo bias, ensuring uniform randomness for all ranges. |
| Term | Definition |
|---|---|
| Drawn Numbers | The 10 numbers (1–40) selected by the backward Fisher-Yates shuffle. These are positions[0..9] + 1 from the shuffled array. The result is a SET — order is presentation-only. |
| Pick Count | Player-selected parameter (1–10) determining how many numbers the player chooses from the grid. More picks = more chances to match, but multipliers scale down. |
| Risk Level | Player-selected parameter (Classic, Low, Medium, High) that determines the multiplier table. Higher risk = more value at rare full-hit outcomes. |
| Hypergeometric Distribution | The probability distribution for hit counts: P(k hits) = C(picks,k) × C(40−picks, 10−k) / C(40,10). Used in the anti-circularity RTP proof. |
| Consolation Payout | Two configurations pay non-zero multipliers on zero hits: LOW picks=1 (0.71×) and MEDIUM picks=1 (0.41×). Design choice within the 99.9% RTP constraint. |
Every Keno game on Duel.com is generated from three inputs: server seed, client seed, and nonce. The casino commits to its server seed by publishing a SHA-256 hash before you place any bets. After you rotate your seed, the server reveals the actual seed — and anyone can verify that the hash matches. This cryptographic commitment makes it impossible for the casino to secretly change your outcome after you bet.
What We Verified
- Casino commits to the server seed hash before any bet is placed
- Client seed is browser-generated — server cannot know it at commitment time (Full Pass origin)
- Players can set or change their client seed at any time via the rotation UI
- Nonce increments by 1 per bet with no gaps or duplicates across 102 epochs
- Drawn numbers are fully determined by the seed inputs before the draw animation plays
- Identical inputs always produce the same drawn set — confirmed across all 5,100 bets
- Your client seed is a genuine input — changing it changes the outcome
What This Means for You
- The casino cannot change which numbers are drawn after you bet
- You contribute randomness the server cannot predict or pre-select against
- Every bet is unique — the nonce ensures no two bets share an outcome
- Any result can be independently verified using the public tools and repo
- Outcomes are tamper-proof and verifiable even months later
- Cherry-picking favourable seeds is structurally impossible
| Test | Status | Finding |
|---|---|---|
| Server seed committed before bet | Pass | SHA-256 hash of server seed published before play — casino cannot change randomness after betting |
| Client seed origin | Pass | Browser-generated (Full Pass) — server commits before client seed is known |
| Client seed control | Pass | Player can set/change client seed via rotation UI at any time |
| Nonce sequencing | Pass | Sequential within each epoch, 0 gaps, 0 duplicates across 102 epochs |
| Hash consistency within epoch | Pass | serverSeedHashed constant across all bets within each of 102 epochs |
| Seed hash integrity | Pass | 102 / 102 revealed seeds hash-verified — commitment chain intact |
| Deterministic output | Pass | Same (serverSeed, clientSeed, nonce) always produces same drawn SET — 5,100/5,100 confirmed |
| Client seed participation | Pass | Client seed is a genuine input — changing it changes the drawn numbers |
All 102 revealed seeds hash-verified. Every seed rotation was verified — the next seed the casino pre-committed always matched what was actually used. Outcomes are fully deterministic — the same server seed, client seed, and nonce always produce the same drawn number set. The casino cannot change your result after you bet.
This section verifies that Duel.com's Keno random number generation produces cryptographically sound, unbiased outputs using only the disclosed inputs. The RNG uses a backward Fisher-Yates shuffle with HMAC-SHA256 — each shuffle step derives a swap index from a 4-byte HMAC chunk with bias-free rejection sampling via the maxFair ceiling. We independently implemented this algorithm, verified it produces the same results as the live game, and confirmed no hidden inputs can influence outcomes.
What We Verified
- HMAC-SHA256 produces cryptographically sound, unpredictable output for each shuffle step
- Only disclosed inputs affect outcomes — no timestamps, no server-side state, no hidden entropy
- Rejection sampling via `maxFair` ceiling eliminates modulo bias for all ranges (2–40)
- Draw distribution follows hypergeometric expectations for all 40 configurations (confirmed over 40M simulated rounds)
- Consecutive outcomes are statistically independent — no patterns, no streaks
- 100.0% of outcomes change with a different client seed (5,100/5,100 tested bets)
What This Means for You
- Each drawn number is generated fairly and cannot be skewed
- All 40 grid positions are equally likely to be drawn — no positional bias
- No hidden randomness or server-side tricks influence which numbers appear
- Consecutive bets are not correlated — past results don't affect future outcomes
- The algorithm depends only on seeds you can verify
| Test | Status | Finding |
|---|---|---|
| RNG derived only from disclosed inputs | Pass | HMAC-SHA256(hexDecode(serverSeed), clientSeed:nonce:cursor) — no hidden entropy |
| Entropy purity | Pass | No timestamps, external APIs, Math.random, or server-side state |
| Algorithm independently implemented | Pass | Independent implementation produces identical results for all 5,100 bets |
| Modulo bias | Pass | Rejection sampling via `maxFair` ceiling eliminates bias for all ranges (2–40) |
| Key encoding verified | Pass | Server seed hex-decoded to bytes (not UTF-8) — confirmed via 5,100-bet recomputation |
| Serial independence | Pass | Lag-1 autocorrelation near zero and runs tests pass across all 40 configs at 1M rounds each |
| Client seed influence | Pass | 100.0% of outcomes change with an alternate client seed — confirmed across all 5,100 bets |
The Keno RNG uses only the disclosed inputs, produces uniform draw distribution across all 40 configurations, and shows no serial dependence across 40M simulated rounds. The client seed is a genuine input — 100.0% of outcomes change with a different seed.
This section validates that the independent verifier produces the exact same drawn number set as the live game for every single bet. It also confirms the payout math and that every multiplier matches Duel's published tables. Any mismatch would invalidate the fairness guarantee.
What We Verified
- Every bet independently recomputed from seeds — full drawn number set verified, not just the payout
- Payout correctness: win_amount = bet × multiplier, exact to 8 decimal places for all 5,100 bets
- Multiplier table produces the correct value for all 40 risk/picks configurations
- Bet amount is not an input to the RNG — drawn numbers depend only on seeds and nonce
- All four capture phases recomputed identically (config coverage, picks=1 edge case, picks=10 max variance, elevated stake)
What This Means for You
- The verifier isn't a simulation — it produces the exact same drawn set as the live game
- Every bet you play can be independently recomputed by anyone
- No hidden logic alters outcomes based on how much you bet or how you play
- The game engine in production matches the published algorithm exactly
| Test | Status | Finding |
|---|---|---|
| Draw recomputation | Pass | 5,100/5,100 exact match — drawn number SET verified for every bet |
| Payout correctness | Pass | All 5,100 bets: win_amount = bet × multiplier, exact to 8 decimal places |
| Multiplier table integrity | Pass | All observed multipliers match kenoConfig.json for all 40 configurations |
| Bet-size independence | Pass | Bet amount is absent from the RNG input — drawn numbers depend only on seeds and nonce |
| Config completeness | Pass | All 40 risk/picks configurations (4 risks × 10 pick counts) covered in live data |
| Multi-phase coverage | Pass | 4 structured phases: config coverage (A), picks=1 edge case (B), picks=10 max variance (C), elevated stake (D) |
All 5,100 bets matched the independent verifier exactly — drawn number sets verified across all four capture phases. Payout math correct. Multiplier table confirmed across all 40 configurations.
This section mathematically verifies that the base-tier 0.1% house edge is exactly what's advertised across all 40 configurations. The key test is anti-circularity: we prove the RTP using independently-derived hypergeometric probabilities applied to the committed multiplier table — no casino-supplied probability data enters the computation. We then confirm it against 40 million simulated rounds and test whether the casino pre-selected favourable seeds.
What We Verified
- House edge is exactly 0.1% — flat across all 40 configurations at the base bet tier
- RTP proven analytically: independently-derived hypergeometric P(hits) × committed multiplier = 99.9% for every configuration
- 40M-round simulation converges on theoretical RTP (mean 99.970%)
- Cherry-pick detection: 102 casino seeds tested — no evidence of seed pre-selection
- Bet amount does not influence drawn numbers — confirmed at $0.01 and $10
What This Means for You
- At the base bet tier, the house edge on Keno is a flat 0.1%, the same across all configurations
- The RTP proof is derived independently — it doesn't rely on trusting the casino
- The casino's seeds show no evidence of being chosen to produce favourable early outcomes
- Your bet amount doesn't affect which numbers are drawn
- Bet-size-scaled house edge — the base-tier margin is 0.1%, scaling up to 1.0% on larger bets (see 4.6b); bet size never affects which numbers are drawn
| Test | Status | Finding |
|---|---|---|
| Anti-circularity | Pass | Hypergeometric P(hits) × multiplier = 99.9% for all 40 configs — derived from C(picks,k)×C(40−picks,10−k)/C(40,10), no casino data used |
| House edge audit | Info | 0.1% base-tier house edge across all 40 configs — derived from the committed `kenoConfig.json` table, verified by anti-circularity Step 17. Scaling to 1.0% on larger bets — see 4.6b |
| Simulated RTP (Pass 1) | Pass | 40M rounds, avg RTP = 99.970%, 0/40 chi-squared failures, 0/40 serial independence failures |
| Cherry-pick detection (Pass 2) | Pass | 102 casino seeds tested across 1,666 combinations — no evidence of seed pre-selection |
| Bet-size invariance | Pass | Bet amount is not an input to the RNG — same draw distribution at $0.01 and $10. Tested in Phase D (100/100) |
| Multiplier formula | Pass | Hypergeometric P(k) × kenoConfig multipliers = 99.9% independently verified for all 40 configs |
| Config completeness | Pass | All 40 risk/picks configurations covered |
| Consolation payout design | Pass | LOW picks=1 (0.71×) and MEDIUM picks=1 (0.41×) on zero hits — within 99.9% RTP constraint |
The 99.9% RTP is proven mathematically from independently-derived hypergeometric probabilities applied to the committed table — P(hits) × multiplier = 0.999 for all 40 configurations. This is an analytic proof, not a statistical estimate. 40M simulated rounds and cherry-pick detection confirm no anomalies. The house edge is 0.1% at the base bet tier; the live game applies bet-size scaling to the multiplier table (0.1%→1.0%) — see 4.6b.
Sections 1–4 prove the game is mathematically fair. Section 5 proves the implementation maintains integrity under non-standard conditions. We applied 15 standard fairness integrity tests covering nonce integrity, seed commitment, outcome determinism, cross-player isolation, and payout integrity. 14 tests passed and 1 is not applicable to this game type.
What We Verified
- Nonce tampering — can the sequence be forced, replayed, or skipped?
- Seed injection — can server or client seed fields be overridden via API?
- Outcome replay — can a completed bet be replayed for duplicate payouts?
- Cross-player isolation — can one player's seeds or outcomes affect another's?
- Payout tampering — can multiplier or payout values be injected client-side?
- Parameter limits — can invalid pick counts or risk levels be submitted?
What This Means for You
- Across the 15 tests we ran, no API path allowed outcomes to be altered, replayed, or injected — by player or casino
- Once a bet is placed, the result cannot be changed or replayed
- Each bet is cryptographically unique and isolated
- Your results are independent of every other player
- The server rejects malformed, out-of-range, and duplicate requests
| Test | Status | Finding |
|---|---|---|
| Nonce integrity | Pass | Sequential, server-controlled, no gaps or duplicates across 102 epochs |
| Seed commitment integrity | Pass | Locked at bet acceptance, unique per epoch — 102/102 verified |
| Outcome determinism | Pass | Identical inputs produce identical outcomes — 5,100/5,100 confirmed |
| Round & player isolation | Pass | Per-user seeds, serial independence confirmed (0/40 fail in simulation) |
| Payout integrity | Pass | Parameter limits enforced (6/6 invalid selectedPositions rejected); injected payout fields ignored (0 honoured); server-computed multiplier consistent across all probes |
15 standard fairness integrity tests: 14 pass, 1 N/A (single-step game).
Every Keno outcome can be independently reproduced using publicly disclosed inputs. No hidden variables, no private backend data. If your calculated drawn number set matches the game result, the bet was provably fair. This section walks you through the process — and provides an independent verification tool built from the same code used in this audit.
Key Principles
- Every Keno outcome can be independently reproduced
- No hidden variables — no private backend data
- If your computed drawn set matches the game result, the bet was provably fair
- Most players can verify directly through the Duel.com fairness UI
What You Need
- Server Seed — revealed after seed rotation (casino entropy)
- Client Seed — your player-controlled seed
- Nonce — the bet number in sequence (ensures uniqueness; increments within each epoch)
Only disclosed inputs are used. Identical inputs always produce identical output.
This section consolidates the open-source repository, datasets, output artifacts, and reproducibility posture of the audit. Every finding, every statistic, every pass/fail result can be independently reproduced by anyone with a computer and an internet connection. The repository is the credential — not this report.
Repository Details
- GitHub: ProvablyFair-org/duel-keno
- Commit: 4fc06ec9b0a29f7e664732fef7295607a58b57c5
- Game: Keno (duel-keno)
- Public Verifier: audit.provablyfair.org/casino/duel/tools/verify-bets
Prerequisites
- Node.js 18+
- npm 8+
- Git
- TypeScript (installed via npm)
Repository Structure
Commands to Reproduce
Audit Reproducibility Pinning
All audit results can be independently reproduced using the pinned commit, dataset, and commands above. The dataset hash ensures you're running against the same 5,100 bets.



