← Takaisin oppaisiin

Provably Fair -opas – Miten kryptokasinoiden reiluus todistetaan matemaattisesti

Tiivistelmä – Miksi provably fair on tärkeä?

Provably fair on ainoa peliteknologia, jossa pelaaja voi itse matemaattisesti todentaa jokaisen kierroksen reiluuden ilman luottamusta kolmanteen osapuoleen. Tämä opas ei ole pintaraapaisu – käymme läpi koko kryptografisen ketjun siemenluvuista hash-funktioihin, konkreettisine todentamisesimerkkineen.

Tärkeimmät opit:


Sisällysluettelo

  1. Commit-reveal -skeema: kryptografinen perusta
  2. SHA-256 hash-funktio syväsukellus
  3. HMAC-SHA256 – siemenlukujen turvallinen yhdistäminen
  4. Server seed, client seed ja nonce – koko työnkulku
  5. Todentamisesimerkki 1: Noppapeli
  6. Todentamisesimerkki 2: Crash-peli
  7. Todentamisesimerkki 3: Korttipeli
  8. Eri pelityyppien provably fair -toteutukset
  9. Crash-pelin kertoimen laskeminen hashista
  10. Korttipakan sekoituksen todentaminen
  11. Hyökkäykset ja haavoittuvuudet
  12. Riippumattomat todentamistyökalut
  13. Mitä provably fair EI takaa
  14. Vertailu: provably fair vs. perinteinen RNG-auditointi
  15. Usein kysytyt kysymykset

Commit-reveal -skeema: kryptografinen perusta

Provably fair -järjestelmän ydin on commit-reveal -skeema (sitoumuksen paljastaminen). Tämä on kryptografinen protokolla, joka ratkaisee pelaamisen perustavanlaatuisen luottamusongelman: miten pelaaja voi varmistua, ettei kasino muuttanut pelitulosta jälkikäteen?

Luottamusongelma ilman kryptografiaa

Perinteisellä nettikasinolla pelitulokset syntyvät palvelimella, johon pelaajalla ei ole pääsyä. Pelaaja luottaa siihen, että ulkoinen auditoija (esim. eCOGRA, iTech Labs, GLI) on tarkastanut satunnaislukugeneraattorin (RNG) ja todennut sen reiluksi. Tämä on luottamukseen perustuva malli: sinun on uskottava auditoijan ja kasinon sanaan.

Commit-reveal kääntää asetelman päälaelleen. Sen sijaan, että luotat johonkin, voit tarkistaa itse.

Commit-reveal kolmessa vaiheessa

Vaihe 1 – Sitoumus (Commit):

Kasino generoi salaisen siemenluvun (server seed) ja laskee siitä kryptografisen hashin. Hash lähetetään pelaajalle ennen pelikierrosta. Tämä on kasinon "sitoumus" – se on lukinnut pelituloksen, mutta pelaaja ei vielä näe itse siementä.

server_seed = "salainen_arvo_xyz123"
hash = SHA-256(server_seed) = "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"

Pelaajalle näytetään: 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069

Vaihe 2 – Pelikierros (Play):

Pelaaja antaa oman siemenlukunsa (client seed) tai hyväksyy automaattisesti generoidun. Kierroksen järjestysnumero (nonce) kasvaa joka kierroksella. Pelitulos lasketaan yhdistämällä nämä kolme arvoa.

client_seed = "pelaajan_oma_seed"
nonce = 42
tulos = f(server_seed, client_seed, nonce)

Vaihe 3 – Paljastus (Reveal):

Kierroksen (tai seed-jakson) jälkeen kasino paljastaa alkuperäisen server seedin. Nyt pelaaja voi:

  1. Laskea SHA-256(paljastettu server_seed) ja verrata sitä ennakkoon saamaansa hashiin
  2. Laskea pelituloksen uudelleen yhdistämällä paljastetun server seedin omaan client seediinsä
  3. Todeta, vastaako laskettu tulos ilmoitettua tulosta

Miksi tämä toimii?

Commit-reveal -skeeman turvallisuus perustuu kahteen kryptografiseen ominaisuuteen:

  1. Yksisuuntaisuus: SHA-256 hashista ei voi laskea takaisin alkuperäistä dataa. Kasino ei voi valita sellaista server seediä, joka tuottaa halutun hashin ja samalla halutun pelituloksen.

  2. Törmäyksettömyys: Kahta eri syötettä, jotka tuottaisivat saman SHA-256 hashin, ei käytännössä ole olemassa. Kasino ei voi vaihtaa server seediä toiseen, joka tuottaisi saman hashin mutta eri pelituloksen.

Analogia: Ajattele commit-reveal -skeemaa kuin sinetöityä kirjekuorta. Kasino kirjoittaa pelituloksen paperille, sulkee sen kirjekuoreen ja antaa sinetöidyn kuoren sinulle ennen peliä. Kierroksen jälkeen kuori avataan. Jos kirjekuoren sisältö vastaa pelitulosta, kasino ei huijannut. SHA-256 hash on "digitaalinen sinetti", jota ei voi väärentää.


SHA-256 hash-funktio syväsukellus

SHA-256 (Secure Hash Algorithm 256-bit) on kryptografinen hajautusfunktio, joka muodostaa provably fair -järjestelmän matemaattisen selkärangan. Se on sama algoritmi, jota Bitcoin-lohkoketju käyttää.

Miten SHA-256 toimii – yksinkertaistettu selitys

SHA-256 ottaa minkä tahansa pituisen syötteen ja tuottaa aina 256-bittisen (64 heksadesimaalimerkin) tulosteen. Funktio on deterministinen – sama syöte tuottaa aina saman tulosteen – ja yksisuuntainen – tulosteesta ei voi laskea syötettä.

Esimerkki 1 – Lyhyt syöte:

Syöte:  "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Esimerkki 2 – Yhden merkin muutos:

Syöte:  "Hello"  (iso H)
SHA-256: 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

Huomaa: yhden ainoan merkin muuttaminen (pienestä h:sta isoon H:hon) muuttaa hashin täysin eri näköiseksi. Tätä kutsutaan lumivyöryefektiksi (avalanche effect). Hashien välillä ei ole havaittavaa yhteyttä, vaikka syötteet eroavat vain yhdellä bitillä.

