-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpollardrho.py
84 lines (68 loc) · 1.75 KB
/
pollardrho.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from sympy.ntheory.modular import crt
import gmpy2
import owiener
import random
import multiprocessing
def load_data(datanum):
with open(file="./test/data%d" % (datanum), mode='r') as file:
n, e, c = file.read(256), file.read(256), file.read(256)
n, e, c = int(n, 16), int(e, 16), int(c, 16)
return n, e, c
def func(x, c, n):
return (x * x + c) % n
def Pollard_Rho(n):
# 使用 https://xz.aliyun.com/t/6703 中的改进算法
# 得到 n 的一个因子
if n == 4:
return 2
cnt=0
while (1):
cnt+=1
if cnt>1000000:
break
c = random.randrange(2, n - 1)
t = gmpy2.mpz(0)
r = gmpy2.mpz(0)
p = gmpy2.mpz(1)
q = gmpy2.mpz(1)
while (1):
for i in range(100):
t = func(t, c, n)
r = func(func(r, c, n), c, n)
if (t == r):
break
else:
q = p * abs(t - r) % n
if (q == 0):
break
p = q
d = gmpy2.gcd(p, n)
if (d > 1):
return d
if (t == r):
break
return 0
def task(num):
n, e, c = load_data(num)
n = gmpy2.mpz(n)
e = gmpy2.mpz(e)
c = gmpy2.mpz(c)
# 得到 p, q
p = Pollard_Rho(n)
if p==0:
return 0
q = n // p
phi = (p - 1) * (q - 1)
# 求 e 关于 phi 的逆元
d = gmpy2.invert(e, phi)
# 求解密文
m = gmpy2.powmod(c, d, n)
print("m = 0x%X" % m)
return hex(m)
# 多线程
def solve(lst):
pool = multiprocessing.Pool(processes=len(lst))
for i in lst:
pool.apply_async(task, (i, ))
pool.close()
pool.join()