a = getPrime(length) b = getPrime(length) n = getPrime(length)
seed = 33477128523140105764301644224721378964069 print("seed = ",seed) for i inrange(10): seed = (a*seed+b)%n ciphertext = seed^plaintext print("a = ",a) print("b = ",b) print("n = ",n) print("c = ",ciphertext) # seed = 33477128523140105764301644224721378964069 # a = 216636540518719887613942270143367229109002078444183475587474655399326769391 # b = 186914533399403414430047931765983818420963789311681346652500920904075344361 # n = 155908129777160236018105193822448288416284495517789603884888599242193844951 # c = 209481865531297761516458182436122824479565806914713408748457524641378381493
题目分析
已知 a b n c=seed^m 求m
m=seed^c 可以求得,而c为已知项,seed 已知
for i in range(10):
seed = (a*seed+b)%n
WP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
from Crypto.Util.number import *
seed = 33477128523140105764301644224721378964069 a = 216636540518719887613942270143367229109002078444183475587474655399326769391 b = 186914533399403414430047931765983818420963789311681346652500920904075344361 n = 155908129777160236018105193822448288416284495517789603884888599242193844951 c = 209481865531297761516458182436122824479565806914713408748457524641378381493 for i inrange(10): seed = (a*seed+b)%n m = seed^c print(m) print(long_to_bytes(m)) # 147424144810829416246263598495658483373775464141840154829404726417260880253 # b'Spirit{0ops!___you_know__LCG!!}'
# a = 59398519837969938359106832224056187683937568250770488082448642852427682484407513407602969 # b = 32787000674666987602016858366912565306237308217749461581158833948068732710645816477126137 # n = 43520375935212094874930431059580037292338304730539718469760580887565958566208139467751467 # c = 8594514452808046357337682911504074858048299513743867887936794439125949418153561841842276
题目分析
已知 a b n 已知密文c 为最终seed
求 m m为初始seed
循环十次 最终得到初始seed
Xn=(a^-1 (Xn+1 - b))%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] #逆元计算
ani=MMI(a,n)
WP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from Crypto.Util.number import * from gmpy2 import gmpy2
a = 59398519837969938359106832224056187683937568250770488082448642852427682484407513407602969 b = 32787000674666987602016858366912565306237308217749461581158833948068732710645816477126137 n = 43520375935212094874930431059580037292338304730539718469760580887565958566208139467751467 c = 8594514452808046357337682911504074858048299513743867887936794439125949418153561841842276
# 这两种都可以去求 逆元 # 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] #逆元计算 # ani=MMI(a,n) ani = gmpy2.invert(a,n) seed=c for i inrange(10): seed = (ani*(seed-b))%n print(seed) print(long_to_bytes(seed)) # 41496207727216587746731918844219889152464603755197286927180022389268761169026372950106493 # b'Spirit{Orzzz__number_the0ry_master!!}'
for i inrange(len(output)-1): t.append(output[i]-output[i-1])
for i inrange(len(output)-3): all_n.append(gcd( (t[i+1]*t[i-1]-t[i]*t[i]) , (t[i+2]*t[i]-t[i+1]*t[i+1]) ))
print(all_n) # 求出来的 模数n 有正有负 需要取绝对值 然后如果模数为1 pass掉 for n in all_n: n = abs(n) if n ==1 : continue # 求a a=((Xn+2-Xn+1)(Xn+1-Xn)^-1)%m MMI = lambda A, n, s=1, t=0, N=0: (n < 2and t % N or MMI(n, A % n, t, s - A // n * t, N or n), -1)[n < 1] # 逆元计算 a = (output[3] - output[2]) * MMI((output[2] - output[1]), n) % n # print(a) ani = MMI(a, n)
# 求b b=(Xn+1 - aXn)%m b = (output[2] - a * output[1]) % n # print(b)
# 求明文m seed0 = ((output[0] - b) * ani) % n print(seed0) print(long_to_bytes(seed0))