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

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

newtype Twofish192 = Twofish192 Twofish

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

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

newtype Twofish256 = Twofish256 Twofish

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

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