elliptic-curve_factorization_method.jl 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #!/usr/bin/julia
  2. # The elliptic-curve factorization method (ECM), due to Hendrik Lenstra.
  3. # Algorithm presented in the YouTube video:
  4. # https://www.youtube.com/watch?v=2JlpeQWtGH8
  5. # See also:
  6. # https://en.wikipedia.org/wiki/Lenstra_elliptic-curve_factorization
  7. using Primes
  8. function ecm(N, arange=100, plimit=10000)
  9. isprime(N) && return N
  10. # TODO: make sure that N is not a perfect power.
  11. P = primes(plimit)
  12. for a in (-arange : arange)
  13. x = 0
  14. y = 1
  15. for B in P
  16. t = B^trunc(Int64, log(B, plimit))
  17. (xn, yn) = (0, 0)
  18. (sx, sy) = (x, y)
  19. first = true
  20. while (t > 0)
  21. if (isodd(t))
  22. if (first)
  23. (xn, yn) = (sx, sy)
  24. first = false
  25. else
  26. g = gcd(sx-xn, N)
  27. if (g > 1)
  28. g == N && break
  29. return g
  30. end
  31. u = invmod(sx-xn, N)
  32. L = ((u*(sy-yn)) % N)
  33. xs = ((L*L - xn - sx) % N)
  34. yn = ((L*(xn - xs) - yn) % N)
  35. xn = xs
  36. end
  37. end
  38. g = gcd(2*sy, N) # TODO: if N is odd, use gcd(sy, N) instead
  39. if (g > 1)
  40. g == N && break
  41. return g
  42. end
  43. u = invmod(2*sy, N)
  44. L = ((u*(3*sx*sx + a)) % N)
  45. x2 = ((L*L - 2*sx) % N)
  46. sy = ((L*(sx - x2) - sy) % N)
  47. sx = x2
  48. sy == 0 && return 1
  49. t >>= 1
  50. end
  51. (x, y) = (xn, yn)
  52. end
  53. end
  54. return 1
  55. end
  56. if (length(ARGS) >= 1)
  57. for n in (ARGS)
  58. println("One factor of ", n, " is: ", ecm(parse(BigInt, n)))
  59. end
  60. else
  61. @time println("One factor of 2^128 + 1 is: ", ecm(big"2"^128 + 1))
  62. end