Miller Rabin primality test

This commit is contained in:
2025-12-24 13:45:44 +01:00
parent d32a7d0f81
commit 0aa0fa2aa3
4 changed files with 41 additions and 10 deletions

View File

@@ -0,0 +1,28 @@
import System.Random (randomRIO)
import ModularArithmeticUtils (modExp, factorOutTwos)
millerRabinWitness :: Integer -> Integer -> Integer -> Integer -> Bool
millerRabinWitness n a d s =
let x0 = modExp a d n
in x0 == 1 || x0 == n - 1 || loop x0 (s - 1)
where
loop _ 0 = False
loop x r =
let x' = (x * x) `mod` n
in x' == n - 1 || loop x' (r - 1)
millerRabin :: Integer -> Integer -> IO Bool
millerRabin n k
| n < 2 = return False
| n == 2 = return True
| even n = return False
| otherwise = do
let (d, s) = factorOutTwos (n - 1)
go k d s
where
go 0 _ _ = return True
go i d s = do
a <- randomRIO (2, n - 2)
if millerRabinWitness n a d s
then go (i - 1) d s
else return False