    {-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Crypto.Nettle.Ciphers
    -- Copyright   :  (c) 2013 Stefan Bühler
    -- License     :  MIT-style (see the file COPYING)
    --
    -- Maintainer  :  stbuehler@web.de
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- This module exports ciphers supported by nettle:
    --   <http://www.lysator.liu.se/~nisse/nettle/>
    --
    -----------------------------------------------------------------------------

    module Crypto.Nettle.Ciphers (
    	-- * Block ciphers
    	-- | Only block ciphers with a 128-bit 'blockSize' (16 bytes) support the XTS cipher mode.
    	--
    	--  For 'aeadInit' only 'AEAD_GCM' and 'AEAD_CCM' (with 'ccmInitTLS') is supported, and only if the the 'blockSize' is 16 bytes.
    	--  In all other cases 'aeadInit' just returns 'Nothing'.

    	-- ** AES
    	  AES
    	, AES128
    	, AES192
    	, AES256
    	-- ** ARCTWO
    	, ARCTWO
    	, arctwoInitEKB
    	, arctwoInitGutmann
    	-- ** BLOWFISH
    	, BLOWFISH
    	-- ** Camellia
    	, Camellia
    	, Camellia128
    	, Camellia192
    	, Camellia256
    	-- ** CAST-128
    	, CAST128
    	-- ** DES
    	, DES
    	-- ** DES3 (EDE)
    	, DES_EDE3
    	-- ** TWOFISH
    	, TWOFISH
    	-- ** SERPENT
    	, SERPENT
    	-- * Stream ciphers
    	-- ** Nonce ciphers
    	, StreamNonceCipher(..)
    	, streamSetNonceWord64
    	-- ** ARCFOUR
    	, ARCFOUR
    	-- ** ChaCha
    	, CHACHA
    	-- ** Salsa20
    	, SALSA20
    	, ESTREAM_SALSA20
    	) where

    import Crypto.Cipher.Types
    import Crypto.Nettle.CCM

    import Data.SecureMem
    import qualified Data.ByteString as B
    import Data.Word (Word64)
    import Data.Bits
    import Data.Tagged

    import Crypto.Nettle.Ciphers.Internal
    import Crypto.Nettle.Ciphers.ForeignImports
    import Nettle.Utils

    -- internal functions are not camelCase on purpose
    {-# ANN module "HLint: ignore Use camelCase" #-}

    #define INSTANCE_CIPHER(Typ) \
    instance Cipher Typ where \
    	{ cipherInit = nettle_cipherInit \
    	; cipherName = witness nc_cipherName \
    	; cipherKeySize = witness nc_cipherKeySize \
    	}
    #define INSTANCE_BLOCKCIPHER(Typ) \
    INSTANCE_CIPHER(Typ); \
    instance BlockCipher Typ where \
    	{ blockSize = witness nbc_blockSize \
    	; ecbEncrypt = nettle_ecbEncrypt \
    	; ecbDecrypt = nettle_ecbDecrypt \
    	; cbcEncrypt = nettle_cbcEncrypt \
    	; cbcDecrypt = nettle_cbcDecrypt \
    	; cfbEncrypt = nettle_cfbEncrypt \
    	; cfbDecrypt = nettle_cfbDecrypt \
    	; ctrCombine = nettle_ctrCombine \
    	; aeadInit AEAD_GCM = nettle_gcm_aeadInit \
    	; aeadInit AEAD_CCM = ccmInitTLS \
    	; aeadInit _        = \_ _ -> Nothing \
    	} ; \
    instance AEADModeImpl Typ NettleGCM where \
    	{ aeadStateAppendHeader = nettle_gcm_aeadStateAppendHeader \
    	; aeadStateEncrypt      = nettle_gcm_aeadStateEncrypt \
    	; aeadStateDecrypt      = nettle_gcm_aeadStateDecrypt \
    	; aeadStateFinalize     = nettle_gcm_aeadStateFinalize \
    	}
    #define INSTANCE_STREAMCIPHER(Typ) \
    INSTANCE_CIPHER(Typ); \
    instance StreamCipher Typ where \
    	{ streamCombine = nettle_streamCombine \
    	}
    #define INSTANCE_STREAMNONCECIPHER(Typ) \
    INSTANCE_STREAMCIPHER(Typ); \
    instance StreamNonceCipher Typ where \
    	{ streamSetNonce = nettle_streamSetNonce \
    	; streamNonceSize = witness nsc_nonceSize \
    	}
    #define INSTANCE_BLOCKEDSTREAMCIPHER(Typ) \
    INSTANCE_CIPHER(Typ); \
    instance StreamCipher Typ where \
    	{ streamCombine = nettle_blockedStreamCombine \
    	}
    #define INSTANCE_BLOCKEDSTREAMNONCECIPHER(Typ) \
    INSTANCE_BLOCKEDSTREAMCIPHER(Typ); \
    instance StreamNonceCipher Typ where \
    	{ streamSetNonce = nettle_blockedStreamSetNonce \
    	; streamNonceSize = witness nbsc_nonceSize \
    	}

    {-|
    'AES' is the generic cipher context for the AES cipher, supporting key sizes
    of 128, 196 and 256 bits (16, 24 and 32 bytes). The 'blockSize' is always 128 bits (16 bytes).

    'aeadInit' only supports the 'AEAD_GCM' mode for now.
    -}
    newtype AES = AES SecureMem
    instance NettleCipher AES where
    	nc_cipherInit :: Tagged AES (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged AES (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_hs_aes_init
    	nc_cipherName :: Tagged AES String
    nc_cipherName    = String -> Tagged AES String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "AES"
    	nc_cipherKeySize :: Tagged AES KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged AES KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged AES KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged AES KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    24,Int
    32]
    	nc_ctx_size :: Tagged AES Int
    nc_ctx_size      = Int -> Tagged AES Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_aes_ctx_size
    	nc_ctx :: AES -> SecureMem
    nc_ctx   (AES SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> AES
    nc_Ctx           = SecureMem -> AES
    AES
    instance NettleBlockCipher AES where
    	nbc_blockSize :: Tagged AES Int
    nbc_blockSize          = Int -> Tagged AES Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_ecb_encrypt :: Tagged AES NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged AES NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_hs_aes_encrypt
    	nbc_ecb_decrypt :: Tagged AES NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged AES NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_hs_aes_decrypt
    	nbc_fun_encrypt :: Tagged AES (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged AES (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_hs_aes_encrypt
    	nbc_fun_decrypt :: Tagged AES (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged AES (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_hs_aes_decrypt

    INSTANCE_BLOCKCIPHER(AES)

    {-|
    'AES128' provides the same interface as 'AES', but is restricted to 128-bit keys.
    -}
    newtype AES128 = AES128 SecureMem
    instance NettleCipher AES128 where
    	nc_cipherInit :: Tagged AES128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged AES128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_aes128_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged AES128 String
    nc_cipherName    = String -> Tagged AES128 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "AES-128"
    	nc_cipherKeySize :: Tagged AES128 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged AES128 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged AES128 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged AES128 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    16
    	nc_ctx_size :: Tagged AES128 Int
    nc_ctx_size      = Int -> Tagged AES128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_aes128_ctx_size
    	nc_ctx :: AES128 -> SecureMem
    nc_ctx (AES128 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> AES128
    nc_Ctx            = SecureMem -> AES128
    AES128
    instance NettleBlockCipher AES128 where
    	nbc_blockSize :: Tagged AES128 Int
    nbc_blockSize          = Int -> Tagged AES128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged AES128 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES128 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes128_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged AES128 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES128 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes128_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged AES128 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged AES128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes128_encrypt
    	nbc_ecb_decrypt :: Tagged AES128 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged AES128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes128_decrypt
    	nbc_fun_encrypt :: Tagged AES128 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged AES128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes128_encrypt
    	nbc_fun_decrypt :: Tagged AES128 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged AES128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes128_decrypt

    INSTANCE_BLOCKCIPHER(AES128)

    {-|
    'AES192' provides the same interface as 'AES', but is restricted to 192-bit keys.
    -}
    newtype AES192 = AES192 SecureMem
    instance NettleCipher AES192 where
    	nc_cipherInit :: Tagged AES192 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged AES192 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_aes192_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged AES192 String
    nc_cipherName    = String -> Tagged AES192 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "AES-192"
    	nc_cipherKeySize :: Tagged AES192 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged AES192 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged AES192 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged AES192 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    24
    	nc_ctx_size :: Tagged AES192 Int
    nc_ctx_size      = Int -> Tagged AES192 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_aes192_ctx_size
    	nc_ctx :: AES192 -> SecureMem
    nc_ctx  (AES192 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> AES192
    nc_Ctx             = SecureMem -> AES192
    AES192
    instance NettleBlockCipher AES192 where
    	nbc_blockSize :: Tagged AES192 Int
    nbc_blockSize          = Int -> Tagged AES192 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged AES192 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES192 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes192_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged AES192 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES192 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes192_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged AES192 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged AES192 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes192_encrypt
    	nbc_ecb_decrypt :: Tagged AES192 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged AES192 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes192_decrypt
    	nbc_fun_encrypt :: Tagged AES192 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged AES192 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes192_encrypt
    	nbc_fun_decrypt :: Tagged AES192 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged AES192 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes192_decrypt

    INSTANCE_BLOCKCIPHER(AES192)

    {-|
    'AES256' provides the same interface as 'AES', but is restricted to 256-bit keys.
    -}
    newtype AES256 = AES256 SecureMem
    instance NettleCipher AES256 where
    	nc_cipherInit :: Tagged AES256 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged AES256 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_aes256_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged AES256 String
    nc_cipherName    = String -> Tagged AES256 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "AES-256"
    	nc_cipherKeySize :: Tagged AES256 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged AES256 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged AES256 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged AES256 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    32
    	nc_ctx_size :: Tagged AES256 Int
    nc_ctx_size      = Int -> Tagged AES256 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_aes256_ctx_size
    	nc_ctx :: AES256 -> SecureMem
    nc_ctx  (AES256 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> AES256
    nc_Ctx             = SecureMem -> AES256
    AES256
    instance NettleBlockCipher AES256 where
    	nbc_blockSize :: Tagged AES256 Int
    nbc_blockSize          = Int -> Tagged AES256 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged AES256 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES256 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes256_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged AES256 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged AES256 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_aes256_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged AES256 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged AES256 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes256_encrypt
    	nbc_ecb_decrypt :: Tagged AES256 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged AES256 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_aes256_decrypt
    	nbc_fun_encrypt :: Tagged AES256 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged AES256 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes256_encrypt
    	nbc_fun_decrypt :: Tagged AES256 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged AES256 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_aes256_decrypt

    INSTANCE_BLOCKCIPHER(AES256)

    {-|
    'ARCTWO' (also known as the trade marked name RC2) is a block cipher specified in RFC 2268.

    The default 'cipherInit' uses @ekb = bit-length of the key@; 'arctwoInitEKB' allows to specify ekb manually.
    'arctwoInitGutmann' uses @ekb = 1024@ (the maximum).

    'ARCTWO' uses keysizes from 1 to 128 bytes, and uses a 'blockSize' of 64 bits (8 bytes).
    -}
    newtype ARCTWO = ARCTWO SecureMem
    instance NettleCipher ARCTWO where
    	nc_cipherInit :: Tagged ARCTWO (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged ARCTWO (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_arctwo_set_key
    	nc_cipherName :: Tagged ARCTWO String
    nc_cipherName    = String -> Tagged ARCTWO String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "ARCTWO"
    	nc_cipherKeySize :: Tagged ARCTWO KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged ARCTWO KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged ARCTWO KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged ARCTWO KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> KeySizeSpecifier
    KeySizeRange Int
    1 Int
    128
    	nc_ctx_size :: Tagged ARCTWO Int
    nc_ctx_size      = Int -> Tagged ARCTWO Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_arctwo_ctx_size
    	nc_ctx :: ARCTWO -> SecureMem
    nc_ctx  (ARCTWO SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> ARCTWO
    nc_Ctx             = SecureMem -> ARCTWO
    ARCTWO
    instance NettleBlockCipher ARCTWO where
    	nbc_blockSize :: Tagged ARCTWO Int
    nbc_blockSize          = Int -> Tagged ARCTWO Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    8
    	nbc_ecb_encrypt :: Tagged ARCTWO NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged ARCTWO NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_arctwo_encrypt
    	nbc_ecb_decrypt :: Tagged ARCTWO NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged ARCTWO NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_arctwo_decrypt
    	nbc_fun_encrypt :: Tagged ARCTWO (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged ARCTWO (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_arctwo_encrypt
    	nbc_fun_decrypt :: Tagged ARCTWO (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged ARCTWO (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_arctwo_decrypt
    INSTANCE_BLOCKCIPHER(ARCTWO)
    {-|
    Initialize cipher with an explicit @ekb@ value (valid values from 1 to 1024, 0 meaning the same as 1024).
    -}
    arctwoInitEKB :: Key ARCTWO -> Word -> ARCTWO
    arctwoInitEKB :: Key ARCTWO -> Word -> ARCTWO
    arctwoInitEKB Key ARCTWO
    k Word
    ekb = (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key ARCTWO -> ARCTWO
    forall c.
    NettleCipher c =>
    (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key c -> c
    nettle_cipherInit' Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    initfun Key ARCTWO
    k where
    	initfun :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    initfun Ptr Word8
    ctxptr Word
    ksize Ptr Word8
    ptr = Ptr Word8 -> Word -> Ptr Word8 -> Word -> IO ()
    c_arctwo_set_key_ekb Ptr Word8
    ctxptr Word
    ksize Ptr Word8
    ptr Word
    ekb
    {-|
    Initialize cipher with @ekb = 1024@.
    -}
    arctwoInitGutmann :: Key ARCTWO -> ARCTWO
    arctwoInitGutmann :: Key ARCTWO -> ARCTWO
    arctwoInitGutmann = (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key ARCTWO -> ARCTWO
    forall c.
    NettleCipher c =>
    (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key c -> c
    nettle_cipherInit' Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_arctwo_set_key_gutmann

    {-|
    'BLOWFISH' is a block cipher designed by Bruce Schneier.
    It uses a 'blockSize' of 64 bits (8 bytes), and a variable key size from 64 to 448 bits (8 to 56 bytes).
    -}
    newtype BLOWFISH = BLOWFISH SecureMem
    instance NettleCipher BLOWFISH where
    	nc_cipherInit :: Tagged BLOWFISH (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged BLOWFISH (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_blowfish_set_key
    	nc_cipherName :: Tagged BLOWFISH String
    nc_cipherName    = String -> Tagged BLOWFISH String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "BLOWFISH"
    	nc_cipherKeySize :: Tagged BLOWFISH KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged BLOWFISH KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged BLOWFISH KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged BLOWFISH KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> KeySizeSpecifier
    KeySizeRange Int
    1 Int
    128
    	nc_ctx_size :: Tagged BLOWFISH Int
    nc_ctx_size      = Int -> Tagged BLOWFISH Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_blowfish_ctx_size
    	nc_ctx :: BLOWFISH -> SecureMem
    nc_ctx  (BLOWFISH SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> BLOWFISH
    nc_Ctx             = SecureMem -> BLOWFISH
    BLOWFISH
    instance NettleBlockCipher BLOWFISH where
    	nbc_blockSize :: Tagged BLOWFISH Int
    nbc_blockSize          = Int -> Tagged BLOWFISH Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    8
    	nbc_ecb_encrypt :: Tagged BLOWFISH NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged BLOWFISH NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_blowfish_encrypt
    	nbc_ecb_decrypt :: Tagged BLOWFISH NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged BLOWFISH NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_blowfish_decrypt
    	nbc_fun_encrypt :: Tagged BLOWFISH (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged BLOWFISH (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_blowfish_encrypt
    	nbc_fun_decrypt :: Tagged BLOWFISH (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged BLOWFISH (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_blowfish_decrypt
    INSTANCE_BLOCKCIPHER(BLOWFISH)

    {-|
    Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph and Telephone Corporation,
    described in RFC3713, and recommended by some Japanese and European authorities as an alternative to AES.
    The algorithm is patented (details see <http://www.lysator.liu.se/~nisse/nettle/nettle.html>).

    Camellia uses a the same 'blockSize' and key sizes as 'AES'.

    'aeadInit' only supports the 'AEAD_GCM' mode for now.
    -}
    newtype Camellia = Camellia SecureMem
    instance NettleCipher Camellia where
    	nc_cipherInit :: Tagged Camellia (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged Camellia (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_hs_camellia_init
    	nc_cipherName :: Tagged Camellia String
    nc_cipherName    = String -> Tagged Camellia String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "Camellia"
    	nc_cipherKeySize :: Tagged Camellia KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged Camellia KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged Camellia KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged Camellia KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    24,Int
    32]
    	nc_ctx_size :: Tagged Camellia Int
    nc_ctx_size      = Int -> Tagged Camellia Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_camellia_ctx_size
    	nc_ctx :: Camellia -> SecureMem
    nc_ctx     (Camellia SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> Camellia
    nc_Ctx             = SecureMem -> Camellia
    Camellia
    instance NettleBlockCipher Camellia where
    	nbc_blockSize :: Tagged Camellia Int
    nbc_blockSize          = Int -> Tagged Camellia Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_ecb_encrypt :: Tagged Camellia NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged Camellia NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_hs_camellia_encrypt
    	nbc_ecb_decrypt :: Tagged Camellia NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged Camellia NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_hs_camellia_decrypt
    	nbc_fun_encrypt :: Tagged Camellia (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged Camellia (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_hs_camellia_encrypt
    	nbc_fun_decrypt :: Tagged Camellia (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged Camellia (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_hs_camellia_decrypt

    INSTANCE_BLOCKCIPHER(Camellia)

    {-|
    'Camellia128' provides the same interface as 'Camellia', but is restricted to 128-bit keys.
    -}
    newtype Camellia128 = Camellia128 SecureMem
    instance NettleCipher Camellia128 where
    	nc_cipherInit :: Tagged Camellia128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged Camellia128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_camellia128_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged Camellia128 String
    nc_cipherName    = String -> Tagged Camellia128 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "Camellia-128"
    	nc_cipherKeySize :: Tagged Camellia128 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged Camellia128 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged Camellia128 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged Camellia128 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    16
    	nc_ctx_size :: Tagged Camellia128 Int
    nc_ctx_size      = Int -> Tagged Camellia128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_camellia128_ctx_size
    	nc_ctx :: Camellia128 -> SecureMem
    nc_ctx  (Camellia128 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> Camellia128
    nc_Ctx             = SecureMem -> Camellia128
    Camellia128
    instance NettleBlockCipher Camellia128 where
    	nbc_blockSize :: Tagged Camellia128 Int
    nbc_blockSize          = Int -> Tagged Camellia128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged Camellia128 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia128 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia128_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged Camellia128 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia128 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia128_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged Camellia128 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged Camellia128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia128_crypt
    	nbc_ecb_decrypt :: Tagged Camellia128 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged Camellia128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia128_crypt
    	nbc_fun_encrypt :: Tagged Camellia128 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia128_crypt
    	nbc_fun_decrypt :: Tagged Camellia128 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia128_crypt

    INSTANCE_BLOCKCIPHER(Camellia128)

    {-|
    'Camellia192' provides the same interface as 'Camellia', but is restricted to 192-bit keys.
    -}
    newtype Camellia192 = Camellia192 SecureMem
    instance NettleCipher Camellia192 where
    	nc_cipherInit :: Tagged Camellia192 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged Camellia192 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_camellia192_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged Camellia192 String
    nc_cipherName    = String -> Tagged Camellia192 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "Camellia-192"
    	nc_cipherKeySize :: Tagged Camellia192 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged Camellia192 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged Camellia192 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged Camellia192 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    24
    	nc_ctx_size :: Tagged Camellia192 Int
    nc_ctx_size      = Int -> Tagged Camellia192 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_camellia192_ctx_size
    	nc_ctx :: Camellia192 -> SecureMem
    nc_ctx  (Camellia192 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> Camellia192
    nc_Ctx             = SecureMem -> Camellia192
    Camellia192
    instance NettleBlockCipher Camellia192 where
    	nbc_blockSize :: Tagged Camellia192 Int
    nbc_blockSize          = Int -> Tagged Camellia192 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged Camellia192 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia192 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia192_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged Camellia192 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia192 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia192_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged Camellia192 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged Camellia192 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia192_crypt
    	nbc_ecb_decrypt :: Tagged Camellia192 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged Camellia192 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia192_crypt
    	nbc_fun_encrypt :: Tagged Camellia192 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia192 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia192_crypt
    	nbc_fun_decrypt :: Tagged Camellia192 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia192 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia192_crypt

    INSTANCE_BLOCKCIPHER(Camellia192)

    {-|
    'Camellia256' provides the same interface as 'Camellia', but is restricted to 256-bit keys.
    -}
    newtype Camellia256 = Camellia256 SecureMem
    instance NettleCipher Camellia256 where
    	nc_cipherInit :: Tagged Camellia256 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged Camellia256 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (\Ptr Word8
    ctx Word
    _ Ptr Word8
    key -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_hs_camellia256_init Ptr Word8
    ctx Ptr Word8
    key)
    	nc_cipherName :: Tagged Camellia256 String
    nc_cipherName    = String -> Tagged Camellia256 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "Camellia-256"
    	nc_cipherKeySize :: Tagged Camellia256 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged Camellia256 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged Camellia256 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged Camellia256 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    32
    	nc_ctx_size :: Tagged Camellia256 Int
    nc_ctx_size      = Int -> Tagged Camellia256 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_hs_camellia256_ctx_size
    	nc_ctx :: Camellia256 -> SecureMem
    nc_ctx  (Camellia256 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> Camellia256
    nc_Ctx             = SecureMem -> Camellia256
    Camellia256
    instance NettleBlockCipher Camellia256 where
    	nbc_blockSize :: Tagged Camellia256 Int
    nbc_blockSize          = Int -> Tagged Camellia256 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_encrypt_ctx_offset :: Tagged Camellia256 (Ptr Word8 -> Ptr Word8)
    nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia256 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia256_ctx_encrypt
    	nbc_decrypt_ctx_offset :: Tagged Camellia256 (Ptr Word8 -> Ptr Word8)
    nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8)
    -> Tagged Camellia256 (Ptr Word8 -> Ptr Word8)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8
    c_hs_camellia256_ctx_decrypt
    	nbc_ecb_encrypt :: Tagged Camellia256 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged Camellia256 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia256_crypt
    	nbc_ecb_decrypt :: Tagged Camellia256 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged Camellia256 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_camellia256_crypt
    	nbc_fun_encrypt :: Tagged Camellia256 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia256 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia256_crypt
    	nbc_fun_decrypt :: Tagged Camellia256 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc
    -> Tagged Camellia256 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_camellia256_crypt

    INSTANCE_BLOCKCIPHER(Camellia256)

    {-|
    'CAST128' is a block cipher specified in RFC 2144. It uses a 64 bit (8 bytes) 'blockSize',
    and a variable key size of 40 up to 128 bits (5 to 16 bytes).
    -}
    newtype CAST128 = CAST128 SecureMem
    instance NettleCipher CAST128 where
    	nc_cipherInit :: Tagged CAST128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged CAST128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_cast5_set_key
    	nc_cipherName :: Tagged CAST128 String
    nc_cipherName    = String -> Tagged CAST128 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "CAST-128"
    	nc_cipherKeySize :: Tagged CAST128 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged CAST128 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged CAST128 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged CAST128 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> KeySizeSpecifier
    KeySizeRange Int
    5 Int
    16
    	nc_ctx_size :: Tagged CAST128 Int
    nc_ctx_size      = Int -> Tagged CAST128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_cast128_ctx_size
    	nc_ctx :: CAST128 -> SecureMem
    nc_ctx  (CAST128 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> CAST128
    nc_Ctx             = SecureMem -> CAST128
    CAST128
    instance NettleBlockCipher CAST128 where
    	nbc_blockSize :: Tagged CAST128 Int
    nbc_blockSize          = Int -> Tagged CAST128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    8
    	nbc_ecb_encrypt :: Tagged CAST128 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged CAST128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_cast128_encrypt
    	nbc_ecb_decrypt :: Tagged CAST128 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged CAST128 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_cast128_decrypt
    	nbc_fun_encrypt :: Tagged CAST128 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged CAST128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_cast128_encrypt
    	nbc_fun_decrypt :: Tagged CAST128 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged CAST128 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_cast128_decrypt

    INSTANCE_BLOCKCIPHER(CAST128)

    {-|
    'DES' is the old Data Encryption Standard, specified by NIST.
    It uses a 'blockSize' of 64 bits (8 bytes), and a key size of 56 bits.

    The key is given as 8 bytes, as one bit per byte is used as a parity bit.
    The parity bit is ignored by this implementation.
    -}
    newtype DES = DES SecureMem
    instance NettleCipher DES where
    	nc_cipherInit :: Tagged DES (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged DES (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged ((Ptr Word8 -> Word -> Ptr Word8 -> IO ())
     -> Tagged DES (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    -> (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged DES (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    ctxptr Word
    _ -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_des_set_key Ptr Word8
    ctxptr
    	nc_cipherName :: Tagged DES String
    nc_cipherName    = String -> Tagged DES String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "DES"
    	nc_cipherKeySize :: Tagged DES KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged DES KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged DES KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged DES KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    8
    	nc_ctx_size :: Tagged DES Int
    nc_ctx_size      = Int -> Tagged DES Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_des_ctx_size
    	nc_ctx :: DES -> SecureMem
    nc_ctx  (DES SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> DES
    nc_Ctx             = SecureMem -> DES
    DES
    instance NettleBlockCipher DES where
    	nbc_blockSize :: Tagged DES Int
    nbc_blockSize          = Int -> Tagged DES Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    8
    	nbc_ecb_encrypt :: Tagged DES NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged DES NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_des_encrypt
    	nbc_ecb_decrypt :: Tagged DES NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged DES NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_des_decrypt
    	nbc_fun_encrypt :: Tagged DES (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged DES (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_des_encrypt
    	nbc_fun_decrypt :: Tagged DES (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged DES (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_des_decrypt

    INSTANCE_BLOCKCIPHER(DES)

    {-|
    'DES_EDE3' uses 3 'DES' keys @k1 || k2 || k3@.
    Encryption first encrypts with k1, then decrypts with k2, then encrypts with k3.

    The 'blockSize' is the same as for 'DES': 64 bits (8 bytes),
    and the keys are simply concatenated, forming a 24 byte key string (with 168 bits actually getting used).
    -}
    newtype DES_EDE3 = DES_EDE3 SecureMem
    instance NettleCipher DES_EDE3 where
    	nc_cipherInit :: Tagged DES_EDE3 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged DES_EDE3 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged ((Ptr Word8 -> Word -> Ptr Word8 -> IO ())
     -> Tagged DES_EDE3 (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    -> (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged DES_EDE3 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    ctxptr Word
    _ -> Ptr Word8 -> Ptr Word8 -> IO ()
    c_des3_set_key Ptr Word8
    ctxptr
    	nc_cipherName :: Tagged DES_EDE3 String
    nc_cipherName    = String -> Tagged DES_EDE3 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "DES-EDE3"
    	nc_cipherKeySize :: Tagged DES_EDE3 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged DES_EDE3 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged DES_EDE3 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged DES_EDE3 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    24
    	nc_ctx_size :: Tagged DES_EDE3 Int
    nc_ctx_size      = Int -> Tagged DES_EDE3 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_des3_ctx_size
    	nc_ctx :: DES_EDE3 -> SecureMem
    nc_ctx  (DES_EDE3 SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> DES_EDE3
    nc_Ctx             = SecureMem -> DES_EDE3
    DES_EDE3
    instance NettleBlockCipher DES_EDE3 where
    	nbc_blockSize :: Tagged DES_EDE3 Int
    nbc_blockSize          = Int -> Tagged DES_EDE3 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    8
    	nbc_ecb_encrypt :: Tagged DES_EDE3 NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged DES_EDE3 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_des3_encrypt
    	nbc_ecb_decrypt :: Tagged DES_EDE3 NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged DES_EDE3 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_des3_decrypt
    	nbc_fun_encrypt :: Tagged DES_EDE3 (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged DES_EDE3 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_des3_encrypt
    	nbc_fun_decrypt :: Tagged DES_EDE3 (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged DES_EDE3 (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_des3_decrypt

    INSTANCE_BLOCKCIPHER(DES_EDE3)

    {-|
    'SERPENT' is one of the AES finalists, designed by Ross Anderson, Eli Biham and Lars Knudsen.

    The 'blockSize' is 128 bits (16 bytes), and the valid key sizes are from 128 bits to 256 bits (16 to 32 bytes),
    although smaller bits are just padded with zeroes.

    'aeadInit' only supports the 'AEAD_GCM' mode for now.
    -}
    newtype SERPENT = SERPENT SecureMem
    instance NettleCipher SERPENT where
    	nc_cipherInit :: Tagged SERPENT (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged SERPENT (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_serpent_set_key
    	nc_cipherName :: Tagged SERPENT String
    nc_cipherName    = String -> Tagged SERPENT String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "SERPENT"
    	nc_cipherKeySize :: Tagged SERPENT KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged SERPENT KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged SERPENT KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged SERPENT KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> KeySizeSpecifier
    KeySizeRange Int
    16 Int
    32
    	nc_ctx_size :: Tagged SERPENT Int
    nc_ctx_size      = Int -> Tagged SERPENT Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_serpent_ctx_size
    	nc_ctx :: SERPENT -> SecureMem
    nc_ctx  (SERPENT SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> SERPENT
    nc_Ctx             = SecureMem -> SERPENT
    SERPENT
    instance NettleBlockCipher SERPENT where
    	nbc_blockSize :: Tagged SERPENT Int
    nbc_blockSize          = Int -> Tagged SERPENT Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_ecb_encrypt :: Tagged SERPENT NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged SERPENT NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_serpent_encrypt
    	nbc_ecb_decrypt :: Tagged SERPENT NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged SERPENT NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_serpent_decrypt
    	nbc_fun_encrypt :: Tagged SERPENT (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged SERPENT (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_serpent_encrypt
    	nbc_fun_decrypt :: Tagged SERPENT (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged SERPENT (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_serpent_decrypt
    INSTANCE_BLOCKCIPHER(SERPENT)

    {-|
    'TWOFISH' is another AES finalist, designed by Bruce Schneier and others.

    'TWOFISH' uses a the same 'blockSize' and key sizes as 'AES'.

    'aeadInit' only supports the 'AEAD_GCM' mode for now.
    -}
    newtype TWOFISH = TWOFISH SecureMem
    instance NettleCipher TWOFISH where
    	nc_cipherInit :: Tagged TWOFISH (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged TWOFISH (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_twofish_set_key
    	nc_cipherName :: Tagged TWOFISH String
    nc_cipherName    = String -> Tagged TWOFISH String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "TWOFISH"
    	nc_cipherKeySize :: Tagged TWOFISH KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged TWOFISH KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged TWOFISH KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged TWOFISH KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    24,Int
    32]
    	nc_ctx_size :: Tagged TWOFISH Int
    nc_ctx_size      = Int -> Tagged TWOFISH Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_twofish_ctx_size
    	nc_ctx :: TWOFISH -> SecureMem
    nc_ctx  (TWOFISH SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> TWOFISH
    nc_Ctx             = SecureMem -> TWOFISH
    TWOFISH
    instance NettleBlockCipher TWOFISH where
    	nbc_blockSize :: Tagged TWOFISH Int
    nbc_blockSize          = Int -> Tagged TWOFISH Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    16
    	nbc_ecb_encrypt :: Tagged TWOFISH NettleCryptFunc
    nbc_ecb_encrypt        = NettleCryptFunc -> Tagged TWOFISH NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_twofish_encrypt
    	nbc_ecb_decrypt :: Tagged TWOFISH NettleCryptFunc
    nbc_ecb_decrypt        = NettleCryptFunc -> Tagged TWOFISH NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_twofish_decrypt
    	nbc_fun_encrypt :: Tagged TWOFISH (FunPtr NettleCryptFunc)
    nbc_fun_encrypt        = FunPtr NettleCryptFunc -> Tagged TWOFISH (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_twofish_encrypt
    	nbc_fun_decrypt :: Tagged TWOFISH (FunPtr NettleCryptFunc)
    nbc_fun_decrypt        = FunPtr NettleCryptFunc -> Tagged TWOFISH (FunPtr NettleCryptFunc)
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged FunPtr NettleCryptFunc
    p_twofish_decrypt
    INSTANCE_BLOCKCIPHER(TWOFISH)

    {-|
    'ARCFOUR' is a stream cipher, also known under the trade marked name RC4.

    Valid key sizes are from 1 to 256 bytes.
    -}
    newtype ARCFOUR = ARCFOUR SecureMem
    instance NettleCipher ARCFOUR where
    	nc_cipherInit :: Tagged ARCFOUR (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged ARCFOUR (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_arcfour_set_key
    	nc_cipherName :: Tagged ARCFOUR String
    nc_cipherName    = String -> Tagged ARCFOUR String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "ARCFOUR"
    	nc_cipherKeySize :: Tagged ARCFOUR KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged ARCFOUR KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged ARCFOUR KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged ARCFOUR KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    24,Int
    32]
    	nc_ctx_size :: Tagged ARCFOUR Int
    nc_ctx_size      = Int -> Tagged ARCFOUR Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_arcfour_ctx_size
    	nc_ctx :: ARCFOUR -> SecureMem
    nc_ctx  (ARCFOUR SecureMem
    c) = SecureMem
    c
    	nc_Ctx :: SecureMem -> ARCFOUR
    nc_Ctx             = SecureMem -> ARCFOUR
    ARCFOUR
    instance NettleStreamCipher ARCFOUR where
    	nsc_streamCombine :: Tagged ARCFOUR NettleCryptFunc
    nsc_streamCombine = NettleCryptFunc -> Tagged ARCFOUR NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_arcfour_crypt
    INSTANCE_STREAMCIPHER(ARCFOUR)

    {-|
    'StreamNonceCipher' are special stream ciphers that can encrypt many messages with the same key;
    setting a nonce restarts the cipher.

    A good value for the nonce is a message/packet counter. Usually a nonce should not be reused with the same key.
    -}
    class StreamCipher cipher => StreamNonceCipher cipher where
    	streamNonceSize :: cipher -> KeySizeSpecifier
    	streamSetNonce  :: cipher -> B.ByteString -> Maybe cipher

    word64BE :: Word64 -> B.ByteString
    word64BE :: Word64 -> ByteString
    word64BE Word64
    value = [Word8] -> ByteString
    B.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Int -> [Word8] -> Word64 -> [Word8]
    forall {t} {t}.
    (Integral t, Num t, Bits t, Eq t) =>
    t -> [Word8] -> t -> [Word8]
    _work (Int
    8::Int) [] Word64
    value where
    	_work :: t -> [Word8] -> t -> [Word8]
    _work t
    0 [Word8]
    r t
    _ = [Word8]
    r
    	_work t
    n [Word8]
    r t
    v = let d :: t
    d = t
    v t -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    8; m :: Word8
    m = t -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral t
    v :: Word8 in t -> [Word8] -> t -> [Word8]
    _work (t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    -t
    1) (Word8
    mWord8 -> [Word8] -> [Word8]
    forall a. a -> [a] -> [a]
    :[Word8]
    r) t
    d

    {-|
    Sets a 'Word64' as 8-byte nonce (bigendian encoded)
    -}
    streamSetNonceWord64 :: StreamNonceCipher cipher => cipher -> Word64 -> Maybe cipher
    streamSetNonceWord64 :: forall cipher.
    StreamNonceCipher cipher =>
    cipher -> Word64 -> Maybe cipher
    streamSetNonceWord64 cipher
    c Word64
    nonce = cipher -> ByteString -> Maybe cipher
    forall cipher.
    StreamNonceCipher cipher =>
    cipher -> ByteString -> Maybe cipher
    streamSetNonce cipher
    c (ByteString -> Maybe cipher) -> ByteString -> Maybe cipher
    forall a b. (a -> b) -> a -> b
    $ Word64 -> ByteString
    word64BE Word64
    nonce

    -- set nonce to 0 on init
    wrap_chacha_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_key Ptr Word8
    ctxptr Word
    _ Ptr Word8
    keyptr = do
    	Ptr Word8 -> Ptr Word8 -> IO ()
    c_chacha_set_key Ptr Word8
    ctxptr Ptr Word8
    keyptr
    	ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr (Int -> Word8 -> ByteString
    B.replicate Int
    8 Word8
    0) ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    _ Ptr Word8
    nonceptr ->
    		Ptr Word8 -> Ptr Word8 -> IO ()
    c_chacha_set_nonce Ptr Word8
    ctxptr Ptr Word8
    nonceptr

    -- check nonce length
    wrap_chacha_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_nonce Ptr Word8
    ctxptr Word
    ivlen Ptr Word8
    ivptr = if Word
    ivlen Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word
    8 then Ptr Word8 -> Ptr Word8 -> IO ()
    c_chacha_set_nonce Ptr Word8
    ctxptr Ptr Word8
    ivptr else String -> IO ()
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Invalid nonce length"

    {-|
    'CHACHA' is a variant of the 'SALSA20' stream cipher, both designed by D. J. Bernstein.

    Key size is 256 bits (32 bytes).

    'CHACHA' works similar to 'SALSA20'; it could theoretically also support 128-bit keys, but there is no need for it as they share the same performance.

    ChaCha uses a blocksize of 64 bytes internally; if crpyted input isn't aligned to 64 bytes it will
    pad it with 0 and store the encrypted padding to xor with future input data.

    Each message also requires a 8-byte ('Word64') nonce (which is initialized to 0; you can use a message sequence number).
    Don't reuse a nonce with the same key.

    Setting a nonce also resets the remaining padding data.
    -}
    newtype CHACHA = CHACHA (SecureMem, B.ByteString)
    instance NettleCipher CHACHA where
    	nc_cipherInit :: Tagged CHACHA (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged CHACHA (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_key
    	nc_cipherName :: Tagged CHACHA String
    nc_cipherName    = String -> Tagged CHACHA String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "ChaCha"
    	nc_cipherKeySize :: Tagged CHACHA KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    32
    	nc_ctx_size :: Tagged CHACHA Int
    nc_ctx_size      = Int -> Tagged CHACHA Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_chacha_ctx_size
    	nc_ctx :: CHACHA -> SecureMem
    nc_ctx (CHACHA (SecureMem
    c, ByteString
    _)) = SecureMem
    c
    	nc_Ctx :: SecureMem -> CHACHA
    nc_Ctx SecureMem
    c           = (SecureMem, ByteString) -> CHACHA
    CHACHA (SecureMem
    c, ByteString
    B.empty)
    instance NettleBlockedStreamCipher CHACHA where
    	nbsc_blockSize :: Tagged CHACHA Int
    nbsc_blockSize     = Int -> Tagged CHACHA Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    64
    	nbsc_IncompleteState :: CHACHA -> ByteString -> CHACHA
    nbsc_IncompleteState (CHACHA (SecureMem
    c, ByteString
    _)) ByteString
    inc = (SecureMem, ByteString) -> CHACHA
    CHACHA (SecureMem
    c, ByteString
    inc)
    	nbsc_incompleteState :: CHACHA -> ByteString
    nbsc_incompleteState (CHACHA (SecureMem
    _, ByteString
    inc)) = ByteString
    inc
    	nbsc_streamCombine :: Tagged CHACHA NettleCryptFunc
    nbsc_streamCombine = NettleCryptFunc -> Tagged CHACHA NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_chacha_crypt
    	nbsc_nonceSize :: Tagged CHACHA KeySizeSpecifier
    nbsc_nonceSize     = KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged CHACHA KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    8
    	nbsc_setNonce :: Tagged CHACHA (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    nbsc_setNonce      = Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged CHACHA (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
     -> Tagged CHACHA (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())))
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged CHACHA (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall a b. (a -> b) -> a -> b
    $ (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall a. a -> Maybe a
    Just Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_chacha_set_nonce
    INSTANCE_BLOCKEDSTREAMNONCECIPHER(CHACHA)

    -- set nonce to 0 on init
    wrap_salsa20_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_key Ptr Word8
    ctxptr Word
    keylen Ptr Word8
    keyptr = do
    	Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_salsa20_set_key Ptr Word8
    ctxptr Word
    keylen Ptr Word8
    keyptr
    	ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr (Int -> Word8 -> ByteString
    B.replicate Int
    8 Word8
    0) ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    _ Ptr Word8
    nonceptr ->
    		Ptr Word8 -> Ptr Word8 -> IO ()
    c_salsa20_set_nonce Ptr Word8
    ctxptr Ptr Word8
    nonceptr

    -- check nonce length
    wrap_salsa20_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_nonce Ptr Word8
    ctxptr Word
    ivlen Ptr Word8
    ivptr = if Word
    ivlen Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word
    8 then Ptr Word8 -> Ptr Word8 -> IO ()
    c_salsa20_set_nonce Ptr Word8
    ctxptr Ptr Word8
    ivptr else String -> IO ()
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Invalid nonce length"

    {-|
    'SALSA20' is a fairly recent stream cipher designed by D. J. Bernstein.

    Valid key sizes are 128 and 256 bits (16 and 32 bytes).

    Salsa20 uses a blocksize of 64 bytes internally; if crpyted input isn't aligned to 64 bytes it will
    pad it with 0 and store the encrypted padding to xor with future input data.

    Each message also requires a 8-byte ('Word64') nonce (which is initialized to 0; you can use a message sequence number).
    Don't reuse a nonce with the same key.

    Setting a nonce also resets the remaining padding data.
    -}
    newtype SALSA20 = SALSA20 (SecureMem, B.ByteString)
    instance NettleCipher SALSA20 where
    	nc_cipherInit :: Tagged SALSA20 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged SALSA20 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_key
    	nc_cipherName :: Tagged SALSA20 String
    nc_cipherName    = String -> Tagged SALSA20 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "Salsa20"
    	nc_cipherKeySize :: Tagged SALSA20 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    32]
    	nc_ctx_size :: Tagged SALSA20 Int
    nc_ctx_size      = Int -> Tagged SALSA20 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_salsa20_ctx_size
    	nc_ctx :: SALSA20 -> SecureMem
    nc_ctx (SALSA20 (SecureMem
    c, ByteString
    _)) = SecureMem
    c
    	nc_Ctx :: SecureMem -> SALSA20
    nc_Ctx SecureMem
    c           = (SecureMem, ByteString) -> SALSA20
    SALSA20 (SecureMem
    c, ByteString
    B.empty)
    instance NettleBlockedStreamCipher SALSA20 where
    	nbsc_blockSize :: Tagged SALSA20 Int
    nbsc_blockSize     = Int -> Tagged SALSA20 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    64
    	nbsc_IncompleteState :: SALSA20 -> ByteString -> SALSA20
    nbsc_IncompleteState (SALSA20 (SecureMem
    c, ByteString
    _)) ByteString
    inc = (SecureMem, ByteString) -> SALSA20
    SALSA20 (SecureMem
    c, ByteString
    inc)
    	nbsc_incompleteState :: SALSA20 -> ByteString
    nbsc_incompleteState (SALSA20 (SecureMem
    _, ByteString
    inc)) = ByteString
    inc
    	nbsc_streamCombine :: Tagged SALSA20 NettleCryptFunc
    nbsc_streamCombine = NettleCryptFunc -> Tagged SALSA20 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_salsa20_crypt
    	nbsc_nonceSize :: Tagged SALSA20 KeySizeSpecifier
    nbsc_nonceSize     = KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged SALSA20 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    8
    	nbsc_setNonce :: Tagged SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    nbsc_setNonce      = Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
     -> Tagged
          SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())))
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall a b. (a -> b) -> a -> b
    $ (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall a. a -> Maybe a
    Just Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_nonce
    INSTANCE_BLOCKEDSTREAMNONCECIPHER(SALSA20)

    {-|
    'ESTREAM_SALSA20' is the same as 'SALSA20', but uses only 12 instead of 20 rounds in mixing.
    -}
    newtype ESTREAM_SALSA20 = ESTREAM_SALSA20 (SecureMem, B.ByteString)
    instance NettleCipher ESTREAM_SALSA20 where
    	nc_cipherInit :: Tagged ESTREAM_SALSA20 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nc_cipherInit    = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged ESTREAM_SALSA20 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_key
    	nc_cipherName :: Tagged ESTREAM_SALSA20 String
    nc_cipherName    = String -> Tagged ESTREAM_SALSA20 String
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged String
    "eSTREAM-Salsa20"
    	nc_cipherKeySize :: Tagged ESTREAM_SALSA20 KeySizeSpecifier
    nc_cipherKeySize = KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ [Int] -> KeySizeSpecifier
    KeySizeEnum [Int
    16,Int
    32]
    	nc_ctx_size :: Tagged ESTREAM_SALSA20 Int
    nc_ctx_size      = Int -> Tagged ESTREAM_SALSA20 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_salsa20_ctx_size
    	nc_ctx :: ESTREAM_SALSA20 -> SecureMem
    nc_ctx (ESTREAM_SALSA20 (SecureMem
    c, ByteString
    _)) = SecureMem
    c
    	nc_Ctx :: SecureMem -> ESTREAM_SALSA20
    nc_Ctx SecureMem
    c           = (SecureMem, ByteString) -> ESTREAM_SALSA20
    ESTREAM_SALSA20 (SecureMem
    c, ByteString
    B.empty)
    instance NettleBlockedStreamCipher ESTREAM_SALSA20 where
    	nbsc_blockSize :: Tagged ESTREAM_SALSA20 Int
    nbsc_blockSize     = Int -> Tagged ESTREAM_SALSA20 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    64
    	nbsc_IncompleteState :: ESTREAM_SALSA20 -> ByteString -> ESTREAM_SALSA20
    nbsc_IncompleteState (ESTREAM_SALSA20 (SecureMem
    c, ByteString
    _)) ByteString
    inc = (SecureMem, ByteString) -> ESTREAM_SALSA20
    ESTREAM_SALSA20 (SecureMem
    c, ByteString
    inc)
    	nbsc_incompleteState :: ESTREAM_SALSA20 -> ByteString
    nbsc_incompleteState (ESTREAM_SALSA20 (SecureMem
    _, ByteString
    inc)) = ByteString
    inc
    	nbsc_streamCombine :: Tagged ESTREAM_SALSA20 NettleCryptFunc
    nbsc_streamCombine = NettleCryptFunc -> Tagged ESTREAM_SALSA20 NettleCryptFunc
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged NettleCryptFunc
    c_salsa20r12_crypt
    	nbsc_nonceSize :: Tagged ESTREAM_SALSA20 KeySizeSpecifier
    nbsc_nonceSize     = KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier)
    -> KeySizeSpecifier -> Tagged ESTREAM_SALSA20 KeySizeSpecifier
    forall a b. (a -> b) -> a -> b
    $ Int -> KeySizeSpecifier
    KeySizeFixed Int
    8
    	nbsc_setNonce :: Tagged
      ESTREAM_SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    nbsc_setNonce      = Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged
         ESTREAM_SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
     -> Tagged
          ESTREAM_SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())))
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged
         ESTREAM_SALSA20 (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
    forall a b. (a -> b) -> a -> b
    $ (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall a. a -> Maybe a
    Just Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    wrap_salsa20_set_nonce
    INSTANCE_BLOCKEDSTREAMNONCECIPHER(ESTREAM_SALSA20)