Provable Fairness Requires Bit-For-Bit Arithmetic Consistency Between Server and Verifier
The article discusses the technical intricacies of ensuring provable fairness in cryptographic systems, particularly focusing on the critical need for the browser-based verifier to match the server’s arithmetic operations exactly, bit for bit. The core issue arises when converting a 256-bit hash into a number between 0 and 1 for game outcomes. Both the server (written in Kotlin) and the browser verifier (written in JavaScript) use 64-bit doubles with 53 bits of precision, but a hash contains more bits than can be precisely represented. The problem occurs when rounding happens multiple times during conversion versus a single rounding, which can cause discrepancies in the final outcome, such as a game multiplying the number by 37 and rounding down landing in a different pocket. The article explains that the Betkyo engine avoids this by constructing the number from two exact pieces added in one operation: the first four bytes divided by 2^32 plus the next bytes divided by 2^56 or 2^64, ensuring only one rounding occurs, matching the server’s single conversion. For games like Crash, which uses exact integer arithmetic on the leading 52 bits without floating-point approximations, the verifier never uses doubles, preventing discrepancies at floor boundaries where floating-point errors could cause false rejections. The article emphasizes that the verifier is not an approximation but the exact same arithmetic as the server, making a rejection meaningful rather than noise. The design ensures that the same function is used by both the generator and verifier, eliminating drift between the two systems. The article concludes that provable fairness is not just a claim but depends on precise arithmetic consistency, with failures indicating actual input differences rather than rounding errors. The technical details are verified through source code references, showing how the implementation matches the server’s behavior exactly.