Esimerkki 3 – Pitkä syöte:

Syöte:  "Tämä on pitkä lause, joka sisältää paljon tekstiä ja erikoismerkkejä: äöå!@#"
SHA-256: (64 heksadesimaalimerkkiä – aina saman pituinen riippumatta syötteen pituudesta)

SHA-256:n kriittiset ominaisuudet provably fair -käytössä

Ominaisuus Selitys Merkitys provably fair -pelissä
Deterministisyys Sama syöte tuottaa aina saman hashin Pelaaja voi toistaa laskelman ja saada saman tuloksen
Yksisuuntaisuus Hashista ei voi laskea alkuperäistä dataa Pelaaja ei voi päätellä server seediä etukäteen annetusta hashista
Törmäysvastus Kahta eri syötettä samalla hashilla ei käytännössä löydy Kasino ei voi vaihtaa server seediä jälkikäteen
Lumivyöryefekti Pieni muutos syötteessä muuttaa hashin täysin Pienikin muutos siemenluvussa tuottaa ennustamattoman eri tuloksen
Kiinteä tulosteen pituus Aina 256 bittiä (64 heksadesimaalimerkkiä) Hashin muoto on standardoitu ja helppo vertailla

Miksi juuri SHA-256?

SHA-256 valitaan provably fair -järjestelmiin kolmesta syystä:

  1. Turvallisuus: Yksikään tunnettu hyökkäys ei murra SHA-256:n yksisuuntaisuutta tai törmäysvastusta. Maailman tehokkain supertietokone tarvitsisi arviolta 2^128 operaatiota törmäyksen löytämiseen – tämä kestäisi miljoonia vuosia.

  2. Standardointi: SHA-256 on NIST:in (National Institute of Standards and Technology) standardoima, ja sitä käytetään laajalti tietoturvassa, TLS-sertifikaateissa ja Bitcoin-lohkoketjussa.

  3. Nopeus: SHA-256 on riittävän nopea laskettavaksi jokaiselle pelikierrokselle reaaliajassa, mutta riittävän hidas brute force -hyökkäyksille.

Heksadesimaalijärjestelmä lyhyesti

SHA-256 hash esitetään heksadesimaalimuodossa (kantaluku 16). Merkit ovat 0-9 ja a-f, yhteensä 16 mahdollista arvoa per merkki. 64 merkin hash sisältää siis:

Mahdollisia hash-arvoja: 16^64 = 2^256 ≈ 1.16 × 10^77

Tämä on astronominen luku – suurempi kuin arvioitu atomien lukumäärä havaittavassa maailmankaikkeudessa (noin 10^80). Käytännössä kahta samaa hashia ei koskaan synny eri syötteistä.


HMAC-SHA256 – siemenlukujen turvallinen yhdistäminen

Pelkkä SHA-256 ei riitä provably fair -järjestelmään. Tarvitaan tapa yhdistää server seed ja client seed turvallisesti siten, että kumpikaan osapuoli ei voi yksin manipuloida tulosta. Tähän käytetään HMAC-SHA256:ta (Hash-based Message Authentication Code).

Miksi pelkkä ketjuttaminen ei riitä?

Yksinkertainen lähestymistapa olisi laskea:

tulos = SHA-256(server_seed + client_seed + nonce)

Tämä on haavoittuva length extension -hyökkäykselle. SHA-256:n sisäisen tilan vuoksi hyökkääjä, joka tuntee SHA-256(viesti) arvon, voi laskea SHA-256(viesti + lisäys) ilman, että tuntee alkuperäistä viestiä. HMAC estää tämän.

HMAC-SHA256:n rakenne

HMAC-SHA256 laskee hashin kahdessa vaiheessa:

HMAC-SHA256(avain, viesti) = SHA-256((avain XOR opad) || SHA-256((avain XOR ipad) || viesti))

Missä:

Käytännössä tämän ei tarvitse huolestuttaa pelaajaa – standardikirjastot laskevat HMAC-SHA256:n yhdellä funktiokutsulla. Oleellista on ymmärtää, miksi HMAC:ia käytetään:

HMAC:n turvallisuustakuut

  1. Server seed toimii avaimena: Kasino ei voi muuttaa avainta (server seediä) jälkikäteen, koska se on sidottu ennakkoon annettuun SHA-256-hashiin.

  2. Client seed on viesti: Pelaaja vaikuttaa tulokseen, koska viesti sisältää hänen siemenlukunsa. Kasino ei voi tietää client seediä etukäteen (ellei pelaaja käytä oletusarvoa).

  3. Nonce estää toistot: Jokainen kierros saa uniikin numeron, joten sama server seed + client seed -yhdistelmä tuottaa eri tuloksen joka kierroksella.

Käytännön merkitys: HMAC-SHA256 takaa, että kasino ei voi valita sellaista server seediä, joka tuottaa halutun tuloksen tietyllä client seedillä. Kasino ei tiedä client seediä sitoutuessaan server seediin, ja pelaaja ei tiedä server seediä valitessaan client seediä. Kumpikaan osapuoli ei voi yksin manipuloida tulosta.


Server seed, client seed ja nonce – koko työnkulku

Koko provably fair -prosessi noudattaa tarkkaa työnkulkua, jossa jokaisella komponentilla on oma roolinsa. Käydään läpi koko ketju alusta loppuun.

Vaihe 1: Server seedin generointi

Kasino generoi kryptografisesti turvallisen satunnaisen merkkijonon. Hyvän käytännön mukainen server seed on:

server_seed = "a8f3e2c1b9d7f6e5a4c3b2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1"

Vaihe 2: Server seed hashin lähettäminen pelaajalle

Kasino laskee server seedistä SHA-256 hashin ja näyttää sen pelaajalle.

server_seed_hash = SHA-256("a8f3e2c1b9d7f6e5a4c3b2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1")
                 = "3c9a5f7e2d1b4c8a6f0e9d3c7b5a1f4e8d2c6b0a9f3e7d1c5b4a8f2e6d0c9b3"

Pelaaja näkee hashin, mutta ei voi päätellä siitä server seediä.

Vaihe 3: Client seedin asettaminen

Pelaaja voi:

client_seed = "oma_valitsemani_seed_2026"

