Files
haskell-math/PollardPminus1.hs
2025-10-17 15:50:59 +02:00

51 lines
1.7 KiB
Haskell

import Text.Read (readMaybe)
import System.Exit (exitSuccess)
import Data.Bits
import Utils (askNumber)
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)
-- 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