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}

相关推荐
aqi0042 分钟前
15天学会AI应用开发(七)有了大模型为什么还要引入RAG
人工智能·python·大模型·ai编程·ai应用
金銀銅鐵3 小时前
用 Python 实现 Take-Away 游戏
python·游戏
copyer_xyf3 小时前
Agent 流程编排
后端·python·agent
copyer_xyf4 小时前
Agent RAG
后端·python·agent
copyer_xyf4 小时前
【RAG】向量数据库:milvus
后端·python·agent
copyer_xyf4 小时前
Agent 记忆管理
后端·python·agent
JieE21211 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
星云穿梭19 小时前
用Python写一个带图形界面的学生管理系统——完整教程
python
Jack2019 小时前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法