difference_of_matrices_factorization_method.sf 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #!/usr/bin/ruby
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 13 March 2021
  4. # https://github.com/trizen
  5. # A new factorization method, using Fibonacci-like matrices.
  6. # The idea is to try to find a non-trivial factor of `n` by checking:
  7. #
  8. # gcd(f(n) - f(k), n)
  9. #
  10. # for several small k >= 1, where f(n) is a C-finite sequence.
  11. # In this method, we take f(n) to be a constant square matrix raised to power n.
  12. # However, this method is too slow in practice for large n.
  13. func fibonacci_matrix(k) is cached {
  14. Matrix.build(k, { |i,j|
  15. #((i == k-1) || (i == j-1)) ? (i - j + 1) : (i + j + 1)
  16. ((i == k-1) || (i == j-1)) ? (i - j - 1) : (i + j + 1)
  17. #((i == k-1) || (i == j-1)) ? (i - j) : (i + j + 1)
  18. #((i == k-1) || (i == j-1)) ? -1 : 1
  19. #((i == k-1) || (i == j-1)) ? 1 : 0
  20. })
  21. }
  22. func f(n, m, k) {
  23. fibonacci_matrix(k).powmod(n,m)
  24. }
  25. func fibonacci_matrix_factor(n, tries = 1e2) {
  26. say "Factoring: #{n}"
  27. var order = n.ilog(2)
  28. var z = f(n, n, order)
  29. tries.times { |k|
  30. say "Testing: #{k}"
  31. for v in (z - f(k, n, order) -> flat) {
  32. var g = gcd(v, n)
  33. return g if (g.is_between(2, n-1))
  34. }
  35. }
  36. return 1
  37. }
  38. say fibonacci_matrix_factor(101*503)
  39. say fibonacci_matrix_factor(503*863)
  40. #say fibonacci_matrix_factor(2**32 + 1)
  41. #say fibonacci_matrix_factor(2695409723)
  42. #say fibonacci_matrix_factor(1489390523)
  43. #say fibonacci_matrix_factor(1e5.random_prime * 1e5.random_prime)