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}

相关推荐
XGeFei5 分钟前
python中子线程与主线程的关系
开发语言·python
aini_lovee6 分钟前
FMCW雷达测速测距系统(锯齿波 + CFAR检测)
算法
Chase_______8 分钟前
【Java杂项】final 关键字详解:变量、方法、类限制与引用可变性
java·开发语言·python
qq_297574679 分钟前
设计模式系列文章(基础篇第 11 篇):模板方法模式——定义算法骨架,实现代码复用与流程统一
算法·设计模式·模板方法模式
lqqjuly17 分钟前
知识蒸馏:理论、算法与可运行实现
人工智能·深度学习·算法
我材不敲代码19 分钟前
Python venv 虚拟环境从入门到精通 + uv 高性能替代工具实战指南
开发语言·python·uv
水上冰石26 分钟前
comfui的sd1.5模型,有多少采样算法,详解每一个采样算法
人工智能·算法
l1t30 分钟前
DeepSeek总结的使用实体-组件-系统和基于存在性处理进行Python编程18-20
开发语言·python
零梦ing37 分钟前
Claude Code 升级后 DeepSeek API 报错 messages[x].role: unknown variant system 终极解决方案
python·claude code·deepseek api 代理
小矮强37 分钟前
点云采集多段线节点高差大?CASS/TerraSolid一键“展平”解决
经验分享·测绘·cass·terrasolid