-- |
-- Module      : Crypto.PubKey.DH
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : Good
--
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Crypto.PubKey.DH
    ( Params(..)
    , PublicNumber(..)
    , PrivateNumber(..)
    , SharedKey(..)
    , generateParams
    , generatePrivate
    , calculatePublic
    , generatePublic
    , getShared
    ) where

import Crypto.Internal.Imports
import Crypto.Number.ModArithmetic (expSafe)
import Crypto.Number.Prime (generateSafePrime)
import Crypto.Number.Generate (generateMax)
import Crypto.Number.Serialize (i2ospOf_)
import Crypto.Random.Types
import Data.ByteArray (ByteArrayAccess, ScrubbedBytes)
import Data.Data

-- | Represent Diffie Hellman parameters namely P (prime), and G (generator).
data Params = Params
    { Params -> Integer
params_p :: Integer
    , Params -> Integer
params_g :: Integer
    , Params -> Int
params_bits :: Int
    } deriving (Int -> Params -> ShowS
[Params] -> ShowS
Params -> String
(Int -> Params -> ShowS)
-> (Params -> String) -> ([Params] -> ShowS) -> Show Params
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Params] -> ShowS
$cshowList :: [Params] -> ShowS
show :: Params -> String
$cshow :: Params -> String
showsPrec :: Int -> Params -> ShowS
$cshowsPrec :: Int -> Params -> ShowS
Show,ReadPrec [Params]
ReadPrec Params
Int -> ReadS Params
ReadS [Params]
(Int -> ReadS Params)
-> ReadS [Params]
-> ReadPrec Params
-> ReadPrec [Params]
-> Read Params
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Params]
$creadListPrec :: ReadPrec [Params]
readPrec :: ReadPrec Params
$creadPrec :: ReadPrec Params
readList :: ReadS [Params]
$creadList :: ReadS [Params]
readsPrec :: Int -> ReadS Params
$creadsPrec :: Int -> ReadS Params
Read,Params -> Params -> Bool
(Params -> Params -> Bool)
-> (Params -> Params -> Bool) -> Eq Params
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Params -> Params -> Bool
$c/= :: Params -> Params -> Bool
== :: Params -> Params -> Bool
$c== :: Params -> Params -> Bool
Eq,Typeable Params
DataType
Constr
Typeable Params
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Params -> c Params)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Params)
-> (Params -> Constr)
-> (Params -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Params))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params))
-> ((forall b. Data b => b -> b) -> Params -> Params)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Params -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Params -> r)
-> (forall u. (forall d. Data d => d -> u) -> Params -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Params -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Params -> m Params)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Params -> m Params)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Params -> m Params)
-> Data Params
Params -> DataType
Params -> Constr
(forall b. Data b => b -> b) -> Params -> Params
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
forall u. (forall d. Data d => d -> u) -> Params -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Params -> m Params
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Params)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
$cParams :: Constr
$tParams :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Params -> m Params
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapMp :: (forall d. Data d => d -> m d) -> Params -> m Params
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapM :: (forall d. Data d => d -> m d) -> Params -> m Params
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapQi :: Int -> (forall d. Data d => d -> u) -> Params -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
gmapQ :: (forall d. Data d => d -> u) -> Params -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Params -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
gmapT :: (forall b. Data b => b -> b) -> Params -> Params
$cgmapT :: (forall b. Data b => b -> b) -> Params -> Params
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Params)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Params)
dataTypeOf :: Params -> DataType
$cdataTypeOf :: Params -> DataType
toConstr :: Params -> Constr
$ctoConstr :: Params -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
$cp1Data :: Typeable Params
Data)

instance NFData Params where
    rnf :: Params -> ()
rnf (Params Integer
p Integer
g Int
bits) = Integer -> ()
forall a. NFData a => a -> ()
rnf Integer
p () -> () -> ()
`seq` Integer -> ()
forall a. NFData a => a -> ()
rnf Integer
g () -> () -> ()
`seq` Int
bits Int -> () -> ()
`seq` ()

