defextract_number(self,x=None): ifself.mti == 0and x isNone: self.twist() y = self.mt[self.mti] y = y ^ y >> 11 y = y ^ y << 7 & 2636928640 y = y ^ y << 15 & 4022730752 y = y ^ y >> 18 self.mti = (self.mti + 1) % 624 return _int32(y)
deftwist(self): for i inrange(0, 624): y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff)) self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624]
if y % 2 != 0: self.mt[i] = self.mt[i] ^ 0x9908b0df
defre_extract(self,m): m=self.re_right(m,18,0xffffffff) m=self.re_left(m,15,4022730752) m=self.re_left(m,7,2636928640) m=self.re_right(m,11) return m&0xffffffff defre_state(self,outputs): iflen(outputs)!=624: raise ValueError("Invalid number of outputs")
self.mt=[self.re_extract(m)for m in outputs] self.mti=0 returnself.mt M1=[] M2=[] rng=MT19937(seed=1123) for i inrange(1248): a=rng.extract_number() if i<624: M1.append(a) else: M2.append(a) print(M1) print(M2) pre=MT19937() pre.re_state(M1) print("预测 RNG:", [pre.extract_number() for _ inrange(10)])
defre_tw1(mt): high=0x80000000 low=0x7fffffff mask=0x9908b0df for i inrange(623,-1,-1): t=mt[i]^mt[(i+397) % 624] if t&high==high: t=t^mask t=t<<1 t|=1#确定位奇数 else: t=t<<1 res=t&high #取得高位 t=mt[i-1]^mt[(i+396) % 624] if t&high==high: t=t^mask t=t<<1 t|=1 else: t=t<<1 res=res+(t&low) mt[i]=res return mt
验证代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
if __name__ == '__main__': M1 = [] M2 = [] rng = MT19937(seed=1123) for i inrange(1248): a = rng.extract_number() if i < 624: M1.append(a) else: M2.append(a) print(f'M1={M1}') print(f'M2={M2}') pre = MT19937() m = pre.re_state(M2) pre.mt=re_tw1(m) print(pre.mt) print("预测 RNG:", [pre.extract_number(x=1) for _ inrange(10)])
for i in tqdm(range(19968)): state = [0]*624 temp = "0"*i + "1"*1 + "0"*(19968-1-i) for j inrange(624): state[j] = int(temp[32*j:32*j+32],2) rng.setstate((3,tuple(state+[624]),None)) M.append(getRows(rng)) M=Matrix(GF(2),M)
from Crypto.Util.number import * from random import * from tqdm import * n=1000 D=[]#1000个得到20 rng=Random()
defgetRows(rng): row=[] for i inrange(n): row+=list(map(int, (bin(rng.getrandbits(20))[2:].zfill(20)))) return row M=[]
for i in tqdm(range(19968)): state = [0]*624 temp = "0"*i + "1"*1 + "0"*(19968-1-i) for j inrange(624): state[j] = int(temp[32*j:32*j+32],2) rng.setstate((3,tuple(state+[624]),None)) M.append(getRows(rng)) M=Matrix(GF(2),M) print("行数:", M.nrows()) print("列数:", M.ncols()) r=[] for i inrange(n): r+=list(map(int, (bin(D[i])[2:].zfill(20)))) r=vector(GF(2),r) y=M.solve_left(r) G=[] for i inrange(624): C=0 for j inrange(32): C<<=1 C|=int(y[32*i+j]) G.append(C)#将恢复的state转化为每个元素32bit的列表 import random RNG1 = random.Random() for i inrange(624): G[i]=int(G[i]) RNG1.setstate((int(3),tuple(G+[int(624)]),None))#将state作为随机数生成器的初始状态,测试生成的state是否正确 P=[RNG1.getrandbits(20) for _ inrange(75)] print(P) print(D[:75])
import random withopen("flag.txt","rb") as f: flag=f.read() for i inrange(2**64): print(random.getrandbits(32)+flag[random.getrandbits(32)%len(flag)]) input()
from Crypto.Util.number import * from random import * from tqdm import * n=2500 D=[] print(len(D)) rng=Random()
defgetRows(rng): row=[] for i inrange(n): row+=list(map(int, (bin(rng.getrandbits(32)>>24)[2:].zfill(8)))) _=rng.getrandbits(32) return row M=[]
for i in tqdm(range(19968)): state = [0]*624 temp = "0"*i + "1"*1 + "0"*(19968-1-i) for j inrange(624): state[j] = int(temp[32*j:32*j+32],2) rng.setstate((3,tuple(state+[624]),None)) M.append(getRows(rng)) M=Matrix(GF(2),M) print("行数:", M.nrows()) print("列数:", M.ncols()) r=[] for i inrange(n): r+=list(map(int, (bin(D[i]>>24)[2:].zfill(8)))) r=vector(GF(2),r) y=M.solve_left(r) G=[] for i inrange(624): C=0 for j inrange(32): C<<=1 C|=int(y[32*i+j]) G.append(C)#将恢复的state转化为每个元素32bit的列表 import random RNG1 = random.Random() for i inrange(624): G[i]=int(G[i]) RNG1.setstate((int(3),tuple(G+[int(624)]),None))#将state作为随机数生成器的初始状态,测试生成的state是否正确
G=[] for i inrange(624): G[i]=int(G[i]) RNG1 = Random() RNG1.setstate((int(3),tuple(G+[int(624)]),None))
flag=[] ind=[] for i inrange(len(X)): a = RNG1.getrandbits(32) b = RNG1.getrandbits(32) f = X[i]-a if0 < f < 255 : flag.append(f) ind.append(b) for fl inrange(len(set(flag)),50):#fl是flag的长度,利用爆破判断长度是否符合条件 TN = [i%fl for i in ind] TF = [] for i inrange(fl): t = TN.index(i) TF.append(flag[t]) TF = bytes(TF) if TF[:6]==(b'TPCTF{'): print(TF)