-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquadratic-integer_factorization_method.sf
53 lines (37 loc) · 1.47 KB
/
quadratic-integer_factorization_method.sf
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
#!/usr/bin/ruby
# Daniel "Trizen" Șuteu
# Date: 22 June 2020
# https://github.com/trizen
# A simple factorization method, using quadratic integers.
# Similar in flavor to Pollard's p-1 and Williams's p+1 methods.
# See also:
# https://en.wikipedia.org/wiki/Quadratic_integer
class QuadraticInteger(a, b, w = 2) { # represents: a + b*sqrt(w), for w >= 0
method powmod(Number n, Number m) {
var (a, b) = (self.a, self.b)
var (c, d) = (1, 0)
do {
(c, d) = ((a*c + b*d*w) % m, (a*d + b*c) % m) if n.is_odd
(a, b) = ((a*a + b*b*w) % m, (2*a*b) % m)
} while (n >>= 1)
return QuadraticInteger(c, d, w)
}
}
func quadratic_factorization (n, B = n.ilog2**2) {
var t = QuadraticInteger(3, 4)
primes_each(2, B.isqrt, {|p|
t = powmod(t, p**ilog(B, p), n)
})
primes_each(B.isqrt, B, {|p|
t = powmod(t, p, n)
if (!is_coprime(t.b, n)) {
var g = gcd(t.b, n)
return g if g.is_between(2, n-1)
}
})
return 1
}
say quadratic_factorization(524934717838728509869) #=> 18711680699 (p+1 is 307-smooth)
say quadratic_factorization(8323759753781305339013) #=> 98561959037 (p+1 is 3917-smooth)
say quadratic_factorization(6486152039244634535185721) #=> 492851064557 (p+1 is 5077-smooth)
say quadratic_factorization(154499342049364226248203335113) #=> 457976616241871 (p-1 is 8081-smooth)