-- | Represent Diffie Hellman public number Y.
newtype PublicNumber = PublicNumber Integer
    deriving (Int -> PublicNumber -> ShowS
[PublicNumber] -> ShowS
PublicNumber -> String
(Int -> PublicNumber -> ShowS)
-> (PublicNumber -> String)
-> ([PublicNumber] -> ShowS)
-> Show PublicNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicNumber] -> ShowS
$cshowList :: [PublicNumber] -> ShowS
show :: PublicNumber -> String
$cshow :: PublicNumber -> String
showsPrec :: Int -> PublicNumber -> ShowS
$cshowsPrec :: Int -> PublicNumber -> ShowS
Show,ReadPrec [PublicNumber]
ReadPrec PublicNumber
Int -> ReadS PublicNumber
ReadS [PublicNumber]
(Int -> ReadS PublicNumber)
-> ReadS [PublicNumber]
-> ReadPrec PublicNumber
-> ReadPrec [PublicNumber]
-> Read PublicNumber
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PublicNumber]
$creadListPrec :: ReadPrec [PublicNumber]
readPrec :: ReadPrec PublicNumber
$creadPrec :: ReadPrec PublicNumber
readList :: ReadS [PublicNumber]
$creadList :: ReadS [PublicNumber]
readsPrec :: Int -> ReadS PublicNumber
$creadsPrec :: Int -> ReadS PublicNumber
Read,PublicNumber -> PublicNumber -> Bool
(PublicNumber -> PublicNumber -> Bool)
-> (PublicNumber -> PublicNumber -> Bool) -> Eq PublicNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicNumber -> PublicNumber -> Bool
$c/= :: PublicNumber -> PublicNumber -> Bool
== :: PublicNumber -> PublicNumber -> Bool
$c== :: PublicNumber -> PublicNumber -> Bool
Eq,Int -> PublicNumber
PublicNumber -> Int
PublicNumber -> [PublicNumber]
PublicNumber -> PublicNumber
PublicNumber -> PublicNumber -> [PublicNumber]
PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
(PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber)
-> (Int -> PublicNumber)
-> (PublicNumber -> Int)
-> (PublicNumber -> [PublicNumber])
-> (PublicNumber -> PublicNumber -> [PublicNumber])
-> (PublicNumber -> PublicNumber -> [PublicNumber])
-> (PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber])
-> Enum PublicNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromThenTo :: PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
enumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
enumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
enumFrom :: PublicNumber -> [PublicNumber]
$cenumFrom :: PublicNumber -> [PublicNumber]
fromEnum :: PublicNumber -> Int
$cfromEnum :: PublicNumber -> Int
toEnum :: Int -> PublicNumber
$ctoEnum :: Int -> PublicNumber
pred :: PublicNumber -> PublicNumber
$cpred :: PublicNumber -> PublicNumber
succ :: PublicNumber -> PublicNumber
$csucc :: PublicNumber -> PublicNumber
Enum,Num PublicNumber
Ord PublicNumber
Num PublicNumber
-> Ord PublicNumber
-> (PublicNumber -> Rational)
-> Real PublicNumber
PublicNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PublicNumber -> Rational
$ctoRational :: PublicNumber -> Rational
$cp2Real :: Ord PublicNumber
$cp1Real :: Num PublicNumber
Real,Integer -> PublicNumber
PublicNumber -> PublicNumber
PublicNumber -> PublicNumber -> PublicNumber
(PublicNumber -> PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber)
-> (Integer -> PublicNumber)
-> Num PublicNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PublicNumber
$cfromInteger :: Integer -> PublicNumber
signum :: PublicNumber -> PublicNumber
$csignum :: PublicNumber -> PublicNumber
abs :: PublicNumber -> PublicNumber
$cabs :: PublicNumber -> PublicNumber
negate :: PublicNumber -> PublicNumber
$cnegate :: PublicNumber -> PublicNumber
* :: PublicNumber -> PublicNumber -> PublicNumber
$c* :: PublicNumber -> PublicNumber -> PublicNumber
- :: PublicNumber -> PublicNumber -> PublicNumber
$c- :: PublicNumber -> PublicNumber -> PublicNumber
+ :: PublicNumber -> PublicNumber -> PublicNumber
$c+ :: PublicNumber -> PublicNumber -> PublicNumber
Num,Eq PublicNumber
Eq PublicNumber
-> (PublicNumber -> PublicNumber -> Ordering)
-> (PublicNumber -> PublicNumber -> Bool)
-> (PublicNumber -> PublicNumber -> Bool)
-> (PublicNumber -> PublicNumber -> Bool)
-> (PublicNumber -> PublicNumber -> Bool)
-> (PublicNumber -> PublicNumber -> PublicNumber)
-> (PublicNumber -> PublicNumber -> PublicNumber)
-> Ord PublicNumber
PublicNumber -> PublicNumber -> Bool
PublicNumber -> PublicNumber -> Ordering
PublicNumber -> PublicNumber -> PublicNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PublicNumber -> PublicNumber -> PublicNumber
$cmin :: PublicNumber -> PublicNumber -> PublicNumber
max :: PublicNumber -> PublicNumber -> PublicNumber
$cmax :: PublicNumber -> PublicNumber -> PublicNumber
>= :: PublicNumber -> PublicNumber -> Bool
$c>= :: PublicNumber -> PublicNumber -> Bool
> :: PublicNumber -> PublicNumber -> Bool
$c> :: PublicNumber -> PublicNumber -> Bool
<= :: PublicNumber -> PublicNumber -> Bool
$c<= :: PublicNumber -> PublicNumber -> Bool
< :: PublicNumber -> PublicNumber -> Bool
$c< :: PublicNumber -> PublicNumber -> Bool
compare :: PublicNumber -> PublicNumber -> Ordering
$ccompare :: PublicNumber -> PublicNumber -> Ordering
$cp1Ord :: Eq PublicNumber
Ord,PublicNumber -> ()
(PublicNumber -> ()) -> NFData PublicNumber
forall a. (a -> ()) -> NFData a
rnf :: PublicNumber -> ()
$crnf :: PublicNumber -> ()
NFData)

