@@ -6,6 +6,56 @@ from gmpy2 import gcd, isqrt, is_prime, next_prime
6
6
import itertools
7
7
8
8
9
+ def prebuilt_params (bits ):
10
+ """
11
+ Bounds estimation
12
+ borrowed from msieve/mpqs.c
13
+ """
14
+ if bits <= 64 :
15
+ return [100 , 40 , 1 * 65536 ]
16
+ if bits <= 128 :
17
+ return [450 , 40 , 1 * 65536 ]
18
+ if bits <= 183 :
19
+ return [2000 , 40 , 1 * 65536 ]
20
+ if bits <= 200 :
21
+ return [3000 , 50 , 1 * 65536 ]
22
+ if bits <= 212 :
23
+ return [5400 , 50 , 3 * 65536 ]
24
+ if bits <= 233 :
25
+ return [10000 , 100 , 3 * 65536 ]
26
+ if bits <= 249 :
27
+ return [27000 , 100 , 3 * 65536 ]
28
+ if bits <= 266 :
29
+ return [50000 , 100 , 3 * 65536 ]
30
+ if bits <= 283 :
31
+ return [55000 , 80 , 3 * 65536 ]
32
+ if bits <= 298 :
33
+ return [60000 , 80 , 9 * 65536 ]
34
+ if bits <= 315 :
35
+ return [80000 , 150 , 9 * 65536 ]
36
+ if bits <= 332 :
37
+ return [100000 , 150 , 9 * 65536 ]
38
+ if bits <= 348 :
39
+ return [140000 , 150 , 9 * 65536 ]
40
+ if bits <= 363 :
41
+ return [210000 , 150 , 13 * 65536 ]
42
+ if bits <= 379 :
43
+ return [300000 , 150 , 17 * 65536 ]
44
+ if bits <= 395 :
45
+ return [400000 , 150 , 21 * 65536 ]
46
+ if bits <= 415 :
47
+ return [500000 , 150 , 25 * 65536 ] # beyond this point you're crazy
48
+ if bits <= 440 :
49
+ return [700000 , 150 , 33 * 65536 ]
50
+ if bits <= 465 :
51
+ return [900000 , 150 , 50 * 65536 ]
52
+ if bits <= 490 :
53
+ return [1100000 , 150 , 75 * 65536 ]
54
+ if bits <= 512 :
55
+ return [1300000 , 150 , 100 * 65536 ]
56
+ return [1300000 , 150 , 100 * 65536 ]
57
+
58
+
9
59
def trial_division_minus_even_powers (n ,P ):
10
60
a = []
11
61
r = n
@@ -33,35 +83,33 @@ def trial_division_minus_even_powers(n,P):
33
83
return [a ,r ,n ]
34
84
35
85
36
- def minifactor (x ,P ):
37
- if not is_prime (x ):
38
- i = isqrt (x )
39
- if pow (i ,2 ) != x : # perfect squares are even powers
40
- p = trial_division_minus_even_powers (x ,P )
41
- if p [1 ] == 1 : # if 1 x is B-smooth
42
- return p
86
+ def minifactor (x , P ):
87
+ if not is_prime (x ) and not is_square (x ):
88
+ p = trial_division_minus_even_powers (x , P )
89
+ if p [1 ] == 1 : # if 1 x is B-smooth
90
+ return p
43
91
44
92
45
93
def QS (N ,differences ,y ):
46
94
i2N = isqrt (N )
47
- X = [Integer ( a ^ 2 - N ) for a in range (i2N + 1 ,i2N + differences )]
95
+ X = [int ( a * a - N ) for a in range (i2N + 1 , i2N + differences )]
48
96
P = list (primes (2 , y ))
49
- F = list (filter (None ,map (minifactor , X , itertools .repeat (P , len (X )))))
97
+ F = list (filter (None , map (minifactor , X , itertools .repeat (P , len (X )))))
50
98
51
99
M = matrix (GF (2 ), len (F ), len (P ), lambda i , j :P [j ] in F [i ][0 ])
52
100
for K in M .left_kernel ().basis ():
53
101
I = [f for f , k in zip (F , K ) if k == 1 ]
54
102
x = product ([int (isqrt (f [2 ] + N )) for f in I ])
55
103
y = isqrt (product ([f [2 ] for f in I ]))
56
104
g0 , g1 = gcd (N , x - y ), gcd (N , x + y )
57
- if N > g0 > 1 :
58
- return g0 , N // g0
59
- if N > g1 > 1 :
60
- return g1 , N // g1
105
+ if N > g0 > 1 or N > g1 > 1 :
106
+ return g0 , g1
61
107
62
108
63
109
if __name__ == "__main__" :
64
- r = QS (Integer (sys .argv [1 ]),int (sys .argv [2 ]),int (sys .argv [3 ]))
110
+ N = int (sys .argv [1 ])
111
+ y ,_ ,diff = prebuilt_params (N .bit_length ())
112
+ r = QS (N , diff * 10 , y * 10 )
65
113
if r != None :
66
114
print ("%d, %d" % r )
67
115
0 commit comments