cryptopals

https://cryptopals.com/
Log | Files | Refs

clone_mt_rng_state.py (1375B)


      1 from random import randint
      2 from mt19937 import MersenneTwister
      3 
      4 def _int32(x):
      5     # Get the 32 least significant bits.
      6     return int(0xffffffff & x)
      7 
      8 def untemper_11(yy):
      9     y = yy ^ ((yy & 0xffe00000) >> 11)
     10     y = yy ^ ((y & 0xfffffc00) >> 11)
     11     y = yy ^ ((y & 0xffffffff) >> 11)
     12     
     13     return _int32(y)
     14 
     15 def untemper_7(yy):
     16     y = yy ^ (((yy & 0x7f) << 7) & 2636928640)
     17     y = yy ^ (((y & 0x3fff) << 7) & 2636928640)
     18     y = yy ^ (((y & 0x1fffff) << 7) & 2636928640)
     19     y = yy ^ (((y & 0xfffffff) << 7) & 2636928640)
     20     y = yy ^ (((y & 0xffffffff) << 7) & 2636928640)
     21 
     22     return _int32(y)
     23 
     24 def untemper_15(yy):
     25     y = yy ^ (((yy & 0x7fff) << 15) & 4022730752)
     26     y = yy ^ (((y & 0x3fffffff) << 15) & 4022730752)
     27     y = yy ^ (((y & 0xffffffff) << 15) & 4022730752)
     28 
     29     return _int32(y)
     30 
     31 def untemper_18(yy):
     32     return _int32(yy ^ yy >> 18)
     33 
     34 def untemper(yy):
     35     y = _int32(yy)
     36     y = untemper_18(y)
     37     y = untemper_15(y)
     38     y = untemper_7(y)
     39     y = untemper_11(y)
     40     return _int32(y)
     41 
     42 unknown_seed = randint(0, 0xffffffff)
     43 mt = MersenneTwister(unknown_seed)
     44 
     45 cloned_mt_state = [0] * 624
     46 
     47 for i in range(624):
     48     cloned_mt_state[i] = untemper(mt.extract_number())
     49 
     50 cloned_mt = MersenneTwister(0)
     51 cloned_mt.set_state(cloned_mt_state)
     52 
     53 print mt.extract_number()
     54 print cloned_mt.extract_number()
     55 print mt.extract_number() == cloned_mt.extract_number()