-- |
-- Module      : Network.TLS.Crypto.IES
-- License     : BSD-style
-- Maintainer  : Kazu Yamamoto <kazu@iij.ad.jp>
-- Stability   : experimental
-- Portability : unknown
--
module Network.TLS.Crypto.IES
    (
      GroupPublic
    , GroupPrivate
    , GroupKey
    -- * Group methods
    , groupGenerateKeyPair
    , groupGetPubShared
    , groupGetShared
    , encodeGroupPublic
    , decodeGroupPublic
    -- * Compatibility with 'Network.TLS.Crypto.DH'
    , dhParamsForGroup
    , dhGroupGenerateKeyPair
    , dhGroupGetPubShared
    ) where

import Control.Arrow
import Crypto.ECC
import Crypto.Error
import Crypto.Number.Generate
import Crypto.PubKey.DH hiding (generateParams)
import Crypto.PubKey.ECIES
import qualified Data.ByteArray as B
import Data.Proxy
import Network.TLS.Crypto.Types
import Network.TLS.Extra.FFDHE
import Network.TLS.Imports
import Network.TLS.RNG
import Network.TLS.Util.Serialization (os2ip,i2ospOf_)

data GroupPrivate = GroupPri_P256 (Scalar Curve_P256R1)
                  | GroupPri_P384 (Scalar Curve_P384R1)
                  | GroupPri_P521 (Scalar Curve_P521R1)
                  | GroupPri_X255 (Scalar Curve_X25519)
                  | GroupPri_X448 (Scalar Curve_X448)
                  | GroupPri_FFDHE2048 PrivateNumber
                  | GroupPri_FFDHE3072 PrivateNumber
                  | GroupPri_FFDHE4096 PrivateNumber
                  | GroupPri_FFDHE6144 PrivateNumber
                  | GroupPri_FFDHE8192 PrivateNumber
                  deriving (GroupPrivate -> GroupPrivate -> Bool
(GroupPrivate -> GroupPrivate -> Bool)
-> (GroupPrivate -> GroupPrivate -> Bool) -> Eq GroupPrivate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GroupPrivate -> GroupPrivate -> Bool
$c/= :: GroupPrivate -> GroupPrivate -> Bool
== :: GroupPrivate -> GroupPrivate -> Bool
$c== :: GroupPrivate -> GroupPrivate -> Bool
Eq, Int -> GroupPrivate -> ShowS
[GroupPrivate] -> ShowS
GroupPrivate -> String
(Int -> GroupPrivate -> ShowS)
-> (GroupPrivate -> String)
-> ([GroupPrivate] -> ShowS)
-> Show GroupPrivate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GroupPrivate] -> ShowS
$cshowList :: [GroupPrivate] -> ShowS
show :: GroupPrivate -> String
$cshow :: GroupPrivate -> String
showsPrec :: Int -> GroupPrivate -> ShowS
$cshowsPrec :: Int -> GroupPrivate -> ShowS
Show)

data GroupPublic = GroupPub_P256 (Point Curve_P256R1)
                 | GroupPub_P384 (Point Curve_P384R1)
                 | GroupPub_P521 (Point Curve_P521R1)
                 | GroupPub_X255 (Point Curve_X25519)
                 | GroupPub_X448 (Point Curve_X448)
                 | GroupPub_FFDHE2048 PublicNumber
                 | GroupPub_FFDHE3072 PublicNumber
                 | GroupPub_FFDHE4096 PublicNumber
                 | GroupPub_FFDHE6144 PublicNumber
                 | GroupPub_FFDHE8192 PublicNumber
                 deriving (GroupPublic -> GroupPublic -> Bool
(GroupPublic -> GroupPublic -> Bool)
-> (GroupPublic -> GroupPublic -> Bool) -> Eq GroupPublic
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GroupPublic -> GroupPublic -> Bool
$c/= :: GroupPublic -> GroupPublic -> Bool
== :: GroupPublic -> GroupPublic -> Bool
$c== :: GroupPublic -> GroupPublic -> Bool
Eq, Int -> GroupPublic -> ShowS
[GroupPublic] -> ShowS
GroupPublic -> String
(Int -> GroupPublic -> ShowS)
-> (GroupPublic -> String)
-> ([GroupPublic] -> ShowS)
-> Show GroupPublic
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GroupPublic] -> ShowS
$cshowList :: [GroupPublic] -> ShowS
show :: GroupPublic -> String
$cshow :: GroupPublic -> String
showsPrec :: Int -> GroupPublic -> ShowS
$cshowsPrec :: Int -> GroupPublic -> ShowS
Show)

type GroupKey = SharedSecret

p256 :: Proxy Curve_P256R1
p256 :: Proxy Curve_P256R1
p256 = Proxy Curve_P256R1
forall k (t :: k). Proxy t
Proxy

p384 :: Proxy Curve_P384R1
p384 :: Proxy Curve_P384R1
p384 = Proxy Curve_P384R1
forall k (t :: k). Proxy t
Proxy

p521 :: Proxy Curve_P521R1
p521 :: Proxy Curve_P521R1
p521 = Proxy Curve_P521R1
forall k (t :: k). Proxy t
Proxy

x25519 :: Proxy Curve_X25519
x25519 :: Proxy Curve_X25519
x25519 = Proxy Curve_X25519
forall k (t :: k). Proxy t
Proxy

x448 :: Proxy Curve_X448
x448 :: Proxy Curve_X448
x448 = Proxy Curve_X448
forall k (t :: k). Proxy t
Proxy

dhParamsForGroup :: Group -> Maybe Params
dhParamsForGroup :: Group -> Maybe Params
dhParamsForGroup Group
FFDHE2048 = Params -> Maybe Params
forall a. a -> Maybe a
Just Params
ffdhe2048
dhParamsForGroup Group
FFDHE3072 = Params -> Maybe Params
forall a. a -> Maybe a
Just Params
ffdhe3072
dhParamsForGroup Group
FFDHE4096 = Params -> Maybe Params
forall a. a -> Maybe a
Just Params
ffdhe4096
dhParamsForGroup Group
FFDHE6144 = Params -> Maybe Params
forall a. a -> Maybe a
Just Params
ffdhe6144
dhParamsForGroup Group
FFDHE8192 = Params -> Maybe Params
forall a. a -> Maybe a
Just Params
ffdhe8192
dhParamsForGroup Group
_         = Maybe Params
forall a. Maybe a
Nothing