Tärkeä huomio: Jos käytät kasinon automaattisesti generoitua client seediä, kasino teoreettisesti tietää sen etukäteen. Tämä ei välttämättä ole ongelma, jos server seed on jo lukittu hashilla, mutta oman client seedin asettaminen on silti parempi käytäntö.

Vaihe 4: Pelikierros

Jokaiselle kierrokselle annetaan kasvava nonce (järjestysnumero). Pelitulos lasketaan:

kierros_1: HMAC-SHA256(server_seed, "oma_valitsemani_seed_2026:1") = "e4a7c2f1..."
kierros_2: HMAC-SHA256(server_seed, "oma_valitsemani_seed_2026:2") = "9b3d8f5e..."
kierros_3: HMAC-SHA256(server_seed, "oma_valitsemani_seed_2026:3") = "1f6a4c9d..."

HMAC-tuloksen heksadesimaalimerkeistä lasketaan pelitulos pelityyppikohtaisella algoritmilla.

Vaihe 5: Seed-jakson päättyminen ja todentaminen

Kun pelaaja pyytää uuden server seedin (seed rotation), kasino:

  1. Paljastaa vanhan server seedin
  2. Generoi uuden server seedin ja lähettää siitä hashin
  3. Uusi seed-jakso alkaa nonce = 1

Nyt pelaaja voi todentaa kaikki edellisen jakson kierrokset.

Työnkulkukaavio

KASINO                                    PELAAJA
  |                                          |
  |-- 1. Generoi server_seed               |
  |-- 2. Laskee SHA-256(server_seed)        |
  |-- 3. Lähettää hashin ------------------>|
  |                                          |-- 4. Asettaa client_seed
  |<-- 5. Lähettää client_seed -------------|
  |                                          |
  |== PELIKIERROS (nonce = N) ==============|
  |                                          |
  |-- 6. Laskee HMAC-SHA256(server_seed,    |
  |       client_seed:nonce)                |
  |-- 7. Muuntaa hashin pelitulokseksi      |
  |-- 8. Näyttää tuloksen ----------------->|
  |                                          |
  |== SEED ROTATION ========================|
  |                                          |
  |-- 9. Paljastaa server_seed ------------>|
  |                                          |-- 10. Tarkistaa:
  |                                          |   SHA-256(server_seed) == hash?
  |                                          |   HMAC tulos == ilmoitettu?
  |-- 11. Generoi uuden server_seed        |
  |-- 12. Lähettää uuden hashin ----------->|

Todentamisesimerkki 1: Noppapeli

Käydään läpi konkreettinen todentamisesimerkki noppapelissä, jossa heitetään kuusisivuista noppaa (tulos 1-6).

Lähtötiedot

server_seed:      "k7x9mP2qL4wR8nT1vB5cF3jH6dA0eG4"
server_seed_hash: "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"
client_seed:      "pelaaja_noppa_42"
nonce:            7

Vaihe 1: Tarkista hash

Ennen kuin arvioit pelitulosta, varmista, että paljastettu server seed vastaa ennakkoon annettua hashia:

SHA-256("k7x9mP2qL4wR8nT1vB5cF3jH6dA0eG4") = ?

Jos tulos == "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"
  -> Server seed on aito, kasino ei vaihtanut sitä
Muuten:
  -> HÄLYTYS: kasino on manipuloinut server seediä!

Vaihe 2: Laske HMAC-SHA256

hmac_tulos = HMAC-SHA256("k7x9mP2qL4wR8nT1vB5cF3jH6dA0eG4", "pelaaja_noppa_42:7")
           = "e4b8c3a1f7d2e6b9c0a5f8d3e1b4c7a2f6d9e0b3c8a1f5d2e7b0c4a9f3d6e8"

Vaihe 3: Muunna nopan silmäluvuksi

Otetaan HMAC-tuloksen ensimmäiset 8 heksadesimaalimerkkiä ja muunnetaan ne kokonaisluvuksi:

ensimmäiset_8 = "e4b8c3a1"
kokonaisluku  = 0xe4b8c3a1 = 3,837,076,897

nopan_tulos = (kokonaisluku % 6) + 1
            = (3837076897 % 6) + 1
            = 3 + 1
            = 4

Nopan tulos on 4.

Vaihe 4: Vertaa ilmoitettuun tulokseen

Jos kasino ilmoitti kierroksen 7 tulokseksi 4, kaikki täsmää. Jos kasino ilmoitti eri tuloksen, kasino on joko huijannut tai käyttää eri algoritmia kuin on dokumentoitu.

Pseudokoodi koko prosessista:

funktio todenna_noppa(server_seed, server_seed_hash, client_seed, nonce, ilmoitettu_tulos):
    // 1. Tarkista server seedin aitous
    laskettu_hash = SHA256(server_seed)
    JOS laskettu_hash != server_seed_hash:
        PALAUTA "VIRHE: Server seed ei vastaa hashia!"

    // 2. Laske pelitulos
    hmac = HMAC_SHA256(server_seed, client_seed + ":" + nonce)
    luku = heksa_kokonaisluvuksi(hmac[0:8])
    tulos = (luku % 6) + 1

    // 3. Vertaa
    JOS tulos == ilmoitettu_tulos:
        PALAUTA "OK: Kierros on todennettavasti reilu"
    MUUTEN:
        PALAUTA "VIRHE: Pelitulos ei täsmää!"

Todentamisesimerkki 2: Crash-peli

Crash-pelit ovat provably fair -teknologian ehkä tunnetuin sovellus. Kerroin nousee 1.00x:stä ylöspäin ja "räjähtää" satunnaisessa kohdassa. Pelaajan pitää lunastaa voittonsa ennen räjähdystä.

Crash-pelin seed-ketju

Monet crash-pelit käyttävät hash-ketjua (hash chain), jossa jokaisen kierroksen tulos johdetaan edellisestä. Tämä mahdollistaa kaikkien tulevien tulosten todentamisen yhdellä ainoalla alkuperäisellä hashilla.

kierros_10000: hash_10000 = alkuperäinen_seed
kierros_9999:  hash_9999  = SHA-256(hash_10000)
kierros_9998:  hash_9998  = SHA-256(hash_9999)
...
kierros_1:     hash_1     = SHA-256(hash_2)

