[Crypto学习笔记] 梅森旋转预测类型题目

少于 1 分钟阅读时长

发布时间:

目录

前置概念

梅森旋转

以下是MT19937的实现代码1:

def _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(1, 624):
            self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)
    def twist(self):
        for i in range(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
    def getstate(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)

其中_int32(x)函数用于强制将数据取到32bits, MT19937类中的函数可以稍微花点时间分析一下.

init

初始函数__init__()中, 初始化624个32bits的随机数储存在mt列表中, 其中初始种子往后具有(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i) % 2^32的随机关系, 置初始的mt列表指针mti=0.

getstate

生成32位的随机数y, 如果指针走完mt列表的一轮, 则调用twist()旋转mt列表, mti指针

如果能获得连续的624个32bits数据(或者说需要获取19968bits数据), 就可以获取算法的所有状态2.

tpctf

randomized_random

参考文献

  1. catalyst.梅森旋转算法(MT19937)及其逆向详解[EB/OL].知乎.https://zhuanlan.zhihu.com/p/599672127.2024-02-05. 

  2. huangx607087.huangx607087对PRNG-MT19937的深一步学习[EB/OL].个人博客.https://huangx607087.online/2021/07/10/Explore-MT19937/#0x03-%E7%BB%99%E5%87%BA%E4%BB%BB%E6%84%8F19937%E4%B8%AAbit-upd-2025-01-22.2021-07-10.