{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
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.Number.Serialize (i2ospOf_)
import Crypto.Random.Types
import Data.ByteArray (ByteArrayAccess, ScrubbedBytes)
import Data.Data
data Params = Params
{ Params -> Integer
params_p :: Integer
, Params -> Integer
params_g :: Integer
, Params -> Int
params_bits :: Int
} deriving (Int -> Params -> ShowS
[Params] -> ShowS
Params -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Params] -> ShowS
$cshowList :: [Params] -> ShowS
show :: Params -> String
$cshow :: Params -> String
showsPrec :: Int -> Params -> ShowS
$cshowsPrec :: Int -> Params -> ShowS
Show,ReadPrec [Params]
ReadPrec Params
Int -> ReadS Params
ReadS [Params]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Params]
$creadListPrec :: ReadPrec [Params]
readPrec :: ReadPrec Params
$creadPrec :: ReadPrec Params
readList :: ReadS [Params]
$creadList :: ReadS [Params]
readsPrec :: Int -> ReadS Params
$creadsPrec :: Int -> ReadS Params
Read,Params -> Params -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Params -> Params -> Bool
$c/= :: Params -> Params -> Bool
== :: Params -> Params -> Bool
$c== :: Params -> Params -> Bool
Eq,Typeable Params
Params -> DataType
Params -> Constr
(forall b. Data b => b -> b) -> Params -> Params
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
forall u. (forall d. Data d => d -> u) -> Params -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Params -> m Params
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Params)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Params -> m Params
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Params -> m Params
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Params -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Params -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Params -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Params -> r
gmapT :: (forall b. Data b => b -> b) -> Params -> Params
$cgmapT :: (forall b. Data b => b -> b) -> Params -> Params
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Params)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Params)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Params)
dataTypeOf :: Params -> DataType
$cdataTypeOf :: Params -> DataType
toConstr :: Params -> Constr
$ctoConstr :: Params -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Params
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Params -> c Params
Data)
instance NFData Params where
rnf :: Params -> ()
rnf (Params Integer
p Integer
g Int
bits) = forall a. NFData a => a -> ()
rnf Integer
p seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf Integer
g seq :: forall a b. a -> b -> b
`seq` Int
bits seq :: forall a b. a -> b -> b
`seq` ()
newtype PublicNumber = PublicNumber Integer
deriving (Int -> PublicNumber -> ShowS
[PublicNumber] -> ShowS
PublicNumber -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicNumber] -> ShowS
$cshowList :: [PublicNumber] -> ShowS
show :: PublicNumber -> String
$cshow :: PublicNumber -> String
showsPrec :: Int -> PublicNumber -> ShowS
$cshowsPrec :: Int -> PublicNumber -> ShowS
Show,ReadPrec [PublicNumber]
ReadPrec PublicNumber
Int -> ReadS PublicNumber
ReadS [PublicNumber]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PublicNumber]
$creadListPrec :: ReadPrec [PublicNumber]
readPrec :: ReadPrec PublicNumber
$creadPrec :: ReadPrec PublicNumber
readList :: ReadS [PublicNumber]
$creadList :: ReadS [PublicNumber]
readsPrec :: Int -> ReadS PublicNumber
$creadsPrec :: Int -> ReadS PublicNumber
Read,PublicNumber -> PublicNumber -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicNumber -> PublicNumber -> Bool
$c/= :: PublicNumber -> PublicNumber -> Bool
== :: PublicNumber -> PublicNumber -> Bool
$c== :: PublicNumber -> PublicNumber -> Bool
Eq,Int -> PublicNumber
PublicNumber -> Int
PublicNumber -> [PublicNumber]
PublicNumber -> PublicNumber
PublicNumber -> PublicNumber -> [PublicNumber]
PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromThenTo :: PublicNumber -> PublicNumber -> PublicNumber -> [PublicNumber]
enumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromTo :: PublicNumber -> PublicNumber -> [PublicNumber]
enumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
$cenumFromThen :: PublicNumber -> PublicNumber -> [PublicNumber]
enumFrom :: PublicNumber -> [PublicNumber]
$cenumFrom :: PublicNumber -> [PublicNumber]
fromEnum :: PublicNumber -> Int
$cfromEnum :: PublicNumber -> Int
toEnum :: Int -> PublicNumber
$ctoEnum :: Int -> PublicNumber
pred :: PublicNumber -> PublicNumber
$cpred :: PublicNumber -> PublicNumber
succ :: PublicNumber -> PublicNumber
$csucc :: PublicNumber -> PublicNumber
Enum,Num PublicNumber
Ord PublicNumber
PublicNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PublicNumber -> Rational
$ctoRational :: PublicNumber -> Rational
Real,Integer -> PublicNumber
PublicNumber -> PublicNumber
PublicNumber -> PublicNumber -> PublicNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PublicNumber
$cfromInteger :: Integer -> PublicNumber
signum :: PublicNumber -> PublicNumber
$csignum :: PublicNumber -> PublicNumber
abs :: PublicNumber -> PublicNumber
$cabs :: PublicNumber -> PublicNumber
negate :: PublicNumber -> PublicNumber
$cnegate :: PublicNumber -> PublicNumber
* :: PublicNumber -> PublicNumber -> PublicNumber
$c* :: PublicNumber -> PublicNumber -> PublicNumber
- :: PublicNumber -> PublicNumber -> PublicNumber
$c- :: PublicNumber -> PublicNumber -> PublicNumber
+ :: PublicNumber -> PublicNumber -> PublicNumber
$c+ :: PublicNumber -> PublicNumber -> PublicNumber
Num,Eq PublicNumber
PublicNumber -> PublicNumber -> Bool
PublicNumber -> PublicNumber -> Ordering
PublicNumber -> PublicNumber -> PublicNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PublicNumber -> PublicNumber -> PublicNumber
$cmin :: PublicNumber -> PublicNumber -> PublicNumber
max :: PublicNumber -> PublicNumber -> PublicNumber
$cmax :: PublicNumber -> PublicNumber -> PublicNumber
>= :: PublicNumber -> PublicNumber -> Bool
$c>= :: PublicNumber -> PublicNumber -> Bool
> :: PublicNumber -> PublicNumber -> Bool
$c> :: PublicNumber -> PublicNumber -> Bool
<= :: PublicNumber -> PublicNumber -> Bool
$c<= :: PublicNumber -> PublicNumber -> Bool
< :: PublicNumber -> PublicNumber -> Bool
$c< :: PublicNumber -> PublicNumber -> Bool
compare :: PublicNumber -> PublicNumber -> Ordering
$ccompare :: PublicNumber -> PublicNumber -> Ordering
Ord,PublicNumber -> ()
forall a. (a -> ()) -> NFData a
rnf :: PublicNumber -> ()
$crnf :: PublicNumber -> ()
NFData)
newtype PrivateNumber = PrivateNumber Integer
deriving (Int -> PrivateNumber -> ShowS
[PrivateNumber] -> ShowS
PrivateNumber -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrivateNumber] -> ShowS
$cshowList :: [PrivateNumber] -> ShowS
show :: PrivateNumber -> String
$cshow :: PrivateNumber -> String
showsPrec :: Int -> PrivateNumber -> ShowS
$cshowsPrec :: Int -> PrivateNumber -> ShowS
Show,ReadPrec [PrivateNumber]
ReadPrec PrivateNumber
Int -> ReadS PrivateNumber
ReadS [PrivateNumber]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PrivateNumber]
$creadListPrec :: ReadPrec [PrivateNumber]
readPrec :: ReadPrec PrivateNumber
$creadPrec :: ReadPrec PrivateNumber
readList :: ReadS [PrivateNumber]
$creadList :: ReadS [PrivateNumber]
readsPrec :: Int -> ReadS PrivateNumber
$creadsPrec :: Int -> ReadS PrivateNumber
Read,PrivateNumber -> PrivateNumber -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrivateNumber -> PrivateNumber -> Bool
$c/= :: PrivateNumber -> PrivateNumber -> Bool
== :: PrivateNumber -> PrivateNumber -> Bool
$c== :: PrivateNumber -> PrivateNumber -> Bool
Eq,Int -> PrivateNumber
PrivateNumber -> Int
PrivateNumber -> [PrivateNumber]
PrivateNumber -> PrivateNumber
PrivateNumber -> PrivateNumber -> [PrivateNumber]
PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromThenTo :: PrivateNumber -> PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromTo :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
$cenumFromThen :: PrivateNumber -> PrivateNumber -> [PrivateNumber]
enumFrom :: PrivateNumber -> [PrivateNumber]
$cenumFrom :: PrivateNumber -> [PrivateNumber]
fromEnum :: PrivateNumber -> Int
$cfromEnum :: PrivateNumber -> Int
toEnum :: Int -> PrivateNumber
$ctoEnum :: Int -> PrivateNumber
pred :: PrivateNumber -> PrivateNumber
$cpred :: PrivateNumber -> PrivateNumber
succ :: PrivateNumber -> PrivateNumber
$csucc :: PrivateNumber -> PrivateNumber
Enum,Num PrivateNumber
Ord PrivateNumber
PrivateNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PrivateNumber -> Rational
$ctoRational :: PrivateNumber -> Rational
Real,Integer -> PrivateNumber
PrivateNumber -> PrivateNumber
PrivateNumber -> PrivateNumber -> PrivateNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PrivateNumber
$cfromInteger :: Integer -> PrivateNumber
signum :: PrivateNumber -> PrivateNumber
$csignum :: PrivateNumber -> PrivateNumber
abs :: PrivateNumber -> PrivateNumber
$cabs :: PrivateNumber -> PrivateNumber
negate :: PrivateNumber -> PrivateNumber
$cnegate :: PrivateNumber -> PrivateNumber
* :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c* :: PrivateNumber -> PrivateNumber -> PrivateNumber
- :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c- :: PrivateNumber -> PrivateNumber -> PrivateNumber
+ :: PrivateNumber -> PrivateNumber -> PrivateNumber
$c+ :: PrivateNumber -> PrivateNumber -> PrivateNumber
Num,Eq PrivateNumber
PrivateNumber -> PrivateNumber -> Bool
PrivateNumber -> PrivateNumber -> Ordering
PrivateNumber -> PrivateNumber -> PrivateNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PrivateNumber -> PrivateNumber -> PrivateNumber
$cmin :: PrivateNumber -> PrivateNumber -> PrivateNumber
max :: PrivateNumber -> PrivateNumber -> PrivateNumber
$cmax :: PrivateNumber -> PrivateNumber -> PrivateNumber
>= :: PrivateNumber -> PrivateNumber -> Bool
$c>= :: PrivateNumber -> PrivateNumber -> Bool
> :: PrivateNumber -> PrivateNumber -> Bool
$c> :: PrivateNumber -> PrivateNumber -> Bool
<= :: PrivateNumber -> PrivateNumber -> Bool
$c<= :: PrivateNumber -> PrivateNumber -> Bool
< :: PrivateNumber -> PrivateNumber -> Bool
$c< :: PrivateNumber -> PrivateNumber -> Bool
compare :: PrivateNumber -> PrivateNumber -> Ordering
$ccompare :: PrivateNumber -> PrivateNumber -> Ordering
Ord,PrivateNumber -> ()
forall a. (a -> ()) -> NFData a
rnf :: PrivateNumber -> ()
$crnf :: PrivateNumber -> ()
NFData)
newtype SharedKey = SharedKey ScrubbedBytes
deriving (Int -> SharedKey -> ShowS
[SharedKey] -> ShowS
SharedKey -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SharedKey] -> ShowS
$cshowList :: [SharedKey] -> ShowS
show :: SharedKey -> String
$cshow :: SharedKey -> String
showsPrec :: Int -> SharedKey -> ShowS
$cshowsPrec :: Int -> SharedKey -> ShowS
Show,SharedKey -> SharedKey -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SharedKey -> SharedKey -> Bool
$c/= :: SharedKey -> SharedKey -> Bool
== :: SharedKey -> SharedKey -> Bool
$c== :: SharedKey -> SharedKey -> Bool
Eq,SharedKey -> Int
forall p. SharedKey -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: forall p. SharedKey -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall p. SharedKey -> Ptr p -> IO ()
withByteArray :: forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall p a. SharedKey -> (Ptr p -> IO a) -> IO a
length :: SharedKey -> Int
$clength :: SharedKey -> Int
ByteArrayAccess,SharedKey -> ()
forall a. (a -> ()) -> NFData a
rnf :: SharedKey -> ()
$crnf :: SharedKey -> ()
NFData)
generateParams :: MonadRandom m =>
Int
-> Integer
-> m Params
generateParams :: forall (m :: * -> *). MonadRandom m => Int -> Integer -> m Params
generateParams Int
bits Integer
generator =
(\Integer
p -> Integer -> Integer -> Int -> Params
Params Integer
p Integer
generator Int
bits) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadRandom m => Int -> m Integer
generateSafePrime Int
bits
generatePrivate :: MonadRandom m => Params -> m PrivateNumber
generatePrivate :: forall (m :: * -> *). MonadRandom m => Params -> m PrivateNumber
generatePrivate (Params Integer
p Integer
_ Int
_) = Integer -> PrivateNumber
PrivateNumber forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadRandom m => Integer -> m Integer
generateMax Integer
p
calculatePublic :: Params -> PrivateNumber -> PublicNumber
calculatePublic :: Params -> PrivateNumber -> PublicNumber
calculatePublic (Params Integer
p Integer
g Int
_) (PrivateNumber Integer
x) = Integer -> PublicNumber
PublicNumber forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Integer
expSafe Integer
g Integer
x Integer
p
generatePublic :: Params -> PrivateNumber -> PublicNumber
generatePublic :: Params -> PrivateNumber -> PublicNumber
generatePublic = Params -> PrivateNumber -> PublicNumber
calculatePublic
getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
getShared (Params Integer
p Integer
_ Int
bits) (PrivateNumber Integer
x) (PublicNumber Integer
y) = ScrubbedBytes -> SharedKey
SharedKey forall a b. (a -> b) -> a -> b
$ forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ ((Int
bits forall a. Num a => a -> a -> a
+ Int
7) forall a. Integral a => a -> a -> a
`div` Int
8) forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> Integer
expSafe Integer
y Integer
x Integer
p