    module Crypto.Cipher.Twofish
        ( Twofish128
        , Twofish192
        , Twofish256
        ) where

    import Crypto.Cipher.Twofish.Primitive
    import Crypto.Cipher.Types
    import Crypto.Cipher.Utils

    newtype Twofish128 = Twofish128 Twofish

    instance Cipher Twofish128 where
        cipherName :: Twofish128 -> String
    cipherName    _ = "Twofish128"
        cipherKeySize :: Twofish128 -> KeySizeSpecifier
    cipherKeySize _ = Int -> KeySizeSpecifier
    KeySizeFixed 16
        cipherInit :: key -> CryptoFailable Twofish128
    cipherInit key :: key
    key  = Twofish -> Twofish128
    Twofish128 (Twofish -> Twofish128)
    -> CryptoFailable Twofish -> CryptoFailable Twofish128
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (key -> CryptoFailable Twofish
    forall key. ByteArray key => key -> CryptoFailable Twofish
    initTwofish (key -> CryptoFailable Twofish)
    -> CryptoFailable key -> CryptoFailable Twofish
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Twofish128 -> key -> CryptoFailable key
    forall key cipher.
    (ByteArrayAccess key, Cipher cipher) =>
    cipher -> key -> CryptoFailable key
    validateKeySize (Twofish128
    forall a. HasCallStack => a
    undefined :: Twofish128) key
    key)

    instance BlockCipher Twofish128 where
        blockSize :: Twofish128 -> Int
    blockSize                 _ = 16
        ecbEncrypt :: Twofish128 -> ba -> ba
    ecbEncrypt (Twofish128 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    encrypt Twofish
    key
        ecbDecrypt :: Twofish128 -> ba -> ba
    ecbDecrypt (Twofish128 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    decrypt Twofish
    key

    newtype Twofish192 = Twofish192 Twofish

    instance Cipher Twofish192 where
        cipherName :: Twofish192 -> String
    cipherName    _ = "Twofish192"
        cipherKeySize :: Twofish192 -> KeySizeSpecifier
    cipherKeySize _ = Int -> KeySizeSpecifier
    KeySizeFixed 24
        cipherInit :: key -> CryptoFailable Twofish192
    cipherInit key :: key
    key  = Twofish -> Twofish192
    Twofish192 (Twofish -> Twofish192)
    -> CryptoFailable Twofish -> CryptoFailable Twofish192
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (key -> CryptoFailable Twofish
    forall key. ByteArray key => key -> CryptoFailable Twofish
    initTwofish (key -> CryptoFailable Twofish)
    -> CryptoFailable key -> CryptoFailable Twofish
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Twofish192 -> key -> CryptoFailable key
    forall key cipher.
    (ByteArrayAccess key, Cipher cipher) =>
    cipher -> key -> CryptoFailable key
    validateKeySize (Twofish192
    forall a. HasCallStack => a
    undefined :: Twofish192) key
    key)

    instance BlockCipher Twofish192 where
        blockSize :: Twofish192 -> Int
    blockSize                 _ = 16
        ecbEncrypt :: Twofish192 -> ba -> ba
    ecbEncrypt (Twofish192 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    encrypt Twofish
    key
        ecbDecrypt :: Twofish192 -> ba -> ba
    ecbDecrypt (Twofish192 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    decrypt Twofish
    key

    newtype Twofish256 = Twofish256 Twofish

    instance Cipher Twofish256 where
        cipherName :: Twofish256 -> String
    cipherName    _ = "Twofish256"
        cipherKeySize :: Twofish256 -> KeySizeSpecifier
    cipherKeySize _ = Int -> KeySizeSpecifier
    KeySizeFixed 32
        cipherInit :: key -> CryptoFailable Twofish256
    cipherInit key :: key
    key  = Twofish -> Twofish256
    Twofish256 (Twofish -> Twofish256)
    -> CryptoFailable Twofish -> CryptoFailable Twofish256
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (key -> CryptoFailable Twofish
    forall key. ByteArray key => key -> CryptoFailable Twofish
    initTwofish (key -> CryptoFailable Twofish)
    -> CryptoFailable key -> CryptoFailable Twofish
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Twofish256 -> key -> CryptoFailable key
    forall key cipher.
    (ByteArrayAccess key, Cipher cipher) =>
    cipher -> key -> CryptoFailable key
    validateKeySize (Twofish256
    forall a. HasCallStack => a
    undefined :: Twofish256) key
    key)

    instance BlockCipher Twofish256 where
        blockSize :: Twofish256 -> Int
    blockSize                 _ = 16
        ecbEncrypt :: Twofish256 -> ba -> ba
    ecbEncrypt (Twofish256 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    encrypt Twofish
    key
        ecbDecrypt :: Twofish256 -> ba -> ba
    ecbDecrypt (Twofish256 key :: Twofish
    key) = Twofish -> ba -> ba
    forall ba. ByteArray ba => Twofish -> ba -> ba
    decrypt Twofish
    key