    -- |
    -- Module      : Crypto.Cipher.Types.Base
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : Stable
    -- Portability : Excellent
    --
    -- Symmetric cipher basic types
    --
    {-# LANGUAGE ExistentialQuantification #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    module Crypto.Cipher.Types.Base
        ( KeySizeSpecifier(..)
        , Cipher(..)
        , AuthTag(..)
        , AEADMode(..)
        , CCM_M(..)
        , CCM_L(..)
        , DataUnitOffset
        ) where

    import           Data.Word
    import           Crypto.Internal.ByteArray (Bytes, ByteArrayAccess, ByteArray)
    import qualified Crypto.Internal.ByteArray as B
    import           Crypto.Internal.DeepSeq
    import           Crypto.Error

    -- | Different specifier for key size in bytes
    data KeySizeSpecifier =
          KeySizeRange Int Int -- ^ in the range [min,max]
        | KeySizeEnum  [Int]   -- ^ one of the specified values
        | KeySizeFixed Int     -- ^ a specific size
        deriving (Int -> KeySizeSpecifier -> ShowS
    [KeySizeSpecifier] -> ShowS
    KeySizeSpecifier -> String
    (Int -> KeySizeSpecifier -> ShowS)
    -> (KeySizeSpecifier -> String)
    -> ([KeySizeSpecifier] -> ShowS)
    -> Show KeySizeSpecifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeySizeSpecifier -> ShowS
    showsPrec :: Int -> KeySizeSpecifier -> ShowS
    $cshow :: KeySizeSpecifier -> String
    show :: KeySizeSpecifier -> String
    $cshowList :: [KeySizeSpecifier] -> ShowS
    showList :: [KeySizeSpecifier] -> ShowS
    Show,KeySizeSpecifier -> KeySizeSpecifier -> Bool
    (KeySizeSpecifier -> KeySizeSpecifier -> Bool)
    -> (KeySizeSpecifier -> KeySizeSpecifier -> Bool)
    -> Eq KeySizeSpecifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    == :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    $c/= :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    /= :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    Eq)

    -- | Offset inside an XTS data unit, measured in block size.
    type DataUnitOffset = Word32

    -- | Authentication Tag for AE cipher mode
    newtype AuthTag = AuthTag { AuthTag -> Bytes
    unAuthTag :: Bytes }
        deriving (Int -> AuthTag -> ShowS
    [AuthTag] -> ShowS
    AuthTag -> String
    (Int -> AuthTag -> ShowS)
    -> (AuthTag -> String) -> ([AuthTag] -> ShowS) -> Show AuthTag
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AuthTag -> ShowS
    showsPrec :: Int -> AuthTag -> ShowS
    $cshow :: AuthTag -> String
    show :: AuthTag -> String
    $cshowList :: [AuthTag] -> ShowS
    showList :: [AuthTag] -> ShowS
    Show, AuthTag -> Int
    (AuthTag -> Int)
    -> (forall p a. AuthTag -> (Ptr p -> IO a) -> IO a)
    -> (forall p. AuthTag -> Ptr p -> IO ())
    -> ByteArrayAccess AuthTag
    forall p. AuthTag -> 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. AuthTag -> (Ptr p -> IO a) -> IO a
    $clength :: AuthTag -> Int
    length :: AuthTag -> Int
    $cwithByteArray :: forall p a. AuthTag -> (Ptr p -> IO a) -> IO a
    withByteArray :: forall p a. AuthTag -> (Ptr p -> IO a) -> IO a
    $ccopyByteArrayToPtr :: forall p. AuthTag -> Ptr p -> IO ()
    copyByteArrayToPtr :: forall p. AuthTag -> Ptr p -> IO ()
    ByteArrayAccess, AuthTag -> ()
    (AuthTag -> ()) -> NFData AuthTag
    forall a. (a -> ()) -> NFData a
    $crnf :: AuthTag -> ()
    rnf :: AuthTag -> ()
    NFData)

    instance Eq AuthTag where
        (AuthTag Bytes
    a) == :: AuthTag -> AuthTag -> Bool
    == (AuthTag Bytes
    b) = Bytes -> Bytes -> Bool
    forall bs1 bs2.
    (ByteArrayAccess bs1, ByteArrayAccess bs2) =>
    bs1 -> bs2 -> Bool
    B.constEq Bytes
    a Bytes
    b

    data CCM_M = CCM_M4 | CCM_M6 | CCM_M8 | CCM_M10 | CCM_M12 | CCM_M14 | CCM_M16 deriving (Int -> CCM_M -> ShowS
    [CCM_M] -> ShowS
    CCM_M -> String
    (Int -> CCM_M -> ShowS)
    -> (CCM_M -> String) -> ([CCM_M] -> ShowS) -> Show CCM_M
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CCM_M -> ShowS
    showsPrec :: Int -> CCM_M -> ShowS
    $cshow :: CCM_M -> String
    show :: CCM_M -> String
    $cshowList :: [CCM_M] -> ShowS
    showList :: [CCM_M] -> ShowS
    Show, CCM_M -> CCM_M -> Bool
    (CCM_M -> CCM_M -> Bool) -> (CCM_M -> CCM_M -> Bool) -> Eq CCM_M
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CCM_M -> CCM_M -> Bool
    == :: CCM_M -> CCM_M -> Bool
    $c/= :: CCM_M -> CCM_M -> Bool
    /= :: CCM_M -> CCM_M -> Bool
    Eq)
    data CCM_L = CCM_L2 | CCM_L3 | CCM_L4 deriving (Int -> CCM_L -> ShowS
    [CCM_L] -> ShowS
    CCM_L -> String
    (Int -> CCM_L -> ShowS)
    -> (CCM_L -> String) -> ([CCM_L] -> ShowS) -> Show CCM_L
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CCM_L -> ShowS
    showsPrec :: Int -> CCM_L -> ShowS
    $cshow :: CCM_L -> String
    show :: CCM_L -> String
    $cshowList :: [CCM_L] -> ShowS
    showList :: [CCM_L] -> ShowS
    Show, CCM_L -> CCM_L -> Bool
    (CCM_L -> CCM_L -> Bool) -> (CCM_L -> CCM_L -> Bool) -> Eq CCM_L
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CCM_L -> CCM_L -> Bool
    == :: CCM_L -> CCM_L -> Bool
    $c/= :: CCM_L -> CCM_L -> Bool
    /= :: CCM_L -> CCM_L -> Bool
    Eq)

    -- | AEAD Mode
    data AEADMode =
          AEAD_OCB -- OCB3
        | AEAD_CCM Int CCM_M CCM_L
        | AEAD_EAX
        | AEAD_CWC
        | AEAD_GCM
        deriving (Int -> AEADMode -> ShowS
    [AEADMode] -> ShowS
    AEADMode -> String
    (Int -> AEADMode -> ShowS)
    -> (AEADMode -> String) -> ([AEADMode] -> ShowS) -> Show AEADMode
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AEADMode -> ShowS
    showsPrec :: Int -> AEADMode -> ShowS
    $cshow :: AEADMode -> String
    show :: AEADMode -> String
    $cshowList :: [AEADMode] -> ShowS
    showList :: [AEADMode] -> ShowS
    Show,AEADMode -> AEADMode -> Bool
    (AEADMode -> AEADMode -> Bool)
    -> (AEADMode -> AEADMode -> Bool) -> Eq AEADMode
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AEADMode -> AEADMode -> Bool
    == :: AEADMode -> AEADMode -> Bool
    $c/= :: AEADMode -> AEADMode -> Bool
    /= :: AEADMode -> AEADMode -> Bool
    Eq)

    -- | Symmetric cipher class.
    class Cipher cipher where
        -- | Initialize a cipher context from a key
        cipherInit    :: ByteArray key => key -> CryptoFailable cipher
        -- | Cipher name
        cipherName    :: cipher -> String
        -- | return the size of the key required for this cipher.
        -- Some cipher accept any size for key
        cipherKeySize :: cipher -> KeySizeSpecifier