-
Notifications
You must be signed in to change notification settings - Fork 0
/
modular_elliptic-curve_arithmetic.sf
104 lines (82 loc) · 2.3 KB
/
modular_elliptic-curve_arithmetic.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
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/ruby
# Modular Elliptic curve arithmetic (without validation).
# See also:
# https://rosettacode.org/wiki/Elliptic_curve_arithmetic
class EllipticCurveMod(x, y, N, A = 0) {
method to_s {
"EC Point at x=#{x}, y=#{y}"
}
method is_zero {
x == 0
}
method neg {
EllipticCurveMod(x, -y)
}
method -(EllipticCurveMod p) {
self + -p
}
method +(EllipticCurveMod p) {
if (p.is_zero) {
return self
}
if (x == p.x) {
return self*2 if (y == p.y)
return EllipticCurveMod(0, 0, N, A)
}
else {
var u = invmod(p.x - x, N) || die gcd(p.x - x, N)
var slope = mulmod(p.y - y, u, N)
var x2 = submod(mulmod(slope, slope, N) - x, p.x, N)
var y2 = submod(mulmod(slope, x - x2, N), y, N)
EllipticCurveMod(x2, y2, N, A)
}
}
method *((0)) {
EllipticCurveMod(0, 0, N, A)
}
method *((1)) {
self
}
method *((2)) {
var l = divmod(3*mulmod(x, x, N) + A, 2*y, N)
var x2 = submod(mulmod(l, l, N), 2*x, N)
var y2 = submod(mulmod(l, x - x2, N), y, N)
EllipticCurveMod(x2, y2, N, A)
}
method *(Number n) {
2*(self * (n>>1)) + self*(n % 2)
}
}
class Number {
method +(EllipticCurveMod p) {
p + self
}
method -(EllipticCurveMod p) {
-p + self
}
method *(EllipticCurveMod p) {
p * self
}
}
func elliptic_curve_factorization(N, alimit = 100, B = 10000) {
for a in (-alimit .. alimit) {
say "Testing: #{a}"
var curve = EllipticCurveMod(0, 1, N, a)
B.each_prime {|p|
var pp = p**B.ilog(p)
try {
curve *= pp
}
catch { |v|
if (v =~ /^(\d+)/) {|m|
return Num(m[0])
}
}
}
}
return 1
}
say ("Found factor: ", elliptic_curve_factorization(14304849576137459)) #=> 16100431
say ("Found factor: ", elliptic_curve_factorization(314159265358979323)) #=> 990371647
#say ("Found factor: ", elliptic_curve_factorization(2**64 + 1)) # takes ~2 seconds
#say ("Found factor: ", elliptic_curve_factorization(2**128 + 1)) # takes ~1 minute