\subsection{Combined Key}

\begin{code}
{-# LANGUAGE StrictData #-}
module Network.Tox.Crypto.CombinedKey where

import qualified Crypto.Saltine.Core.Box as Sodium (beforeNM)

import           Network.Tox.Crypto.Key  (CombinedKey, Key (..), PublicKey,
                                          SecretKey)


{-------------------------------------------------------------------------------
 -
 - :: Implementation.
 -
 ------------------------------------------------------------------------------}

\end{code}

A Combined Key is computed from a Secret Key and a Public Key using the NaCl
function \texttt{crypto\_box\_beforenm}.  Given two Key Pairs KP1 (SK1, PK1) and
KP2 (SK2, PK2), the Combined Key computed from (SK1, PK2) equals the one
computed from (SK2, PK1).  This allows for symmetric encryption, as peers can
derive the same shared key from their own secret key and their peer's public
key.

\begin{code}

precompute :: SecretKey -> PublicKey -> CombinedKey
precompute :: SecretKey -> PublicKey -> CombinedKey
precompute (Key SecretKey
sk) (Key PublicKey
pk) =
  CombinedKey -> CombinedKey
forall a. a -> Key a
Key (CombinedKey -> CombinedKey) -> CombinedKey -> CombinedKey
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey -> CombinedKey
Sodium.beforeNM SecretKey
sk PublicKey
pk

\end{code}

In the Tox protocol, packets are encrypted using the public key of the receiver
and the secret key of the sender.  The receiver decrypts the packets using the
receiver's secret key and the sender's public key.

The fact that the same key is used to encrypt and decrypt packets on both sides
means that packets being sent could be replayed back to the sender if there is
nothing to prevent it.

The shared key generation is the most resource intensive part of the
encryption/decryption which means that resource usage can be reduced
considerably by saving the shared keys and reusing them later as much as
possible.