Ketju lasketaan takaperin – viimeinen kierros generoidaan ensin. Näin kasino sitoutuu kaikkiin tuleviin tuloksiin kerralla, eikä voi muuttaa yhtäkään niistä jälkikäteen, koska muutos yhdessä hashissa muuttaisi kaikki sen jälkeiset hashit.

Konkreettinen crash-esimerkki

game_hash:  "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
salt:       "0000000000000000000fa3b65e43e4240d71762a5bf397d5304b2596d116859c"

Vaihe 1: Laske HMAC

hmac_tulos = HMAC-SHA256(game_hash, salt)
           = "f3e8d2c7b1a6f5e0d4c9b3a8f2e7d1c6b0a5f4e9d3c8b2a7f1e6d0c5b4a9f3"

Vaihe 2: Poimi luku hashista

Otetaan HMAC-tuloksen ensimmäiset 13 heksadesimaalimerkkiä (52 bittiä):

ensimmäiset_13 = "f3e8d2c7b1a6f"
luku = 0xf3e8d2c7b1a6f = 4,290,912,882,886,255

Vaihe 3: Laske crash-kerroin

Yleinen kaava crash-kertoimen laskemiseen:

JOS luku % 33 == 0:
    kerroin = 1.00  (instant crash)
MUUTEN:
    kerroin = kaatto((2^52) / (luku + 1) * (1 - talon_etu))

Missä:
  - 2^52 = 4,503,599,627,370,496
  - talon_etu = tyypillisesti 0.01 (1 %) tai 0.03 (3 %)
  - kaatto = pyöristys alaspäin kahteen desimaaliin

Esimerkkimme luvuilla (talon etu 1 %):

kerroin = kaatto(4503599627370496 / (4290912882886255 + 1) * 0.99)
        = kaatto(1.0496 * 0.99)
        = kaatto(1.0391)
        = 1.03

Crash-kerroin olisi 1.03x – peli räjähtäisi hyvin nopeasti.

Huomio instant crashista: Modulo 33 -tarkistus tarkoittaa, että noin 3 % (1/33) kaikista kierroksista on instant crash (kerroin 1.00x, jolloin kaikki häviävät). Tämä on yksi tapa, jolla talon etu toteutuu crash-pelissä.


Todentamisesimerkki 3: Korttipeli

Korttipelien provably fair -toteutus on monimutkaisempi kuin noppapelin, koska täytyy sekoittaa 52 kortin pakka sen sijaan, että generoidaan yksi luku.

Fisher-Yates -sekoitus hashista

Korttipakan sekoitus käyttää Fisher-Yates -algoritmia (tunnetaan myös Knuth-sekoituksena), jossa satunnaisuus johdetaan HMAC-SHA256:sta.

Alkuperäinen pakka (järjestyksessä):
[A♠, 2♠, 3♠, ..., K♠, A♥, 2♥, ..., K♥, A♦, 2♦, ..., K♦, A♣, 2♣, ..., K♣]
Indeksit: [0, 1, 2, ..., 51]

Sekoitusalgoritmi

funktio sekoita_pakka(server_seed, client_seed, nonce):
    pakka = [0, 1, 2, ..., 51]  // 52 korttia

    JOKAISELLE i VÄLILLÄ 51 -> 1 (laskeva):
        // Laske satunnainen indeksi HMAC:sta
        hmac = HMAC_SHA256(server_seed, client_seed + ":" + nonce + ":" + i)
        luku = heksa_kokonaisluvuksi(hmac[0:8])
        j = luku % (i + 1)   // satunnainen indeksi välillä [0, i]

        // Vaihda kortit paikoillaan
        vaihda(pakka[i], pakka[j])

    PALAUTA pakka

Konkreettinen esimerkki

server_seed: "card_server_seed_abc123def456"
client_seed: "blackjack_pelaaja"
nonce:       15

// Iteraatio i=51:
hmac = HMAC-SHA256("card_server_seed_abc123def456", "blackjack_pelaaja:15:51")
     = "7a3f5c..."
luku = 0x7a3f5c28 = 2,050,948,136
j = 2050948136 % 52 = 28
-> Vaihdetaan pakka[51] ja pakka[28]

// Iteraatio i=50:
hmac = HMAC-SHA256("card_server_seed_abc123def456", "blackjack_pelaaja:15:50")
     = "c1d9e4..."
luku = 0xc1d9e4a7 = 3,252,044,967
j = 3252044967 % 51 = 6
-> Vaihdetaan pakka[50] ja pakka[6]

// ... ja niin edelleen 49 kertaa

Lopputuloksena on sekoitettu pakka, jonka jokainen pelaaja voi todentaa itsenäisesti.

Tärkeä huomio: Korttipelien todentaminen vaatii, että kasino dokumentoi tarkasti, missä järjestyksessä indeksit 0–51 vastaavat kortteja. Eri kasinot voivat käyttää eri järjestystä (esim. 0 = A♠ tai 0 = 2♣).


Eri pelityyppien provably fair -toteutukset

Eri pelityypit käyttävät erilaisia algoritmeja HMAC-tuloksen muuntamiseen pelitulokseksi. Perusperiaate on aina sama (commit-reveal + HMAC-SHA256), mutta muunnoslogiikka vaihtelee.

Noppa- ja kolikkopelit

Yksinkertaisin toteutus. HMAC-tuloksen ensimmäiset heksadesimaalimerkit muunnetaan luvuksi, joka skaalataan haluttuun tulosavaruuteen.

Kolikko (50/50): tulos = (luku % 2)  // 0 = kruuna, 1 = klaava
Noppa (1-6):     tulos = (luku % 6) + 1
Noppa (1-100):   tulos = (luku % 100) + 1

Kolikkopelisimulaaatiot (slots)

Kolikkopelien provably fair -toteutus on monimutkaisempi, koska jokainen kela on erillinen satunnainen tulos.

5-kelainen kolikkopeli:
  kela_1 = HMAC-SHA256(server_seed, client_seed + ":1:" + nonce)
  kela_2 = HMAC-SHA256(server_seed, client_seed + ":2:" + nonce)
  kela_3 = HMAC-SHA256(server_seed, client_seed + ":3:" + nonce)
  kela_4 = HMAC-SHA256(server_seed, client_seed + ":4:" + nonce)
  kela_5 = HMAC-SHA256(server_seed, client_seed + ":5:" + nonce)

