chinese_factorization_method.sf 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 18 May 2020
  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, p = 3, crt = Mod(1, 2), L = n*n) {
  20. var v = crt.lift
  21. if (!is_coprime(n, v)) {
  22. return gcd(n, v)
  23. }
  24. if (v > L) {
  25. return nil
  26. }
  27. var inverses = (1..^p -> map {|a| chinese(crt, Mod(a, p)) }.grep { .lift > v }.sort.flip)
  28. for inv in (inverses) {
  29. with (__FUNC__(n, p.next_prime, inv, L)) {|t|
  30. return t if defined(t)
  31. }
  32. }
  33. return nil
  34. }
  35. say CRT_factor(43*97, 5) #=> 43
  36. say CRT_factor(503*863) #=> 863
  37. say CRT_factor(2**32 + 1, 11) #=> 641