Counter-Based Random Number Generation

In [38]:
from Crypto.Cipher import AES
import os
import numpy as np
import matplotlib.pyplot as plt
In [7]:
#secret = os.urandom(BLOCK_SIZE)
secret = np.array([23842839,234234,2342314,2342342], dtype=np.uint32)
In [12]:
counter = np.array([1,0,0,0], dtype=np.uint32)
In [13]:
aes = AES.new(secret)
In [14]:
aes.encrypt(counter)
Out[14]:
b'0\xa8\xa9N\xad\x8d_gIC\x0fb\xb0E\xa34'
In [15]:
aes.encrypt(counter)
Out[15]:
b'0\xa8\xa9N\xad\x8d_gIC\x0fb\xb0E\xa34'
In [33]:
x = np.fromstring(aes.encrypt(counter), dtype=np.uint32)
counter[0] += 1
x
Out[33]:
array([3145698134, 4097296222, 1305499519, 1043286573], dtype=uint32)

Batched Random Number Generation

In [43]:
counters = np.zeros((100000, 4), dtype=np.uint32)
counters[:, 0] = np.arange(len(counters))
In [44]:
numbers = np.fromstring(aes.encrypt(counters), dtype=np.uint32).reshape(-1)
In [45]:
plt.hist(numbers)
Out[45]:
(array([ 40000.,  39778.,  40012.,  40060.,  40176.,  40116.,  39876.,
         40196.,  39793.,  39993.]),
 array([  3.20370000e+04,   4.29525053e+08,   8.59018069e+08,
          1.28851109e+09,   1.71800410e+09,   2.14749712e+09,
          2.57699013e+09,   3.00648315e+09,   3.43597617e+09,
          3.86546918e+09,   4.29496220e+09]),
 <a list of 10 Patch objects>)
  • How would you convert that to real numbers between 0 and 1?