已知a,b,n,c

题目:

from Crypto.Util.number import *
flag = b'Spirit{*****************************}'

plaintext = bytes_to_long(flag)
length = plaintext.bit_length()

a = getPrime(length)
b = getPrime(length)
n = getPrime(length)

seed = plaintext

for i in range(10):
    seed = (a*seed+b)%n
ciphertext = seed

print("a = ",a)
print("b = ",b)
print("n = ",n)
print("c = ",ciphertext)

# a =  59398519837969938359106832224056187683937568250770488082448642852427682484407513407602969
# b =  32787000674666987602016858366912565306237308217749461581158833948068732710645816477126137
# n =  43520375935212094874930431059580037292338304730539718469760580887565958566208139467751467
# c =  8594514452808046357337682911504074858048299513743867887936794439125949418153561841842276

解题思路:

  • 根据题意求flag相当于求plaintext,求plaintext相当于求初始seed,我们知道lcg算法十次之后的seed=ciphertext=c,而c我们已知,我们还知道a,b,n;所以这道题要我们从lcg十次之后的seed推算出初始seed
  • 用公式1: Xn=(a-1** (Xn+1 - b))%n**
  • 这里a-1是a相对于模数m的逆元,他也有公式
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] #逆元计算

解答:

import gmpy2
from Crypto.Util.number import *
a =  59398519837969938359106832224056187683937568250770488082448642852427682484407513407602969
b =  32787000674666987602016858366912565306237308217749461581158833948068732710645816477126137
n =  43520375935212094874930431059580037292338304730539718469760580887565958566208139467751467
c =  8594514452808046357337682911504074858048299513743867887936794439125949418153561841842276
seed = c
inv_a = gmpy2.invert(a,n)
for i in range(10):
    seed = (seed - b) * inv_a % n
m = seed
print(long_to_bytes(m))
#Spirit{Orzzz__number_the0ry_master!!}
posted @ 2025-03-12 00:02  sevensnight  阅读(10)  评论(0)    收藏  举报