-- |
-- Module      : Crypto.Cipher.DES
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : stable
-- Portability : good
--
-- DES, which is here because callers still meet it rather than because it
-- should be chosen: its 56-bit key is exhaustible.  Prefer "Crypto.Cipher.AES".
module Crypto.Cipher.DES (
    DES,
) where

import Crypto.Cipher.DES.Primitive
import Crypto.Cipher.Types
import Crypto.Error
import Crypto.Internal.ByteArray (ByteArrayAccess)
import qualified Crypto.Internal.ByteArray as B

-- | DES Context
data DES = DES Schedule Schedule
    deriving (DES -> DES -> Bool
(DES -> DES -> Bool) -> (DES -> DES -> Bool) -> Eq DES
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DES -> DES -> Bool
== :: DES -> DES -> Bool
$c/= :: DES -> DES -> Bool
/= :: DES -> DES -> Bool
Eq)

instance Cipher DES where
    cipherName :: DES -> String
cipherName DES
_ = String
"DES"
    cipherKeySize :: DES -> KeySizeSpecifier
cipherKeySize DES
_ = Int -> KeySizeSpecifier
KeySizeFixed Int
8
    cipherInit :: forall key. ByteArray key => key -> CryptoFailable DES
cipherInit key
k = key -> CryptoFailable DES
forall key. ByteArrayAccess key => key -> CryptoFailable DES
initDES key
k

instance BlockCipher DES where
    blockSize :: DES -> Int
blockSize DES
_ = Int
8
    ecbEncrypt :: forall ba. ByteArray ba => DES -> ba -> ba
ecbEncrypt (DES Schedule
enc Schedule
_) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
enc
    ecbDecrypt :: forall ba. ByteArray ba => DES -> ba -> ba
ecbDecrypt (DES Schedule
_ Schedule
dec) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
dec

initDES :: ByteArrayAccess key => key -> CryptoFailable DES
initDES :: forall key. ByteArrayAccess key => key -> CryptoFailable DES
initDES key
k
    | key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
8 =
        DES -> CryptoFailable DES
forall a. a -> CryptoFailable a
CryptoPassed (DES -> CryptoFailable DES) -> DES -> CryptoFailable DES
forall a b. (a -> b) -> a -> b
$ Schedule -> Schedule -> DES
DES ([(Direction, key)] -> Schedule
forall key. ByteArrayAccess key => [(Direction, key)] -> Schedule
schedule [(Direction
Encrypt, key
k)]) ([(Direction, key)] -> Schedule
forall key. ByteArrayAccess key => [(Direction, key)] -> Schedule
schedule [(Direction
Decrypt, key
k)])
    | Bool
otherwise = CryptoError -> CryptoFailable DES
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid