module Codec.Crypto.AES.Monad(
AES, AEST, Mode(..), Direction(..), Cryptable(..), runAEST, runAES
) where
import qualified Codec.Crypto.AES.IO as AES
import Codec.Crypto.AES.IO(Mode(..), Direction(..), newCtx, AESCtx)
import Control.Applicative
import Control.Monad.ST.Lazy
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.UnsafeIO
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
type AEST m a = ReaderT AESCtx (WriterT BL.ByteString m) a
type AES s a = AEST (ST s) a
runAEST :: MonadUnsafeIO m =>
Mode
-> B.ByteString
-> B.ByteString
-> Direction
-> AEST m a
-> m (a, BL.ByteString)
runAEST mode key iv dir aes = do
ctx <- liftUnsafeIO $ newCtx mode key iv dir
runWriterT $ runReaderT aes ctx
runAES :: Mode
-> B.ByteString
-> B.ByteString
-> Direction
-> (forall s. AES s a)
-> (a, BL.ByteString)
runAES mode key iv dir aes = runST $ runAEST mode key iv dir aes
class Cryptable a where
crypt :: a -> AES s a
instance Cryptable B.ByteString where
crypt bs = do
ctx <- ask
crypted <- liftUnsafeIO $ AES.crypt ctx bs
tell $ BL.fromChunks [crypted]
return crypted
instance Cryptable BL.ByteString where
crypt (BL.toChunks -> chunks) = snd <$> listen (mapM_ crypt chunks)