Twofish-0.2: Data/Cipher.hs
{-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies,
GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
-- | This module provides support for block ciphers
module Data.Cipher
(
-- * Classes
Cipher(encrypt, decrypt)
,MonadCbc
-- * Types
,Cbc
,CbcT
-- * Functions
,evalCbc
,evalCbcT
,cbcEncrypt
,cbcDecrypt
) where
import Control.Monad.State
import Data.Bits
-- |Contains the result of an operation in the context of
-- cipher-block-chaining mode.
newtype Cbc c iv a = Cbc (State (c, iv) a)
deriving (Monad, Functor)
-- |CbcT is the monad transformer version of Cbc
newtype CbcT c iv m a = CbcT (StateT (c, iv) m a)
deriving (Monad, Functor, MonadTrans)
-- |Evaluates a cipher-block-chaining-mode operation, given
-- a cipher and an initialization vector (IV).
evalCbc :: Cbc c w a -> c -> w -> a
evalCbc (Cbc s) c iv = evalState s (c, iv)
-- |This is the monad tranformer version of evalCbc
evalCbcT :: (Monad m) => CbcT c w m a -> c -> w -> m a
evalCbcT (CbcT s) c iv = evalStateT s (c, iv)
-- | A cipher
class (Bits w) => Cipher w c | c -> w where
encrypt :: c -> w -> w
decrypt :: c -> w -> w
-- | Any monad that contains the result of an operation in the
-- context of cipher-block-chaining mode.
class (Bits w, Cipher w c, MonadState (c, w) s) => MonadCbc c w s m | m -> c, m -> w, m -> s where
monadCbc :: s w -> m w
instance (Bits w, Cipher w c) => MonadCbc c w (State (c, w)) (Cbc c w) where
monadCbc = Cbc
instance (Bits w, Cipher w c, Monad m) => MonadCbc c w (StateT (c, w) m) (CbcT c w m) where
monadCbc = CbcT
-- |This is the fundamental cipher-block-chaining encryption protocol
cbcEncrypt :: (MonadCbc c w s m) => w -> m w
cbcEncrypt w = monadCbc $ do (c, iv) <- get
let w' = encrypt c (w `xor` iv)
put (c, w')
return w'
-- |This is the fundamental cipher-block-chaining decryption protocol
cbcDecrypt :: (MonadCbc c w s m) => w -> m w
cbcDecrypt w = monadCbc $ do (c, iv) <- get
let w' = decrypt c w `xor` iv
put (c, w)
return w'