a = 227534804674212294373456976878991674591 b = 218174184596792028429991024115182554493 n = 103062888820337978910105855710820590574814030029886609905720019096651060712461 s2 = 29312131474314770241680760398669700939670692727273348413246711409796444883599 s3 = (s2 * a + b) % n s1 = ((s2 - b) * gmpy2.invert(a, n)) % n
b 未知
已知乘数 a、模数 n,但不知增量 b,但知道连续两个输出,就能推算出 b:
b=(si−si−1a)modn
1 2 3 4 5
a = 192588738683067832869240203685434639117 n = 98050903778398182124874337920935505944420404837269997836081281971360568748291 s1 = 56877403406926375972348286664767936935900247160292261457124625361059643277984 s2 = 81044863851407226329153956857965274264068864480980462430979569542522955371451L b = (s2 - s1 * a) % n
s = [s1, s2, s3, s4, s5, s6] t = [s[i] - s[i-1] for i in range(1, len(s))] tt = [(t[i-2] * t[i] - t[i-1] * t[i-1]) for i in range(2, len(s)-2)] print reduce(gmpy2.gcd, tt)
还可以根据 a 来减小 n 的差错。
求 a 中 要计算 si+1−si 在模 n 下的逆元,因此两者肯定互素。如果不互素,n 就除以从 2 开始的素数,直到可以整除,然后再判断 si+1−si 与 n 是否互素。
1 2 3 4 5 6 7 8 9 10 11 12 13
from Crypto.Util.number import sieve_base
defcheck_n(s, n): for i in range(len(s)-1): if gmpy2.gcd(s[i+1] - s[i], n) != 1: returnFalse returnTrue
whilenot check_n(s, n): for i in sieve_base: if n % i == 0: n = n // i break