Numpy uses plain old implementation of Mersenne Twister as the default pseudo
random number generation.

Now Mersenne Twister by itself is not so bad, what’s
bad is actually the seed initialization ( i.e. deriving the initial state of
the random number generator from the seed ) same as explained in the
Wikipedia Implementation
which has been replaced in
Improved Initialization
with a more non-linear initialization with an array of seeds.

So, given a few (very few actually) outputs from the numpy random RNG, can you
recover the flag?

Note that the seed is a 32-bit value and can be bruteforced easily, thats not the goal of this challenge, the goal of the challenge is to figure out a way which works equivalently well for MT-19937-64 bit as 64-bit is out of the bounds of bruteforce for a reasonably practical CTFer :P

```
import os
from numpy import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from secret import flag
def rand_32():
return int.from_bytes(os.urandom(4),'big')
flag = pad(flag,16)
random.seed(rand_32())
iv,key = random.bytes(16), random.bytes(16)
cipher = AES.new(key,iv=iv,mode=AES.MODE_CBC)
flag = iv+cipher.encrypt(flag)
print(flag.hex())
# output
# ba84b595a6c47ab8b5229df78b313fd983368f94c86e063ad9e60b53debf4cf062e0e7ee\
# 975a58ede95877add16603d089a7c01b5581278440b2fc8a25e698ae869a2c67de7b8a5e\
# bbe47fcb6cb210237d6cb60d06dabbf7756a2364ba2fbb5b0f0c04fb4383f66ff755c725\
# 2b699c33
```