Introduction to Provably Fair

F5 Works
3 min readJun 24, 2016

Random is not TRUE random

When you build a software system with a Random Number Generator (e.g. lucky draw), technically it could not be 100% random, it is just super difficult for outsider to guess. One key factor to control the randomness is called seed.

With the same seed value, the outcome is always the same. For example:

generate = Random.new(1234) # 1234 is the seed value here
generate.rand(100) # pick a random number from 1 to 100
=> 47
generate.rand(100) # pick another random number from 1 to 100
=> 83

If I use the same seed value to generate again:

generate = Random.new(1234) # 1234 is the seed value here
generate.rand(100) # pick a random number from 1 to 100
=> 47
generate.rand(100) # pick another random number from 1 to 100
=> 83

so, you can see here, if the seed is known, the outcome is actually predictable.

Design a lucky draw that is fair to players

This predictability can also be used to prove that the vendor did not manipulate the result for their own benefit. There is an algorithm calledProvably Fair. It is a way to scientifically prove your system is fair to the players.

here is the TLDR; version:
1) Lottery owner pre-define (or generate) the seed for an upcoming lucky draw event;
2) Lottery owner publish the hash* value of the seed before the lucky draw game;
3) After the game, the plain text form of the seed is published too, for players to verify the seed has not been changed by any body during the game.

*Note: Hash value is a transformed version of the original value, which is easy to verify, but difficult to reverse. For example:

Digest::SHA256.hexdigest "1234"
=> "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"

It takes ages to find out the original value of “03ac67421…”, but it is easy to verify that hash value of “1234” is “03ac67421…”

Provably Fair example

Here are the detailed steps for a Provably Fair design with players’ involvement. The main objective is to form the seed values from both players and lottery owner, so that no single party can predict the seed value before the draw happens.

I am using a shuffle card deck as the example:

1) Generate a “Server Seed”

Server Seed=87a127a48db58da45dce1691e35b93bd
Original Deck=[1,2,3,4......49]

2) Then shuffle the original deck using the Server Seed

Shuffled Deck = [4,13,9,8,30....]

3) Hash the shuffled deck with server seed, to become “Secret”

Secret = Hash (Server Seed + Shuffled Deck)

4) This secret is published, meaning both server seed and the shuffled deck wont be changed.

5) Then players can start participating and add new seeds (Client Seeds) until the draw happens

Client Seeds = 06f22224537b02a3c59f69e65fec4130

6) When it is time to do the final shuffle to draw the result, system combines both Server Seed and Client Seed to shuffle the card:

Final Deck = shuffle ( Shuffled Deck, (Server Seed + Client Seed) )

7) Finally, all information will be published after the game, for people to verify that the draw result is the output of all the Server Seeds and Client Seeds.

Since the final shuffle including both Server seed and Client seed, this imply NO SINGLE PARTY can control the random process; this is Provably Fair.

Steven Wong

F5 Works

--

--

F5 Works

We are experienced development team based in Hong Kong. Passion in web, mobile app applications development and design.