Vero
The vero package generates random numbers for online casinos games such as dice, roll, crash, etc.
All the algorithms are provably fair.
Install
go get github.com/pastc/vero
Features
- No third-party dependencies
- Provably fair
- Many games:
Guide
Common arguments
// Generated automatically. Is private and is changed periodically. It should become public after being decommissioned.
var serverSeed string
// Generated uniquely to each player. Can be changed anytime by the player themselves.
var clientSeed string
// Generated automatically. Is public and is changed periodically.
var publicSeed string
// A number that is incremented by 1 for each game played.
var nonce int
// A number that is incremented by 1 if the randomly generated value goes out of bounds and eventually exhausts all available random numbers within the available hash.
// Should be 0 when calling the function from outside.
var iteration int
Crash
Arguments
var serverSeed string
// houseEdge i.e, percentage that the house gets.
var houseEdge float64
Example
// Remember to divide the crashPoint by 100 to get the percentage
crashPoint, err := vero.Crash(serverSeed, houseEdge)
if err != nil {
log.Fatal(err)
}
Explanation
-
The function calculates an HMAC-SHA256 hash using the serverSeed
and a combined seed
. This hash is used as a
source of randomness.
-
The most significant 52 bits of the hash are extracted and interpreted as a hexadecimal number, which is then
converted to an integer (h
).
-
The value e
(2^52) is calculated, which is approximately 4.5035e+15. This value represents the maximum value that
can be represented precisely in the mantissa of a 64-bit floating-point number.
-
The function then calculates the crash point multiplier (result
) using the values of h
and e
. The
formula (100*e - float64(h)) / (e - float64(h))
maps the value of h
(which is in the range [0, e]
) to a value
in the range [100, infinity]
.
-
The houseEdgeModifier
is calculated based on the specified house edge percentage. For example, if the house edge is
5%, the houseEdgeModifier
will be 0.95 with the lowest crashing point of 100.
-
The final crash point multiplier (endResult
) is calculated by multiplying result by houseEdgeModifier
and
ensuring that it is at least 100 (the minimum crash point).
-
The function returns the crash point multiplier endResult
as an integer, which represents the crash point
multiplier.
Dice
Arguments
var serverSeed string
var clientSeed string
var nonce int
var iteration int
Example
// Remember to divide the value by 100 to get a number from 0 to 99.99
value, err := vero.Dice(serverSeed, clientSeed, nonce, 0)
if err != nil {
log.Fatal(err)
}
Explanation
-
The function calculates an HMAC-SHA512 hash using the serverSeed
and a combined seed
. This hash is used as a
source of randomness.
-
The GetLucky
function extracts a substring of length 5 from the hash
string starting at the position index*5
.
This substring is then converted from a hexadecimal string to an integer. The function returns the random integer and
any error that may have occurred during the conversion.
-
The for loop ensures that the lucky
integer is above 10^6 (1000000) since it will be divided by 10^4 (10000) later.
-
If it is under 10^6, then the index
is incremented by 1 and the GetLucky
is called again.
-
This continues until the index
goes out of bounds. If that happens, the Dice
function is called with the iteration
value incremented by 1.
-
The final number (luckyNumber
) is calculated by using the formula math.Mod(float64(lucky), math.Pow(10, 4))
which
divides the value of lucky by 10^4 (10000) and gets the remainder. This ensures that the final number is in the range
of [0, 9999]
.
-
The function returns the random value luckyNumber
.
Explanation
Roll
Arguments
var serverSeed string
var publicSeed string
var nonce int
// maximum represents the maximum value that can be rolled, counting from 0.
//
// Example if maximum is 5:
// 0, 1, 2, 3, 4
var maximum int
// colorMap represents the colors mapped to values.
var colorMap map[int]string
// baitMap represents the baits mapped to values.
var baitMap map[int]string
Example
// color represents the color that it landed on
// value represents the number that it landed on
color, value, err := vero.Dice(serverSeed, publicSeed, nonce, maximum, colorMap, baitMap)
if err != nil {
log.Fatal(err)
}
Explanation
-
The function calculates an HMAC-SHA256 hash using the serverSeed
and a combined seed
. This hash is used as a
source of randomness.
-
The GetRandomInt
function extracts a substring of length 13 from the hash
string starting at the position 0
.
-
This substring is then converted from a hexadecimal string to an integer.
-
The value e
(2^52) is calculated, which is approximately 4.5035e+15. This value represents the maximum value
that can be represented precisely in the mantissa of a 64-bit floating-point number.
-
The formula math.Floor((float64(valueFromHash) / e) * float64(max))
calculates a random number that is in the
range of [0, max]
.
-
The function returns the random integer and any error that may have occurred during the conversion.
-
The GetRollColor
function finds the corresponding color and bait from the index number rollValue
which was
returned from GetRandomInt
.
-
The function returns the random value rollValue
, the color and bait rollColor
.
Plinko
Arguments
var serverSeed string
var clientSeed string
var nonce int
var iteration int
// rows represents the number of rows in the triangle.
var rows int
Example
// column represents the index of the column that the ball dropped into.
column, err := vero.Plinko(serverSeed, clientSeed, nonce, 0, rows)
if err != nil {
log.Fatal(err)
}
Explanation
Think of it as a Pascal's triangle.
0 0
1 0 1
2 0 1 2
3 0 1 2 3
-
Variable coordinate
is initialised to track the net deviation from the center position.
-
The for loop loops for any number in the range [0, rows]
.
-
The function calculates an HMAC-SHA256 hash using the serverSeed
and a combined seed
. This hash is used as a
source of randomness.
-
The GetLucky
function extracts a substring of length 5 from the hash
string starting at the
position index*5
. This substring is then converted from a hexadecimal string to an integer. The function
returns the random integer and any error that may have occurred during the conversion.
-
The for loop ensures that the lucky
integer is above 10^6 (1000000) since it will be divided by 10^4 (10000)
later. If it is under 10^6, then the index
is incremented by 1 and the GetLucky
is called again. This
continues until the index
goes out of bounds. If that happens, the Dice
function is called with
the iteration
value incremented by 1.
-
The final number (luckyNumber
) is calculated by using the formula math.Mod(float64(lucky), math.Pow(10, 4))
which divides the value of lucky by 10^4 (10000) and gets the remainder. This ensures that the final number is in
the range of [0, 9999]
.
-
If the luckyNumber is in the range of [0, 4999]
the ball goes to the left. (coordinate -= 1)
If the luckyNumber is in the range of [5000, 9999]
the ball goes to the right. (coordinate += 1)
-
The function returns the column number (rows + coordinate) / 2
that the ball landed on.
Documentation
Full go doc
style documentation for the package can be viewed online without
installing this package by using the GoDoc site here:
https://pkg.go.dev/github.com/pastc/vero