-- | Represent Diffie Hellman private number X.
newtype PrivateNumber = PrivateNumber Integer
    deriving (Int -> PrivateNumber -> ShowS
[PrivateNumber] -> ShowS
PrivateNumber -> String
(Int -> PrivateNumber -> ShowS)
-> (PrivateNumber -> String)
-> ([PrivateNumber] -> ShowS)
-> Show PrivateNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrivateNumber] -> ShowS
$cshowList :: [PrivateNumber] -> ShowS
show :: PrivateNumber -> String
$cshow :: PrivateNumber -> String
showsPrec :: Int -> PrivateNumber -> ShowS
$cshowsPrec :: Int -> PrivateNumber -> ShowS
Show,ReadPrec [PrivateNumber]
ReadPrec PrivateNumber
Int -> ReadS PrivateNumber
ReadS [PrivateNumber]
(Int -> ReadS PrivateNumber)
-> ReadS [PrivateNumber]
-> ReadPrec PrivateNumber
-> ReadPrec [PrivateNumber]
-> Read PrivateNumber
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PrivateNumber]
$creadListPrec :: ReadPrec [PrivateNumber]
readPrec :: ReadPrec PrivateNumber
$creadPrec :: ReadPrec PrivateNumber
readList :: ReadS [PrivateNumber]
$creadList :: ReadS [PrivateNumber]
readsPrec :: Int -> ReadS PrivateNumber
$creadsPrec :: Int -> ReadS PrivateNumber
Read,PrivateNumber -> PrivateNumber -> Bool
(PrivateNumber -> PrivateNumber -> Bool)
-> (PrivateNumber -> PrivateNumber -> Bool) -> Eq PrivateNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrivateNumber -> PrivateNumber -> Bool
$c/= :: PrivateNumber -> PrivateNumber -> Bool
== :: PrivateNumber -> PrivateNumber -> Bool
$c== :: PrivateNumber -> PrivateNumber -> Bool
Eq,Int -> PrivateNumber
PrivateNumber -> Int
PrivateNumber -> [PrivateNumber]
PrivateNumber -> PrivateNumber
PrivateNumber -> PrivateNumber -> [PrivateNumber]
PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
(PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber)
-> (Int -> PrivateNumber)
-> (PrivateNumber -> Int)
-> (PrivateNumber -> [PrivateNumber])
-> (PrivateNumber -> PrivateNumber -> [PrivateNumber])
-> (PrivateNumber -> PrivateNumber -> [PrivateNumber])
-> (PrivateNumber
    -> PrivateNumber -> PrivateNumber -> [PrivateNumber])
