LCG变体

题目:

from Crypto.Util.number import *

flag = b'NSSCTF{******}'

class LCG:
    def __init__(self, seed, a, b, m):
        self.seed = seed  # 初始种子
        self.a = a  # 乘数
        self.b = b  # 增量
        self.m = m  # 模数

    def generate(self):
        self.seed = self.a * (self.seed - self.b) % self.m
        return self.seed

lcg = LCG(bytes_to_long(flag), getPrime(256), getPrime(256), getPrime(256))

for i in range(getPrime(16)):
    lcg.generate()

print(lcg.generate())
print(lcg.generate())
print(lcg.generate())
print(lcg.generate())
print(lcg.generate())

'''
57648351648792284446777383544515312078150027665462203747924668509833442797796
90378879763416486117626477831653213918315023665514305359005153448529276829825
21826576702665114807208181233864324586557058567478767825970403161758214940301
47594460970742467761038407996122637655856234121180714918606854365482948918701
11871076497267630136796123094001159466754095580273018347962555675375123133730
'''

解题思路:

  • 需要注意的是,这里所给的LCG递归式是self.seed = self.a * (self.seed - self.b) % self.m
  • 我们只需要把-ab看成一个整体,这样我们就可以转化为标准式ax+b的形式
  • 还需要注意得到的m是其倍数

解答:

import gmpy2
from Crypto.Util.number import GCD, isPrime, long_to_bytes

c=[57648351648792284446777383544515312078150027665462203747924668509833442797796,
   90378879763416486117626477831653213918315023665514305359005153448529276829825,
   21826576702665114807208181233864324586557058567478767825970403161758214940301,
   47594460970742467761038407996122637655856234121180714918606854365482948918701,
   11871076497267630136796123094001159466754095580273018347962555675375123133730]

t=[]
for i in range(1,len(c)):
    t.append(c[i]-c[i-1])

m = 0
for i in range(1,len(t)-1):
    m = GCD(t[i+1]*t[i-1]-t[i]**2, m)
print(isPrime(m))   # False m的倍数
print(m)
#430799744310334360363379121857013767962457275253944408631590707485837972511596

for i in range(1,100):
    if isPrime(m//i):
        print(i)   # i是4
        m//=i
        break

a = (c[3]-c[2])*gmpy2.invert(c[2]-c[1],m) % m
b = (c[2]-a*c[1]) % m
# print(gmpy2.gcd(a,m))
# print(gmpy2.gcd(b,m))
a_1=gmpy2.invert(a,m)

for i in range(2**16):
    c[1] = (c[1]-b) * a_1 % m
    flag = long_to_bytes(c[1])

    if b'NSSCTF{' in flag:
        print(flag)
        break
#NSSCTF{another_lcg}
posted @ 2025-03-12 00:03  sevensnight  阅读(38)  评论(0)    收藏  举报