1-- |
2-- Module      : Crypto.PubKey.ECC.DH
3-- License     : BSD-style
4-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
5-- Stability   : experimental
6-- Portability : unknown
7--
8-- Elliptic curve Diffie Hellman
9--
10module Crypto.PubKey.ECC.DH
11    (
12      Curve
13    , PublicPoint
14    , PrivateNumber
15    , SharedKey(..)
16    , generatePrivate
17    , calculatePublic
18    , getShared
19    ) where
20
21import Crypto.Number.Generate (generateMax)
22import Crypto.Number.Serialize (i2ospOf_)
23import Crypto.PubKey.ECC.Prim (pointMul)
24import Crypto.Random.Types
25import Crypto.PubKey.DH (SharedKey(..))
26import Crypto.PubKey.ECC.Types (PublicPoint, PrivateNumber, Curve, Point(..), curveSizeBits)
27import Crypto.PubKey.ECC.Types (ecc_n, ecc_g, common_curve)
28
29-- | Generating a private number d.
30generatePrivate :: MonadRandom m => Curve -> m PrivateNumber
31generatePrivate curve = generateMax n
32  where
33    n = ecc_n $ common_curve curve
34
35-- | Generating a public point Q.
36calculatePublic :: Curve -> PrivateNumber -> PublicPoint
37calculatePublic curve d = q
38  where
39    g = ecc_g $ common_curve curve
40    q = pointMul curve d g
41
42-- | Generating a shared key using our private number and
43--   the other party public point.
44getShared :: Curve -> PrivateNumber -> PublicPoint -> SharedKey
45getShared curve db qa = SharedKey $ i2ospOf_ ((nbBits + 7) `div` 8) x
46  where
47    Point x _ = pointMul curve db qa
48    nbBits    = curveSizeBits curve
49