aboutsummaryrefslogtreecommitdiff
path: root/code/python/ecm.py
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-02-26 17:12:06 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2025-02-26 17:12:06 +0100
commit7f1b8a358515b45d717c3c4b5baf2fbc0f568170 (patch)
tree3e51ad948d132ccad19da053bb083d8b760b4ec2 /code/python/ecm.py
downloadecm-7f1b8a358515b45d717c3c4b5baf2fbc0f568170.tar.gz
ecm-7f1b8a358515b45d717c3c4b5baf2fbc0f568170.zip
Initial commit
Diffstat (limited to '')
-rwxr-xr-xcode/python/ecm.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/code/python/ecm.py b/code/python/ecm.py
new file mode 100755
index 0000000..662facf
--- /dev/null
+++ b/code/python/ecm.py
@@ -0,0 +1,75 @@
1#! /bin/env python
2
3from sys import argv
4from random import randint
5from math import sqrt
6from dataclasses import dataclass
7
8@dataclass
9class Point:
10 x: int = 0
11 y: int = 0
12 is_zero: bool = False
13
14@dataclass
15class FactorFound(Exception):
16 factor: int = 0
17
18# Returns gcd(a, b) and x, y such that ax + by = gcd(a,b)
19def extended_gcd(a: int, b: int) -> (int, int, int):
20 if b == 0:
21 return a, 1, 0
22 g, x, y = extended_gcd(b, a % b)
23 return g, y, x - y * (a // b)
24
25def inverse_modulo(a: int, n: int) -> int:
26 g, x, y = extended_gcd(a, n)
27 if g != 1:
28 raise FactorFound(g)
29 return x
30
31def ec_sum(p: Point, q: Point, A: int, n: int) -> Point:
32 if p.is_zero:
33 return q
34 if q.is_zero:
35 return p
36 if (p.x - q.x) % n == 0 and (p.y + q.y) % n == 0:
37 return Point(is_zero = True)
38
39 if (p.x - q.x) % n != 0:
40 k = ((p.y - q.y) * inverse_modulo(p.x - q.x, n)) % n
41 else:
42 k = ((3 * p.x**2 + A) * inverse_modulo(p.y + q.y, n)) % n
43
44 x = (k**2 - p.x - q.x) % n
45 y = (k * (p.x - x) - p.y) % n
46
47 return Point(x = x, y = y)
48
49def ec_mul(M: int, p: Point, A: int, n: int) -> Point:
50 if M == 0:
51 return Point(is_zero = True)
52 if M % 2 == 0:
53 return ec_mul(M // 2, ec_sum(p, p, A, n), A, n)
54 return ec_sum(p, ec_mul(M - 1, p, A, n), A, n)
55
56# Elliptic curve factorization method
57# If n is prime, this method goes into an infinite loop
58def find_factor(n: int) -> int:
59 bound = max(int(sqrt(sqrt(sqrt(n)))), 256)
60
61 while True:
62 A = randint(0,n)
63 p = Point(x = randint(0,n), y = randint(0,n))
64 M = 2
65 while M < bound and not p.is_zero:
66 try:
67 p = ec_mul(M, p, A, n)
68 except FactorFound as ff:
69 #print("Found with A =", A, "M =", M, "and P =", p)
70 return ff.factor
71 M += 1
72
73N = int(argv[-1])
74f = find_factor(N)
75print(N, "=", f, "*", N//f)

Generated with cgit - Back to sebastiano.tronto.net