    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}

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

    import Crypto.Internal.Imports
    import Crypto.Number.Generate (generateMax)
    import Crypto.Number.ModArithmetic (expSafe)
    import Crypto.Number.Prime (generateSafePrime)
    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
    $cshowsPrec :: Int -> Params -> ShowS
    showsPrec :: Int -> Params -> ShowS
    $cshow :: Params -> String
    show :: Params -> String
    $cshowList :: [Params] -> ShowS
    showList :: [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
    $creadsPrec :: Int -> ReadS Params
    readsPrec :: Int -> ReadS Params
    $creadList :: ReadS [Params]
    readList :: ReadS [Params]
    $creadPrec :: ReadPrec Params
    readPrec :: ReadPrec Params
    $creadListPrec :: ReadPrec [Params]
    readListPrec :: ReadPrec [Params]
    Read, Params -> Params -> Bool
    (Params -> Params -> Bool)
    -> (Params -> Params -> Bool) -> Eq Params
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Params -> Params -> Bool
    == :: Params -> Params -> Bool
    $c/= :: Params -> Params -> Bool
    /= :: Params -> Params -> Bool
    Eq, Typeable Params
    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 -> Constr
    Params -> DataType
    (forall b. Data b => b -> b) -> Params -> 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)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Params -> c Params
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Params -> c Params
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Params
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Params
    $ctoConstr :: Params -> Constr
    toConstr :: Params -> Constr
    $cdataTypeOf :: Params -> DataType
    dataTypeOf :: Params -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Params)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Params)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
    $cgmapT :: (forall b. Data b => b -> b) -> Params -> Params
    gmapT :: (forall b. Data b => b -> b) -> Params -> Params
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
    gmapQl :: forall r r'.
    (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
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Params -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Params -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Params -> m Params
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (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
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (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
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Params -> m 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 () -> () -> ()
    forall a b. a -> b -> b
    `seq` Integer -> ()
    forall a. NFData a => a -> ()
    rnf Integer
    g () -> () -> ()
    forall a b. a -> b -> b
    `seq` Int
    bits Int -> () -> ()
    forall a b. a -> b -> b
    `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
    $cshowsPrec :: Int -> PublicNumber -> ShowS
    showsPrec :: Int -> PublicNumber -> ShowS
    $cshow :: PublicNumber -> String
    show :: PublicNumber -> String
    $cshowList :: [PublicNumber] -> ShowS
    showList :: [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
    $creadsPrec :: Int -> ReadS PublicNumber
    readsPrec :: Int -> ReadS PublicNumber
    $creadList :: ReadS [PublicNumber]
    readList :: ReadS [PublicNumber]
    $creadPrec :: ReadPrec PublicNumber
    readPrec :: ReadPrec PublicNumber
    $creadListPrec :: ReadPrec [PublicNumber]
    readListPrec :: ReadPrec [PublicNumber]
    Read, PublicNumber -> PublicNumber -> Bool
    (PublicNumber -> PublicNumber -> Bool)
    -> (PublicNumber -> PublicNumber -> Bool) -> Eq PublicNumber
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PublicNumber -> PublicNumber -> Bool
    == :: PublicNumber -> PublicNumber -> Bool
    $c/= :: PublicNumber -> PublicNumber -> Bool
    /= :: 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
    $csucc :: PublicNumber -> PublicNumber
    succ :: PublicNumber -> PublicNumber
    $cpred :: PublicNumber -> PublicNumber
    pred :: PublicNumber -> PublicNumber
    $ctoEnum :: Int -> PublicNumber
    toEnum :: Int -> PublicNumber
    $cfromEnum :: PublicNumber -> Int
    fromEnum :: PublicNumber -> Int
    $cenumFrom :: PublicNumber -> [PublicNumber]
    enumFrom :: PublicNumber -> [PublicNumber]
    $cenumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
    enumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
    $cenumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
    enumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
    $cenumFromThenTo :: PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
    enumFromThenTo :: PublicNumber -> PublicNumber -> 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
    $ctoRational :: PublicNumber -> Rational
    toRational :: PublicNumber -> Rational
    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
    $c+ :: PublicNumber -> PublicNumber -> PublicNumber
    + :: PublicNumber -> PublicNumber -> PublicNumber
    $c- :: PublicNumber -> PublicNumber -> PublicNumber
    - :: PublicNumber -> PublicNumber -> PublicNumber
    $c* :: PublicNumber -> PublicNumber -> PublicNumber
    * :: PublicNumber -> PublicNumber -> PublicNumber
    $cnegate :: PublicNumber -> PublicNumber
    negate :: PublicNumber -> PublicNumber
    $cabs :: PublicNumber -> PublicNumber
    abs :: PublicNumber -> PublicNumber
    $csignum :: PublicNumber -> PublicNumber
    signum :: PublicNumber -> PublicNumber
    $cfromInteger :: Integer -> PublicNumber
    fromInteger :: Integer -> 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
    $ccompare :: PublicNumber -> PublicNumber -> Ordering
    compare :: PublicNumber -> PublicNumber -> Ordering
    $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
    >= :: PublicNumber -> PublicNumber -> Bool
    $cmax :: PublicNumber -> PublicNumber -> PublicNumber
    max :: PublicNumber -> PublicNumber -> PublicNumber
    $cmin :: PublicNumber -> PublicNumber -> PublicNumber
    min :: PublicNumber -> PublicNumber -> PublicNumber
    Ord, PublicNumber -> ()
    (PublicNumber -> ()) -> NFData PublicNumber
    forall a. (a -> ()) -> NFData a
    $crnf :: PublicNumber -> ()
    rnf :: 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
    $cshowsPrec :: Int -> PrivateNumber -> ShowS
    showsPrec :: Int -> PrivateNumber -> ShowS
    $cshow :: PrivateNumber -> String
    show :: PrivateNumber -> String
    $cshowList :: [PrivateNumber] -> ShowS
    showList :: [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
    $creadsPrec :: Int -> ReadS PrivateNumber
    readsPrec :: Int -> ReadS PrivateNumber
    $creadList :: ReadS [PrivateNumber]
    readList :: ReadS [PrivateNumber]
    $creadPrec :: ReadPrec PrivateNumber
    readPrec :: ReadPrec PrivateNumber
    $creadListPrec :: ReadPrec [PrivateNumber]
    readListPrec :: ReadPrec [PrivateNumber]
    Read, PrivateNumber -> PrivateNumber -> Bool
    (PrivateNumber -> PrivateNumber -> Bool)
    -> (PrivateNumber -> PrivateNumber -> Bool) -> Eq PrivateNumber
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PrivateNumber -> PrivateNumber -> Bool
    == :: PrivateNumber -> PrivateNumber -> Bool
    $c/= :: PrivateNumber -> PrivateNumber -> Bool
    /= :: 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
    $csucc :: PrivateNumber -> PrivateNumber
    succ :: PrivateNumber -> PrivateNumber
    $cpred :: PrivateNumber -> PrivateNumber
    pred :: PrivateNumber -> PrivateNumber
    $ctoEnum :: Int -> PrivateNumber
    toEnum :: Int -> PrivateNumber
    $cfromEnum :: PrivateNumber -> Int
    fromEnum :: PrivateNumber -> Int
    $cenumFrom :: PrivateNumber -> [PrivateNumber]
    enumFrom :: PrivateNumber -> [PrivateNumber]
    $cenumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
    enumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
    $cenumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
    enumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
    $cenumFromThenTo :: PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
    enumFromThenTo :: PrivateNumber -> PrivateNumber -> 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
    $ctoRational :: PrivateNumber -> Rational
    toRational :: PrivateNumber -> Rational
    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
    $c+ :: PrivateNumber -> PrivateNumber -> PrivateNumber
    + :: PrivateNumber -> PrivateNumber -> PrivateNumber
    $c- :: PrivateNumber -> PrivateNumber -> PrivateNumber
    - :: PrivateNumber -> PrivateNumber -> PrivateNumber
    $c* :: PrivateNumber -> PrivateNumber -> PrivateNumber
    * :: PrivateNumber -> PrivateNumber -> PrivateNumber
    $cnegate :: PrivateNumber -> PrivateNumber
    negate :: PrivateNumber -> PrivateNumber
    $cabs :: PrivateNumber -> PrivateNumber
    abs :: PrivateNumber -> PrivateNumber
    $csignum :: PrivateNumber -> PrivateNumber
    signum :: PrivateNumber -> PrivateNumber
    $cfromInteger :: Integer -> PrivateNumber
    fromInteger :: Integer -> 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
    $ccompare :: PrivateNumber -> PrivateNumber -> Ordering
    compare :: PrivateNumber -> PrivateNumber -> Ordering
    $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
    >= :: PrivateNumber -> PrivateNumber -> Bool
    $cmax :: PrivateNumber -> PrivateNumber -> PrivateNumber
    max :: PrivateNumber -> PrivateNumber -> PrivateNumber
    $cmin :: PrivateNumber -> PrivateNumber -> PrivateNumber
    min :: PrivateNumber -> PrivateNumber -> PrivateNumber
    Ord, PrivateNumber -> ()
    (PrivateNumber -> ()) -> NFData PrivateNumber
    forall a. (a -> ()) -> NFData a
    $crnf :: PrivateNumber -> ()
    rnf :: 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
    $cshowsPrec :: Int -> SharedKey -> ShowS
    showsPrec :: Int -> SharedKey -> ShowS
    $cshow :: SharedKey -> String
    show :: SharedKey -> String
    $cshowList :: [SharedKey] -> ShowS
    showList :: [SharedKey] -> ShowS
    Show, SharedKey -> SharedKey -> Bool
    (SharedKey -> SharedKey -> Bool)
    -> (SharedKey -> SharedKey -> Bool) -> Eq SharedKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SharedKey -> SharedKey -> Bool
    == :: SharedKey -> SharedKey -> Bool
    $c/= :: SharedKey -> SharedKey -> Bool
    /= :: SharedKey -> SharedKey -> Bool
    Eq, SharedKey -> Int
    (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
    $clength :: SharedKey -> Int
    length :: SharedKey -> Int
    $cwithByteArray :: forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
    withByteArray :: forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
    $ccopyByteArrayToPtr :: forall p. SharedKey -> Ptr p -> IO ()
    copyByteArrayToPtr :: forall p. SharedKey -> Ptr p -> IO ()
    ByteArrayAccess, SharedKey -> ()
    (SharedKey -> ()) -> NFData SharedKey
    forall a. (a -> ()) -> NFData a
    $crnf :: SharedKey -> ()
    rnf :: 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 :: forall (m :: * -> *). MonadRandom m => 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 :: forall (m :: * -> *). MonadRandom m => 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