complex_modular_exponentiation.sf 710 B

123456789101112131415161718192021222324252627282930313233
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 24 May 2020
  4. # https://github.com/trizen
  5. # Modular exponentiation of a Gaussian integer.
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Modular_exponentiation
  8. func complex_powmod(a, b, n, m) {
  9. # Computes:
  10. # (a + b*i)^n mod m
  11. var (x, y) = (1, 0)
  12. #~ do {
  13. #~ (x, y) = ((x*a - y*b)%m, (x*b + y*a)%m) if n.is_odd
  14. #~ (a, b) = ((a*a - b*b)%m, (2*a*b)%m)
  15. #~ } while (n >>= 1)
  16. do {
  17. (x, y) = (mulsubmulmod(x,a,y,b,m), muladdmulmod(x,b,y,a,m)) if n.is_odd
  18. (a, b) = (mulsubmulmod(a,a,b,b,m), mulmod(2*a,b,m))
  19. } while (n >>= 1)
  20. (x, y)
  21. }
  22. say [complex_powmod(3, 4, 1000, 1e6)] #=> [585313, 426784]