from gmpy2 import * a = 2 n = 2 whileTrue: a = powmod(a, n, N) res = gcd(a-1, N) if res != 1and res != N: q = N // res d = invert(e, (res-1)*(q-1)) m = powmod(c, d, N) print(m) break n += 1
p+1光滑
Williams’s p + 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
defmlucas(v, a, n): """ Helper function for williams_pp1(). Multiplies along a Lucas sequence modulo n. """ v1, v2 = v, (v**2 - 2) % n for bit inbin(a)[3:]: v1, v2 = ((v1**2 - 2) % n, (v1*v2 - v) % n) if bit == "0"else ((v1*v2 - v) % n, (v2**2 - 2) % n) return v1
for v in count(1): for p in primegen(): e = ilog(isqrt(n), p) if e == 0: break for _ in xrange(e): v = mlucas(v, p, n) g = gcd(v-2, n) if1 < g < n: return g # g|n if g == n: break