\subsection{Key Pair}
A Key Pair is a pair of Secret Key and Public Key. A new key pair is generated
using the \texttt{crypto\_box\_keypair} function of the NaCl crypto library. Two
separate calls to the key pair generation function must return distinct key
pairs. See the \href{https://nacl.cr.yp.to/box.html}{NaCl documentation} for
details.
A Public Key can be computed from a Secret Key using the NaCl function
\texttt{crypto\_scalarmult\_base}, which computes the scalar product of a
standard group element and the Secret Key. See the
\href{https://nacl.cr.yp.to/scalarmult.html}{NaCl documentation} for details.
\begin{code}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Trustworthy #-}
module Network.Tox.Crypto.KeyPair where
import Control.Applicative ((<$>))
import qualified Crypto.Saltine.Class as Sodium (decode, encode)
import qualified Crypto.Saltine.Core.Box as Sodium (newKeypair)
import qualified Crypto.Saltine.Core.ScalarMult as Sodium (multBase)
import Data.Binary (Binary)
import Data.MessagePack (MessagePack (..))
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Network.MessagePack.Rpc (Doc (..))
import qualified Network.MessagePack.Rpc as Rpc
import Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)
import Network.Tox.Crypto.Key (Key (..))
import qualified Network.Tox.Crypto.Key as Key
data KeyPair = KeyPair
{ secretKey :: Key.SecretKey
, publicKey :: Key.PublicKey
}
deriving (Eq, Show, Read, Generic, Typeable)
instance Binary KeyPair
instance MessagePack KeyPair
newKeyPair :: IO KeyPair
newKeyPair = do
(sk, pk) <- Sodium.newKeypair
return $ KeyPair (Key sk) (Key pk)
newKeyPairR :: Rpc.Rpc (Rpc.ReturnsM IO KeyPair)
newKeyPairR =
Rpc.stubs "KeyPair.newKeyPair"
(RetM "keyPair")
newKeyPair
fromSecretKey :: Key.SecretKey -> KeyPair
fromSecretKey sk =
let
skBytes = Sodium.encode sk
Just skScalar = Sodium.decode skBytes
pkGroupElement = Sodium.multBase skScalar
pkBytes = Sodium.encode pkGroupElement
Just pk = Sodium.decode pkBytes
in
KeyPair sk pk
fromSecretKeyR :: Rpc.Rpc (Key.SecretKey -> Rpc.Returns KeyPair)
fromSecretKeyR =
Rpc.stubs "KeyPair.fromSecretKey"
(Arg "key" $ Ret "keyPair")
fromSecretKey
instance Arbitrary KeyPair where
arbitrary =
fromSecretKey <$> arbitrary
\end{code}