Provably Fair

What is it?

Players always fear to be cheated on an online casino. This is understandable because it is technically very easy for an online casino to just make you lose. The solution came from the Bitcoin gambling community and it's called "provably fair". Provably fair is a tool that enables you (the player) to verify each roll result and make sure you are not being cheated!

Find out more at Wikipedia or use Google yourself!

How we do it for BlackJack

Check your results

The information needed to check your results can be found in the round and bet history. During every round the Round ID and Public Seed are shown on the top left of the page.

Calculated Dealer Cards:
Calculated Player Cards:

Source Code

function outcomeGenerator(server_secret, client_seed)
{
    this.server_secret_ = server_secret || "";
    this.client_seed_ = client_seed || "";
}

outcomeGenerator.prototype = {
    constructor:outcomeGenerator,

	setServerSecret:function(secret)
	{
		this.server_secret_ = secret;
	},

	setClientSeed:function(seed)
	{
		this.client_seed_ = seed;
	},

	getDealerOutcome:function(round_id, card_number)
	{
		var hash = keccak_512.create();
		hash.update(this.server_secret_);
		hash.update(this.client_seed_);
		hash.update(round_id.toString());
		hash.update(card_number.toString());

		return hash.hex();
	},

	getPlayerOutcome:function(round_id, card_number, steam_id)
	{
		var hash = keccak_512.create();
		hash.update(this.server_secret_);
		hash.update(steam_id);
		hash.update(round_id.toString());
		hash.update(card_number.toString());

		return hash.hex();
	}
};


function getCardNumber(outcome_hash)
{
    var sub_hash = "";
    for(var i = 0; i < outcome_hash.length; ++i)
    {
        sub_hash += outcome_hash[i];

        if(sub_hash.length > 4)
        {
            var num = parseInt(sub_hash, 16);

            if((num != NaN) && (num < 999999))
            {
                return 1 + (num % 52);
            }

            sub_hash = "";
        }
    }

    return 1;
}


function getDealerCards(outcome_gen, round_id, n)
{
	var cards = [];

	for(var i = 0; i < n; ++i)
	{
		cards.push(getCardNumber(outcome_gen.getDealerOutcome(round_id, i+1)));
	}

	return cards;
}


function getPlayerCards(outcome_gen, round_id, steam_id, n)
{
	var cards = [];

	for(var i = 0; i < n; ++i)
	{
		cards.push(getCardNumber(outcome_gen.getPlayerOutcome(round_id, i+1, steam_id)));
	}

	return cards;
}

