Pollard p-1
This commit is contained in:
59
PollardPminus1.hs
Normal file
59
PollardPminus1.hs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import Text.Read (readMaybe)
|
||||||
|
import System.Exit (exitSuccess)
|
||||||
|
import Data.Bits
|
||||||
|
|
||||||
|
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."
|
||||||
|
|
||||||
|
askNumber :: String -> IO Integer
|
||||||
|
askNumber s = do
|
||||||
|
putStrLn s
|
||||||
|
input <- getLine
|
||||||
|
case readMaybe input of
|
||||||
|
Just n | n > 1 -> return n
|
||||||
|
_ -> do
|
||||||
|
putStrLn "Not a valid integer"
|
||||||
|
exitSuccess
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
Reference in New Issue
Block a user