-> Enum PrivateNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromThenTo :: PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFrom :: PrivateNumber -> [PrivateNumber]
$cenumFrom :: PrivateNumber -> [PrivateNumber]
fromEnum :: PrivateNumber -> Int
$cfromEnum :: PrivateNumber -> Int
toEnum :: Int -> PrivateNumber
$ctoEnum :: Int -> PrivateNumber
pred :: PrivateNumber -> PrivateNumber
$cpred :: PrivateNumber -> PrivateNumber
succ :: PrivateNumber -> PrivateNumber
$csucc :: PrivateNumber -> PrivateNumber
Enum,Num PrivateNumber
Ord PrivateNumber
Num PrivateNumber
-> Ord PrivateNumber
-> (PrivateNumber -> Rational)
-> Real PrivateNumber
PrivateNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PrivateNumber -> Rational
$ctoRational :: PrivateNumber -> Rational
$cp2Real :: Ord PrivateNumber
$cp1Real :: Num PrivateNumber
Real,Integer -> PrivateNumber
PrivateNumber -> PrivateNumber
PrivateNumber -> PrivateNumber -> PrivateNumber
(PrivateNumber -> PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber)
-> (Integer -> PrivateNumber)
-> Num PrivateNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PrivateNumber
$cfromInteger :: Integer -> PrivateNumber
signum :: PrivateNumber -> PrivateNumber
$csignum :: PrivateNumber -> PrivateNumber
abs :: PrivateNumber -> PrivateNumber
$cabs :: PrivateNumber -> PrivateNumber
negate :: PrivateNumber -> PrivateNumber
$cnegate :: PrivateNumber -> PrivateNumber
* :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c* :: PrivateNumber -> PrivateNumber -> PrivateNumber
- :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c- :: PrivateNumber -> PrivateNumber -> PrivateNumber
+ :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c+ :: PrivateNumber -> PrivateNumber -> PrivateNumber
Num,Eq PrivateNumber
Eq PrivateNumber
-> (PrivateNumber -> PrivateNumber -> Ordering)
-> (PrivateNumber -> PrivateNumber -> Bool)
-> (PrivateNumber -> PrivateNumber -> Bool)
-> (PrivateNumber -> PrivateNumber -> Bool)
-> (PrivateNumber -> PrivateNumber -> Bool)
-> (PrivateNumber -> PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PrivateNumber -> PrivateNumber)
-> Ord PrivateNumber
PrivateNumber -> PrivateNumber -> Bool
PrivateNumber -> PrivateNumber -> Ordering
PrivateNumber -> PrivateNumber -> PrivateNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PrivateNumber -> PrivateNumber -> PrivateNumber
$cmin :: PrivateNumber -> PrivateNumber -> PrivateNumber
max :: PrivateNumber -> PrivateNumber -> PrivateNumber
$cmax :: PrivateNumber -> PrivateNumber -> PrivateNumber
>= :: PrivateNumber -> PrivateNumber -> Bool
$c>= :: PrivateNumber -> PrivateNumber -> Bool
> :: PrivateNumber -> PrivateNumber -> Bool
$c> :: PrivateNumber -> PrivateNumber -> Bool
<= :: PrivateNumber -> PrivateNumber -> Bool
$c<= :: PrivateNumber -> PrivateNumber -> Bool
< :: PrivateNumber -> PrivateNumber -> Bool
$c< :: PrivateNumber -> PrivateNumber -> Bool
compare :: PrivateNumber -> PrivateNumber -> Ordering
$ccompare :: PrivateNumber -> PrivateNumber -> Ordering
$cp1Ord :: Eq PrivateNumber
Ord,PrivateNumber -> ()
(PrivateNumber -> ()) -> NFData PrivateNumber
forall a. (a -> ()) -> NFData a
rnf :: PrivateNumber -> ()
$crnf :: PrivateNumber -> ()
NFData)

