Provably Fair Float Generator System
This system is designed to provide a secure, tamper-proof method for generating random numbers (as floating-point numbers between 0 and 1) using a Provably Fair algorithm. The core principle is to ensure that neither the server nor the player can predict or control the outcome of a giveaway or objective generation ahead of time. Upon completion, the server will reveal its secret seed, allowing players to verify the fairness of the results.
How It Works
The float generation system uses a combination of:
- Server Main Seed: A secret string known only to the server until results are revealed.
- Public Seed: A string chosen by the client (user), which they can modify.
- Nonce: A number incremented after each event or round to prevent repetition.
- Cursor: Determines how many 32-byte hashes to generate for chaining randomness.
These inputs are combined via HMACSHA256
to produce cryptographically strong, deterministic random data.
GenerateBytes Function
This function takes the server main seed, public seed, nonce, and cursor, then produces a byte array by chaining HMAC-SHA256 hashes. Each hash uses the server main seed as a key and a message built from the public seed, nonce, and iteration index.
public static byte[] GenerateBytes(string serverSeed, string player(s)Seed, int nonce, int cursor)
{
byte[] result = new byte[32 * (cursor + 1)];
int byteIndex = 0;
for (int i = 0; i < cursor + 1; i++)
{
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(serverSeed)))
{
byte[] inputBytes = Encoding.UTF8.GetBytes($"{player(s)Seed}:{nonce}:{i}");
byte[] hashBytes = hmac.ComputeHash(inputBytes);
int bytesCopied = Math.Min(32, hashBytes.Length);
Array.Copy(hashBytes, 0, result, byteIndex, bytesCopied);
byteIndex += bytesCopied;
}
}
return result;
}
This produces a reliable, deterministic sequence of bytes, used as the foundation for fair and transparent random number generation.
GenerateFloats Function
This function takes the generated bytes from GenerateBytes
and converts them into floating-point numbers between 0 and 1.
Each float is created by combining four sequential bytes and scaling them based on their position to ensure even distribution.
public static List<double> GenerateFloats(string serverSeed, string player(s)Seed, int nonce, int cursor, int count)
{
List<double> floatList = new List<double>();
byte[] bytes = GenerateBytes(serverSeed, player(s)Seed, nonce, cursor);
for (int i = 0; i < count * 4; i += 4)
{
byte[] chunk = new byte[4];
Array.Copy(bytes, i, chunk, 0, 4);
double floatValue = 0;
for (int j = 0; j < 4; j++)
{
floatValue += chunk[j] / Math.Pow(256, j + 1);
}
floatList.Add(floatValue);
}
return floatList;
}
The result is a list of provably fair, pseudorandom floating-point numbers ready for use in generating giveaway outcomes, objectives, or other random logic-driven applications.
Provable Fairness Verification Process
By combining a server main seed (revealed after use), a public player(s) seed (always publically displayed and changeable in account settings), and a nonce (unique per event), this system ensures that neither party can alter or influence generation after seeing the other’s input.
Players can verify fairness by:
- Recording their public seed and nonce before the event begins.
- Waiting for the server to reveal its server main seed after the results are final.
- Running the same algorithm locally to reproduce the float values from the seeds and nonce.
- Confirming that the generated numbers match the results exactly.