- Server should save a random bytestring
PS(regenerated after each full match) for each player.PSshould be visible on game UI. - Server should publish a global 1024-bit (128 bytes) random bytestring
GS(changed every X minutes). Current and nextGSshould be visible on game UI. - When a match starts, save timestamp
T1. - When a round starts, save timestamp
T2, and generate a random bytestringR. Then, generate random seed for this round by calculating SHA512 hash of concatenation of following elements (||denotes concatenation):
- T1
- T2
- R
- HMAC-SHA512(GS, T1 || T2 || R)
- HMAC-SHA512(PS, T1 || T2 || R) for each player
- Use RFC7539 ChaCha20 as random number generator. Key, nonce and block count are sliced from the hash generated in step #4. Generated bitstream should be XORed with
GSto produce output. - Use Fisher–Yates algorithm to shuffle the tiles.
- All random bytestrings should be at least 32 bytes long, and preferably generated from
/dev/urandomorRDRAND. - All timestamps should be at least in millisecond precision
- All seed materials should be saved in game record for verification
T1,T2andRshould be kept on server-side and NOT revealed to players until the match is completed
- Random number generator with deterministic seed allows players to verify that tiles are shuffled using this algorithm
GSandPSensure that server can't use a pre-generated tile list for a specific gameT1,T2andRintroduce randomness into the algorithm, and ensure player can't compute tile list for games in progress- XORing with
GSis for increasing number of possible permutions to 1024bit