chinese_factorization_method_2.sf 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 01 June 2022
  4. # https://github.com/trizen
  5. # Concept for an integer factorization method based on the Chinese Remainder Theorem (CRT).
  6. # Example:
  7. # n = 43*97
  8. # We have:
  9. # n == 1 mod 2
  10. # n == 1 mod 3
  11. # n == 1 mod 5
  12. # n == 6 mod 7
  13. # n == 2 mod 11
  14. # 43 = chinese(Mod(1,2), Mod(1,3), Mod(3,5), Mod(1,7))
  15. # 97 = chinese(Mod(1,2), Mod(1,3), Mod(2,5), Mod(6,7))
  16. # For some small primes p, we try to find pairs of a and b, such that:
  17. # a*b == n mod p
  18. # Then using either the `a` or the `b` values, we can construct a factor of n, using the CRT.
  19. func CRT_factor(n) {
  20. return n if n.is_prime
  21. var congruences = [
  22. Mod(0, 1)
  23. ]
  24. 2..n.isqrt -> each_prime {|p|
  25. var r = n%p
  26. if (r == 0) {
  27. return p
  28. }
  29. var new_congruences = []
  30. var mods = (1..^p -> map { Mod(_, p) })
  31. mods.each {|t|
  32. congruences.each {|c|
  33. var z = chinese(c, t)
  34. with (gcd(z.lift, n)) { |g|
  35. if (g.is_ntf(n)) {
  36. return g
  37. }
  38. }
  39. new_congruences << z
  40. }
  41. }
  42. congruences = new_congruences
  43. }
  44. return 1
  45. }
  46. say CRT_factor(43*97) #=> 97
  47. say CRT_factor(503*863) #=> 864
  48. say CRT_factor(2**32 + 1) #=> 641
  49. say CRT_factor(2**64 + 1) #=> 274177
  50. say CRT_factor(273511610089) #=> 723907