Jokaisen kelan symboli määräytyy:
  symboli_indeksi = luku % symbolien_lukumäärä

Plinko ja minesweeper

Plinko-pelissä (pallo putoaa piikkien läpi) jokainen "vasemmalle/oikealle" -päätös on erillinen bitti HMAC-tuloksesta:

Plinko (16 riviä):
  hmac = HMAC-SHA256(server_seed, client_seed + ":" + nonce)
  rivi_1: suunta = (hmac_bitti_0 == 0) ? vasen : oikea
  rivi_2: suunta = (hmac_bitti_1 == 0) ? vasen : oikea
  ...
  rivi_16: suunta = (hmac_bitti_15 == 0) ? vasen : oikea

Minesweeper-pelissä miinojen sijainnit valitaan hash-pohjaisella satunnaisotannalla.

Roulette

hmac = HMAC-SHA256(server_seed, client_seed + ":" + nonce)
luku = heksa_kokonaisluvuksi(hmac[0:8])
tulos = luku % 37   // eurooppalainen roulette: 0-36

Yhteenvetotaulukko

Pelityyppi Tulosavaruus HMAC:sta käytetyt merkit Muunnoslogiikka
Noppa 1–6 tai 0–99.99 Ensimmäiset 8 Modulo + skaalaus
Crash 1.00x – ∞ Ensimmäiset 13 2^52 / (luku + 1) * etu
Korttipeli 52 kortin pakka 8 per kortti (51 iteraatiota) Fisher-Yates shuffle
Kolikkopeli Symbolit per kela 8 per kela Modulo per kela
Plinko Vasen/oikea per rivi 1 bitti per rivi Bittitarkistus
Roulette 0–36 Ensimmäiset 8 Modulo 37

Crash-pelin kertoimen laskeminen hashista

Crash-pelit ansaitsevat oman syväsukelluksen, koska niiden matematiikka on erityisen mielenkiintoinen ja monille pelaajille hämmentävä.

Kertoimen jakaumafunktio

Crash-kertoimen teoreettinen todennäköisyysjakauma noudattaa käänteisfunktiota:

P(kerroin >= x) = 1/x   (ilman talon etua)
P(kerroin >= x) = (1 - talon_etu) / x   (talon edulla)

Tämä tarkoittaa:

Talon etu crash-pelissä

Talon etu toteutuu crash-pelissä kahdella mekanismilla:

1. Instant crash (1.00x): Noin 1/33 (≈ 3 %) kierroksista räjähtää välittömästi. Pelaaja häviää panoksensa ilman mahdollisuutta lunastaa.

2. Kertoimen skaalaus: Loput kierrokset käyttävät kaavaa, jossa (1 - talon_etu) -kerroin pienentää kaikkia kertoimia marginaalisesti.

Odotettu talon etu = instant_crash_osuus + (1 - instant_crash_osuus) * talon_etu_kerroin
                   ≈ 1/33 + (32/33) * 0.01
                   ≈ 3.03 % + 0.97 %
                   ≈ 4 %

Käytännön merkitys: Crash-pelin RTP on tyypillisesti noin 96–97 %. Tämä tarkoittaa, että pitkällä aikavälillä jokaista panostettua euroa kohden kasino pitää 3–4 senttiä.

Kertoimen todentamisen pseudokoodi

funktio laske_crash_kerroin(game_hash, salt):
    hmac = HMAC_SHA256(game_hash, salt)

    // Instant crash -tarkistus
    JOS heksa_kokonaisluvuksi(hmac[0:8]) % 33 == 0:
        PALAUTA 1.00

    // Ota 52 bittiä (13 heksadesimaalimerkkiä)
    h = heksa_kokonaisluvuksi(hmac[0:13])

    // Laske kerroin
    e = 2^52
    kerroin = kaatto_kahteen_desimaaliin(e / (h + 1) * 0.99)

    // Minimikerroin on 1.00
    PALAUTA max(1.00, kerroin)

Hash-ketjun todentaminen

Crash-pelien hash-ketju mahdollistaa kaikkien pelien todentamisen taaksepäin:

// Tiedät viimeisimmän kierroksen hashin (game_hash_N)
// Voit todentaa kaikki edeltävät kierrokset:

game_hash_N-1 = SHA-256(game_hash_N)
game_hash_N-2 = SHA-256(game_hash_N-1)
...ja niin edelleen

// Jokaisen kierroksen crash-kerroin:
kerroin_N   = laske_crash_kerroin(game_hash_N, salt)
kerroin_N-1 = laske_crash_kerroin(game_hash_N-1, salt)

Käytännön todentamisvinkki: Useat kasinot julkaisevat alkuperäisen seedin (ensimmäisen game_hashin ketjussa) ja saltin. Tällä tiedolla voit laskea jokaisen yksittäisen kierroksen crash-kertoimen ja todentaa, ettei kasino ole muuttanut yhtäkään tulosta.


Korttipakan sekoituksen todentaminen

Korttipelien provably fair -todentaminen on kaikkein yksityiskohtaisin prosessi, koska se vaatii 51 erillisen satunnaisluvun generoinnin ja Fisher-Yates -algoritmin tarkan seuraamisen.

Miksi Fisher-Yates?

Fisher-Yates on ainoa sekoitusalgoritmi, joka takaa tasaisen jakauman – jokainen 52! (noin 8 × 10^67) mahdollista pakkajärjestystä on yhtä todennäköinen. Naiivi sekoitus (esim. jokaiselle kortille satunnainen paikka) tuottaa vinoutuneen jakauman.

Korttien koodaus

Tyypillinen korttienkoodaus:

Indeksi 0-12:  A♠, 2♠, 3♠, 4♠, 5♠, 6♠, 7♠, 8♠, 9♠, 10♠, J♠, Q♠, K♠
Indeksi 13-25: A♥, 2♥, 3♥, 4♥, 5♥, 6♥, 7♥, 8♥, 9♥, 10♥, J♥, Q♥, K♥
Indeksi 26-38: A♦, 2♦, 3♦, 4♦, 5♦, 6♦, 7♦, 8♦, 9♦, 10♦, J♦, Q♦, K♦
Indeksi 39-51: A♣, 2♣, 3♣, 4♣, 5♣, 6♣, 7♣, 8♣, 9♣, 10♣, J♣, Q♣, K♣

