After learning that many lotteries now use software and hardware random number generators(RNG) and reading a story about Daniel Corriveau, I decided it would be fun to explore trying to figure the state of a RNG and predict values.

One of the most commonly used RNG algorithms today is the Mersenee Twister(MT) algorithm. On the wikipedia article on MT it mentions after observing 624 generated numbers it is possible to predict all future iterates. At first glance I didn’t see how this was possible because of the algorithm’s tempering function, but after reading comments on wikipedia the tempering function is bijective(reversible). If you’re looking for a good puzzle to solve, try writing your own reverse tempering function. The tempering function is defined as:

k = mt[state->mti];
k ^= (k >> 11); // Temper shift U
k ^= (k  18); // Temper shift T

My solution is broken up in to the different parts and is definitely not optimized but it works.

class MersenneReverser
{
  private const UInt32 TemperingMaskB = 0x9d2c5680;
  private const UInt32 TemperingMaskC = 0xefc60000;

  static UInt32 undoTemper(UInt32 y)
  {
    y = undoTemperShiftL(y);
    y = undoTemperShiftT(y);
    y = undoTemperShiftS(y);
    y = undoTemperShiftU(y);
    return y;
  }
  static UInt32 undoTemperShiftL(UInt32 y)
  {
    UInt32 last14 = y >> 18;
    UInt32 final = y ^ last14;
    return final;
  }
  static UInt32 undoTemperShiftT(UInt32 y)
  {
    UInt32 first17 = y  11;
    UInt32 b = y ^ a;
    UInt32 c = b >> 11;
    UInt32 final = y ^ c;
    return final;
  }
}

So then after observing 624 values and using the reverse temper function it is possible fill in the 624 internal state values of the mersenne twister algorithm and predict all the future values. Unfortunately this doesn’t help in many ways for practical purposes, since you need all 624 values unaltered. Take for instance the lottery. First, you don’t actually know the random number. Second, most likely the random number was used to shuffle the numbers in a certain way and only a portion of the random number was used. Third, if the algorithm gets reseeded each time you don’t know your 624 consecutive values. Also, some of the newer versions of the MT generate two values and combine them to create a better random double.