var cardDecks =
{
    "cards":
    {
        1: {"image": "/static/img/cards/spades/A.png", "value": [1,11]},
        2: {"image": "/static/img/cards/spades/2.png", "value": [2]},
        3: {"image": "/static/img/cards/spades/3.png", "value": [3]},
        4: {"image": "/static/img/cards/spades/4.png", "value": [4]},
        5: {"image": "/static/img/cards/spades/5.png", "value": [5]},
        6: {"image": "/static/img/cards/spades/6.png", "value": [6]},
        7: {"image": "/static/img/cards/spades/7.png", "value": [7]},
        8: {"image": "/static/img/cards/spades/8.png", "value": [8]},
        9: {"image": "/static/img/cards/spades/9.png", "value": [9]},
        10: {"image": "/static/img/cards/spades/10.png", "value": [10]},
        11: {"image": "/static/img/cards/spades/J.png", "value": [10]},
        12: {"image": "/static/img/cards/spades/Q.png", "value": [10]},
        13: {"image": "/static/img/cards/spades/K.png", "value": [10]},

        14: {"image": "/static/img/cards/hearts/A.png", "value": [1,11]},
        15: {"image": "/static/img/cards/hearts/2.png", "value": [2]},
        16: {"image": "/static/img/cards/hearts/3.png", "value": [3]},
        17: {"image": "/static/img/cards/hearts/4.png", "value": [4]},
        18: {"image": "/static/img/cards/hearts/5.png", "value": [5]},
        19: {"image": "/static/img/cards/hearts/6.png", "value": [6]},
        20: {"image": "/static/img/cards/hearts/7.png", "value": [7]},
        21: {"image": "/static/img/cards/hearts/8.png", "value": [8]},
        22: {"image": "/static/img/cards/hearts/9.png", "value": [9]},
        23: {"image": "/static/img/cards/hearts/10.png", "value": [10]},
        24: {"image": "/static/img/cards/hearts/J.png", "value": [10]},
        25: {"image": "/static/img/cards/hearts/Q.png", "value": [10]},
        26: {"image": "/static/img/cards/hearts/K.png", "value": [10]},

        27: {"image": "/static/img/cards/clubs/A.png", "value": [1,11]},
        28: {"image": "/static/img/cards/clubs/2.png", "value": [2]},
        29: {"image": "/static/img/cards/clubs/3.png", "value": [3]},
        30: {"image": "/static/img/cards/clubs/4.png", "value": [4]},
        31: {"image": "/static/img/cards/clubs/5.png", "value": [5]},
        32: {"image": "/static/img/cards/clubs/6.png", "value": [6]},
        33: {"image": "/static/img/cards/clubs/7.png", "value": [7]},
        34: {"image": "/static/img/cards/clubs/8.png", "value": [8]},
        35: {"image": "/static/img/cards/clubs/9.png", "value": [9]},
        36: {"image": "/static/img/cards/clubs/10.png", "value": [10]},
        37: {"image": "/static/img/cards/clubs/J.png", "value": [10]},
        38: {"image": "/static/img/cards/clubs/Q.png", "value": [10]},
        39: {"image": "/static/img/cards/clubs/K.png", "value": [10]},

        40: {"image": "/static/img/cards/diamonds/A.png", "value": [1,11]},
        41: {"image": "/static/img/cards/diamonds/2.png", "value": [2]},
        42: {"image": "/static/img/cards/diamonds/3.png", "value": [3]},
        43: {"image": "/static/img/cards/diamonds/4.png", "value": [4]},
        44: {"image": "/static/img/cards/diamonds/5.png", "value": [5]},
        45: {"image": "/static/img/cards/diamonds/6.png", "value": [6]},
        46: {"image": "/static/img/cards/diamonds/7.png", "value": [7]},
        47: {"image": "/static/img/cards/diamonds/8.png", "value": [8]},
        48: {"image": "/static/img/cards/diamonds/9.png", "value": [9]},
        49: {"image": "/static/img/cards/diamonds/10.png", "value": [10]},
        50: {"image": "/static/img/cards/diamonds/J.png", "value": [10]},
        51: {"image": "/static/img/cards/diamonds/Q.png", "value": [10]},
        52: {"image": "/static/img/cards/diamonds/K.png", "value": [10]},

        "back": {"image": "/static/img/cards/back_2.png", "value": false}
    }
}


window.onload = function()
{
	var round_id = ""; //the round id of which you want to get the cards
	var steam_id = ""; //the steamid for which you want to get the cards
	var server_secret = ""; //the server_secret that was active for the round of which you want to get the cards
	var client_secret = ""; //the client secret that was given to you for the round of which you want to get the cards
	var n = 5; //number of cards to calculate

	var outcome_gen = new outcomeGenerator(server_secret, client_secret);

	console.log("dealer cards: " + getDealerCards(outcome_gen, round_id, n)); //use results to get card value from cardDecks object
	console.log("player cards: " + getPlayerCards(outcome_gen, round_id, steam_id, n));


}

How we do it for Roulette

Check your results

The information needed to check your results can be found in the round and bet history. Below you will find the source code to show how bets can be confirmed.

Source Code

function outcomeGenerator(server_secret, client_seed)
{
    this.server_secret_ = server_secret || "";
    this.client_seed_ = client_seed || "";
}

outcomeGenerator.prototype = {
    constructor:outcomeGenerator,

    setServerSecret:function(secret)
    {
        this.server_secret_ = secret;
    },

    setClientSeed:function(seed)
    {
        this.client_seed_ = seed;
    },

    getDealerOutcome:function(round_id, card_number)
    {
        var hash = keccak_512.create();
        hash.update(this.server_secret_);
        hash.update(this.client_seed_);
        hash.update(round_id.toString());
        hash.update(card_number.toString());

        return hash.hex();
    }
};


function getCardNumber(outcome_hash)
{
    var sub_hash = "";
    for(var i = 0; i < outcome_hash.length; ++i)
    {
        sub_hash += outcome_hash[i];

        if(sub_hash.length > 4)
        {
            var num = parseInt(sub_hash, 16);

            if((num != NaN) && (num < 999999))
            {
                return num % 15;
            }

            sub_hash = "";
        }
    }

    return 1;
}