Tärkeä varoitus: Eri kasinot käyttävät eri koodauksia! Ennen todentamista varmista kasinon dokumentaatiosta, miten kortit on numeroitu. Väärä koodaus tuottaa vääriä todentamistuloksia, vaikka algoritmi olisi oikein.

Todentamisen haasteet korttipelissä

  1. 51 erillistä HMAC-laskua tarvitaan per pakka – manuaalinen todentaminen on käytännössä mahdotonta
  2. Eri kasinot käyttävät eri korttijärjestystä – koodaus on varmistettava tapauskohtaisesti
  3. Monipaikkapelit (blackjack, poker): Pelaaja näkee vain omat korttinsa pelin aikana, mutta voi todentaa koko pakan sekoituksen jälkikäteen

Suosittelemme käyttämään kasinon omaa todentamistyökalua tai riippumatonta verifiointisivustoa korttipelien todentamiseen.


Hyökkäykset ja haavoittuvuudet

Provably fair -järjestelmä on matemaattisesti vahva, mutta sen toteutuksessa voi olla haavoittuvuuksia. On tärkeää ymmärtää, miten järjestelmää voi teoreettisesti tai käytännössä murtaa.

1. Heikko satunnaislukugeneraattori (RNG)

Hyökkäys: Jos kasino käyttää heikkoa tai ennustettavaa satunnaislukugeneraattoria server seedin luomiseen, hyökkääjä voi ennustaa tulevia server seedejä.

Esimerkki: JavaScript-kielessä Math.random() ei ole kryptografisesti turvallinen. Jos kasino käyttäisi sitä server seedin generointiin:

// VAARALLINEN – ennustettava!
server_seed = Math.random().toString(36).substring(2)

// TURVALLINEN – kryptografinen satunnaisuus
server_seed = crypto.randomBytes(32).toString('hex')

Puolustus: Kasino tulee käyttää kryptografisesti turvallista satunnaislukugeneraattoria (CSPRNG), kuten crypto.randomBytes() (Node.js) tai /dev/urandom (Linux).

Pelaajan huomio: Provably fair ei kerro sinulle, miten server seed on generoitu. Tämä on "musta aukko" järjestelmässä – sinun on luotettava siihen, että kasino käyttää kunnollista RNG:tä.

2. Server seedin uudelleenkäyttö

Hyökkäys: Jos kasino käyttää samaa server seediä usealle pelaajalle tai usealle seed-jaksolle, hyökkääjä voi päätellä server seedin analysoimalla useiden pelaajien pelituloksia.

Puolustus: Jokaisen pelaajan jokaisen seed-jakson tulee käyttää uniikkia server seediä. Vastuullinen kasino generoi uuden seedin jokaiselle seed-jaksolle.

3. Client seedin manipulointi

Hyökkäys: Jos kasino generoi client seedin pelaajan puolesta ja tietää sen etukäteen, kasino tuntee molemmat siemenluvut jo ennen pelikierrosta. Teoriassa kasino voisi valita sellaisen server seedin, joka tuottaa haluamansa tuloksen tietyllä client seedillä.

Puolustus: Aseta aina oma client seed. Älä käytä kasinon automaattisesti generoitua oletusarvoa, jos haluat maksimoida todennettavuuden.

Hyvä client seed: "oma_uniikki_seed_28032026_session3"
Huono client seed: (kasinon automaattisesti asettama oletusarvo)

4. Nonce-manipulointi

Hyökkäys: Kasino voisi hypätä yli nonce-arvoja tai toistaa niitä. Jos nonce 42 tuottaa kasinolle edullisen tuloksen, kasino voisi teoriassa käyttää sitä uudelleen.

Puolustus: Seuraa nonce-arvojen kasvamista. Noncen tulee kasvaa täsmälleen yhdellä joka kierros (1, 2, 3, ...). Jos huomaat aukkoja tai toistoja, kyseessä on manipulointi.

5. Ajoitushyökkäys (timing attack)

Hyökkäys: Kasino voisi teoriassa viivästyttää hash-sitoumuksen paljastamista ja laskea useita server seedejä löytääkseen itselleen edullisen tuloksen.

Puolustus: Hash-sitoumus pitää näyttää pelaajalle ennen kuin pelaaja tekee mitään toimenpiteitä (panos, kortin nosto). Jos hash ilmestyy vasta panoksen jälkeen, järjestelmä ei ole luotettava.

6. Puutteellinen dokumentaatio

Hyökkäys: Kasino voi käyttää eri algoritmia kuin mitä se dokumentoi. Esimerkiksi dokumentaatio kertoo "ensimmäiset 8 heksadesimaalimerkkiä", mutta todellisuudessa käytetään ensimmäisiä 10 merkkiä. Tulos näyttää todennettavalta, mutta pelaajan laskema tulos ei täsmää.

Puolustus: Testaa todentaminen useilla kierroksilla. Jos tuloksesi poikkeavat systemaattisesti kasinon ilmoittamista, algoritmi on dokumentoitu väärin tai sitä on muutettu.

Yhteenveto haavoittuvuuksista

Haavoittuvuus Vakavuus Pelaajan havaittavissa? Puolustus
Heikko RNG Kriittinen Ei suoraan Luota vain auditoituihin kasinoihin
Seed-uudelleenkäyttö Korkea Vaikeasti Vaihda seed usein, vertaile muiden pelaajien kanssa
Client seed -manipulointi Korkea Kyllä Aseta aina oma client seed
Nonce-manipulointi Keskitaso Kyllä Seuraa nonce-sekvenssiä
Ajoitushyökkäys Keskitaso Osittain Hash pitää näkyä ennen panosta
Puutteellinen dokumentaatio Keskitaso Kyllä (testaamalla) Todenna useita kierroksia

Riippumattomat todentamistyökalut

Provably fair -todentaminen ei vaadi teknistä osaamista, jos käytät oikeita työkaluja. Tässä ovat tärkeimmät resurssit.

Online SHA-256 -laskurit