-- | Represent Diffie Hellman shared secret.
newtype SharedKey = SharedKey ScrubbedBytes
    deriving (Int -> SharedKey -> ShowS
[SharedKey] -> ShowS
SharedKey -> String
(Int -> SharedKey -> ShowS)
-> (SharedKey -> String)
-> ([SharedKey] -> ShowS)
-> Show SharedKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SharedKey] -> ShowS
$cshowList :: [SharedKey] -> ShowS
show :: SharedKey -> String
$cshow :: SharedKey -> String
showsPrec :: Int -> SharedKey -> ShowS
$cshowsPrec :: Int -> SharedKey -> ShowS
Show,SharedKey -> SharedKey -> Bool
(SharedKey -> SharedKey -> Bool)
-> (SharedKey -> SharedKey -> Bool) -> Eq SharedKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SharedKey -> SharedKey -> Bool
$c/= :: SharedKey -> SharedKey -> Bool
== :: SharedKey -> SharedKey -> Bool
$c== :: SharedKey -> SharedKey -> Bool
Eq,SharedKey -> Int
SharedKey -> Ptr p -> IO ()
SharedKey -> (Ptr p -> IO a) -> IO a
(SharedKey -> Int)
-> (forall p a. SharedKey -> (Ptr p -> IO a) -> IO a)
-> (forall p. SharedKey -> Ptr p -> IO ())
-> ByteArrayAccess SharedKey
forall p. SharedKey -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: SharedKey -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall p. SharedKey -> Ptr p -> IO ()
withByteArray :: SharedKey -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
length :: SharedKey -> Int
$clength :: SharedKey -> Int
ByteArrayAccess,SharedKey -> ()
(SharedKey -> ()) -> NFData SharedKey
forall a. (a -> ()) -> NFData a
rnf :: SharedKey -> ()
$crnf :: SharedKey -> ()
NFData)

-- | generate params from a specific generator (2 or 5 are common values)
-- we generate a safe prime (a prime number of the form 2p+1 where p is also prime)
generateParams :: MonadRandom m =>
                  Int                   -- ^ number of bits
               -> Integer               -- ^ generator
               -> m Params
generateParams :: Int -> Integer -> m Params
generateParams Int
bits Integer
generator =
    (\Integer
p -> Integer -> Integer -> Int -> Params
Params Integer
p Integer
generator Int
bits) (Integer -> Params) -> m Integer -> m Params
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m Integer
forall (m :: * -> *). MonadRandom m => Int -> m Integer
generateSafePrime Int
bits

-- | generate a private number with no specific property
-- this number is usually called X in DH text.
generatePrivate :: MonadRandom m => Params -> m PrivateNumber
generatePrivate :: Params -> m PrivateNumber
generatePrivate (Params Integer
p Integer
_ Int
_) = Integer -> PrivateNumber
PrivateNumber (Integer -> PrivateNumber) -> m Integer -> m PrivateNumber
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> m Integer
forall (m :: * -> *). MonadRandom m => Integer -> m Integer
generateMax Integer
p

-- | calculate the public number from the parameters and the private key
-- this number is usually called Y in DH text.
calculatePublic :: Params -> PrivateNumber -> PublicNumber
calculatePublic :: Params -> PrivateNumber -> PublicNumber
calculatePublic (Params Integer
p Integer
g Int
_) (PrivateNumber Integer
x) = Integer -> PublicNumber
PublicNumber (Integer -> PublicNumber) -> Integer -> PublicNumber
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Integer
expSafe Integer
g Integer
x Integer
p

-- | calculate the public number from the parameters and the private key
-- this number is usually called Y in DH text.
--
-- DEPRECATED use calculatePublic
generatePublic :: Params -> PrivateNumber -> PublicNumber
generatePublic :: Params -> PrivateNumber -> PublicNumber
generatePublic = Params -> PrivateNumber -> PublicNumber
calculatePublic
-- commented until 0.3 {-# DEPRECATED generatePublic "use calculatePublic" #-}

-- | generate a shared key using our private number and the other party public number
getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared (Params Integer
p Integer
_ Int
bits) (PrivateNumber Integer
x) (PublicNumber Integer
y) = ScrubbedBytes -> SharedKey
SharedKey (ScrubbedBytes -> SharedKey) -> ScrubbedBytes -> SharedKey
forall a b. (a -> b) -> a -> b
$ Int -> Integer -> ScrubbedBytes
forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ ((Int
bits Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8) (Integer -> ScrubbedBytes) -> Integer -> ScrubbedBytes
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Integer
expSafe Integer
y Integer
x Integer
p