NSSCTF_crypto_[LitCTF 2023]babyLCG

python 复制代码
from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
bit_len = m.bit_length()
a = getPrime(bit_len)
b = getPrime(bit_len)
p = getPrime(bit_len+1)

seed = m
result = []
for i in range(10):
    seed = (a*seed+b)%p
    result.append(seed)
print(result)
"""
result = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]
"""

题目描述

题目给出了一个使用 线性同余生成器 (LCG) 生成的 10 个连续伪随机数,要求恢复初始种子 (即 flag)。

数学原理

LCG 的递推公式为:

其中 pp是未知的大质数,aa 和 bb 是未知乘数和加数,s0s0​ 是初始种子。

我们有连续输出 s1,s2,...,s10


完整代码

python 复制代码
from Crypto.Util.number import long_to_bytes
from math import gcd

# 给定的输出序列
result = [
    699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878,
    193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390,
    1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943,
    659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506,
    111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829,
    1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909,
    655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698,
    1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851,
    492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509,
    70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265
]

# ============================================================
# 第一步:恢复模数 p
# ============================================================

# 计算相邻状态的差值 t_i = s_{i+1} - s_i (i = 0..8)
t = []
for i in range(len(result) - 1):
    t.append(result[i+1] - result[i])

# 利用 t_{i+1} * t_{i-1} - t_i^2 ≡ 0 (mod p)
# 多个这样的值求 gcd 得到 p 的倍数,进而得到 p
U = []
for i in range(1, len(t) - 1):
    U.append(t[i+1] * t[i-1] - t[i]**2)

# 求这些数的最大公约数
p = abs(U[0])
for x in U[1:]:
    p = gcd(p, x)

# 如果 p 含有小因子,可以尝试进一步分解,通常 p 就是素数
print(f"[+] 恢复的模数 p = {p}")

# ============================================================
# 第二步:恢复乘数 a
# ============================================================

# 由 t_1 ≡ a * t_0 (mod p),得到 a = t_1 * t_0^{-1} mod p
a = (t[1] * pow(t[0], -1, p)) % p
print(f"[+] 恢复的乘数 a = {a}")

# ============================================================
# 第三步:恢复加数 b
# ============================================================

# 由 s_2 ≡ a * s_1 + b (mod p),得到 b = s_2 - a * s_1 mod p
b = (result[2] - a * result[1]) % p
print(f"[+] 恢复的加数 b = {b}")

# ============================================================
# 第四步:恢复初始种子 s_0(即 m)
# ============================================================

# 由 s_1 ≡ a * s_0 + b (mod p),得到 s_0 = (s_1 - b) * a^{-1} mod p
seed = ((result[0] - b) * pow(a, -1, p)) % p
print(f"[+] 恢复的初始种子 s_0 = {seed}")

# ============================================================
# 第五步:获取 flag
# ============================================================

flag = long_to_bytes(seed)
print(f"[+] Flag: {flag.decode()}")

运行后flag为

NSSCTF{31fcd7832029a87f6c9f760fcf297b2f}

相关推荐
大鱼>5 分钟前
因子挖掘+回测+RL交易:量化金融完整系统
人工智能·深度学习·算法·金融
编程阿峰28 分钟前
Python 环境配置(二)安装jupyter、matplotlib、numpy库
开发语言·python·jupyter·numpy·matplotlib
AC赳赳老秦29 分钟前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
金銀銅鐵1 小时前
[Python] 一次打开多个常用的网址
python
明如正午1 小时前
【python】Python + OpenCV 实现视频关键帧提取与智能去重
python·opencv·音视频
aqi001 小时前
15天学会AI应用开发(十八)使用LangGraph实现精确记忆功能
人工智能·python·大模型·ai编程·ai应用
c238562 小时前
《枚举算法 “翻译官”:用 enum class 给 “游游的礼盒” 算分》
c语言·c++·算法
swany2 小时前
同步数据中,只需要几秒钟 & milvus向量数据库不可用 dify1.16.1 升级后踩坑记录
开发语言·python·numpy