groupGenerateKeyPair :: MonadRandom r => Group -> r (GroupPrivate, GroupPublic)
groupGenerateKeyPair :: Group -> r (GroupPrivate, GroupPublic)
groupGenerateKeyPair Group
P256   =
    (Scalar Curve_P256R1 -> GroupPrivate
GroupPri_P256,Point Curve_P256R1 -> GroupPublic
GroupPub_P256) (Scalar Curve_P256R1 -> GroupPrivate,
 Point Curve_P256R1 -> GroupPublic)
-> r (KeyPair Curve_P256R1) -> r (GroupPrivate, GroupPublic)
forall (r :: * -> *) a.
MonadRandom r =>
(Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` Proxy Curve_P256R1 -> r (KeyPair Curve_P256R1)
forall curve (randomly :: * -> *) (proxy :: * -> *).
(EllipticCurve curve, MonadRandom randomly) =>
proxy curve -> randomly (KeyPair curve)
curveGenerateKeyPair Proxy Curve_P256R1
p256
groupGenerateKeyPair Group
P384   =
    (Scalar Curve_P384R1 -> GroupPrivate
GroupPri_P384,Point Curve_P384R1 -> GroupPublic
GroupPub_P384) (Scalar Curve_P384R1 -> GroupPrivate,
 Point Curve_P384R1 -> GroupPublic)
-> r (KeyPair Curve_P384R1) -> r (GroupPrivate, GroupPublic)
forall (r :: * -> *) a.
MonadRandom r =>
(Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` Proxy Curve_P384R1 -> r (KeyPair Curve_P384R1)
forall curve (randomly :: * -> *) (proxy :: * -> *).
(EllipticCurve curve, MonadRandom randomly) =>
proxy curve -> randomly (KeyPair curve)
curveGenerateKeyPair Proxy Curve_P384R1
p384
groupGenerateKeyPair Group
P521   =
    (Scalar Curve_P521R1 -> GroupPrivate
GroupPri_P521,Point Curve_P521R1 -> GroupPublic
GroupPub_P521) (Scalar Curve_P521R1 -> GroupPrivate,
 Point Curve_P521R1 -> GroupPublic)
-> r (KeyPair Curve_P521R1) -> r (GroupPrivate, GroupPublic)
forall (r :: * -> *) a.
MonadRandom r =>
(Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` Proxy Curve_P521R1 -> r (KeyPair Curve_P521R1)
forall curve (randomly :: * -> *) (proxy :: * -> *).
(EllipticCurve curve, MonadRandom randomly) =>
proxy curve -> randomly (KeyPair curve)
curveGenerateKeyPair Proxy Curve_P521R1
p521
groupGenerateKeyPair Group
X25519 =
    (Scalar Curve_X25519 -> GroupPrivate
GroupPri_X255,Point Curve_X25519 -> GroupPublic
GroupPub_X255) (Scalar Curve_X25519 -> GroupPrivate,
 Point Curve_X25519 -> GroupPublic)
-> r (KeyPair Curve_X25519) -> r (GroupPrivate, GroupPublic)
forall (r :: * -> *) a.
MonadRandom r =>
(Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` Proxy Curve_X25519 -> r (KeyPair Curve_X25519)
forall curve (randomly :: * -> *) (proxy :: * -> *).
(EllipticCurve curve, MonadRandom randomly) =>
proxy curve -> randomly (KeyPair curve)
curveGenerateKeyPair Proxy Curve_X25519
x25519
groupGenerateKeyPair Group
X448 =
    (Scalar Curve_X448 -> GroupPrivate
GroupPri_X448,Point Curve_X448 -> GroupPublic
GroupPub_X448) (Scalar Curve_X448 -> GroupPrivate,
 Point Curve_X448 -> GroupPublic)
-> r (KeyPair Curve_X448) -> r (GroupPrivate, GroupPublic)
forall (r :: * -> *) a.
MonadRandom r =>
(Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` Proxy Curve_X448 -> r (KeyPair Curve_X448)
forall curve (randomly :: * -> *) (proxy :: * -> *).
(EllipticCurve curve, MonadRandom randomly) =>
proxy curve -> randomly (KeyPair curve)
curveGenerateKeyPair Proxy Curve_X448
x448
groupGenerateKeyPair Group
FFDHE2048 = Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
ffdhe2048 Int
exp2048 PrivateNumber -> GroupPrivate
GroupPri_FFDHE2048 PublicNumber -> GroupPublic
GroupPub_FFDHE2048
groupGenerateKeyPair Group
FFDHE3072 = Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
ffdhe3072 Int
exp3072 PrivateNumber -> GroupPrivate
GroupPri_FFDHE3072 PublicNumber -> GroupPublic
GroupPub_FFDHE3072
groupGenerateKeyPair Group
FFDHE4096 = Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
ffdhe4096 Int
exp4096 PrivateNumber -> GroupPrivate
GroupPri_FFDHE4096 PublicNumber -> GroupPublic
GroupPub_FFDHE4096
groupGenerateKeyPair Group
FFDHE6144 = Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
ffdhe6144 Int
exp6144 PrivateNumber -> GroupPrivate
GroupPri_FFDHE6144 PublicNumber -> GroupPublic
GroupPub_FFDHE6144
groupGenerateKeyPair Group
FFDHE8192 = Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
ffdhe8192 Int
exp8192 PrivateNumber -> GroupPrivate
GroupPri_FFDHE8192 PublicNumber -> GroupPublic
GroupPub_FFDHE8192

dhGroupGenerateKeyPair :: MonadRandom r => Group -> r (Params, PrivateNumber, PublicNumber)
dhGroupGenerateKeyPair :: Group -> r (Params, PrivateNumber, PublicNumber)
dhGroupGenerateKeyPair Group
FFDHE2048 = Params
-> r (PrivateNumber, PublicNumber)
-> r (Params, PrivateNumber, PublicNumber)
forall (f :: * -> *) a b.
Functor f =>
Params -> f (a, b) -> f (Params, a, b)
addParams Params
ffdhe2048 (Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
ffdhe2048 Int
exp2048)
dhGroupGenerateKeyPair Group
FFDHE3072 = Params
-> r (PrivateNumber, PublicNumber)
-> r (Params, PrivateNumber, PublicNumber)
forall (f :: * -> *) a b.
Functor f =>
Params -> f (a, b) -> f (Params, a, b)
addParams Params
ffdhe3072 (Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
ffdhe3072 Int
exp3072)
dhGroupGenerateKeyPair Group
FFDHE4096 = Params
-> r (PrivateNumber, PublicNumber)
-> r (Params, PrivateNumber, PublicNumber)
forall (f :: * -> *) a b.
Functor f =>
Params -> f (a, b) -> f (Params, a, b)
addParams Params
ffdhe4096 (Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
ffdhe4096 Int
exp4096)
dhGroupGenerateKeyPair Group
FFDHE6144 = Params
-> r (PrivateNumber, PublicNumber)
-> r (Params, PrivateNumber, PublicNumber)
forall (f :: * -> *) a b.
Functor f =>
Params -> f (a, b) -> f (Params, a, b)
addParams Params
ffdhe6144 (Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
ffdhe6144 Int
exp6144)
dhGroupGenerateKeyPair Group
FFDHE8192 = Params
-> r (PrivateNumber, PublicNumber)
-> r (Params, PrivateNumber, PublicNumber)
forall (f :: * -> *) a b.
Functor f =>
Params -> f (a, b) -> f (Params, a, b)
addParams Params
ffdhe8192 (Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
ffdhe8192 Int
exp8192)
dhGroupGenerateKeyPair Group
grp       = String -> r (Params, PrivateNumber, PublicNumber)
forall a. HasCallStack => String -> a
error (String
"invalid FFDHE group: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Group -> String
forall a. Show a => a -> String
show Group
grp)

addParams :: Functor f => Params -> f (a, b) -> f (Params, a, b)
addParams :: Params -> f (a, b) -> f (Params, a, b)
addParams Params
params = ((a, b) -> (Params, a, b)) -> f (a, b) -> f (Params, a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((a, b) -> (Params, a, b)) -> f (a, b) -> f (Params, a, b))
-> ((a, b) -> (Params, a, b)) -> f (a, b) -> f (Params, a, b)
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) -> (Params
params, a
a, b
b)

fs :: MonadRandom r
   => (Scalar a -> GroupPrivate, Point a -> GroupPublic)
   -> r (KeyPair a)
   -> r (GroupPrivate, GroupPublic)
(Scalar a -> GroupPrivate
t1, Point a -> GroupPublic
t2) fs :: (Scalar a -> GroupPrivate, Point a -> GroupPublic)
-> r (KeyPair a) -> r (GroupPrivate, GroupPublic)
`fs` r (KeyPair a)
action = do
    KeyPair a
keypair <- r (KeyPair a)
action
    let pub :: Point a
pub = KeyPair a -> Point a
forall curve. KeyPair curve -> Point curve
keypairGetPublic KeyPair a
keypair
        pri :: Scalar a
pri = KeyPair a -> Scalar a
forall curve. KeyPair curve -> Scalar curve
keypairGetPrivate KeyPair a
keypair
    (GroupPrivate, GroupPublic) -> r (GroupPrivate, GroupPublic)
forall (m :: * -> *) a. Monad m => a -> m a
return (Scalar a -> GroupPrivate
t1 Scalar a
pri, Point a -> GroupPublic
t2 Point a
pub)

gen :: MonadRandom r
    => Params
    -> Int
    -> (PrivateNumber -> GroupPrivate)
    -> (PublicNumber -> GroupPublic)
    -> r (GroupPrivate, GroupPublic)
gen :: Params
-> Int
-> (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> r (GroupPrivate, GroupPublic)
gen Params
params Int
expBits PrivateNumber -> GroupPrivate
priTag PublicNumber -> GroupPublic
pubTag = (PrivateNumber -> GroupPrivate
priTag (PrivateNumber -> GroupPrivate)
-> (PublicNumber -> GroupPublic)
-> (PrivateNumber, PublicNumber)
-> (GroupPrivate, GroupPublic)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** PublicNumber -> GroupPublic
pubTag) ((PrivateNumber, PublicNumber) -> (GroupPrivate, GroupPublic))
-> r (PrivateNumber, PublicNumber) -> r (GroupPrivate, GroupPublic)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Params -> Int -> r (PrivateNumber, PublicNumber)
forall (r :: * -> *).
MonadRandom r =>
Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
params Int
expBits

gen' :: MonadRandom r
     => Params
     -> Int
     -> r (PrivateNumber, PublicNumber)
gen' :: Params -> Int -> r (PrivateNumber, PublicNumber)
gen' Params
params Int
expBits = (PrivateNumber -> PrivateNumber
forall a. a -> a
id (PrivateNumber -> PrivateNumber)
-> (PrivateNumber -> PublicNumber)
-> PrivateNumber
-> (PrivateNumber, PublicNumber)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Params -> PrivateNumber -> PublicNumber
calculatePublic Params
params) (PrivateNumber -> (PrivateNumber, PublicNumber))
-> r PrivateNumber -> r (PrivateNumber, PublicNumber)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> r PrivateNumber
forall (r :: * -> *). MonadRandom r => Int -> r PrivateNumber
generatePriv Int
expBits

groupGetPubShared :: MonadRandom r => GroupPublic -> r (Maybe (GroupPublic, GroupKey))
groupGetPubShared :: GroupPublic -> r (Maybe (GroupPublic, GroupKey))
groupGetPubShared (GroupPub_P256 Point Curve_P256R1
pub) =
    ((Point, GroupKey) -> (GroupPublic, GroupKey))
-> Maybe (Point, GroupKey) -> Maybe (GroupPublic, GroupKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Point -> GroupPublic)
-> (Point, GroupKey) -> (GroupPublic, GroupKey)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Point Curve_P256R1 -> GroupPublic
Point -> GroupPublic
GroupPub_P256) (Maybe (Point, GroupKey) -> Maybe (GroupPublic, GroupKey))
-> (CryptoFailable (Point, GroupKey) -> Maybe (Point, GroupKey))
-> CryptoFailable (Point, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable (Point, GroupKey) -> Maybe (Point, GroupKey)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Point, GroupKey) -> Maybe (GroupPublic, GroupKey))
-> r (CryptoFailable (Point, GroupKey))
-> r (Maybe (GroupPublic, GroupKey))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P256R1
-> Point Curve_P256R1
-> r (CryptoFailable (Point Curve_P256R1, GroupKey))
forall (randomly :: * -> *) curve (proxy :: * -> *).
(MonadRandom randomly, EllipticCurveDH curve) =>
proxy curve
-> Point curve -> randomly (CryptoFailable (Point curve, GroupKey))
deriveEncrypt Proxy Curve_P256R1
p256 Point Curve_P256R1
pub
groupGetPubShared (GroupPub_P384 Point Curve_P384R1
pub) =
    ((Point SEC_p384r1, GroupKey) -> (GroupPublic, GroupKey))
-> Maybe (Point SEC_p384r1, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Point SEC_p384r1 -> GroupPublic)
-> (Point SEC_p384r1, GroupKey) -> (GroupPublic, GroupKey)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Point SEC_p384r1 -> GroupPublic
Point Curve_P384R1 -> GroupPublic
GroupPub_P384) (Maybe (Point SEC_p384r1, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> (CryptoFailable (Point SEC_p384r1, GroupKey)
    -> Maybe (Point SEC_p384r1, GroupKey))
-> CryptoFailable (Point SEC_p384r1, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable (Point SEC_p384r1, GroupKey)
-> Maybe (Point SEC_p384r1, GroupKey)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Point SEC_p384r1, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> r (CryptoFailable (Point SEC_p384r1, GroupKey))
-> r (Maybe (GroupPublic, GroupKey))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P384R1
-> Point Curve_P384R1
-> r (CryptoFailable (Point Curve_P384R1, GroupKey))
forall (randomly :: * -> *) curve (proxy :: * -> *).
(MonadRandom randomly, EllipticCurveDH curve) =>
proxy curve
-> Point curve -> randomly (CryptoFailable (Point curve, GroupKey))
deriveEncrypt Proxy Curve_P384R1
p384 Point Curve_P384R1
pub
groupGetPubShared (GroupPub_P521 Point Curve_P521R1
pub) =
    ((Point SEC_p521r1, GroupKey) -> (GroupPublic, GroupKey))
-> Maybe (Point SEC_p521r1, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Point SEC_p521r1 -> GroupPublic)
-> (Point SEC_p521r1, GroupKey) -> (GroupPublic, GroupKey)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Point SEC_p521r1 -> GroupPublic
Point Curve_P521R1 -> GroupPublic
GroupPub_P521) (Maybe (Point SEC_p521r1, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> (CryptoFailable (Point SEC_p521r1, GroupKey)
    -> Maybe (Point SEC_p521r1, GroupKey))
-> CryptoFailable (Point SEC_p521r1, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable (Point SEC_p521r1, GroupKey)
-> Maybe (Point SEC_p521r1, GroupKey)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Point SEC_p521r1, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> r (CryptoFailable (Point SEC_p521r1, GroupKey))
-> r (Maybe (GroupPublic, GroupKey))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P521R1
-> Point Curve_P521R1
-> r (CryptoFailable (Point Curve_P521R1, GroupKey))
forall (randomly :: * -> *) curve (proxy :: * -> *).
(MonadRandom randomly, EllipticCurveDH curve) =>
proxy curve
-> Point curve -> randomly (CryptoFailable (Point curve, GroupKey))
deriveEncrypt Proxy Curve_P521R1
p521 Point Curve_P521R1
pub
groupGetPubShared (GroupPub_X255 Point Curve_X25519
pub) =
    ((PublicKey, GroupKey) -> (GroupPublic, GroupKey))
-> Maybe (PublicKey, GroupKey) -> Maybe (GroupPublic, GroupKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((PublicKey -> GroupPublic)
-> (PublicKey, GroupKey) -> (GroupPublic, GroupKey)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Point Curve_X25519 -> GroupPublic
PublicKey -> GroupPublic
GroupPub_X255) (Maybe (PublicKey, GroupKey) -> Maybe (GroupPublic, GroupKey))
-> (CryptoFailable (PublicKey, GroupKey)
    -> Maybe (PublicKey, GroupKey))
-> CryptoFailable (PublicKey, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable (PublicKey, GroupKey) -> Maybe (PublicKey, GroupKey)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (PublicKey, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> r (CryptoFailable (PublicKey, GroupKey))
-> r (Maybe (GroupPublic, GroupKey))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_X25519
-> Point Curve_X25519
-> r (CryptoFailable (Point Curve_X25519, GroupKey))
forall (randomly :: * -> *) curve (proxy :: * -> *).
(MonadRandom randomly, EllipticCurveDH curve) =>
proxy curve
-> Point curve -> randomly (CryptoFailable (Point curve, GroupKey))
deriveEncrypt Proxy Curve_X25519
x25519 Point Curve_X25519
pub
groupGetPubShared (GroupPub_X448 Point Curve_X448
pub) =
    ((PublicKey, GroupKey) -> (GroupPublic, GroupKey))
-> Maybe (PublicKey, GroupKey) -> Maybe (GroupPublic, GroupKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((PublicKey -> GroupPublic)
-> (PublicKey, GroupKey) -> (GroupPublic, GroupKey)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Point Curve_X448 -> GroupPublic
PublicKey -> GroupPublic
GroupPub_X448) (Maybe (PublicKey, GroupKey) -> Maybe (GroupPublic, GroupKey))
-> (CryptoFailable (PublicKey, GroupKey)
    -> Maybe (PublicKey, GroupKey))
-> CryptoFailable (PublicKey, GroupKey)
-> Maybe (GroupPublic, GroupKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable (PublicKey, GroupKey) -> Maybe (PublicKey, GroupKey)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (PublicKey, GroupKey)
 -> Maybe (GroupPublic, GroupKey))
-> r (CryptoFailable (PublicKey, GroupKey))
-> r (Maybe (GroupPublic, GroupKey))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_X448
-> Point Curve_X448
-> r (CryptoFailable (Point Curve_X448, GroupKey))
forall (randomly :: * -> *) curve (proxy :: * -> *).
(MonadRandom randomly, EllipticCurveDH curve) =>
proxy curve
-> Point curve -> randomly (CryptoFailable (Point curve, GroupKey))
deriveEncrypt Proxy Curve_X448
x448 Point Curve_X448
pub
groupGetPubShared (GroupPub_FFDHE2048 PublicNumber
pub) = Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
ffdhe2048 Int
exp2048 PublicNumber
pub PublicNumber -> GroupPublic
GroupPub_FFDHE2048
groupGetPubShared (GroupPub_FFDHE3072 PublicNumber
pub) = Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
ffdhe3072 Int
exp3072 PublicNumber
pub PublicNumber -> GroupPublic
GroupPub_FFDHE3072
groupGetPubShared (GroupPub_FFDHE4096 PublicNumber
pub) = Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
ffdhe4096 Int
exp4096 PublicNumber
pub PublicNumber -> GroupPublic
GroupPub_FFDHE4096
groupGetPubShared (GroupPub_FFDHE6144 PublicNumber
pub) = Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
ffdhe6144 Int
exp6144 PublicNumber
pub PublicNumber -> GroupPublic
GroupPub_FFDHE6144
groupGetPubShared (GroupPub_FFDHE8192 PublicNumber
pub) = Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
ffdhe8192 Int
exp8192 PublicNumber
pub PublicNumber -> GroupPublic
GroupPub_FFDHE8192

dhGroupGetPubShared :: MonadRandom r => Group -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
dhGroupGetPubShared :: Group -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
dhGroupGetPubShared Group
FFDHE2048 PublicNumber
pub = Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
ffdhe2048 Int
exp2048 PublicNumber
pub
dhGroupGetPubShared Group
FFDHE3072 PublicNumber
pub = Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
ffdhe3072 Int
exp3072 PublicNumber
pub
dhGroupGetPubShared Group
FFDHE4096 PublicNumber
pub = Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
ffdhe4096 Int
exp4096 PublicNumber
pub
dhGroupGetPubShared Group
FFDHE6144 PublicNumber
pub = Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
ffdhe6144 Int
exp6144 PublicNumber
pub
dhGroupGetPubShared Group
FFDHE8192 PublicNumber
pub = Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
forall (r :: * -> *).
MonadRandom r =>
Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
ffdhe8192 Int
exp8192 PublicNumber
pub
dhGroupGetPubShared Group
_         PublicNumber
_   = Maybe (PublicNumber, SharedKey)
-> r (Maybe (PublicNumber, SharedKey))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (PublicNumber, SharedKey)
forall a. Maybe a
Nothing

getPubShared :: MonadRandom r
             => Params
             -> Int
             -> PublicNumber
             -> (PublicNumber -> GroupPublic)
             -> r (Maybe (GroupPublic, GroupKey))
getPubShared :: Params
-> Int
-> PublicNumber
-> (PublicNumber -> GroupPublic)
-> r (Maybe (GroupPublic, GroupKey))
getPubShared Params
params Int
expBits PublicNumber
pub PublicNumber -> GroupPublic
pubTag | Bool -> Bool
not (Params -> PublicNumber -> Bool
valid Params
params PublicNumber
pub) = Maybe (GroupPublic, GroupKey) -> r (Maybe (GroupPublic, GroupKey))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (GroupPublic, GroupKey)
forall a. Maybe a
Nothing
                                       | Bool
otherwise = do
    PrivateNumber
mypri <- Int -> r PrivateNumber
forall (r :: * -> *). MonadRandom r => Int -> r PrivateNumber
generatePriv Int
expBits
    let mypub :: PublicNumber
mypub = Params -> PrivateNumber -> PublicNumber
calculatePublic Params
params PrivateNumber
mypri
    let SharedKey ScrubbedBytes
share = Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared Params
params PrivateNumber
mypri PublicNumber
pub
    Maybe (GroupPublic, GroupKey) -> r (Maybe (GroupPublic, GroupKey))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (GroupPublic, GroupKey)
 -> r (Maybe (GroupPublic, GroupKey)))
-> Maybe (GroupPublic, GroupKey)
-> r (Maybe (GroupPublic, GroupKey))
forall a b. (a -> b) -> a -> b
$ (GroupPublic, GroupKey) -> Maybe (GroupPublic, GroupKey)
forall a. a -> Maybe a
Just (PublicNumber -> GroupPublic
pubTag PublicNumber
mypub, ScrubbedBytes -> GroupKey
SharedSecret ScrubbedBytes
share)

getPubShared' :: MonadRandom r
              => Params
              -> Int
              -> PublicNumber
              -> r (Maybe (PublicNumber, SharedKey))
getPubShared' :: Params
-> Int -> PublicNumber -> r (Maybe (PublicNumber, SharedKey))
getPubShared' Params
params Int
expBits PublicNumber
pub
    | Bool -> Bool
not (Params -> PublicNumber -> Bool
valid Params
params PublicNumber
pub) = Maybe (PublicNumber, SharedKey)
-> r (Maybe (PublicNumber, SharedKey))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (PublicNumber, SharedKey)
forall a. Maybe a
Nothing
    | Bool
otherwise = do
        PrivateNumber
mypri <- Int -> r PrivateNumber
forall (r :: * -> *). MonadRandom r => Int -> r PrivateNumber
generatePriv Int
expBits
        let share :: ScrubbedBytes
share = SharedKey -> ScrubbedBytes
stripLeadingZeros (Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared Params
params PrivateNumber
mypri PublicNumber
pub)
        Maybe (PublicNumber, SharedKey)
-> r (Maybe (PublicNumber, SharedKey))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (PublicNumber, SharedKey)
 -> r (Maybe (PublicNumber, SharedKey)))
-> Maybe (PublicNumber, SharedKey)
-> r (Maybe (PublicNumber, SharedKey))
forall a b. (a -> b) -> a -> b
$ (PublicNumber, SharedKey) -> Maybe (PublicNumber, SharedKey)
forall a. a -> Maybe a
Just (Params -> PrivateNumber -> PublicNumber
calculatePublic Params
params PrivateNumber
mypri, ScrubbedBytes -> SharedKey
SharedKey ScrubbedBytes
share)

groupGetShared ::  GroupPublic -> GroupPrivate -> Maybe GroupKey
groupGetShared :: GroupPublic -> GroupPrivate -> Maybe GroupKey
groupGetShared (GroupPub_P256 Point Curve_P256R1
pub) (GroupPri_P256 Scalar Curve_P256R1
pri) = CryptoFailable GroupKey -> Maybe GroupKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable GroupKey -> Maybe GroupKey)
-> CryptoFailable GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ Proxy Curve_P256R1
-> Point Curve_P256R1
-> Scalar Curve_P256R1
-> CryptoFailable GroupKey
forall curve (proxy :: * -> *).
EllipticCurveDH curve =>
proxy curve
-> Point curve -> Scalar curve -> CryptoFailable GroupKey
deriveDecrypt Proxy Curve_P256R1
p256 Point Curve_P256R1
pub Scalar Curve_P256R1
pri
groupGetShared (GroupPub_P384 Point Curve_P384R1
pub) (GroupPri_P384 Scalar Curve_P384R1
pri) = CryptoFailable GroupKey -> Maybe GroupKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable GroupKey -> Maybe GroupKey)
-> CryptoFailable GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ Proxy Curve_P384R1
-> Point Curve_P384R1
-> Scalar Curve_P384R1
-> CryptoFailable GroupKey
forall curve (proxy :: * -> *).
EllipticCurveDH curve =>
proxy curve
-> Point curve -> Scalar curve -> CryptoFailable GroupKey
deriveDecrypt Proxy Curve_P384R1
p384 Point Curve_P384R1
pub Scalar Curve_P384R1
pri
groupGetShared (GroupPub_P521 Point Curve_P521R1
pub) (GroupPri_P521 Scalar Curve_P521R1
pri) = CryptoFailable GroupKey -> Maybe GroupKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable GroupKey -> Maybe GroupKey)
-> CryptoFailable GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ Proxy Curve_P521R1
-> Point Curve_P521R1
-> Scalar Curve_P521R1
-> CryptoFailable GroupKey
forall curve (proxy :: * -> *).
EllipticCurveDH curve =>
proxy curve
-> Point curve -> Scalar curve -> CryptoFailable GroupKey
deriveDecrypt Proxy Curve_P521R1
p521 Point Curve_P521R1
pub Scalar Curve_P521R1
pri
groupGetShared (GroupPub_X255 Point Curve_X25519
pub) (GroupPri_X255 Scalar Curve_X25519
pri) = CryptoFailable GroupKey -> Maybe GroupKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable GroupKey -> Maybe GroupKey)
-> CryptoFailable GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ Proxy Curve_X25519
-> Point Curve_X25519
-> Scalar Curve_X25519
-> CryptoFailable GroupKey
forall curve (proxy :: * -> *).
EllipticCurveDH curve =>
proxy curve
-> Point curve -> Scalar curve -> CryptoFailable GroupKey
deriveDecrypt Proxy Curve_X25519
x25519 Point Curve_X25519
pub Scalar Curve_X25519
pri
groupGetShared (GroupPub_X448 Point Curve_X448
pub) (GroupPri_X448 Scalar Curve_X448
pri) = CryptoFailable GroupKey -> Maybe GroupKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable GroupKey -> Maybe GroupKey)
-> CryptoFailable GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ Proxy Curve_X448
-> Point Curve_X448 -> Scalar Curve_X448 -> CryptoFailable GroupKey
forall curve (proxy :: * -> *).
EllipticCurveDH curve =>
proxy curve
-> Point curve -> Scalar curve -> CryptoFailable GroupKey
deriveDecrypt Proxy Curve_X448
x448 Point Curve_X448
pub Scalar Curve_X448
pri
groupGetShared (GroupPub_FFDHE2048 PublicNumber
pub) (GroupPri_FFDHE2048 PrivateNumber
pri) = Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
ffdhe2048 PublicNumber
pub PrivateNumber
pri
groupGetShared (GroupPub_FFDHE3072 PublicNumber
pub) (GroupPri_FFDHE3072 PrivateNumber
pri) = Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
ffdhe3072 PublicNumber
pub PrivateNumber
pri
groupGetShared (GroupPub_FFDHE4096 PublicNumber
pub) (GroupPri_FFDHE4096 PrivateNumber
pri) = Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
ffdhe4096 PublicNumber
pub PrivateNumber
pri
groupGetShared (GroupPub_FFDHE6144 PublicNumber
pub) (GroupPri_FFDHE6144 PrivateNumber
pri) = Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
ffdhe6144 PublicNumber
pub PrivateNumber
pri
groupGetShared (GroupPub_FFDHE8192 PublicNumber
pub) (GroupPri_FFDHE8192 PrivateNumber
pri) = Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
ffdhe8192 PublicNumber
pub PrivateNumber
pri
groupGetShared GroupPublic
_ GroupPrivate
_ = Maybe GroupKey
forall a. Maybe a
Nothing

calcShared :: Params -> PublicNumber -> PrivateNumber -> Maybe SharedSecret
calcShared :: Params -> PublicNumber -> PrivateNumber -> Maybe GroupKey
calcShared Params
params PublicNumber
pub PrivateNumber
pri
    | Params -> PublicNumber -> Bool
valid Params
params PublicNumber
pub = GroupKey -> Maybe GroupKey
forall a. a -> Maybe a
Just (GroupKey -> Maybe GroupKey) -> GroupKey -> Maybe GroupKey
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> GroupKey
SharedSecret ScrubbedBytes
share
    | Bool
otherwise        = Maybe GroupKey
forall a. Maybe a
Nothing
  where
    SharedKey ScrubbedBytes
share = Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared Params
params PrivateNumber
pri PublicNumber
pub

encodeGroupPublic :: GroupPublic -> ByteString
encodeGroupPublic :: GroupPublic -> ByteString
encodeGroupPublic (GroupPub_P256 Point Curve_P256R1
p) = Proxy Curve_P256R1 -> Point Curve_P256R1 -> ByteString
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> Point curve -> bs
encodePoint Proxy Curve_P256R1
p256 Point Curve_P256R1
p
encodeGroupPublic (GroupPub_P384 Point Curve_P384R1
p) = Proxy Curve_P384R1 -> Point Curve_P384R1 -> ByteString
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> Point curve -> bs
encodePoint Proxy Curve_P384R1
p384 Point Curve_P384R1
p
encodeGroupPublic (GroupPub_P521 Point Curve_P521R1
p) = Proxy Curve_P521R1 -> Point Curve_P521R1 -> ByteString
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> Point curve -> bs
encodePoint Proxy Curve_P521R1
p521 Point Curve_P521R1
p
encodeGroupPublic (GroupPub_X255 Point Curve_X25519
p) = Proxy Curve_X25519 -> Point Curve_X25519 -> ByteString
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> Point curve -> bs
encodePoint Proxy Curve_X25519
x25519 Point Curve_X25519
p
encodeGroupPublic (GroupPub_X448 Point Curve_X448
p) = Proxy Curve_X448 -> Point Curve_X448 -> ByteString
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> Point curve -> bs
encodePoint Proxy Curve_X448
x448 Point Curve_X448
p
encodeGroupPublic (GroupPub_FFDHE2048 PublicNumber
p) = Params -> PublicNumber -> ByteString
enc Params
ffdhe2048 PublicNumber
p
encodeGroupPublic (GroupPub_FFDHE3072 PublicNumber
p) = Params -> PublicNumber -> ByteString
enc Params
ffdhe3072 PublicNumber
p
encodeGroupPublic (GroupPub_FFDHE4096 PublicNumber
p) = Params -> PublicNumber -> ByteString
enc Params
ffdhe4096 PublicNumber
p
encodeGroupPublic (GroupPub_FFDHE6144 PublicNumber
p) = Params -> PublicNumber -> ByteString
enc Params
ffdhe6144 PublicNumber
p
encodeGroupPublic (GroupPub_FFDHE8192 PublicNumber
p) = Params -> PublicNumber -> ByteString
enc Params
ffdhe8192 PublicNumber
p

enc :: Params -> PublicNumber -> ByteString
enc :: Params -> PublicNumber -> ByteString
enc Params
params (PublicNumber Integer
p) = Int -> Integer -> ByteString
forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ ((Params -> Int
params_bits Params
params 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
p

decodeGroupPublic :: Group -> ByteString -> Either CryptoError GroupPublic
decodeGroupPublic :: Group -> ByteString -> Either CryptoError GroupPublic
decodeGroupPublic Group
P256   ByteString
bs = CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable GroupPublic -> Either CryptoError GroupPublic)
-> CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ Point Curve_P256R1 -> GroupPublic
Point -> GroupPublic
GroupPub_P256 (Point -> GroupPublic)
-> CryptoFailable Point -> CryptoFailable GroupPublic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P256R1
-> ByteString -> CryptoFailable (Point Curve_P256R1)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (Point curve)
decodePoint Proxy Curve_P256R1
p256 ByteString
bs
decodeGroupPublic Group
P384   ByteString
bs = CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable GroupPublic -> Either CryptoError GroupPublic)
-> CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ Point SEC_p384r1 -> GroupPublic
Point Curve_P384R1 -> GroupPublic
GroupPub_P384 (Point SEC_p384r1 -> GroupPublic)
-> CryptoFailable (Point SEC_p384r1) -> CryptoFailable GroupPublic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P384R1
-> ByteString -> CryptoFailable (Point Curve_P384R1)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (Point curve)
decodePoint Proxy Curve_P384R1
p384 ByteString
bs
decodeGroupPublic Group
P521   ByteString
bs = CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable GroupPublic -> Either CryptoError GroupPublic)
-> CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ Point SEC_p521r1 -> GroupPublic
Point Curve_P521R1 -> GroupPublic
GroupPub_P521 (Point SEC_p521r1 -> GroupPublic)
-> CryptoFailable (Point SEC_p521r1) -> CryptoFailable GroupPublic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P521R1
-> ByteString -> CryptoFailable (Point Curve_P521R1)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (Point curve)
decodePoint Proxy Curve_P521R1
p521 ByteString
bs
decodeGroupPublic Group
X25519 ByteString
bs = CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable GroupPublic -> Either CryptoError GroupPublic)
-> CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ Point Curve_X25519 -> GroupPublic
PublicKey -> GroupPublic
GroupPub_X255 (PublicKey -> GroupPublic)
-> CryptoFailable PublicKey -> CryptoFailable GroupPublic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_X25519
-> ByteString -> CryptoFailable (Point Curve_X25519)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (Point curve)
decodePoint Proxy Curve_X25519
x25519 ByteString
bs
decodeGroupPublic Group
X448 ByteString
bs = CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a. CryptoFailable a -> Either CryptoError a
eitherCryptoError (CryptoFailable GroupPublic -> Either CryptoError GroupPublic)
-> CryptoFailable GroupPublic -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ Point Curve_X448 -> GroupPublic
PublicKey -> GroupPublic
GroupPub_X448 (PublicKey -> GroupPublic)
-> CryptoFailable PublicKey -> CryptoFailable GroupPublic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_X448 -> ByteString -> CryptoFailable (Point Curve_X448)
forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (Point curve)
decodePoint Proxy Curve_X448
x448 ByteString
bs
decodeGroupPublic Group
FFDHE2048 ByteString
bs = GroupPublic -> Either CryptoError GroupPublic
forall a b. b -> Either a b
Right (GroupPublic -> Either CryptoError GroupPublic)
-> (Integer -> GroupPublic)
-> Integer
-> Either CryptoError GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicNumber -> GroupPublic
GroupPub_FFDHE2048 (PublicNumber -> GroupPublic)
-> (Integer -> PublicNumber) -> Integer -> GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> PublicNumber
PublicNumber (Integer -> Either CryptoError GroupPublic)
-> Integer -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
bs
decodeGroupPublic Group
FFDHE3072 ByteString
bs = GroupPublic -> Either CryptoError GroupPublic
forall a b. b -> Either a b
Right (GroupPublic -> Either CryptoError GroupPublic)
-> (Integer -> GroupPublic)
-> Integer
-> Either CryptoError GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicNumber -> GroupPublic
GroupPub_FFDHE3072 (PublicNumber -> GroupPublic)
-> (Integer -> PublicNumber) -> Integer -> GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> PublicNumber
PublicNumber (Integer -> Either CryptoError GroupPublic)
-> Integer -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
bs
decodeGroupPublic Group
FFDHE4096 ByteString
bs = GroupPublic -> Either CryptoError GroupPublic
forall a b. b -> Either a b
Right (GroupPublic -> Either CryptoError GroupPublic)
-> (Integer -> GroupPublic)
-> Integer
-> Either CryptoError GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicNumber -> GroupPublic
GroupPub_FFDHE4096 (PublicNumber -> GroupPublic)
-> (Integer -> PublicNumber) -> Integer -> GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> PublicNumber
PublicNumber (Integer -> Either CryptoError GroupPublic)
-> Integer -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
bs
decodeGroupPublic Group
FFDHE6144 ByteString
bs = GroupPublic -> Either CryptoError GroupPublic
forall a b. b -> Either a b
Right (GroupPublic -> Either CryptoError GroupPublic)
-> (Integer -> GroupPublic)
-> Integer
-> Either CryptoError GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicNumber -> GroupPublic
GroupPub_FFDHE6144 (PublicNumber -> GroupPublic)
-> (Integer -> PublicNumber) -> Integer -> GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> PublicNumber
PublicNumber (Integer -> Either CryptoError GroupPublic)
-> Integer -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
bs
decodeGroupPublic Group
FFDHE8192 ByteString
bs = GroupPublic -> Either CryptoError GroupPublic
forall a b. b -> Either a b
Right (GroupPublic -> Either CryptoError GroupPublic)
-> (Integer -> GroupPublic)
-> Integer
-> Either CryptoError GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicNumber -> GroupPublic
GroupPub_FFDHE8192 (PublicNumber -> GroupPublic)
-> (Integer -> PublicNumber) -> Integer -> GroupPublic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> PublicNumber
PublicNumber (Integer -> Either CryptoError GroupPublic)
-> Integer -> Either CryptoError GroupPublic
forall a b. (a -> b) -> a -> b
$ ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
bs

-- Check that group element in not in the 2-element subgroup { 1, p - 1 }.
-- See RFC 7919 section 3 and NIST SP 56A rev 2 section 5.6.2.3.1.
valid :: Params -> PublicNumber -> Bool
valid :: Params -> PublicNumber -> Bool
valid (Params Integer
p Integer
_ Int
_) (PublicNumber Integer
y) = Integer
1 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
y Bool -> Bool -> Bool
&& Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
p Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

-- strips leading zeros from the result of getShared, as required
-- for DH(E) premaster secret in SSL/TLS before version 1.3.
stripLeadingZeros :: SharedKey -> B.ScrubbedBytes
stripLeadingZeros :: SharedKey -> ScrubbedBytes
stripLeadingZeros (SharedKey ScrubbedBytes
sb) = (ScrubbedBytes, ScrubbedBytes) -> ScrubbedBytes
forall a b. (a, b) -> b
snd ((ScrubbedBytes, ScrubbedBytes) -> ScrubbedBytes)
-> (ScrubbedBytes, ScrubbedBytes) -> ScrubbedBytes
forall a b. (a -> b) -> a -> b
$ (Word8 -> Bool) -> ScrubbedBytes -> (ScrubbedBytes, ScrubbedBytes)
forall bs. ByteArray bs => (Word8 -> Bool) -> bs -> (bs, bs)
B.span (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0) ScrubbedBytes
sb

-- Use short exponents as optimization, see RFC 7919 section 5.2.
generatePriv :: MonadRandom r => Int -> r PrivateNumber
generatePriv :: Int -> r PrivateNumber
generatePriv Int
e = Integer -> PrivateNumber
PrivateNumber (Integer -> PrivateNumber) -> r Integer -> r PrivateNumber
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Maybe GenTopPolicy -> Bool -> r Integer
forall (m :: * -> *).
MonadRandom m =>
Int -> Maybe GenTopPolicy -> Bool -> m Integer
generateParams Int
e (GenTopPolicy -> Maybe GenTopPolicy
forall a. a -> Maybe a
Just GenTopPolicy
SetHighest) Bool
False

-- Short exponent bit sizes from RFC 7919 appendix A, rounded to next
-- multiple of 16 bits, i.e. going through a function like:
-- let shortExp n = head [ e | i <- [1..], let e = n + i, e `mod` 16 == 0 ]
exp2048 :: Int
exp3072 :: Int
exp4096 :: Int
exp6144 :: Int
exp8192 :: Int
exp2048 :: Int
exp2048 = Int
240 -- shortExp 225
exp3072 :: Int
exp3072 = Int
288 -- shortExp 275
exp4096 :: Int
exp4096 = Int
336 -- shortExp 325
exp6144 :: Int
exp6144 = Int
384 -- shortExp 375
exp8192 :: Int
exp8192 = Int
416 -- shortExp 400