Yksinkertaisin tapa tarkistaa server seedin hash on käyttää online SHA-256 -laskuria:

  1. Kopioi kasinon paljastama server seed
  2. Syötä se SHA-256-laskuriin
  3. Vertaa tulosta kasinon ennakkoon antamaan hashiin

Varoitus: Käytä vain tunnettuja ja luotettavia laskureita. Pahimmassa tapauksessa epäluotettava laskuri voi tallentaa syöttämäsi seedin.

HMAC-SHA256 -laskurit

Pelituloksen todentaminen vaatii HMAC-SHA256 -laskurin:

  1. Syötä server seed (avain/key)
  2. Syötä client_seed:nonce (viesti/message)
  3. Tulos on HMAC-hash, josta pelitulos lasketaan

Kasinokohtaiset todentamistyökalut

Useimmat provably fair -kasinot tarjoavat oman todentamissivun. Näiden käyttäminen on helpointa, mutta muista: kasinon oma työkalu ei ole riippumaton todentaminen. Se todistaa vain, että kasinon oma laskenta on johdonmukainen – ei sitä, ettei kasinolla ole toista, piilotettua algoritmia.

Suositus: Käytä kasinon todentamistyökalua nopeaan tarkistukseen, mutta tee ajoittain riippumaton todentaminen ulkoisella työkalulla tai omalla koodilla. Yksikin epäjohdonmukaisuus on vakava varoitusmerkki.

Oma todentamisskripti

Jos osaat ohjelmoida, voit kirjoittaa oman todentamisskriptin. Pseudokoodi:

// Node.js-esimerkki
const crypto = require('crypto');

funktio todenna(serverSeed, serverSeedHash, clientSeed, nonce) {
    // 1. Tarkista server seed hash
    const laskettuHash = crypto
        .createHash('sha256')
        .update(serverSeed)
        .digest('hex');

    if (laskettuHash !== serverSeedHash) {
        return 'VIRHE: Hash ei täsmää!';
    }

    // 2. Laske HMAC
    const hmac = crypto
        .createHmac('sha256', serverSeed)
        .update(clientSeed + ':' + nonce)
        .digest('hex');

    // 3. Muunna pelitulokseksi (esim. noppa 1-6)
    const luku = parseInt(hmac.substring(0, 8), 16);
    const tulos = (luku % 6) + 1;

    return 'Todentaminen onnistui. Pelitulos: ' + tulos;
}

Mitä provably fair EI takaa

Tämä on ehkä oppaan tärkein osio. Provably fair -leima antaa monelle pelaajalle virheellisen turvallisuudentunteen. On kriittistä ymmärtää järjestelmän rajat.

1. Provably fair ei takaa reilua palautusprosenttia (RTP)

Provably fair todistaa, että pelitulos on laskettu ennalta määrätyllä tavalla. Se ei kerro, onko talon etu kohtuullinen.

Esimerkki: Kuvittele noppapeli, jossa heität kuusisivuista noppaa. Jos heität 1–5, häviät panoksesi. Jos heität 6, voitat 5x panoksesi. Peli on provably fair (jokainen heitto on todennettavissa), mutta talon etu on:

Odotettu arvo = (5/6 × -1) + (1/6 × 5) = -0.833 + 0.833 = 0

Tässä tapauksessa talon etu on 0 % (reilu peli). Mutta entä jos voitto olisi vain 4x?

Odotettu arvo = (5/6 × -1) + (1/6 × 4) = -0.833 + 0.667 = -0.167
Talon etu = 16.7 %

Peli on edelleen provably fair, mutta talon etu on 16.7 % – paljon korkeampi kuin useimmissa kasinopeleissä.

2. Provably fair ei takaa kasinon vakavaraisuutta

Provably fair -kasino voi olla täysin rehellinen pelitulosten suhteen mutta silti olla kykenemätön maksamaan voittoja. Kasinon kassanhallinta on täysin erillinen asia todennettavuudesta.

Tunnetuimpia esimerkkejä:

3. Provably fair ei takaa RNG:n laatua

Kuten haavoittuvuusosiossa käsiteltiin, provably fair -ketju toimii oikein vain, jos alkuperäinen server seed on aidosti satunnainen. Jos kasino käyttää heikkoa satunnaislukugeneraattoria, tulokset voivat olla ennustettavia, vaikka hash-verifikaatio menee läpi moitteettomasti.

4. Provably fair ei korvaa sääntelyä

Sääntely kattaa pelaajaturvan kokonaisvaltaisesti: vastuullinen pelaaminen, rahanpesun esto, pelaajien varojen suojaaminen, riitojenratkaisu. Provably fair kattaa vain yhden pienen osan: pelitulosten todennettavuuden.

5. Provably fair ei suojaa huonoilta ehdoilta

Bonusehdot, kierrätysvaatimukset, maksimivoittokatot – nämä ovat kasinon liiketoimintapäätöksiä, joihin provably fair ei ota kantaa. Kasino voi tarjota todennettavasti reiluja pelejä mutta silti asettaa kohtuuttomia ehtoja bonuksille ja nostoille.


Vertailu: provably fair vs. perinteinen RNG-auditointi

Molemmat järjestelmät pyrkivät takaamaan pelien reiluuden, mutta eri tavoin. Kumpi on parempi? Vastaus riippuu näkökulmasta.

Ominaisuus Provably fair Perinteinen RNG-auditointi
Todentamisen tekijä Pelaaja itse Ulkoinen auditoija (eCOGRA, iTech Labs, GLI)
Todentamisen ajankohta Jokainen kierros, reaaliajassa Jaksottaisesti (kuukausittain tai vuosittain)
Tekninen vaativuus Vaatii pelaajalta ymmärrystä Ei vaadi pelaajalta mitään
Luottamusmalli Nollaluottamus (trust-minimized) Luotetaan auditoijaan ja kasinoon
RTP:n todentaminen Ei sisälly – vain satunnaisuus Sisältyy auditointiin
Sääntelyn vaatimus Ei yleensä riitä sääntelyvaatimuksiin Täyttää MGA:n ja muiden lisenssien vaatimukset
Manipuloinnin havaitseminen Pelaaja voi havaita välittömästi Havaitaan vasta seuraavassa auditoinnissa
Kattavuus 100 % kierroksista todennettavissa Otospohjainen tarkistus
Pelaajan varojen suoja Ei kata Yleensä osa lisenssivaatimuksia
Kustannus kasinolle Matala (toteutus kerran) Korkea (jatkuvat auditoinnit)