function getDealerCards(outcome_gen, round_id, n)
{
    var cards = [];

    for(var i = 0; i < n; ++i)
    {
        cards.push(getCardNumber(outcome_gen.getDealerOutcome(round_id, i+1)));
    }

    return cards;
}

var cardDecks =
{
    "cards":
    {
        1: {"image": "/static/img/cards/spades/AS.png", "value": [1,11]}, //special ace (green)
        2: {"image": "/static/img/cards/spades/2.png", "value": [2]},
        3: {"image": "/static/img/cards/spades/3.png", "value": [3]},
        4: {"image": "/static/img/cards/spades/4.png", "value": [4]},
        5: {"image": "/static/img/cards/spades/5.png", "value": [5]},
        6: {"image": "/static/img/cards/spades/6.png", "value": [6]},
        7: {"image": "/static/img/cards/spades/7.png", "value": [7]},
        8: {"image": "/static/img/cards/spades/8.png", "value": [8]},
        9: {"image": "/static/img/cards/spades/9.png", "value": [9]},
        10: {"image": "/static/img/cards/spades/10.png", "value": [10]},
        11: {"image": "/static/img/cards/spades/J.png", "value": [10]},
        12: {"image": "/static/img/cards/spades/Q.png", "value": [10]},
        13: {"image": "/static/img/cards/spades/K.png", "value": [10]},

        14: {"image": "/static/img/cards/hearts/AS.png", "value": [1,11]}, //special ace (green)
        15: {"image": "/static/img/cards/hearts/2.png", "value": [2]},
        16: {"image": "/static/img/cards/hearts/3.png", "value": [3]},
        17: {"image": "/static/img/cards/hearts/4.png", "value": [4]},
        18: {"image": "/static/img/cards/hearts/5.png", "value": [5]},
        19: {"image": "/static/img/cards/hearts/6.png", "value": [6]},
        20: {"image": "/static/img/cards/hearts/7.png", "value": [7]},
        21: {"image": "/static/img/cards/hearts/8.png", "value": [8]},
        22: {"image": "/static/img/cards/hearts/9.png", "value": [9]},
        23: {"image": "/static/img/cards/hearts/10.png", "value": [10]},
        24: {"image": "/static/img/cards/hearts/J.png", "value": [10]},
        25: {"image": "/static/img/cards/hearts/Q.png", "value": [10]},
        26: {"image": "/static/img/cards/hearts/K.png", "value": [10]},

        27: {"image": "/static/img/cards/clubs/AS.png", "value": [1,11]}, //special ace (green)
        28: {"image": "/static/img/cards/clubs/2.png", "value": [2]},
        29: {"image": "/static/img/cards/clubs/3.png", "value": [3]},
        30: {"image": "/static/img/cards/clubs/4.png", "value": [4]},
        31: {"image": "/static/img/cards/clubs/5.png", "value": [5]},
        32: {"image": "/static/img/cards/clubs/6.png", "value": [6]},
        33: {"image": "/static/img/cards/clubs/7.png", "value": [7]},
        34: {"image": "/static/img/cards/clubs/8.png", "value": [8]},
        35: {"image": "/static/img/cards/clubs/9.png", "value": [9]},
        36: {"image": "/static/img/cards/clubs/10.png", "value": [10]},
        37: {"image": "/static/img/cards/clubs/J.png", "value": [10]},
        38: {"image": "/static/img/cards/clubs/Q.png", "value": [10]},
        39: {"image": "/static/img/cards/clubs/K.png", "value": [10]},

        40: {"image": "/static/img/cards/diamonds/AS.png", "value": [1,11]}, //special ace (green)
        41: {"image": "/static/img/cards/diamonds/2.png", "value": [2]},
        42: {"image": "/static/img/cards/diamonds/3.png", "value": [3]},
        43: {"image": "/static/img/cards/diamonds/4.png", "value": [4]},
        44: {"image": "/static/img/cards/diamonds/5.png", "value": [5]},
        45: {"image": "/static/img/cards/diamonds/6.png", "value": [6]},
        46: {"image": "/static/img/cards/diamonds/7.png", "value": [7]},
        47: {"image": "/static/img/cards/diamonds/8.png", "value": [8]},
        48: {"image": "/static/img/cards/diamonds/9.png", "value": [9]},
        49: {"image": "/static/img/cards/diamonds/10.png", "value": [10]},
        50: {"image": "/static/img/cards/diamonds/J.png", "value": [10]},
        51: {"image": "/static/img/cards/diamonds/Q.png", "value": [10]},
        52: {"image": "/static/img/cards/diamonds/K.png", "value": [10]},
        53: {"image": "/static/img/cards/live/1.png", "value": [10]},
        54: {"image": "/static/img/cards/live/1.png", "value": [10]},

        "back": {"image": "/static/img/cards/back_2.png", "value": false}
    }
}


