MT19937算法

admin 2025年3月16日21:46:46评论15 views字数 3413阅读11分22秒阅读模式
 

MT19937算法
MT19937算法及攻击方式

梅森旋转算法

Mersenne twister

梅森旋转算法(Mersenne twister)是一种周期很长的的伪随机数生成算法,可以快速的产生高质量的伪随机数,python,php以及多种语言中的随机数模块均采用此算法。

1

HELLO SKSEC

MT19937算法原理

梅森旋转算法的最长周期取自一个梅森素数 2^19937^-1,由此命名为MT9937。常见的两种为32位的**MT19937-32**和64位的**MT19937-64**

mt19937的随机数生成器结构由一个32位的种子,然后生成一个具有624个32位数的状态数组。这些整数按顺序输出,全部输出后对该状态应用算法以获取下一组 624 个整数。

生成时分三个过程:

MT19937算法
- 利用seed初始化状态

- 对状态进行旋转

- 根据状态提取伪随机数

32位的MT19937的python代码```pythondef _int32(x):    return int(0xFFFFFFFF & x)class MT19937:    def __init__(self, seed):        self.mt = [0] * 624        self.mt[0] = seed        self.mti = 0        for i in range(1624):            self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)def extract_number(self):        if self.mti == 0:            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)def twist(self):        for i in range(0624):            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```
2

HELLO SKSEC

攻击

SKSEC

已知624组

这种情况只需要将已知的624组填入状态矩阵,即可进行预测和回溯。

有许多可以进行这类攻击的py库,如**randcrack**,**mt19937predictor**等,使用方法大同小异。

```pythonfrom randcrack import RandCrack#已知连续随机数data=[...]RC = RandCrack()for i in data:    RC.submit(i)#给出足够多的随机数后,使用predict_getrandbits()即可预测随机数flag = RC.predict_getrandbits(32)```
SKSEC

实际应用中,并不是所有的伪随机数都是32位的,也会出现8位、16位、64位、96位。当然也有可能出现其他不规则的情况。因此,上面提到的“连续624组32位”可以被替换成,“连续19968个比特位”。

任意19968个bit

在使用**getrandbits()**时如果是输出32的倍数时,会将前生成的32比特放在低位,新生成的拼接在高位。

而getrandbits(16) 中,只返回高16比特,其余比特位被丢弃。getrandbits(33) 中,低 32 比特取自第一组,而高1位取自第二组的最高位比特,第二组低31比特被丢弃。

如果给出了不连续的19968比特,这时候我们可以使用已知的部分构建矩阵求解:

对于每一个比特位b~i~,可以和状态矩阵state用一个线性关系表示出来

s*t=b_i

当我们有足够多的b之后就可以构成下面的矩阵方程

s*T=b

其中s和b为长19968的向量,T为19968*19968的矩阵。

如果T是满秩的,求解这个矩阵方程就可以得到s的唯一解,成功复原state,便可以进行溯源和预测。

所以接下来我们只要想办法获得b和T即可。

1

b的获取

事实上只要我们的已知的任意位置数据大于19968比特即可,但是我们需要知道其对应的位置来确定线性关系以构造方程。

2

T的获取

虽然已知数据中我们并没有办法获得T,但是其实这个线性关系是可以根据**MT19937**算法本身得到的。也就是说,如果已知b的对应比特在MT19937产生的随机数输出的位置,则其对应的T也是固定的。

寻找T的过程类似于一个黑盒调用。具体来说,如果我们取s为:(1,0,0,...,0)

按照这个s设置state,然后调用getrandbits(),生成我们已知位置的比特,得到 b' ,此时得到的 b' 既是T的第一行。

同理,我们接下来取s:(0,1,0,...,0)

得到T的第二行。全部进行完即可得到完整的T。

转载自[Explore MT19937 - huangx607087's Blog](https://huangx607087.online/2021/07/10/Explore-MT19937/)

```pythonDall=list(map(int,open('data3.txt','r').readlines()))from Crypto.Util.number import *from random import *from tqdm import *n=1250D=Dall[:n]rng=Random()def getRows(rng):    #这一部分根据题目实际编写,必须和题目实际比特获取顺序和方式完全一致,且确保比特数大于19937,并且请注意zfill。    row=[]    for i in range(n):        row+=list(map(int, (bin(rng.getrandbits(16))[2:].zfill(16))))    return rowM=[]for i in tqdm_notebook(range(19968)):#这一部分为固定套路,具体原因已经写在注释中了    """    referennce:    糖醋小鸡块 2025/1/21 20:26:51    这部分代码相当于取了一组线性基    糖醋小鸡块 2025/1/21 20:26:56    因为mt19937是线性的    """    state = [0]*624    temp = "0"*i + "1"*1 + "0"*(19968-1-i)    for j in range(624):        state[j] = int(temp[32*j:32*j+32],2)    rng.setstate((3,tuple(state+[624]),None)) #这个setstate也是固定格式,已于2025.1.21测试    M.append(getRows(rng))M=Matrix(GF(2),M)y=[]for i in range(n):    y+=list(map(int, (bin(D[i])[2:].zfill(16))))y=vector(GF(2),y)s=M.solve_left(y)#print(s)G=[]for i in range(624):    C=0    for j in range(32):        C<<=1        C|=int(s[32*i+j])    G.append(C)import randomRNG1 = random.Random()for i in range(624):    G[i]=int(G[i])RNG1.setstate((int(3),tuple(G+[int(624)]),None))print([RNG1.getrandbits(16for _ in range(75)])print(D[:75])```
 

原文始发于微信公众号(SKSEC):【表哥有话说 第114期】MT19937

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月16日21:46:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   MT19937算法https://cn-sec.com/archives/3846768.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息