{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Crypto.PubKey.DH
( Params(..)
, PublicNumber
, PrivateNumber
, SharedKey
, generateParams
, generatePrivate
, calculatePublic
, generatePublic
, getShared
) where
import Crypto.Number.ModArithmetic (expSafe)
import Crypto.Number.Prime (generateSafePrime)
import Crypto.Number.Generate (generateMax)
import Crypto.Types.PubKey.DH
import Crypto.Random
import Control.Arrow (first)
generateParams :: CPRG g => g -> Int -> Integer -> (Params, g)
generateParams rng bits generator =
first (\p -> Params p generator) $ generateSafePrime rng bits
generatePrivate :: CPRG g => g -> Params -> (PrivateNumber, g)
generatePrivate rng (Params p _) = first PrivateNumber $ generateMax rng 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