lucas_flt_factorization_method.sf 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/ruby
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 24 February 2021
  4. # https://github.com/trizen
  5. # A new factorization method, inspired by Fermat's Little Theorem (FLT), implemented
  6. # using Lucas sequences, for numbers that have prime factors close to each other.
  7. # The idea is to try to find a non-trivial factor of `n` by checking:
  8. # gcd(V_n(P, Q) - V_k(P, Q), n)
  9. # for several small k >= 1, where V_n(P,Q) is the Lucas V sequence.
  10. # See also:
  11. # https://en.wikipedia.org/wiki/Lucas_sequence
  12. func lucas_FLT_factor(n, P = 3, Q = -1, tries = 1e4) {
  13. var (a, b, z) = (2, P, lucasVmod(P, Q, n, n))
  14. #var (a, b, z) = (0, 1, lucasUmod(P, Q, n, n))
  15. if (z == P) { # can't factor Lucas pseudoprimes
  16. return 1
  17. }
  18. tries.times {
  19. var g = gcd(z - b, n)
  20. if (g.is_between(2, n-1)) {
  21. return g
  22. }
  23. (a, b) = (b, (P*b - Q*a) % n)
  24. (a, b) = (b, (P*b - Q*a) % n)
  25. }
  26. return 1
  27. }
  28. var p = 1e20.random_prime
  29. var n = (p * p.next_prime * p.next_prime.next_prime)
  30. say "Factoring: #{n}"
  31. say ("Factor found: ", lucas_FLT_factor(n))
  32. say ''
  33. say lucas_FLT_factor(1169586052690021349455126348204184925097724507); #=> 166585508879747
  34. say lucas_FLT_factor(61881629277526932459093227009982733523969186747); #=> 1233150073853267
  35. say lucas_FLT_factor(57981220983721718930050466285761618141354457135475808219583649146881, 8, -7); #=> 213745738248483841
  36. say lucas_FLT_factor(random_prime(1e30) * (2**128 + 1), 3, -4); #=> 340282366920938463463374607431768211457
  37. say ''
  38. say lucas_FLT_factor(335603208601);
  39. say lucas_FLT_factor(30459888232201);
  40. say lucas_FLT_factor(162021627721801);
  41. say lucas_FLT_factor(1372144392322327801);
  42. say lucas_FLT_factor(7520940423059310542039581);
  43. say lucas_FLT_factor(8325544586081174440728309072452661246289);
  44. say lucas_FLT_factor(181490268975016506576033519670430436718066889008242598463521);
  45. say lucas_FLT_factor(57981220983721718930050466285761618141354457135475808219583649146881, 8, -7);
  46. say lucas_FLT_factor(131754870930495356465893439278330079857810087607720627102926770417203664110488210785830750894645370240615968198960237761, 8, -7);
  47. say ''
  48. say lucas_FLT_factor(16641689036184776955112478816668559); #=> 140501852609
  49. say lucas_FLT_factor(17350074279723825442829581112345759); #=> 142467792809
  50. say lucas_FLT_factor(61881629277526932459093227009982733523969186747); #=> 1233150073853267
  51. say lucas_FLT_factor(173315617708997561998574166143524347111328490824959334367069087); #=> 173823271649325368927
  52. say lucas_FLT_factor(2425361208749736840354501506901183117777758034612345610725789878400467); #=> 19760381716819645293083