A = Matrix([ [s0 ,s1 ,1/m ,0 ,0 ], [1 ,1 ,0 ,1/m ,0 ], [-s1 ,-s2 ,0 ,0 ,1 ], [m ,0 ,0 ,0 ,0 ], [0 ,m ,0 ,0 ,0 ] ]) A = A.LLL() a = None b = None for l in A: if l[0] == 0and l[1] == 0: if l[-1] == 1: a, b = l[2] * m, l[3] * m elif l[-1] == -1: a, b = -l[2] * m, -l[3] * m else: continue ifnot a ornot b: raise ValueError("[*] No solves") a %= m b %= m
# In[2]: classLCG: def__init__(self): m = getPrime(256) a = getRandomRange(2, m) b = getRandomRange(2, m) seed = getRandomRange(2, m) self._key = {'a':a, 'b':b, 'm':m} self._state = seed defnext(self): self._state = (self._key['a'] * self._state + self._key['b']) % self._key['m'] return self._state defexport_key(self): return self._key # In[3]: data = [] for i in range(6): data.append(prng.next()) from functools import reduce delta = [d1 - d0 for (d0, d1) in zip(data, data[1:])] m_mul = [d0 * d2 - d1 * d1 for (d0, d1, d2) in zip(delta, delta[1:], delta[2:])] m = reduce(GCD, m_mul) factors = factor(m) if len(factors) > 1: for (prime, degree) in factors: if size(prime) == 256: m = prime break m //= (prime**degree) print(m)
# In[4]: prng = LCG(128) data = [] for i in range(20): data.append(prng.next()) leak_data = [] for i in range(20): leak_data.append(data[i] - data[i] % 2^48) print(prng.export_key())
# In[29]: deflcg(seed, a, b, m): x = seed % m whileTrue: x = (a * x + b) % m yield x
# In[51]: a = 94105412428421315937226606524092193902 b = 272271222013811783094314393442542793059 m = 335812331024081385414724338959789210621 A = Matrix(ZZ, 10, 10) A[0, 0] = m for i in range(1, 10): A[i, 0] = a^i A[i, i] = -1 AL = A.LLL() delta_Y = vector([leak_data[i + 1] - leak_data[i] for i in range(10)]) W1 = AL * delta_Y W2 = vector([round(RR(w) / m) * m - w for w in W1]) delta_Z = AL.solve_right(W2) delta_X = delta_Y + delta_Z x0 = (inverse(a - 1, m) * (delta_X[0] - b)) % m rand_iter = lcg(x0, a, b, m) for i in range(20): x = next(rand_iter) print(x)
int[] state; // Iterate through the state for (i = 0; i < 624; i++) { // y is the first bit of the current number, // and the last 31 bits of the next number int y = (state[i] & 0x80000000) + (state[(i + 1) % 624] & 0x7fffffff); // first bitshift y by 1 to the right int next = y >>> 1; // xor it with the 397th next number next ^= state[(i + 397) % 624]; // if y is odd, xor with magic number if ((y & 1L) == 1L) { next ^= 0x9908b0df; } // now we have the result state[i] = next; }
from typing import List from binascii import unhexlify
rand_buffer = '' states = []
defread_data() -> List[int]: with open('random', 'r') as f: data = [int(line.rstrip('\n')) for line in f] assert(len(data) >= 624) return data ''' data = [random.getrandbits(32) for i in range(624)] return data '''
defunBitshiftLeftXor(value, shift, mask): i = 0 res = 0 while i * shift < 32: partMask = (0xffffffff >> (32 - shift)) << (shift * i) part = value & partMask value ^= (part << shift) & mask res |= part i += 1 return res
defunBitshiftRightXor(value, shift, mask): i = 0 res = 0 while i * shift < 32: partMask = ((0xffffffff << (32 - shift)) & 0xffffffff) >> (shift * i) part = value & partMask value ^= (part >> shift) & mask res |= part i += 1 return res
defcrack_states(data: List[int]) -> List[int]: states = [] for i in range(624): value = data[i] value = unBitshiftRightXor(value, 18, 0xffffffff) value = unBitshiftLeftXor(value, 15, 0xefc60000) value = unBitshiftLeftXor(value, 7, 0x9d2c5680) value = unBitshiftRightXor(value, 11, 0xffffffff) states.append(value) return states
defpredict_randbits(bit_length): assert(bit_length % 4 == 0) global states global rand_buffer if len(rand_buffer) >= (bit_length // 4): res = rand_buffer[:bit_length // 4] rand_buffer = rand_buffer[bit_length // 4:] return res else: for i in range(624): y = (states[i] & 0x80000000) + (states[(i + 1) % 624] & 0x7fffffff) res = y >> 1 res ^= states[(i + 397) % 624] if y & 1 == 1: res ^= 0x9908b0df states[i] = res for i in range(624): value = states[i] value ^= (value >> 11) value ^= (value << 7) & 0x9d2c5680 value ^= (value << 15) & 0xefc60000 value ^= (value >> 18) rand_buffer += hex(value)[2:].rjust(8, '0') res = rand_buffer[:bit_length // 4] rand_buffer = rand_buffer[bit_length // 4:] return res
defbacktrace_randbits(bit_length): assert(bit_length % 4 == 0) global states for i in range(623, -1, -1): res = 0 tmp = states[i] tmp ^= states[(i + 397) % 624] if (tmp & 0x80000000) == 0x80000000: tmp ^= 0x9908b0df res = (tmp << 1) & 0x80000000#the first bit of the res # the remaining 31 bits of the res tmp = states[(i - 1 + 624) % 624] tmp ^= states[(i + 396) % 624] if (tmp & 0x80000000) == 0x80000000: tmp ^= 0x9908b0df res |= 1 res |= (tmp << 1) & 0x7fffffff states[i] = res value = '' for state in states[-(bit_length // 32 + 1):]: state ^= (state >> 11) state ^= (state << 7) & 0x9d2c5680 state ^= (state << 15) & 0xefc60000 state ^= (state >> 18) value += hex(state)[2:].rjust(8, '0') return value[-bit_length // 4:]
defmain(): global states data = read_data() # predict states = crack_states(data[-624:]) print(int(predict_randbits(32), 16)) # backtrace ''' states = crack_states(data[:624]) print(backtrace_randbits(32 * 4)) '''
if __name__ == '__main__': main()
More
或者python2下直接调用randcrack
1 2 3 4 5 6 7 8 9 10 11
from randcrack import RandCrack
Rand = RandCrack() with open('random', 'r') as f: data = [int(line.rstrip('\n')) for line in f] assert(len(data) >= 624) for i in range(624): Rand.submit(data[i]) for i in range(624, len(data)): Rand.predict_randrange(0, 0xffffffff) print Rand.predict_randrange(0, 0xffffffff)