module ModularArithmeticUtils (modExp, modMul, legendre) where import Data.Bits (testBit, shiftR) -- Modular exponentiation: compute a^b mod m modExp :: Integer -> Integer -> Integer -> Integer modExp b 0 m = 1 modExp b e m = t * modExp ((b * b) `mod` m) (shiftR e 1) m `mod` m where t = if testBit e 0 then b `mod` m else 1 -- Compute (a * b) mod m modMul :: Integer -> Integer -> Integer -> Integer modMul a b m = (a * b) `mod` m -- Compute the Legendre symbol (a/p) -- (a/p) = a^((p-1)/2) mod p -- (a/p) in {-1, 0, 1} legendre :: Integer -> Integer -> Integer legendre a p = modExp a ((p - 1) `div` 2) p