module Crypto.PubKey.Rabin.Types
( Error(..)
, generatePrimes
) where
import Crypto.Number.Basic (numBits)
import Crypto.Number.Prime (generatePrime, findPrimeFromWith)
import Crypto.Random.Types
type PrimeCondition = Integer -> Bool
data Error = MessageTooLong
| MessageNotRecognized
| InvalidParameters
deriving (Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
(Int -> Error -> ShowS)
-> (Error -> String) -> ([Error] -> ShowS) -> Show Error
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Error -> ShowS
showsPrec :: Int -> Error -> ShowS
$cshow :: Error -> String
show :: Error -> String
$cshowList :: [Error] -> ShowS
showList :: [Error] -> ShowS
Show, Error -> Error -> Bool
(Error -> Error -> Bool) -> (Error -> Error -> Bool) -> Eq Error
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Error -> Error -> Bool
== :: Error -> Error -> Bool
$c/= :: Error -> Error -> Bool
/= :: Error -> Error -> Bool
Eq)
generatePrimes :: MonadRandom m
=> Int
-> PrimeCondition
-> PrimeCondition
-> m (Integer, Integer)
generatePrimes :: forall (m :: * -> *).
MonadRandom m =>
Int -> PrimeCondition -> PrimeCondition -> m (Integer, Integer)
generatePrimes Int
size PrimeCondition
pCond PrimeCondition
qCond =
let pBits :: Int
pBits = (Int
8Int -> Int -> Int
forall a. Num a => a -> a -> a
*(Int
size Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2))
qBits :: Int
qBits = (Int
8Int -> Int -> Int
forall a. Num a => a -> a -> a
*(Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int
size Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)))
in do
Integer
p <- Int -> PrimeCondition -> m Integer
forall {m :: * -> *}.
MonadRandom m =>
Int -> PrimeCondition -> m Integer
generatePrime' Int
pBits PrimeCondition
pCond
Integer
q <- Int -> PrimeCondition -> m Integer
forall {m :: * -> *}.
MonadRandom m =>
Int -> PrimeCondition -> m Integer
generatePrime' Int
qBits PrimeCondition
qCond
(Integer, Integer) -> m (Integer, Integer)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer
p, Integer
q)
where
generatePrime' :: Int -> PrimeCondition -> m Integer
generatePrime' Int
bits PrimeCondition
cond = do
Integer
pr' <- Int -> m Integer
forall (m :: * -> *). MonadRandom m => Int -> m Integer
generatePrime Int
bits
let pr :: Integer
pr = PrimeCondition -> Integer -> Integer
findPrimeFromWith PrimeCondition
cond Integer
pr'
if Integer -> Int
numBits Integer
pr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
bits then Integer -> m Integer
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
pr
else Int -> PrimeCondition -> m Integer
generatePrime' Int
bits PrimeCondition
cond