import Text.Read (readMaybe) import System.Exit (exitSuccess) import Utils (askNumber) import ModularArithmeticUtils (modExp) main :: IO () main = do n <- askNumber "Enter an integer n>1 to factor:" b <- askNumber "Enter the bound B:" putStrLn ("n = " ++ show n) case pollardP1 n b of Just factor -> do putStrLn ("Found factor: " ++ show factor) let otherFactor = n `div` factor putStrLn ("Other factor: " ++ show otherFactor) Nothing -> do putStrLn "Failed to find a factor using Pollard p-1 method. n could be prime or different parameters needed." -- Pollard p-1 factorization algorithm pollardP1 :: Integer -> Integer -> Maybe Integer pollardP1 n b = tryBases [2..5] where tryBases [] = Nothing tryBases (a:as) = case pollardP1WithParams n a b of Just factor -> Just factor Nothing -> tryBases as -- Pollard p-1 with configurable parameters pollardP1WithParams :: Integer -> Integer -> Integer -> Maybe Integer pollardP1WithParams n a b = go a 2 where go currentA k | k > b = Nothing -- Bound exceeded, failed to find factor | otherwise = let newA = modExp currentA k n d = gcd (newA - 1) n in if d > 1 && d < n then Just d -- Found a non-trivial factor else if d == n then Nothing -- Found n itself, try with different parameters else go newA (k + 1)