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.Random.Types
import Data.Data
data Params = Params
{ params_p :: Integer
, params_g :: Integer
} deriving (Show,Read,Eq,Data,Typeable)
newtype PublicNumber = PublicNumber Integer
deriving (Show,Read,Eq,Enum,Real,Num,Ord)
newtype PrivateNumber = PrivateNumber Integer
deriving (Show,Read,Eq,Enum,Real,Num,Ord)
newtype SharedKey = SharedKey Integer
deriving (Show,Read,Eq,Enum,Real,Num,Ord)
generateParams :: MonadRandom m => Int -> Integer -> m Params
generateParams bits generator =
(\p -> Params p generator) <$> generateSafePrime bits
generatePrivate :: MonadRandom m => Params -> m PrivateNumber
generatePrivate (Params p _) = PrivateNumber <$> generateMax p
calculatePublic :: Params -> PrivateNumber -> PublicNumber
calculatePublic (Params p g) (PrivateNumber x) = PublicNumber $ expSafe g x p
generatePublic :: Params -> PrivateNumber -> PublicNumber
generatePublic = calculatePublic
getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared (Params p _) (PrivateNumber x) (PublicNumber y) = SharedKey $ expSafe y x p