{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- |
-- Module      : Crypto.Internal.Poly1305
-- License     : BSD-style
-- Maintainer  : Kazu Yamamoto <kazu@iij.ad.jp>
-- Stability   : experimental
-- Portability : unknown
--
-- The Poly1305 key with its constructor, for the modules here that build one
-- from bytes whose length they already know.  "Crypto.MAC.Poly1305" exports
-- the type without the constructor, so that outside this library a key can
-- only be made by 'key', which checks.
module Crypto.Internal.Poly1305 (
    Key (..),
    key,
) where

import Crypto.Error
import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes)
import qualified Crypto.Internal.ByteArray as B
import Crypto.Internal.DeepSeq

-- | A Poly1305 key: thirty-two bytes, and the length is checked here rather
-- than at every use.  'Crypto.MAC.Poly1305.initialize' and
-- 'Crypto.MAC.Poly1305.auth' take one of these and cannot fail, so a caller
-- that holds a key does not carry an error case for a length it already knows
-- is right.
newtype Key = Key ScrubbedBytes
    deriving (Key -> Int
(Key -> Int)
-> (forall p a. Key -> (Ptr p -> IO a) -> IO a)
-> (forall p. Key -> Ptr p -> IO ())
-> ByteArrayAccess Key
forall p. Key -> 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. Key -> (Ptr p -> IO a) -> IO a
$clength :: Key -> Int
length :: Key -> Int
$cwithByteArray :: forall p a. Key -> (Ptr p -> IO a) -> IO a
withByteArray :: forall p a. Key -> (Ptr p -> IO a) -> IO a
$ccopyByteArrayToPtr :: forall p. Key -> Ptr p -> IO ()
copyByteArrayToPtr :: forall p. Key -> Ptr p -> IO ()
ByteArrayAccess, Key -> Key -> Bool
(Key -> Key -> Bool) -> (Key -> Key -> Bool) -> Eq Key
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Key -> Key -> Bool
== :: Key -> Key -> Bool
$c/= :: Key -> Key -> Bool
/= :: Key -> Key -> Bool
Eq, Key -> ()
(Key -> ()) -> NFData Key
forall a. (a -> ()) -> NFData a
$crnf :: Key -> ()
rnf :: Key -> ()
NFData)

-- | Take thirty-two bytes for a key.  A different length is reported as
-- 'CryptoError_MacKeyInvalid'; nothing else about a key can be wrong.
key :: ByteArrayAccess ba => ba -> CryptoFailable Key
key :: forall ba. ByteArrayAccess ba => ba -> CryptoFailable Key
key ba
k
    | ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = CryptoError -> CryptoFailable Key
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_MacKeyInvalid
    | Bool
otherwise = Key -> CryptoFailable Key
forall a. a -> CryptoFailable a
CryptoPassed (Key -> CryptoFailable Key) -> Key -> CryptoFailable Key
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> Key
Key (ScrubbedBytes -> Key) -> ScrubbedBytes -> Key
forall a b. (a -> b) -> a -> b
$ ba -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert ba
k