window.onload = function()
{
    var round_id = ""; //the round id of which you want to get the cards
    var server_secret = ""; //the server_secret that was active for the round of which you want to get the cards
    var client_secret = ""; //the client secret that was given to you for the round of which you want to get the cards
    var n = 5; //number of cards to calculate

    var outcome_gen = new outcomeGenerator(server_secret, client_secret);

    console.log("dealer cards: " + getDealerCards(outcome_gen, round_id, n)); //use results to get card value from cardDecks object
}

How we do it for Coinflip

Check your results

The information needed to check your results can be found in the Coinflip history. Below you will find the source code to show how bets can be confirmed.

Source Code

var gameSecret = ""; // secret server hash during the game
var gameHash = ""; // Public hash during the game
var gameId = ""; // game id
var hash = keccak_512.create();
hash.update(gameSecret.toString());
hash.update(gameHash.toString());
hash.update(gameId.toString());
var hash = hash.hex();

//console.log(hash);
var winningPercentage = getWinPercentage(hash)
//console.log(winningPercentage);
var winning_choice = winningPercentage < 50.0 ? 0 : 1;

var winning_choice_text;
if(winning_choice === 0) {
    winning_choice_text = "Kings";
} else {
    winning_choice_text = "Queens";
}


function getWinPercentage(outcome_hash) //This will return a percentage, lower than 50 will be Kings, and 50 or higher will be Queen.
{
var sub_hash = "";
for(var i = 0; i < outcome_hash.length; ++i)
{
    sub_hash += outcome_hash[i];

    if(sub_hash.length > 4)
    {
        var num = parseInt(sub_hash, 16);

        if((num != NaN) && (num < 999999))
        {
            return (num % 10000) / 100.0;
        }

        sub_hash = "";
    }
}

return 0.01;
}

How we do it for the Lottery

Check your results

The information needed to check your results can be found in the lottery history. During every round the lottery client secret is shown on the lottery page.

The lottery results checker will come soon...

Source Code

function outcomeGenerator(server_secret, client_seed)
{
    this.server_secret_ = server_secret || "";
    this.client_seed_ = client_seed || "";
}

outcomeGenerator.prototype = {
    constructor:outcomeGenerator,

    setServerSecret:function(secret)
    {
        this.server_secret_ = secret;
    },

    setClientSeed:function(seed)
    {
        this.client_seed_ = seed;
    },

    getTicketOutcome:function(round_id, ticket_size)
    {
        var hash = keccak_512.create();
        hash.update(this.server_secret_);
        hash.update(this.client_seed_);
        hash.update(round_id.toString());
        hash.update(ticket_size.toString());

        return hash.hex();
    }
};


function getTicketIndex(outcome_hash, ticket_size)
{
    var sub_hash = "";
    for(var i = 0; i < outcome_hash.length; ++i)
    {
        sub_hash += outcome_hash[i];

        if(sub_hash.length > 5)
        {
            var num = parseInt(sub_hash, 16);

            if(num != NaN)
            {
                return (num % ticket_size);
            }

            sub_hash = "";
        }
    }

    return 1;
}


window.onload = function()
{
    var round_id = 123; //the round id of which you want to get the result
    var ticket_size = 123; //the amount of tickets int he round for which you want to get the result
    var server_secret = ""; //the server_secret that was active for the round of which you want to get the result
    var client_secret = ""; //the client secret that was given to you for the round of which you want to get the result

    var outcome_gen = new outcomeGenerator(server_secret, client_secret);

    console.log("winning index: " + getTicketIndex(outcome_gen.getTicketOutcome(round_id, ticket_size), ticket_size).toString());
}