Difference between revisions of "SIBR:Random number generator"

From Blaseball Wiki

m
(Add RNG details)
Line 2: Line 2:
  
 
XorShift128+ is not [[Wikipedia:Cryptographically-secure pseudorandom number generator|cryptographically secure]]. With three known consecutive outputs, the RNG state can be fully reconstructed,<ref>https://blog.securityevaluators.com/hacking-the-javascript-lottery-80cc437e3b7f</ref> allowing us to determine what all subsequent values would be. Furthermore, the algorithm is fully reversible so we can determine all preceding values as well.<ref>https://blog.securityevaluators.com/xorshift128-backward-ff3365dc0c17</ref> Using this technique, we can select a player whose earliest recorded stats were unchanged since generation, recover the RNG state from when that player was created, and examine the surrounding values to find stats for other players that were created at the same time.
 
XorShift128+ is not [[Wikipedia:Cryptographically-secure pseudorandom number generator|cryptographically secure]]. With three known consecutive outputs, the RNG state can be fully reconstructed,<ref>https://blog.securityevaluators.com/hacking-the-javascript-lottery-80cc437e3b7f</ref> allowing us to determine what all subsequent values would be. Furthermore, the algorithm is fully reversible so we can determine all preceding values as well.<ref>https://blog.securityevaluators.com/xorshift128-backward-ff3365dc0c17</ref> Using this technique, we can select a player whose earliest recorded stats were unchanged since generation, recover the RNG state from when that player was created, and examine the surrounding values to find stats for other players that were created at the same time.
 +
 +
==RNG details==
 +
XorShift128+ uses two 64-bit state variables, which we call <code>s0</code> and <code>s1</code>. Knowing the value of these for a given output value is sufficient to recreate the RNG output both forward and backward from that point. However, the Blaseball sim uses Node.js running on the V8 Javascript engine, which introduces a complication: XorShift128+ is used to pre-generate a batch of 64 random values, which are then returned in reverse order. When correlating known values with the expected RNG output, we must determine where the boundaries are for these blocks and reverse each set of 64 values.
 +
 +
Therefore, we use a triple of <code>(s0, s1, offset)</code> to fully describe a point in the output stream, where <code>offset</code> is the index within a 64-value block. For example, <code>(78357228809041901, 13627021481113128807, 29)</code> gives us the [https://rng.sibr.dev/?s0=78357228809041901&s1=13627021481113128807&offset=29 first of the series of rolls] used to generate [[Lars Taylor]] prior to Season 1.
  
 
==Player generation==
 
==Player generation==

Revision as of 12:52, 19 August 2021

The Blaseball backend uses a pseudorandom number generator called XorShift128+ to generate random values. These values are used for a variety of purposes, including attributes for newly-hatched players and determining event outcomes during games.

XorShift128+ is not cryptographically secure. With three known consecutive outputs, the RNG state can be fully reconstructed,[1] allowing us to determine what all subsequent values would be. Furthermore, the algorithm is fully reversible so we can determine all preceding values as well.[2] Using this technique, we can select a player whose earliest recorded stats were unchanged since generation, recover the RNG state from when that player was created, and examine the surrounding values to find stats for other players that were created at the same time.

RNG details

XorShift128+ uses two 64-bit state variables, which we call s0 and s1. Knowing the value of these for a given output value is sufficient to recreate the RNG output both forward and backward from that point. However, the Blaseball sim uses Node.js running on the V8 Javascript engine, which introduces a complication: XorShift128+ is used to pre-generate a batch of 64 random values, which are then returned in reverse order. When correlating known values with the expected RNG output, we must determine where the boundaries are for these blocks and reverse each set of 64 values.

Therefore, we use a triple of (s0, s1, offset) to fully describe a point in the output stream, where offset is the index within a 64-value block. For example, (78357228809041901, 13627021481113128807, 29) gives us the first of the series of rolls used to generate Lars Taylor prior to Season 1.

Player generation

When a new player is created, their attributes are generated by a series of consecutive rolls in the following order:

first name
last name
thwackability
moxie
divinity
musclitude
patheticism
buoyancy
baseThirst
laserlikeness
groundFriction
continuation
indulgence
martyrdom
tragicness
shakespearianism
suppression
unthwackability
coldness
overpowerment
ruthlessness
omniscience
tenaciousness
watchfulness
anticapitalism
chasiness
pressurization
cinnamon, if player has 'cinnamon' field
soul = floor(rand()*8+2)
allergy = rand() < 0.5, if player has 'peanutAllergy' field
fate = floor(rand()*100), if player has 'fate' field
ritual (value unknown), if s12 or later
blood = floor(rand()*13), if s12 or later
coffee = floor(rand()*13), if s12 or later

See also