Paras ratkaisu: molemmat yhdessä

Ihannetilanteessa kasino tarjoaa sekä provably fair -pelejä että ulkoisen auditoijan sertifioinnin. Tämä antaa pelaajalle:

Valitettavasti tämä yhdistelmä on harvinainen. Useimmat provably fair -kasinot toimivat Curacao-lisenssillä ilman merkittävää auditointia, ja useimmat MGA-lisenssoidut kasinot eivät tarjoa provably fair -pelejä.


Usein kysytyt kysymykset

Miten voin tarkistaa, onko provably fair -peli todella reilu?

Pyydä kasinolta server seed (vaihda uuteen seed-jaksoon), kopioi paljastettu server seed, ja laske SHA-256 hash esimerkiksi online-laskurilla. Jos hash vastaa ennakkoon annettua hashia, server seed on aito. Laske sitten HMAC-SHA256 server seedistä ja client_seed:nonce -yhdistelmästä ja muunna tulos pelitulokseksi kasinon dokumentoimalla algoritmilla. Jos tulos vastaa ilmoitettua, peli on todennettavasti reilu.

Pitääkö jokainen kierros todentaa erikseen?

Ei. Provably fairin voima on siinä, että todentamisen mahdollisuus on olemassa. Jo pelkästään se, että pelaajat voivat tarkistaa tuloksia, estää kasinoa huijaamasta – koska kiinnijääminen olisi väistämätöntä. Käytännössä riittää, että tarkastat satunnaisia kierroksia ajoittain.

Voiko kasino huijata provably fair -pelissä?

Teoreettisesti kyllä, mutta käytännössä se vaatii haavoittuvuuksien hyödyntämistä (heikko RNG, client seedin tietäminen etukäteen). Matemaattisesti oikein toteutettu provably fair -järjestelmä on erittäin vaikea huijata ilman, että pelaajat havaitsevat sen. Suurin riski ei ole pelitulosten manipulointi vaan muut asiat: vakavaraisuus, nostojen viivästyttäminen, epäreilut ehdot.

Mikä ero on SHA-256:lla ja HMAC-SHA256:lla?

SHA-256 on pelkkä hash-funktio: se ottaa yhden syötteen ja tuottaa hashin. HMAC-SHA256 on viestintunnistuskoodi, joka käyttää SHA-256:ta sisäisesti mutta ottaa kaksi syötettä – avaimen (server seed) ja viestin (client seed + nonce). HMAC on suunniteltu kestämään hyökkäyksiä, joille pelkkä SHA-256 + ketjuttaminen on haavoittuvainen.

Onko provably fair -kasino aina parempi kuin perinteinen?

Ei välttämättä. Provably fair kattaa vain pelitulosten todennettavuuden. MGA-lisensoitu perinteinen kasino tarjoaa paremman pelaajaturvan: varojen erottelu, riitojenratkaisu, vastuullisen pelaamisen työkalut, säännöllinen auditointi. Provably fair on arvokas lisäominaisuus, mutta se ei korvaa kokonaisvaltaista sääntelyä.

Mitä teen, jos todentaminen epäonnistuu?

Jos laskettu hash ei vastaa ennakkoon annettua hashia tai pelitulos ei vastaa laskettua, tee seuraavat toimenpiteet:

  1. Tarkista, että käytit oikeaa algoritmia ja oikeita syötteitä (kirjoitusvirheet ovat yleisin syy)
  2. Varmista, että käytit oikeaa nonce-arvoa
  3. Tarkista, vastaako kasinon dokumentaatio todellista algoritmia
  4. Jos virhe on todellinen, tallenna kaikki todisteet (kuvakaappaukset, seed-arvot, hashit)
  5. Raportoi asiasta kasinon asiakaspalveluun ja provably fair -yhteisöfoorumeilla
  6. Varoita muita pelaajia

Miten crash-pelin hash-ketju toimii?

Crash-pelit generoivat tyypillisesti 10 000 tai enemmän hashin ketjun etukäteen. Ketju lasketaan takaperin: viimeisen kierroksen hash generoidaan ensin, ja jokainen edeltävä hash on seuraavan SHA-256-hash. Näin kaikki tulokset ovat ennalta määrättyjä, eikä kasino voi muuttaa mitään yksittäistä tulosta ilman, että koko ketju rikkoutuu.

Voiko provably fairin toteuttaa kolikkopeleihin (sloteihin)?

Kyllä, mutta rajoitetusti. Provably fair -kolikkopelit käyttävät yleensä yksinkertaistettuja mekaniikoita (esim. 3-5 kelaa, rajoitetut symbolit). Perinteiset kolikkopelien valmistajat (NetEnt, Pragmatic Play) eivät käytä provably fairiä, koska heidän pelinsä käyttävät monimutkaisia RTP-taulukoita ja bonusmekaniikoita, joiden todennettavuus vaatisi kaikkien sisäisten parametrien julkistamista.

Kuinka usein client seed kannattaa vaihtaa?

Hyvä käytäntö on vaihtaa client seed säännöllisesti – esimerkiksi joka pelisession alussa tai joka päivä. Tärkeämpää kuin vaihtotiheys on se, että asetat oman client seedin kasinon oletusten sijaan.


Tämä artikkeli on päivitetty 28.3.2026. Sisältö on laadittu toimituksen toimesta perustuen kryptografiseen tutkimuskirjallisuuteen, avoimeen lähdekoodiin ja provably fair -protokollien tekniseen dokumentaatioon. Artikkeli ei sisällä kasinolistauksia eikä suosittele yksittäisiä kasinoita. Rahapelaaminen on 18+ -toimintaa ja siihen liittyy aina häviämisen riski. Pelaa vastuullisesti.

Lähteet: NIST FIPS 180-4 (SHA-256 standardi), RFC 2104 (HMAC), Bitcointalk-foorumin provably fair -dokumentaatio, Fisher-Yates shuffle -alkuperäisjulkaisu (1938), Knuth – The Art of Computer Programming Vol. 2.