1-- | 2-- Module : Crypto.PubKey.DH 3-- License : BSD-style 4-- Maintainer : Vincent Hanquez <vincent@snarc.org> 5-- Stability : experimental 6-- Portability : Good 7-- 8{-# LANGUAGE DeriveDataTypeable #-} 9{-# LANGUAGE GeneralizedNewtypeDeriving #-} 10module Crypto.PubKey.DH 11 ( Params(..) 12 , PublicNumber(..) 13 , PrivateNumber(..) 14 , SharedKey(..) 15 , generateParams 16 , generatePrivate 17 , calculatePublic 18 , generatePublic 19 , getShared 20 ) where 21 22import Crypto.Internal.Imports 23import Crypto.Number.ModArithmetic (expSafe) 24import Crypto.Number.Prime (generateSafePrime) 25import Crypto.Number.Generate (generateMax) 26import Crypto.Number.Serialize (i2ospOf_) 27import Crypto.Random.Types 28import Data.ByteArray (ByteArrayAccess, ScrubbedBytes) 29import Data.Data 30 31-- | Represent Diffie Hellman parameters namely P (prime), and G (generator). 32data Params = Params 33 { params_p :: Integer 34 , params_g :: Integer 35 , params_bits :: Int 36 } deriving (Show,Read,Eq,Data) 37 38instance NFData Params where 39 rnf (Params p g bits) = rnf p `seq` rnf g `seq` bits `seq` () 40 41-- | Represent Diffie Hellman public number Y. 42newtype PublicNumber = PublicNumber Integer 43 deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData) 44 45-- | Represent Diffie Hellman private number X. 46newtype PrivateNumber = PrivateNumber Integer 47 deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData) 48 49-- | Represent Diffie Hellman shared secret. 50newtype SharedKey = SharedKey ScrubbedBytes 51 deriving (Show,Eq,ByteArrayAccess,NFData) 52 53-- | generate params from a specific generator (2 or 5 are common values) 54-- we generate a safe prime (a prime number of the form 2p+1 where p is also prime) 55generateParams :: MonadRandom m => 56 Int -- ^ number of bits 57 -> Integer -- ^ generator 58 -> m Params 59generateParams bits generator = 60 (\p -> Params p generator bits) <$> generateSafePrime bits 61 62-- | generate a private number with no specific property 63-- this number is usually called X in DH text. 64generatePrivate :: MonadRandom m => Params -> m PrivateNumber 65generatePrivate (Params p _ _) = PrivateNumber <$> generateMax p 66 67-- | calculate the public number from the parameters and the private key 68-- this number is usually called Y in DH text. 69calculatePublic :: Params -> PrivateNumber -> PublicNumber 70calculatePublic (Params p g _) (PrivateNumber x) = PublicNumber $ expSafe g x p 71 72-- | calculate the public number from the parameters and the private key 73-- this number is usually called Y in DH text. 74-- 75-- DEPRECATED use calculatePublic 76generatePublic :: Params -> PrivateNumber -> PublicNumber 77generatePublic = calculatePublic 78-- commented until 0.3 {-# DEPRECATED generatePublic "use calculatePublic" #-} 79 80-- | generate a shared key using our private number and the other party public number 81getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey 82getShared (Params p _ bits) (PrivateNumber x) (PublicNumber y) = SharedKey $ i2ospOf_ ((bits + 7) `div` 8) $ expSafe y x p 83