L = [] for i in trange(length): state = [0]*624 temp = "0"*i + "1"*1 + "0"*(length-1-i) for j inrange(624): state[j] = int(temp[32*j:32*j+32],2) RNG.setstate((3,tuple(state+[624]),None)) L.append(construct_a_row(RNG))
L = Matrix(GF(2),L) ''' #test (ttt is init state) sss = "" for i in ttt: sss += bin(i)[2:].zfill(32) sss = list(map(int,sss)) sss = vector(GF(2),sss) print(sss*L) '''
s = L.solve_left(vector(GF(2),[1]*length)) init = "".join(list(map(str,s))) state = [] for i inrange(624): state.append(int(init[32*i:32*i+32],2))
############################################################ part2 get flag RNG1 = Random() RNG1.setstate((3,tuple(state+[624]),None)) defN(k): return RNG1.getrandbits(1) & 0if k == 0else RNG1.getrandbits(k) for i inrange(100000): N(N(N(1)))
from Crypto.Util.number import * from output import gift,c from random import * from tqdm import *
if(0): #test RNG1 = Random() print(RNG1.getstate()) defSS(k): return RNG1.getrandbits(1) & 0if k == 0else RNG1.getrandbits(k) gift = [] for i inrange(50000): gift.append(SS(SS(5)))
############################################################ part1 get state RNG = Random() length = 19968
defconstruct_a_row(RNG): ind = 0 row = [] while(1): if(len(bin(gift[ind])[2:]) == 31): t1 = bin(RNG.getrandbits(5))[2:].zfill(5) for tt in t1: row.append(int(tt)) t2 = bin(RNG.getrandbits(31))[2:].zfill(31) for tt in t2: row.append(int(tt)) else: RNG.getrandbits(32) RNG.getrandbits(32) if(len(row) >= length): return row ind += 1
L = [] for i in trange(length): state = [0]*624 temp = "0"*i + "1"*1 + "0"*(length-1-i) for j inrange(624): state[j] = int(temp[32*j:32*j+32],2) RNG.setstate((3,tuple(state+[624]),None)) L.append(construct_a_row(RNG))
L = Matrix(GF(2),L)
known = [] for i in gift: if(len(bin(i)[2:]) == 31): known += [1,1,1,1,1] known += list(map(int,bin(i)[2:])) if(len(known) >= length): break s = L.solve_left(vector(GF(2),known)) init = "".join(list(map(str,s))) for i inrange(624): state.append(int(init[32*i:32*i+32],2))
############################################################ part2 get flag RNG2 = Random() RNG2.setstate((3,tuple(state+[624]),None)) defSS(k): return RNG2.getrandbits(1) & 0if k == 0else RNG2.getrandbits(k) for i inrange(50000): SS(SS(5))
if(0): #test from random import randint ns = [randint(200,256) for i inrange(16)] lfsr = [LFSR(ns[i],K[i],MASK) for i inrange(16)] output = [] for i inrange(nums): output.append(sum(lfsr[j]() for j inrange(16))) print(ns)
##################################################### part1 find useful data in out useful_index = [] for i inrange(len(output)): if(output[i] == 0): useful_index.append(["1",0]) elif(output[i] == 16): useful_index.append(["0",0]) elif(output[i] == 1): useful_index.append(["1",1/16]) elif(output[i] == 15): useful_index.append(["0",1/16]) elif(output[i] == 2): useful_index.append(["1",2/16]) elif(output[i] == 14): useful_index.append(["0",2/16]) else: useful_index.append(["01",1])
##################################################### part2 remove some n possible = [[] for i inrange(16)] for i in trange(16): for n inrange(200,256+1): lfsri = LFSR(n,K[i],MASK) rate = 1 for t inrange(nums): temp = str(lfsri()) if(temp in useful_index[t][0]): rate *= useful_index[t][1] if(rate >= 1/100000000000000000000): possible[i].append(n) assert [] notin possible
from random import choice
for t inrange(10): ns = [] for i inrange(16): ns.append(choice(possible[i])) lfsr = [LFSR(ns[i],K[i],MASK) for i inrange(16)] output = [] for i inrange(nums): output.append(sum(lfsr[j]() for j inrange(16))) output = [] for i inrange(5000): output.append(sum(lfsr[j]() for j inrange(16)))
h = sha256(str(output).encode()).digest() h = bytes_to_long(h) print(long_to_bytes(h^c))