diff --git a/Benchmarks/Benchmarks.hs b/Benchmarks/Benchmarks.hs
deleted file mode 100644
--- a/Benchmarks/Benchmarks.hs
+++ /dev/null
@@ -1,113 +0,0 @@
-{-# LANGUAGE CPP #-}
-import Criterion
-import Criterion.Environment
-import Criterion.Config
-import Criterion.Monad
-import Criterion.Analysis
-import Criterion.Measurement
-
-import Text.Printf
-
-import Control.Monad.Trans
-
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as L
-
-import qualified Crypto.Cipher.AES.Haskell as AES
-#ifdef HAVE_AESNI
-import qualified Crypto.Cipher.AES.X86NI as AESNI
-#endif
-import qualified Crypto.Cipher.RC4 as RC4
-import qualified Crypto.Cipher.Blowfish as Blowfish
-import qualified Crypto.Cipher.Camellia as Camellia
-
-import Crypto.Classes
-import qualified Crypto.Modes as CAPI
-
-(Right key128) = AES.initKey128 $ B.replicate 16 0
-aesEncrypt128 = AES.encrypt key128
-aesEncrypt128CBC = AES.encryptCBC key128 (B.replicate 16 0)
-
-(Right key192) = AES.initKey192 $ B.replicate 24 0
-aesEncrypt192 = AES.encrypt key192
-aesEncrypt192CBC = AES.encryptCBC key192 (B.replicate 16 0)
-(Right key256) = AES.initKey256 $ B.replicate 32 0
-aesEncrypt256 = AES.encrypt key256
-aesEncrypt256CBC = AES.encryptCBC key256 (B.replicate 16 0)
-
-(Just capi_key128) = buildKey (B.replicate 16 0) :: Maybe AES.AES128
-aesEncrypt128CBC_capi = fst . CAPI.cbc' capi_key128 CAPI.zeroIV
-
-#ifdef HAVE_AESNI
-key128_ni = AESNI.initKey128 $ B.replicate 16 0
-aesniEncrypt128 = AESNI.encrypt key128_ni
-
-aesniEncrypt128CBC = AESNI.encryptCBC key128_ni (B.replicate 16 0)
-#endif
-
-(Right blowfishKey) = Blowfish.initKey $ B.empty
-blowfishEncrypt = Blowfish.encrypt blowfishKey
-
-(Right camelliaKey128) = Camellia.initKey128 $ B.replicate 16 0
-camelliaEncrypt128 = Camellia.encrypt camelliaKey128
-
-rc4Key = RC4.initCtx $ replicate 16 0
-rc4Encrypt = snd . RC4.encrypt rc4Key 
-
-b16 f   = whnf f $ B.replicate 16 0
-b32 f   = whnf f $ B.replicate 32 0
-b128 f  = whnf f $ B.replicate 128 0
-b512 f  = whnf f $ B.replicate 512 0
-b1024 f = whnf f $ B.replicate 1024 0
-b4096 f = whnf f $ B.replicate 4096 0
-
-doCipher env f = do
-	mean16   <- runBenchmark env (b16 f)   >>= \sample -> analyseMean sample 100
-	mean32   <- runBenchmark env (b32 f)   >>= \sample -> analyseMean sample 100
-	mean128  <- runBenchmark env (b128 f)  >>= \sample -> analyseMean sample 100
-	mean512  <- runBenchmark env (b512 f)  >>= \sample -> analyseMean sample 100
-	mean1024 <- runBenchmark env (b1024 f) >>= \sample -> analyseMean sample 100
-	mean4096 <- runBenchmark env (b4096 f) >>= \sample -> analyseMean sample 100
-	return (mean16, mean32, mean128, mean512, mean1024, mean4096)
-
-norm :: Int -> Double -> Double
-norm n time
-	| n < 1024  = 1.0 / (time * (1024 / fromIntegral n))
-	| n == 1024 = 1.0 / time
-	| n > 1024  = 1.0 / (time / (fromIntegral n / 1024))
-
-pn :: Int -> Double -> String
-pn n time = printf "%.1f K/s" (norm n time)
-
-doOne env (cipherName, f) = do
-	(mean16, mean32, mean128, mean512, mean1024, mean4096) <- doCipher env f
-	let s = printf "%12s: %12s %12s %12s %12s %12s %12s\n                %12s %12s %12s %12s %12s %12s"
-	               cipherName
-	               (secs mean16) (secs mean32) (secs mean128)
-	               (secs mean512) (secs mean1024) (secs mean4096)
-	               (pn 16 mean16) (pn 32 mean32) (pn 128 mean128)
-	               (pn 512 mean512) (pn 1024 mean1024) (pn 4096 mean4096)
-	return s
-
-main = withConfig defaultConfig $ do
-	env <- measureEnvironment
-	l   <- mapM (doOne env)
-		[ ("RC4"        , rc4Encrypt)
-		, ("Blowfish"   , blowfishEncrypt)
-		, ("Camellia128", camelliaEncrypt128)
-		, ("AES128"     , aesEncrypt128)
-		, ("AES128-CBC" , aesEncrypt128CBC)
-#ifdef HAVE_AESNI
-		, ("AES128-ni"  , aesniEncrypt128)
-		, ("AES128ni-CBC" , aesniEncrypt128CBC)
-#endif
-		-- , ("AES128-CBC-capi", aesEncrypt128CBC_capi)
-		, ("AES192"     , aesEncrypt192)
-		, ("AES192-CBC" , aesEncrypt192CBC)
-		, ("AES256"     , aesEncrypt256)
-		, ("AES256-CBC" , aesEncrypt256CBC)
-		]
-	liftIO $ printf "%12s| %12s %12s %12s %12s %12s %12s\n"
-	                "cipher" "16 bytes" "32 bytes" "64 bytes" "512 bytes" "1024 bytes" "4096 bytes"
-	liftIO $ printf "=============================================================================================\n"
-	mapM_ (liftIO . putStrLn) l
diff --git a/Crypto/Cipher.hs b/Crypto/Cipher.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/Cipher.hs
@@ -0,0 +1,57 @@
+-- |
+-- Module      : Crypto.Cipher
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : stable
+-- Portability : good
+--
+-- All the cipher functionalities are available through the
+-- BlockCipher and StreamCipher classes.
+--
+-- A simplified example (with simplified error handling):
+--
+-- > import Crypto.Cipher
+-- > import Data.ByteString (ByteString)
+-- > import qualified Data.ByteString as B
+-- >
+-- > initAES256 :: ByteString -> AES256
+-- > initAES256 = either (error . show) cipherInit . makeKey
+-- >
+-- > cbcEncryption :: AES256 -> ByteString -> ByteString -> ByteString
+-- > cbcEncryption ctx ivRaw plainText = cbcEncrypt ctx iv plainText
+-- >   where iv = maybe (error "invalid IV") id $ ivRaw
+--
+module Crypto.Cipher
+    (
+    -- * Cipher classes
+      Cipher(..)
+    , BlockCipher(..)
+    , StreamCipher(..)
+    -- * Key
+    , Key
+    , makeKey
+    -- * Initialization Vector (IV)
+    , IV
+    , makeIV
+    , nullIV
+    , ivAdd
+    -- * Authenticated Encryption with Associated Data (AEAD)
+    , AEAD
+    , aeadAppendHeader
+    , aeadEncrypt
+    , aeadDecrypt
+    , aeadFinalize
+    -- * Cipher implementations
+    , AES128, AES192, AES256
+    , Blowfish, Blowfish64, Blowfish128, Blowfish256, Blowfish448
+    , DES
+    , DES_EEE3, DES_EDE3, DES_EEE2, DES_EDE2
+    , Camellia128
+    ) where
+
+import Crypto.Cipher.Types
+import Crypto.Cipher.AES (AES128, AES192, AES256)
+import Crypto.Cipher.Blowfish
+import Crypto.Cipher.DES
+import Crypto.Cipher.TripleDES
+import Crypto.Cipher.Camellia
diff --git a/Crypto/Cipher/AES.hs b/Crypto/Cipher/AES.hs
deleted file mode 100644
--- a/Crypto/Cipher/AES.hs
+++ /dev/null
@@ -1,12 +0,0 @@
--- |
--- Module      : Crypto.Cipher.AES
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Crypto.Cipher.AES
-	( module Crypto.Cipher.AES.Haskell
-	) where
-
-import Crypto.Cipher.AES.Haskell
diff --git a/Crypto/Cipher/AES/Haskell.hs b/Crypto/Cipher/AES/Haskell.hs
deleted file mode 100644
--- a/Crypto/Cipher/AES/Haskell.hs
+++ /dev/null
@@ -1,1030 +0,0 @@
-{-# LANGUAGE BangPatterns, MagicHash #-}
--- |
--- Module      : Crypto.Cipher.AES.Haskell
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Crypto.Cipher.AES.Haskell
-	( Key
-	, IV
-	-- * Basic encryption and decryption
-	, encrypt
-	, decrypt
-	-- * CBC encryption and decryption
-	, encryptCBC
-	, decryptCBC
-	-- * key building mechanism
-	, initKey128
-	, initKey192
-	, initKey256
-	-- * Wrappers for "crypto-api" instances
-	, AES128
-	, AES192
-	, AES256
-	) where
-
-import Data.Word
-import Data.Vector.Unboxed (Vector)
-import qualified Data.Vector.Unboxed as V
-import Data.Bits
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Unsafe as B
-import qualified Data.ByteString.Internal as B
-
-import GHC.Prim (indexWord8OffAddr#, indexWord32OffAddr#, word2Int#, Addr#, remInt#)
-import GHC.Word
-import GHC.Types
-
-import Foreign.Ptr
-import Foreign.Storable
-
-import Data.Tagged (Tagged(..))
-import Crypto.Classes (BlockCipher(..))
-import Data.Serialize (Serialize(..), getByteString, putByteString)
-
-import Control.Monad (forM_)
-import Control.Monad.Primitive
-
-import Data.Primitive.ByteArray
-
-import System.Endian (getSystemEndianness, Endianness(..))
-
-newtype AES128 = A128 { unA128 :: Key }
-newtype AES192 = A192 { unA192 :: Key }
-newtype AES256 = A256 { unA256 :: Key }
-
-instance BlockCipher AES128 where
-	blockSize    = Tagged 128
-	encryptBlock = encrypt . unA128
-	decryptBlock = decrypt . unA128
-	buildKey b   = either (const Nothing) (Just . A128) $ initKey128 b
-	keyLength    = Tagged 128
-
-instance BlockCipher AES192 where
-	blockSize    = Tagged 128
-	encryptBlock = encrypt . unA192
-	decryptBlock = decrypt . unA192
-	buildKey b   = either (const Nothing) (Just . A192) $ initKey192 b
-	keyLength    = Tagged 192
-
-instance BlockCipher AES256 where
-	blockSize    = Tagged 128
-	encryptBlock = encrypt . unA256
-	decryptBlock = decrypt . unA256
-	buildKey b   = either (const Nothing) (Just . A256) $ initKey256 b
-	keyLength    = Tagged 256
-
-serializeKey :: Key -> ByteString
-serializeKey (Key v)
-	| V.length v == 176 = B.pack $ map (V.unsafeIndex v) [0..15]
-	| V.length v == 208 = B.pack $ map (V.unsafeIndex v) [0..23]
-	| otherwise         = B.pack $ map (V.unsafeIndex v) [0..31]
-
-instance Serialize AES128 where
-	put = putByteString . serializeKey . unA128
-	get = do
-		raw <- getByteString (128 `div` 8)
-		case buildKey raw of
-			Nothing -> fail "Invalid raw key material."
-			Just k  -> return k
-
-instance Serialize AES192 where
-	put = putByteString . serializeKey . unA192
-	get = do
-		raw <- getByteString (192 `div` 8)
-		case buildKey raw of
-			Nothing -> fail "Invalid raw key material."
-			Just k  -> return k
-
-instance Serialize AES256 where
-	put = putByteString . serializeKey . unA256
-	get = do
-		raw <- getByteString (256 `div` 8)
-		case buildKey raw of
-			Nothing -> fail "Invalid raw key material."
-			Just k  -> return k
-
-data Key = Key (Vector Word8)
-	deriving (Show,Eq)
-
-type IV = B.ByteString
-type Block = B.ByteString
-
-type AESState = MutableByteArray RealWorld
-
-{- | encrypt using CBC mode
- - IV need to be 16 bytes and the data to encrypt a multiple of 16 bytes -}
-encryptCBC :: Key -> IV -> B.ByteString -> B.ByteString
-encryptCBC key iv b
-	| B.length iv /= 16        = error "invalid IV length"
-	| B.length b `mod` 16 /= 0 = error "invalid data length"
-	| otherwise                = B.concat $ encryptIter iv (makeChunks b)
-		where
-			encryptIter _   []     = []
-			encryptIter iv' (x:xs) =
-				let r = coreEncrypt key $ B.pack $ B.zipWith xor iv' x in
-				r : encryptIter r xs
-
-{- | encrypt using simple ECB mode -}
-encrypt :: Key -> B.ByteString -> B.ByteString
-encrypt key b
-	| B.length b `mod` 16 /= 0 = error "invalid data length"
-	| otherwise                = B.concat $ doChunks (coreEncrypt key) b
-
-{- | decrypt using CBC mode
- - IV need to be 16 bytes and the data to decrypt a multiple of 16 bytes -}
-decryptCBC :: Key -> IV -> B.ByteString -> B.ByteString
-decryptCBC key iv b
-	| B.length iv /= 16        = error "invalid IV length"
-	| B.length b `mod` 16 /= 0 = error "invalid data length"
-	| otherwise                = B.concat $ decryptIter iv (makeChunks b)
-		where
-			decryptIter _   []     = []
-			decryptIter iv' (x:xs) =
-				let r = B.pack $ B.zipWith xor iv' $ coreDecrypt key x in
-				r : decryptIter x xs
-
-{- | decrypt using simple ECB mode -}
-decrypt :: Key -> B.ByteString -> B.ByteString
-decrypt key b
-	| B.length b `mod` 16 /= 0 = error "invalid data length"
-	| otherwise                = B.concat $ doChunks (coreDecrypt key) b
-
-doChunks :: (B.ByteString -> B.ByteString) -> B.ByteString -> [B.ByteString]
-doChunks f b
-    | B.null b  = []
-    | otherwise =
-        let (x, rest) = B.splitAt 16 b in
-        if B.length rest >= 16
-            then f x : doChunks f rest
-            else [ f x ]
-
-makeChunks :: B.ByteString -> [B.ByteString]
-makeChunks = doChunks id
-
-newAESState :: IO AESState
-newAESState = newAlignedPinnedByteArray 16 16
-
-coreEncrypt :: Key -> Block -> Block
-coreEncrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do
-	st <- newAESState
-	swapBlock input st
-	aesMain (getNbr key) key st
-	swapBlockInv st ptr
-
-coreDecrypt :: Key -> Block -> Block
-coreDecrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do
-	st <- newAESState
-	swapBlock input st
-	aesMainInv (getNbr key) key st
-	swapBlockInv st ptr
-
-getNbr :: Key -> Int
-getNbr (Key v)
-	| V.length v == 176 = 10
-	| V.length v == 208 = 12
-	| otherwise         = 14
-
-initKey128, initKey192, initKey256 :: ByteString -> Either String Key
-
-initKey128 = initKey 16
-initKey192 = initKey 24
-initKey256 = initKey 32
-
-initKey :: Int -> ByteString -> Either String Key
-initKey sz b
-	| B.length b == sz = Right $ coreExpandKey (V.generate sz $ B.unsafeIndex b)
-	| otherwise        = Left "wrong key size"
-
-aesMain :: Int -> Key -> AESState -> IO ()
-aesMain nbr key blk = do
-	addRoundKey key 0 blk
-	forM_ [1..nbr-1] $ \i -> do
-		shiftRows blk >> mixColumns blk >> addRoundKey key i blk
-	shiftRows blk >> addRoundKey key nbr blk
-
-aesMainInv :: Int -> Key -> AESState -> IO ()
-aesMainInv nbr key blk = do
-	addRoundKey key nbr blk
-	forM_ (reverse [1..nbr-1]) $ \i -> do
-		shiftRowsInv blk >> addRoundKey key i blk >> mixColumnsInv blk
-	shiftRowsInv blk >> addRoundKey key 0 blk
-
-{-# INLINE swapIndex #-}
-swapIndex :: Int -> Int
-swapIndex 0 = 0
-swapIndex 1 = 4
-swapIndex 2 = 8
-swapIndex 3 = 12
-swapIndex 4 = 1
-swapIndex 5 = 5
-swapIndex 6 = 9
-swapIndex 7 = 13
-swapIndex 8 = 2
-swapIndex 9 = 6
-swapIndex 10 = 10
-swapIndex 11 = 14
-swapIndex 12 = 3
-swapIndex 13 = 7
-swapIndex 14 = 11
-swapIndex 15 = 15
-swapIndex _  = 0
-
-coreExpandKey :: Vector Word8 -> Key
-coreExpandKey vkey
-	| V.length vkey == 16 = Key (V.concat (ek0 : ekN16))
-	| V.length vkey == 24 = Key (V.concat (ek0 : ekN24))
-	| V.length vkey == 32 = Key (V.concat (ek0 : ekN32))
-	| otherwise           = Key (V.empty)
-	where
-		ek0 = vkey
-		ekN16 = reverse $ snd $ foldl (generateFold generate16) (ek0, []) [1..10]
-
-		ekN24 =
-			let (lk, acc) = foldl (generateFold generate24) (ek0, []) [1..7] in
-			let nk = generate16 lk 8 in
-			reverse (nk : acc)
-
-		ekN32 =
-			let (lk, acc) = foldl (generateFold generate32) (ek0, []) [1..6] in
-			let nk = generate16 lk 7 in
-			reverse (nk : acc)
-
-		generateFold gen (prevk, accK) it = let nk = gen prevk it in (nk, nk : accK)
-
-		generate16 prevk it =
-			let len = V.length prevk in
-			let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)
-			                (V.unsafeIndex prevk $ len - 3)
-			                (V.unsafeIndex prevk $ len - 2)
-			                (V.unsafeIndex prevk $ len - 1) in
-			let eg0@(e0,e1,e2,e3)     = xorVector prevk 0 v0   in
-			let eg1@(e4,e5,e6,e7)     = xorVector prevk 4 eg0  in
-			let eg2@(e8,e9,e10,e11)   = xorVector prevk 8 eg1  in
-			let     (e12,e13,e14,e15) = xorVector prevk 12 eg2 in
-			V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15]
-
-		generate24 prevk it =
-			let len = V.length prevk in
-			let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)
-			                (V.unsafeIndex prevk $ len - 3)
-			                (V.unsafeIndex prevk $ len - 2)
-			                (V.unsafeIndex prevk $ len - 1) in
-			let eg0@(e0,e1,e2,e3)     = xorVector prevk 0 v0   in
-			let eg1@(e4,e5,e6,e7)     = xorVector prevk 4 eg0  in
-			let eg2@(e8,e9,e10,e11)   = xorVector prevk 8 eg1  in
-			let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in
-			let eg4@(e16,e17,e18,e19) = xorVector prevk 16 eg3 in
-			let     (e20,e21,e22,e23) = xorVector prevk 20 eg4 in
-			V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23]
-
-		generate32 prevk it =
-			let len = V.length prevk in
-			let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)
-			                (V.unsafeIndex prevk $ len - 3)
-			                (V.unsafeIndex prevk $ len - 2)
-			                (V.unsafeIndex prevk $ len - 1) in
-			let eg0@(e0,e1,e2,e3)     = xorVector prevk 0 v0   in
-			let eg1@(e4,e5,e6,e7)     = xorVector prevk 4 eg0  in
-			let eg2@(e8,e9,e10,e11)   = xorVector prevk 8 eg1  in
-			let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in
-			let eg4@(e16,e17,e18,e19) = xorSboxVector prevk 16 eg3 in
-			let eg5@(e20,e21,e22,e23) = xorVector prevk 20 eg4 in
-			let eg6@(e24,e25,e26,e27) = xorVector prevk 24 eg5 in
-			let     (e28,e29,e30,e31) = xorVector prevk 28 eg6 in
-			V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16
-			           ,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31]
-
-		xorVector k i (t0,t1,t2,t3) =
-			( V.unsafeIndex k (i+0) `xor` t0
-			, V.unsafeIndex k (i+1) `xor` t1
-			, V.unsafeIndex k (i+2) `xor` t2
-			, V.unsafeIndex k (i+3) `xor` t3
-			)
-
-		xorSboxVector k i (t0,t1,t2,t3) =
-			( V.unsafeIndex k (i+0) `xor` sbox t0
-			, V.unsafeIndex k (i+1) `xor` sbox t1
-			, V.unsafeIndex k (i+2) `xor` sbox t2
-			, V.unsafeIndex k (i+3) `xor` sbox t3
-			)
-
-		cR0 it r0 r1 r2 r3 =
-			(sbox r1 `xor` rcon it, sbox r2, sbox r3, sbox r0)
-
-rotateR' :: Word32 -> Int -> Word32
-rotateR' = case getSystemEndianness of
-           LittleEndian -> rotateR
-           BigEndian    -> rotateL
-{-# INLINE rotateR' #-}
-
-rotateL' :: Word32 -> Int -> Word32
-rotateL' = case getSystemEndianness of
-           LittleEndian -> rotateL
-           BigEndian    -> rotateR
-{-# INLINE rotateL' #-}
-
-
-{-# INLINE shiftRows #-}
-shiftRows :: AESState -> IO ()
-shiftRows blk = do
-	r32 blk 0 >>= w32 blk 0 . msbox32
-	r32 blk 1 >>= \t1 -> w32 blk 1 $ rotateR' (msbox32 t1) 8
-	r32 blk 2 >>= \t2 -> w32 blk 2 $ rotateR' (msbox32 t2) 16
-	r32 blk 3 >>= \t3 -> w32 blk 3 $ rotateR' (msbox32 t3) 24
-
-{-# INLINE addRoundKey #-}
-addRoundKey :: Key -> Int -> AESState -> IO ()
-addRoundKey (Key key) i blk = forM_ [0..15] $ \n -> do
-	r8 blk n >>= \v1 -> w8 blk n $ v1 `xor` V.unsafeIndex key (16 * i + swapIndex n)
-
-{-# INLINE mixColumns #-}
-mixColumns :: AESState -> IO ()
-mixColumns state = pr 0 >> pr 1 >> pr 2 >> pr 3
-	where
-		{-# INLINE pr #-}
-		pr i = do
-			cpy0 <- r8 state (0 * 4 + i)
-			cpy1 <- r8 state (1 * 4 + i)
-			cpy2 <- r8 state (2 * 4 + i)
-			cpy3 <- r8 state (3 * 4 + i)
-
-			let state0 = gm2 cpy0 `xor` gm1 cpy3 `xor` gm1 cpy2 `xor` gm3 cpy1
-			let state4 = gm2 cpy1 `xor` gm1 cpy0 `xor` gm1 cpy3 `xor` gm3 cpy2
-			let state8 = gm2 cpy2 `xor` gm1 cpy1 `xor` gm1 cpy0 `xor` gm3 cpy3
-			let state12 = gm2 cpy3 `xor` gm1 cpy2 `xor` gm1 cpy1 `xor` gm3 cpy0
-
-			w8 state (0 * 4 + i) state0
-			w8 state (1 * 4 + i) state4
-			w8 state (2 * 4 + i) state8
-			w8 state (3 * 4 + i) state12
-		{-# INLINE gm1 #-}
-		gm1 a = a
-
-{-# INLINE shiftRowsInv #-}
-shiftRowsInv :: AESState -> IO ()
-shiftRowsInv blk = do
-	r32 blk 0 >>= w32 blk 0 . mrsbox32
-	r32 blk 1 >>= \t1 -> w32 blk 1 $ mrsbox32 $ rotateL' t1 8
-	r32 blk 2 >>= \t2 -> w32 blk 2 $ mrsbox32 $ rotateL' t2 16
-	r32 blk 3 >>= \t3 -> w32 blk 3 $ mrsbox32 $ rotateL' t3 24
-
-{-# INLINE mixColumnsInv #-}
-mixColumnsInv :: AESState -> IO ()
-mixColumnsInv state = pr 0 >> pr 1 >> pr 2 >> pr 3
-	where
-		{-# INLINE pr #-}
-		pr i = do
-			cpy0 <- r8 state (0 * 4 + i)
-			cpy1 <- r8 state (1 * 4 + i)
-			cpy2 <- r8 state (2 * 4 + i)
-			cpy3 <- r8 state (3 * 4 + i)
-
-			let state0  = gm14 cpy0 `xor` gm9 cpy3 `xor` gm13 cpy2 `xor` gm11 cpy1
-			let state4  = gm14 cpy1 `xor` gm9 cpy0 `xor` gm13 cpy3 `xor` gm11 cpy2
-			let state8  = gm14 cpy2 `xor` gm9 cpy1 `xor` gm13 cpy0 `xor` gm11 cpy3
-			let state12 = gm14 cpy3 `xor` gm9 cpy2 `xor` gm13 cpy1 `xor` gm11 cpy0
-
-			w8 state (0 * 4 + i) state0
-			w8 state (1 * 4 + i) state4
-			w8 state (2 * 4 + i) state8
-			w8 state (3 * 4 + i) state12
-
-{-# INLINE r8 #-}
-r8 :: AESState -> Int -> IO Word8
-r8 = readByteArray
-
-{-# INLINE w8 #-}
-w8 :: AESState -> Int -> Word8 -> IO ()
-w8 = writeByteArray
-
-{-# INLINE r32 #-}
-r32 :: AESState -> Int -> IO Word32
-r32 = readByteArray
-
-{-# INLINE w32 #-}
-w32 :: AESState -> Int -> Word32 -> IO ()
-w32 = writeByteArray
-
-msbox32 :: Word32 -> Word32
-msbox32 w = sbox4 a .|. sbox3 b .|. sbox2 c .|. sbox1 d
-	where
-		a = fromIntegral (w `shiftR` 24)
-		b = fromIntegral (w `shiftR` 16)
-		c = fromIntegral (w `shiftR` 8)
-		d = fromIntegral w
-
-mrsbox32 :: Word32 -> Word32
-mrsbox32 w = fromIntegral (rsbox a) `shiftL` 24 .|.
-             fromIntegral (rsbox b) `shiftL` 16 .|.
-             fromIntegral (rsbox c) `shiftL` 8  .|.
-             fromIntegral (rsbox d)
-	where
-		a = fromIntegral (w `shiftR` 24)
-		b = fromIntegral (w `shiftR` 16)
-		c = fromIntegral (w `shiftR` 8)
-		d = fromIntegral w
-
-
-{-# INLINE swapBlock #-}
-swapBlock :: ByteString -> AESState -> IO ()
-swapBlock b blk = do -- V.generate 16 (\i -> B.unsafeIndex b $ swapIndex i)
-	forM_ [0..15] $ \i -> w8 blk i $ B.unsafeIndex b $ swapIndex i
-
-{-# INLINE swapBlockInv #-}
-swapBlockInv :: AESState -> Ptr Word8 -> IO ()
-swapBlockInv blk ptr = forM_ [0..15] $ \i -> r8 blk (swapIndex i) >>= pokeByteOff ptr i
-
-{-# INLINE sbox #-}
-sbox :: Word8 -> Word8
-sbox (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x63\x7c\x77\x7b\xf2\x6b\x6f\xc5\
-		\\x30\x01\x67\x2b\xfe\xd7\xab\x76\
-		\\xca\x82\xc9\x7d\xfa\x59\x47\xf0\
-		\\xad\xd4\xa2\xaf\x9c\xa4\x72\xc0\
-		\\xb7\xfd\x93\x26\x36\x3f\xf7\xcc\
-		\\x34\xa5\xe5\xf1\x71\xd8\x31\x15\
-		\\x04\xc7\x23\xc3\x18\x96\x05\x9a\
-		\\x07\x12\x80\xe2\xeb\x27\xb2\x75\
-		\\x09\x83\x2c\x1a\x1b\x6e\x5a\xa0\
-		\\x52\x3b\xd6\xb3\x29\xe3\x2f\x84\
-		\\x53\xd1\x00\xed\x20\xfc\xb1\x5b\
-		\\x6a\xcb\xbe\x39\x4a\x4c\x58\xcf\
-		\\xd0\xef\xaa\xfb\x43\x4d\x33\x85\
-		\\x45\xf9\x02\x7f\x50\x3c\x9f\xa8\
-		\\x51\xa3\x40\x8f\x92\x9d\x38\xf5\
-		\\xbc\xb6\xda\x21\x10\xff\xf3\xd2\
-		\\xcd\x0c\x13\xec\x5f\x97\x44\x17\
-		\\xc4\xa7\x7e\x3d\x64\x5d\x19\x73\
-		\\x60\x81\x4f\xdc\x22\x2a\x90\x88\
-		\\x46\xee\xb8\x14\xde\x5e\x0b\xdb\
-		\\xe0\x32\x3a\x0a\x49\x06\x24\x5c\
-		\\xc2\xd3\xac\x62\x91\x95\xe4\x79\
-		\\xe7\xc8\x37\x6d\x8d\xd5\x4e\xa9\
-		\\x6c\x56\xf4\xea\x65\x7a\xae\x08\
-		\\xba\x78\x25\x2e\x1c\xa6\xb4\xc6\
-		\\xe8\xdd\x74\x1f\x4b\xbd\x8b\x8a\
-		\\x70\x3e\xb5\x66\x48\x03\xf6\x0e\
-		\\x61\x35\x57\xb9\x86\xc1\x1d\x9e\
-		\\xe1\xf8\x98\x11\x69\xd9\x8e\x94\
-		\\x9b\x1e\x87\xe9\xce\x55\x28\xdf\
-		\\x8c\xa1\x89\x0d\xbf\xe6\x42\x68\
-		\\x41\x99\x2d\x0f\xb0\x54\xbb\x16"#
-
-{-# INLINE sbox1 #-}
-{-# INLINE sbox2 #-}
-{-# INLINE sbox3 #-}
-{-# INLINE sbox4 #-}
-sbox1, sbox2, sbox3, sbox4 :: Word8 -> Word32
-sbox1 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))
-	where !(Table table) = sbox1Tab
-sbox2 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))
-	where !(Table table) = sbox2Tab
-sbox3 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))
-	where !(Table table) = sbox3Tab
-sbox4 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))
-	where !(Table table) = sbox4Tab
-
-sbox1Tab, sbox2Tab, sbox3Tab, sbox4Tab :: Table
-sbox1Tab = if getSystemEndianness == LittleEndian then sbox_x000 else sbox_000x
-sbox2Tab = if getSystemEndianness == LittleEndian then sbox_0x00 else sbox_00x0
-sbox3Tab = if getSystemEndianness == LittleEndian then sbox_00x0 else sbox_0x00
-sbox4Tab = if getSystemEndianness == LittleEndian then sbox_000x else sbox_x000
-
-data Table = Table !Addr#
-
-sbox_000x, sbox_00x0, sbox_0x00, sbox_x000 :: Table
-sbox_000x = Table
-		"\x00\x00\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\
-		\\x00\x00\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\
-		\\x00\x00\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\
-		\\x00\x00\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\
-		\\x00\x00\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\
-		\\x00\x00\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\
-		\\x00\x00\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\
-		\\x00\x00\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\
-		\\x00\x00\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\
-		\\x00\x00\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\
-		\\x00\x00\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\
-		\\x00\x00\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\
-		\\x00\x00\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\
-		\\x00\x00\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\
-		\\x00\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\
-		\\x00\x00\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\
-		\\x00\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\
-		\\x00\x00\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\
-		\\x00\x00\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\
-		\\x00\x00\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\
-		\\x00\x00\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\
-		\\x00\x00\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\
-		\\x00\x00\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\
-		\\x00\x00\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\
-		\\x00\x00\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\
-		\\x00\x00\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\
-		\\x00\x00\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\
-		\\x00\x00\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\
-		\\x00\x00\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\
-		\\x00\x00\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\
-		\\x00\x00\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\
-		\\x00\x00\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\
-		\\x00\x00\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\
-		\\x00\x00\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\
-		\\x00\x00\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\
-		\\x00\x00\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\
-		\\x00\x00\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\
-		\\x00\x00\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\
-		\\x00\x00\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\
-		\\x00\x00\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\
-		\\x00\x00\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\
-		\\x00\x00\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\
-		\\x00\x00\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\
-		\\x00\x00\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\
-		\\x00\x00\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\
-		\\x00\x00\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\
-		\\x00\x00\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\
-		\\x00\x00\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\
-		\\x00\x00\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\
-		\\x00\x00\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\
-		\\x00\x00\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\
-		\\x00\x00\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\
-		\\x00\x00\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\
-		\\x00\x00\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\
-		\\x00\x00\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\
-		\\x00\x00\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\
-		\\x00\x00\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\
-		\\x00\x00\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\
-		\\x00\x00\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\
-		\\x00\x00\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\
-		\\x00\x00\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\
-		\\x00\x00\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\
-		\\x00\x00\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\
-		\\x00\x00\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16"#
-
-sbox_00x0 = Table
-		"\x00\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\
-		\\x00\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\
-		\\x00\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\
-		\\x00\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\
-		\\x00\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\
-		\\x00\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\
-		\\x00\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\
-		\\x00\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\
-		\\x00\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\
-		\\x00\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\
-		\\x00\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\
-		\\x00\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\
-		\\x00\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\
-		\\x00\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\
-		\\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\
-		\\x00\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\
-		\\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\
-		\\x00\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\
-		\\x00\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\
-		\\x00\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\
-		\\x00\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\
-		\\x00\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\
-		\\x00\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\
-		\\x00\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\
-		\\x00\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\
-		\\x00\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\
-		\\x00\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\
-		\\x00\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\
-		\\x00\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\
-		\\x00\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\
-		\\x00\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\
-		\\x00\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\
-		\\x00\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\
-		\\x00\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\
-		\\x00\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\
-		\\x00\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\
-		\\x00\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\
-		\\x00\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\
-		\\x00\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\
-		\\x00\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\
-		\\x00\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\
-		\\x00\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\
-		\\x00\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\
-		\\x00\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\
-		\\x00\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\
-		\\x00\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\
-		\\x00\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\
-		\\x00\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\
-		\\x00\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\
-		\\x00\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\
-		\\x00\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\
-		\\x00\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\
-		\\x00\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\
-		\\x00\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\
-		\\x00\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\
-		\\x00\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\
-		\\x00\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\
-		\\x00\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\
-		\\x00\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\
-		\\x00\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\
-		\\x00\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\
-		\\x00\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\
-		\\x00\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\
-		\\x00\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00"#
-
-sbox_0x00 = Table
-		"\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\x00\
-		\\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\x00\
-		\\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\x00\
-		\\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\x00\
-		\\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\x00\
-		\\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\x00\
-		\\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\x00\
-		\\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\x00\
-		\\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\x00\
-		\\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\x00\
-		\\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\x00\
-		\\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\x00\
-		\\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\x00\
-		\\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\x00\
-		\\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\x00\
-		\\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\x00\
-		\\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\x00\
-		\\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\x00\
-		\\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\x00\
-		\\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\x00\
-		\\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\
-		\\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\x00\
-		\\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\x00\
-		\\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\x00\
-		\\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\x00\
-		\\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\x00\
-		\\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\
-		\\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\x00\
-		\\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\x00\
-		\\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\x00\
-		\\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\x00\
-		\\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\x00\
-		\\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\x00\
-		\\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\x00\
-		\\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\x00\
-		\\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\x00\
-		\\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\x00\
-		\\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\x00\
-		\\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\x00\
-		\\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\x00\
-		\\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\x00\
-		\\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\x00\
-		\\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\x00\
-		\\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\x00\
-		\\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\x00\
-		\\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\x00\
-		\\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\x00\
-		\\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\x00\
-		\\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\x00\
-		\\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\x00\
-		\\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\x00\
-		\\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\x00\
-		\\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\x00\
-		\\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x00\
-		\\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\x00\
-		\\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\x00\
-		\\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\
-		\\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\x00\
-		\\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\x00\
-		\\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\x00\
-		\\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\x00\
-		\\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\x00\
-		\\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\x00\
-		\\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00\x00"#
-
-sbox_x000 = Table
-		"\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\x00\x00\
-		\\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\x00\x00\
-		\\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\x00\x00\
-		\\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\x00\x00\
-		\\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\x00\x00\
-		\\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\x00\x00\
-		\\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\x00\x00\
-		\\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\x00\x00\
-		\\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\x00\x00\
-		\\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\x00\x00\
-		\\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\x00\x00\
-		\\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\x00\x00\
-		\\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\x00\x00\
-		\\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\x00\x00\
-		\\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\x00\x00\
-		\\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\x00\x00\
-		\\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\x00\x00\
-		\\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\x00\x00\
-		\\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\x00\x00\
-		\\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\x00\x00\
-		\\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\
-		\\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\x00\x00\
-		\\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\x00\x00\
-		\\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\x00\x00\
-		\\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\x00\x00\
-		\\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\x00\x00\
-		\\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\x00\
-		\\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\x00\x00\
-		\\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\x00\x00\
-		\\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\x00\x00\
-		\\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\x00\x00\
-		\\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\x00\x00\
-		\\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\x00\x00\
-		\\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\x00\x00\
-		\\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\x00\x00\
-		\\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\x00\x00\
-		\\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\x00\x00\
-		\\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\x00\x00\
-		\\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\x00\x00\
-		\\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\x00\x00\
-		\\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\x00\x00\
-		\\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\x00\x00\
-		\\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\x00\x00\
-		\\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\x00\x00\
-		\\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\x00\x00\
-		\\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\x00\x00\
-		\\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\x00\x00\
-		\\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\x00\x00\
-		\\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\x00\x00\
-		\\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\x00\x00\
-		\\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\x00\x00\
-		\\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\x00\x00\
-		\\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\x00\x00\
-		\\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x00\x00\
-		\\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\x00\x00\
-		\\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\x00\x00\
-		\\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00\
-		\\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\x00\x00\
-		\\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\x00\x00\
-		\\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\x00\x00\
-		\\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\x00\x00\
-		\\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\x00\x00\
-		\\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\x00\x00\
-		\\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00\x00\x00"#
-
-
-{-# INLINE rsbox #-}
-rsbox :: Word8 -> Word8
-rsbox (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x52\x09\x6a\xd5\x30\x36\xa5\x38\
-		\\xbf\x40\xa3\x9e\x81\xf3\xd7\xfb\
-		\\x7c\xe3\x39\x82\x9b\x2f\xff\x87\
-		\\x34\x8e\x43\x44\xc4\xde\xe9\xcb\
-		\\x54\x7b\x94\x32\xa6\xc2\x23\x3d\
-		\\xee\x4c\x95\x0b\x42\xfa\xc3\x4e\
-		\\x08\x2e\xa1\x66\x28\xd9\x24\xb2\
-		\\x76\x5b\xa2\x49\x6d\x8b\xd1\x25\
-		\\x72\xf8\xf6\x64\x86\x68\x98\x16\
-		\\xd4\xa4\x5c\xcc\x5d\x65\xb6\x92\
-		\\x6c\x70\x48\x50\xfd\xed\xb9\xda\
-		\\x5e\x15\x46\x57\xa7\x8d\x9d\x84\
-		\\x90\xd8\xab\x00\x8c\xbc\xd3\x0a\
-		\\xf7\xe4\x58\x05\xb8\xb3\x45\x06\
-		\\xd0\x2c\x1e\x8f\xca\x3f\x0f\x02\
-		\\xc1\xaf\xbd\x03\x01\x13\x8a\x6b\
-		\\x3a\x91\x11\x41\x4f\x67\xdc\xea\
-		\\x97\xf2\xcf\xce\xf0\xb4\xe6\x73\
-		\\x96\xac\x74\x22\xe7\xad\x35\x85\
-		\\xe2\xf9\x37\xe8\x1c\x75\xdf\x6e\
-		\\x47\xf1\x1a\x71\x1d\x29\xc5\x89\
-		\\x6f\xb7\x62\x0e\xaa\x18\xbe\x1b\
-		\\xfc\x56\x3e\x4b\xc6\xd2\x79\x20\
-		\\x9a\xdb\xc0\xfe\x78\xcd\x5a\xf4\
-		\\x1f\xdd\xa8\x33\x88\x07\xc7\x31\
-		\\xb1\x12\x10\x59\x27\x80\xec\x5f\
-		\\x60\x51\x7f\xa9\x19\xb5\x4a\x0d\
-		\\x2d\xe5\x7a\x9f\x93\xc9\x9c\xef\
-		\\xa0\xe0\x3b\x4d\xae\x2a\xf5\xb0\
-		\\xc8\xeb\xbb\x3c\x83\x53\x99\x61\
-		\\x17\x2b\x04\x7e\xba\x77\xd6\x26\
-		\\xe1\x69\x14\x63\x55\x21\x0c\x7d"#
-
-{-# INLINE rcon #-}
-rcon :: Int -> Word8
-rcon (I# i) = W8# (indexWord8OffAddr# table (i `remInt#` 51#))
-	where !table =
-		"\x8d\x01\x02\x04\x08\x10\x20\x40\
-		\\x80\x1b\x36\x6c\xd8\xab\x4d\x9a\
-		\\x2f\x5e\xbc\x63\xc6\x97\x35\x6a\
-		\\xd4\xb3\x7d\xfa\xef\xc5\x91\x39\
-		\\x72\xe4\xd3\xbd\x61\xc2\x9f\x25\
-		\\x4a\x94\x33\x66\xcc\x83\x1d\x3a\
-		\\x74\xe8\xcb"#
-
-{-# INLINE gm2 #-}
-{-# INLINE gm3 #-}
-{-# INLINE gm9 #-}
-{-# INLINE gm11 #-}
-{-# INLINE gm13 #-}
-{-# INLINE gm14 #-}
-gm2, gm3, gm9, gm11, gm13, gm14 :: Word8 -> Word8
-gm2 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x02\x04\x06\x08\x0a\x0c\x0e\
-		\\x10\x12\x14\x16\x18\x1a\x1c\x1e\
-		\\x20\x22\x24\x26\x28\x2a\x2c\x2e\
-		\\x30\x32\x34\x36\x38\x3a\x3c\x3e\
-		\\x40\x42\x44\x46\x48\x4a\x4c\x4e\
-		\\x50\x52\x54\x56\x58\x5a\x5c\x5e\
-		\\x60\x62\x64\x66\x68\x6a\x6c\x6e\
-		\\x70\x72\x74\x76\x78\x7a\x7c\x7e\
-		\\x80\x82\x84\x86\x88\x8a\x8c\x8e\
-		\\x90\x92\x94\x96\x98\x9a\x9c\x9e\
-		\\xa0\xa2\xa4\xa6\xa8\xaa\xac\xae\
-		\\xb0\xb2\xb4\xb6\xb8\xba\xbc\xbe\
-		\\xc0\xc2\xc4\xc6\xc8\xca\xcc\xce\
-		\\xd0\xd2\xd4\xd6\xd8\xda\xdc\xde\
-		\\xe0\xe2\xe4\xe6\xe8\xea\xec\xee\
-		\\xf0\xf2\xf4\xf6\xf8\xfa\xfc\xfe\
-		\\x1b\x19\x1f\x1d\x13\x11\x17\x15\
-		\\x0b\x09\x0f\x0d\x03\x01\x07\x05\
-		\\x3b\x39\x3f\x3d\x33\x31\x37\x35\
-		\\x2b\x29\x2f\x2d\x23\x21\x27\x25\
-		\\x5b\x59\x5f\x5d\x53\x51\x57\x55\
-		\\x4b\x49\x4f\x4d\x43\x41\x47\x45\
-		\\x7b\x79\x7f\x7d\x73\x71\x77\x75\
-		\\x6b\x69\x6f\x6d\x63\x61\x67\x65\
-		\\x9b\x99\x9f\x9d\x93\x91\x97\x95\
-		\\x8b\x89\x8f\x8d\x83\x81\x87\x85\
-		\\xbb\xb9\xbf\xbd\xb3\xb1\xb7\xb5\
-		\\xab\xa9\xaf\xad\xa3\xa1\xa7\xa5\
-		\\xdb\xd9\xdf\xdd\xd3\xd1\xd7\xd5\
-		\\xcb\xc9\xcf\xcd\xc3\xc1\xc7\xc5\
-		\\xfb\xf9\xff\xfd\xf3\xf1\xf7\xf5\
-		\\xeb\xe9\xef\xed\xe3\xe1\xe7\xe5"#
-
-gm3 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x03\x06\x05\x0c\x0f\x0a\x09\
-		\\x18\x1b\x1e\x1d\x14\x17\x12\x11\
-		\\x30\x33\x36\x35\x3c\x3f\x3a\x39\
-		\\x28\x2b\x2e\x2d\x24\x27\x22\x21\
-		\\x60\x63\x66\x65\x6c\x6f\x6a\x69\
-		\\x78\x7b\x7e\x7d\x74\x77\x72\x71\
-		\\x50\x53\x56\x55\x5c\x5f\x5a\x59\
-		\\x48\x4b\x4e\x4d\x44\x47\x42\x41\
-		\\xc0\xc3\xc6\xc5\xcc\xcf\xca\xc9\
-		\\xd8\xdb\xde\xdd\xd4\xd7\xd2\xd1\
-		\\xf0\xf3\xf6\xf5\xfc\xff\xfa\xf9\
-		\\xe8\xeb\xee\xed\xe4\xe7\xe2\xe1\
-		\\xa0\xa3\xa6\xa5\xac\xaf\xaa\xa9\
-		\\xb8\xbb\xbe\xbd\xb4\xb7\xb2\xb1\
-		\\x90\x93\x96\x95\x9c\x9f\x9a\x99\
-		\\x88\x8b\x8e\x8d\x84\x87\x82\x81\
-		\\x9b\x98\x9d\x9e\x97\x94\x91\x92\
-		\\x83\x80\x85\x86\x8f\x8c\x89\x8a\
-		\\xab\xa8\xad\xae\xa7\xa4\xa1\xa2\
-		\\xb3\xb0\xb5\xb6\xbf\xbc\xb9\xba\
-		\\xfb\xf8\xfd\xfe\xf7\xf4\xf1\xf2\
-		\\xe3\xe0\xe5\xe6\xef\xec\xe9\xea\
-		\\xcb\xc8\xcd\xce\xc7\xc4\xc1\xc2\
-		\\xd3\xd0\xd5\xd6\xdf\xdc\xd9\xda\
-		\\x5b\x58\x5d\x5e\x57\x54\x51\x52\
-		\\x43\x40\x45\x46\x4f\x4c\x49\x4a\
-		\\x6b\x68\x6d\x6e\x67\x64\x61\x62\
-		\\x73\x70\x75\x76\x7f\x7c\x79\x7a\
-		\\x3b\x38\x3d\x3e\x37\x34\x31\x32\
-		\\x23\x20\x25\x26\x2f\x2c\x29\x2a\
-		\\x0b\x08\x0d\x0e\x07\x04\x01\x02\
-		\\x13\x10\x15\x16\x1f\x1c\x19\x1a"#
-
-gm9 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x09\x12\x1b\x24\x2d\x36\x3f\
-		\\x48\x41\x5a\x53\x6c\x65\x7e\x77\
-		\\x90\x99\x82\x8b\xb4\xbd\xa6\xaf\
-		\\xd8\xd1\xca\xc3\xfc\xf5\xee\xe7\
-		\\x3b\x32\x29\x20\x1f\x16\x0d\x04\
-		\\x73\x7a\x61\x68\x57\x5e\x45\x4c\
-		\\xab\xa2\xb9\xb0\x8f\x86\x9d\x94\
-		\\xe3\xea\xf1\xf8\xc7\xce\xd5\xdc\
-		\\x76\x7f\x64\x6d\x52\x5b\x40\x49\
-		\\x3e\x37\x2c\x25\x1a\x13\x08\x01\
-		\\xe6\xef\xf4\xfd\xc2\xcb\xd0\xd9\
-		\\xae\xa7\xbc\xb5\x8a\x83\x98\x91\
-		\\x4d\x44\x5f\x56\x69\x60\x7b\x72\
-		\\x05\x0c\x17\x1e\x21\x28\x33\x3a\
-		\\xdd\xd4\xcf\xc6\xf9\xf0\xeb\xe2\
-		\\x95\x9c\x87\x8e\xb1\xb8\xa3\xaa\
-		\\xec\xe5\xfe\xf7\xc8\xc1\xda\xd3\
-		\\xa4\xad\xb6\xbf\x80\x89\x92\x9b\
-		\\x7c\x75\x6e\x67\x58\x51\x4a\x43\
-		\\x34\x3d\x26\x2f\x10\x19\x02\x0b\
-		\\xd7\xde\xc5\xcc\xf3\xfa\xe1\xe8\
-		\\x9f\x96\x8d\x84\xbb\xb2\xa9\xa0\
-		\\x47\x4e\x55\x5c\x63\x6a\x71\x78\
-		\\x0f\x06\x1d\x14\x2b\x22\x39\x30\
-		\\x9a\x93\x88\x81\xbe\xb7\xac\xa5\
-		\\xd2\xdb\xc0\xc9\xf6\xff\xe4\xed\
-		\\x0a\x03\x18\x11\x2e\x27\x3c\x35\
-		\\x42\x4b\x50\x59\x66\x6f\x74\x7d\
-		\\xa1\xa8\xb3\xba\x85\x8c\x97\x9e\
-		\\xe9\xe0\xfb\xf2\xcd\xc4\xdf\xd6\
-		\\x31\x38\x23\x2a\x15\x1c\x07\x0e\
-		\\x79\x70\x6b\x62\x5d\x54\x4f\x46"#
-
-gm11 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x0b\x16\x1d\x2c\x27\x3a\x31\
-		\\x58\x53\x4e\x45\x74\x7f\x62\x69\
-		\\xb0\xbb\xa6\xad\x9c\x97\x8a\x81\
-		\\xe8\xe3\xfe\xf5\xc4\xcf\xd2\xd9\
-		\\x7b\x70\x6d\x66\x57\x5c\x41\x4a\
-		\\x23\x28\x35\x3e\x0f\x04\x19\x12\
-		\\xcb\xc0\xdd\xd6\xe7\xec\xf1\xfa\
-		\\x93\x98\x85\x8e\xbf\xb4\xa9\xa2\
-		\\xf6\xfd\xe0\xeb\xda\xd1\xcc\xc7\
-		\\xae\xa5\xb8\xb3\x82\x89\x94\x9f\
-		\\x46\x4d\x50\x5b\x6a\x61\x7c\x77\
-		\\x1e\x15\x08\x03\x32\x39\x24\x2f\
-		\\x8d\x86\x9b\x90\xa1\xaa\xb7\xbc\
-		\\xd5\xde\xc3\xc8\xf9\xf2\xef\xe4\
-		\\x3d\x36\x2b\x20\x11\x1a\x07\x0c\
-		\\x65\x6e\x73\x78\x49\x42\x5f\x54\
-		\\xf7\xfc\xe1\xea\xdb\xd0\xcd\xc6\
-		\\xaf\xa4\xb9\xb2\x83\x88\x95\x9e\
-		\\x47\x4c\x51\x5a\x6b\x60\x7d\x76\
-		\\x1f\x14\x09\x02\x33\x38\x25\x2e\
-		\\x8c\x87\x9a\x91\xa0\xab\xb6\xbd\
-		\\xd4\xdf\xc2\xc9\xf8\xf3\xee\xe5\
-		\\x3c\x37\x2a\x21\x10\x1b\x06\x0d\
-		\\x64\x6f\x72\x79\x48\x43\x5e\x55\
-		\\x01\x0a\x17\x1c\x2d\x26\x3b\x30\
-		\\x59\x52\x4f\x44\x75\x7e\x63\x68\
-		\\xb1\xba\xa7\xac\x9d\x96\x8b\x80\
-		\\xe9\xe2\xff\xf4\xc5\xce\xd3\xd8\
-		\\x7a\x71\x6c\x67\x56\x5d\x40\x4b\
-		\\x22\x29\x34\x3f\x0e\x05\x18\x13\
-		\\xca\xc1\xdc\xd7\xe6\xed\xf0\xfb\
-		\\x92\x99\x84\x8f\xbe\xb5\xa8\xa3"#
-
-gm13 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x0d\x1a\x17\x34\x39\x2e\x23\
-		\\x68\x65\x72\x7f\x5c\x51\x46\x4b\
-		\\xd0\xdd\xca\xc7\xe4\xe9\xfe\xf3\
-		\\xb8\xb5\xa2\xaf\x8c\x81\x96\x9b\
-		\\xbb\xb6\xa1\xac\x8f\x82\x95\x98\
-		\\xd3\xde\xc9\xc4\xe7\xea\xfd\xf0\
-		\\x6b\x66\x71\x7c\x5f\x52\x45\x48\
-		\\x03\x0e\x19\x14\x37\x3a\x2d\x20\
-		\\x6d\x60\x77\x7a\x59\x54\x43\x4e\
-		\\x05\x08\x1f\x12\x31\x3c\x2b\x26\
-		\\xbd\xb0\xa7\xaa\x89\x84\x93\x9e\
-		\\xd5\xd8\xcf\xc2\xe1\xec\xfb\xf6\
-		\\xd6\xdb\xcc\xc1\xe2\xef\xf8\xf5\
-		\\xbe\xb3\xa4\xa9\x8a\x87\x90\x9d\
-		\\x06\x0b\x1c\x11\x32\x3f\x28\x25\
-		\\x6e\x63\x74\x79\x5a\x57\x40\x4d\
-		\\xda\xd7\xc0\xcd\xee\xe3\xf4\xf9\
-		\\xb2\xbf\xa8\xa5\x86\x8b\x9c\x91\
-		\\x0a\x07\x10\x1d\x3e\x33\x24\x29\
-		\\x62\x6f\x78\x75\x56\x5b\x4c\x41\
-		\\x61\x6c\x7b\x76\x55\x58\x4f\x42\
-		\\x09\x04\x13\x1e\x3d\x30\x27\x2a\
-		\\xb1\xbc\xab\xa6\x85\x88\x9f\x92\
-		\\xd9\xd4\xc3\xce\xed\xe0\xf7\xfa\
-		\\xb7\xba\xad\xa0\x83\x8e\x99\x94\
-		\\xdf\xd2\xc5\xc8\xeb\xe6\xf1\xfc\
-		\\x67\x6a\x7d\x70\x53\x5e\x49\x44\
-		\\x0f\x02\x15\x18\x3b\x36\x21\x2c\
-		\\x0c\x01\x16\x1b\x38\x35\x22\x2f\
-		\\x64\x69\x7e\x73\x50\x5d\x4a\x47\
-		\\xdc\xd1\xc6\xcb\xe8\xe5\xf2\xff\
-		\\xb4\xb9\xae\xa3\x80\x8d\x9a\x97"#
-
-gm14 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))
-	where !table =
-		"\x00\x0e\x1c\x12\x38\x36\x24\x2a\
-		\\x70\x7e\x6c\x62\x48\x46\x54\x5a\
-		\\xe0\xee\xfc\xf2\xd8\xd6\xc4\xca\
-		\\x90\x9e\x8c\x82\xa8\xa6\xb4\xba\
-		\\xdb\xd5\xc7\xc9\xe3\xed\xff\xf1\
-		\\xab\xa5\xb7\xb9\x93\x9d\x8f\x81\
-		\\x3b\x35\x27\x29\x03\x0d\x1f\x11\
-		\\x4b\x45\x57\x59\x73\x7d\x6f\x61\
-		\\xad\xa3\xb1\xbf\x95\x9b\x89\x87\
-		\\xdd\xd3\xc1\xcf\xe5\xeb\xf9\xf7\
-		\\x4d\x43\x51\x5f\x75\x7b\x69\x67\
-		\\x3d\x33\x21\x2f\x05\x0b\x19\x17\
-		\\x76\x78\x6a\x64\x4e\x40\x52\x5c\
-		\\x06\x08\x1a\x14\x3e\x30\x22\x2c\
-		\\x96\x98\x8a\x84\xae\xa0\xb2\xbc\
-		\\xe6\xe8\xfa\xf4\xde\xd0\xc2\xcc\
-		\\x41\x4f\x5d\x53\x79\x77\x65\x6b\
-		\\x31\x3f\x2d\x23\x09\x07\x15\x1b\
-		\\xa1\xaf\xbd\xb3\x99\x97\x85\x8b\
-		\\xd1\xdf\xcd\xc3\xe9\xe7\xf5\xfb\
-		\\x9a\x94\x86\x88\xa2\xac\xbe\xb0\
-		\\xea\xe4\xf6\xf8\xd2\xdc\xce\xc0\
-		\\x7a\x74\x66\x68\x42\x4c\x5e\x50\
-		\\x0a\x04\x16\x18\x32\x3c\x2e\x20\
-		\\xec\xe2\xf0\xfe\xd4\xda\xc8\xc6\
-		\\x9c\x92\x80\x8e\xa4\xaa\xb8\xb6\
-		\\x0c\x02\x10\x1e\x34\x3a\x28\x26\
-		\\x7c\x72\x60\x6e\x44\x4a\x58\x56\
-		\\x37\x39\x2b\x25\x0f\x01\x13\x1d\
-		\\x47\x49\x5b\x55\x7f\x71\x63\x6d\
-		\\xd7\xd9\xcb\xc5\xef\xe1\xf3\xfd\
-		\\xa7\xa9\xbb\xb5\x9f\x91\x83\x8d"#
diff --git a/Crypto/Cipher/Blowfish.hs b/Crypto/Cipher/Blowfish.hs
deleted file mode 100644
--- a/Crypto/Cipher/Blowfish.hs
+++ /dev/null
@@ -1,457 +0,0 @@
--- |
--- Module      : Crypto.Cipher.Blowfish
--- License     : BSD-style
--- Stability   : experimental
--- Portability : Good
-
--- Crypto.Cipher.Blowfish, copyright (c) 2012 Stijn van Drongelen
--- based on: BlowfishAux.hs (C) 2002 HardCore SoftWare, Doug Hoyte
---           (as found in Crypto-4.2.4)
-
-module Crypto.Cipher.Blowfish (Blowfish, Key, initKey, encrypt, decrypt) where
-
-import Crypto.Classes
-import Data.Vector (Vector, (!), (//))
-import qualified Data.Vector as V
-import Data.Bits
-import Data.Char
-import Data.Word
-import qualified Data.ByteString as B
-import Data.Tagged
-import Data.Serialize
-
-type Pbox = Vector Word32
-type Sbox = Vector Word32
-
-data Blowfish = Blowfish { bfKey :: Key
-                         , bfState :: BlowfishState
-                         }
-data BlowfishState = BF Pbox Sbox Sbox Sbox Sbox
-data Key = Key { unKey :: Vector Word32 }
-    deriving (Eq, Show)
-
-encrypt, decrypt :: Key -> B.ByteString -> B.ByteString
-encrypt = cipher . selectEncrypt . bfState . initBoxes
-decrypt = cipher . selectEncrypt . bfState . initBoxes
-
-instance Serialize Blowfish where
-    put = put . bfKey
-    get = fmap initBoxes get
-
-instance Serialize Key where
-    put = putByteString . keyToByteString
-    get = do
-        bs <- getByteString (18 * 4)
-        case keyFromByteString bs of
-            Right k -> return k
-            Left _ -> fail "Invalid raw key material."
-
-instance BlockCipher Blowfish where
-	blockSize    = Tagged 64
-	encryptBlock = cipher . selectEncrypt . bfState
-	decryptBlock = cipher . selectDecrypt . bfState
-	buildKey     = either (const Nothing) (Just . initBoxes) . initKey
-	keyLength    = Tagged 448 -- Actually 1 through 448 inclusive.
-
-selectEncrypt, selectDecrypt :: BlowfishState -> (Pbox, BlowfishState)
-selectEncrypt x@(BF p _ _ _ _) = (p, x)
-selectDecrypt x@(BF p _ _ _ _) = (V.reverse p, x)
-
-cipher :: (Pbox, BlowfishState) -> B.ByteString -> B.ByteString
-cipher (p, bs) b
-    | B.length b == 0 = B.empty
-    | B.length b `mod` 8 /= 0 = error "invalid data length"
-    | otherwise = B.concat $ doChunks 8 (fromW32Pair . coreCrypto p bs . toW32Pair) b
-
-initBoxes :: Key -> Blowfish
-initBoxes k = let (BF p s0 s1 s2 s3) = bfMakeKey k
-              in Blowfish k (BF p s0 s1 s2 s3)
-
-initKey :: B.ByteString -> Either String Key
-initKey b
-    | B.length b > (448 `div` 8) = fail "key too large"
-    | B.length b == 0 = keyFromByteString (B.replicate (18*4) 0)
-    | otherwise = keyFromByteString . B.pack . take (18*4) . cycle . B.unpack $ b
-
-keyFromByteString :: B.ByteString -> Either String Key
-keyFromByteString k
-    | B.length k /= (18 * 4) = fail "Incorrect expanded key length."
-    | otherwise = return . Key . (\ws -> V.generate 18 (ws!!)) . w8tow32 . B.unpack $ k
-  where        
-    w8tow32 :: [Word8] -> [Word32]
-    w8tow32 [] = []
-    w8tow32 (a:b:c:d:xs) = ( (fromIntegral a `shiftL` 24) .|.
-                             (fromIntegral b `shiftL` 16) .|.
-                             (fromIntegral c `shiftL`  8) .|.
-                             (fromIntegral d) ) : w8tow32 xs
-    w8tow32 _ = error $ "internal error: Crypto.Cipher.Blowfish:keyFromByteString"
-
-keyToByteString :: Key -> B.ByteString
-keyToByteString = B.pack . w32tow8 . (\x -> map (x!) [0..17]) . unKey
-  where
-    w32tow8 :: [Word32] -> [Word8]
-    w32tow8 = map fromIntegral . concat . map f
-    f w = [ (w `shiftR` 24) .&. 0xff
-          , (w `shiftR` 16) .&. 0xff
-          , (w `shiftR` 8) .&. 0xff
-          , w .&. 0xff
-          ]
-
-coreCrypto :: Pbox -> BlowfishState -> (Word32, Word32) -> (Word32, Word32)
-coreCrypto p bs i = (\(l,r) -> (r `xor` p!17, l `xor` p!16))
-                  $ V.foldl' (doRound bs) i (V.take 16 p)
-  where
-    doRound :: BlowfishState -> (Word32, Word32) -> Word32 -> (Word32, Word32)
-    doRound (BF _ s0 s1 s2 s3) (l,r) pv =
-        let newr = l `xor` pv
-            newl = r `xor` (f newr)
-        in (newl, newr)
-          where
-            f   :: Word32 -> Word32
-            f t = let a = s0 ! (fromIntegral $ (t `shiftR` 24) .&. 0xff)
-                      b = s1 ! (fromIntegral $ (t `shiftR` 16) .&. 0xff)
-                      c = s2 ! (fromIntegral $ (t `shiftR` 8) .&. 0xff)
-                      d = s3 ! (fromIntegral $ t .&. 0xff)
-                  in ((a + b) `xor` c) + d
-
-bfMakeKey :: Key -> BlowfishState
-bfMakeKey (Key k) = procKey (0,0) (BF (V.zipWith xor k iPbox) iSbox0 iSbox1 iSbox2 iSbox3) 0
-
-procKey :: (Word32, Word32) -> BlowfishState -> Int -> BlowfishState
-procKey _     tpbf                    1042 = tpbf
-procKey (l,r) tpbf@(BF p s0 s1 s2 s3)    i = procKey (nl,nr) (newbf i) (i+2)
-  where (nl,nr) = coreCrypto p tpbf (l,r)
-        newbf x | x <   18 = (BF (p//[(x,nl),(x+1,nr)]) s0 s1 s2 s3)
-                | x <  274 = (BF p (s0//[(x-18,nl),(x-17,nr)]) s1 s2 s3)
-                | x <  530 = (BF p s0 (s1//[(x-274,nl),(x-273,nr)]) s2 s3)
-                | x <  786 = (BF p s0 s1 (s2//[(x-530,nl),(x-529,nr)]) s3)
-                | x < 1042 = (BF p s0 s1 s2 (s3//[(x-786,nl),(x-785,nr)]))
-                | otherwise = error "internal error: Crypto.Cipher.Blowfish:procKey "
-
-
-doChunks :: Int -> (B.ByteString -> B.ByteString) -> B.ByteString -> [B.ByteString]
-doChunks n f b =
-	let (x, rest) = B.splitAt n b in
-	if B.length rest >= n
-		then f x : doChunks n f rest
-		else [ f x ]
-
-toW32Pair :: B.ByteString -> (Word32, Word32)
-toW32Pair b = let (x1, x2) = B.splitAt 4 b
-                  w1 = decode32be x1
-                  w2 = decode32be x2
-              in (w1,w2)
-
-fromW32Pair :: (Word32, Word32) -> B.ByteString
-fromW32Pair (w1,w2)
-    = let w1' = fromIntegral w1
-          w2' = fromIntegral w2
-          w = (w1' `shiftL` 32) .|. w2'
-      in encode64be w
-
-decode32be :: B.ByteString -> Word32
-decode32be s = id $!
-    (fromIntegral (s `B.index` 0) `shiftL` 24) .|.
-    (fromIntegral (s `B.index` 1) `shiftL` 16) .|.
-    (fromIntegral (s `B.index` 2) `shiftL`  8) .|.
-    (fromIntegral (s `B.index` 3) )
-
-encode64be :: Word64 -> B.ByteString
-encode64be w = B.pack . map fromIntegral $
-                [ (w `shiftR` 56) .&. 0xff
-                , (w `shiftR` 48) .&. 0xff
-                , (w `shiftR` 40) .&. 0xff
-                , (w `shiftR` 32) .&. 0xff
-                , (w `shiftR` 24) .&. 0xff
-                , (w `shiftR` 16) .&. 0xff
-                , (w `shiftR` 8) .&. 0xff
-                , w .&. 0xff
-                ]
-
----------- INITIAL S AND P BOXES ARE THE HEXADECIMAL DIGITS OF PI ------------
-
--- TODO build these tables using TemplateHaskell and a digit extraction algorithm
-
-mkBox :: [Char] -> Vector Word32
-mkBox = V.fromList . map decode32be . doChunks 4 id . B.pack . map (fromIntegral . ord)
-
-iPbox :: Pbox
-iPbox = mkBox "\
-    \\x24\x3f\x6a\x88\x85\xa3\x08\xd3\x13\x19\x8a\x2e\x03\x70\x73\x44\
-    \\xa4\x09\x38\x22\x29\x9f\x31\xd0\x08\x2e\xfa\x98\xec\x4e\x6c\x89\
-    \\x45\x28\x21\xe6\x38\xd0\x13\x77\xbe\x54\x66\xcf\x34\xe9\x0c\x6c\
-    \\xc0\xac\x29\xb7\xc9\x7c\x50\xdd\x3f\x84\xd5\xb5\xb5\x47\x09\x17\
-    \\x92\x16\xd5\xd9\x89\x79\xfb\x1b\
-    \"
-
-iSbox0 :: Sbox
-iSbox0  = mkBox "\
-    \\xd1\x31\x0b\xa6\x98\xdf\xb5\xac\x2f\xfd\x72\xdb\xd0\x1a\xdf\xb7\
-    \\xb8\xe1\xaf\xed\x6a\x26\x7e\x96\xba\x7c\x90\x45\xf1\x2c\x7f\x99\
-    \\x24\xa1\x99\x47\xb3\x91\x6c\xf7\x08\x01\xf2\xe2\x85\x8e\xfc\x16\
-    \\x63\x69\x20\xd8\x71\x57\x4e\x69\xa4\x58\xfe\xa3\xf4\x93\x3d\x7e\
-    \\x0d\x95\x74\x8f\x72\x8e\xb6\x58\x71\x8b\xcd\x58\x82\x15\x4a\xee\
-    \\x7b\x54\xa4\x1d\xc2\x5a\x59\xb5\x9c\x30\xd5\x39\x2a\xf2\x60\x13\
-    \\xc5\xd1\xb0\x23\x28\x60\x85\xf0\xca\x41\x79\x18\xb8\xdb\x38\xef\
-    \\x8e\x79\xdc\xb0\x60\x3a\x18\x0e\x6c\x9e\x0e\x8b\xb0\x1e\x8a\x3e\
-    \\xd7\x15\x77\xc1\xbd\x31\x4b\x27\x78\xaf\x2f\xda\x55\x60\x5c\x60\
-    \\xe6\x55\x25\xf3\xaa\x55\xab\x94\x57\x48\x98\x62\x63\xe8\x14\x40\
-    \\x55\xca\x39\x6a\x2a\xab\x10\xb6\xb4\xcc\x5c\x34\x11\x41\xe8\xce\
-    \\xa1\x54\x86\xaf\x7c\x72\xe9\x93\xb3\xee\x14\x11\x63\x6f\xbc\x2a\
-    \\x2b\xa9\xc5\x5d\x74\x18\x31\xf6\xce\x5c\x3e\x16\x9b\x87\x93\x1e\
-    \\xaf\xd6\xba\x33\x6c\x24\xcf\x5c\x7a\x32\x53\x81\x28\x95\x86\x77\
-    \\x3b\x8f\x48\x98\x6b\x4b\xb9\xaf\xc4\xbf\xe8\x1b\x66\x28\x21\x93\
-    \\x61\xd8\x09\xcc\xfb\x21\xa9\x91\x48\x7c\xac\x60\x5d\xec\x80\x32\
-    \\xef\x84\x5d\x5d\xe9\x85\x75\xb1\xdc\x26\x23\x02\xeb\x65\x1b\x88\
-    \\x23\x89\x3e\x81\xd3\x96\xac\xc5\x0f\x6d\x6f\xf3\x83\xf4\x42\x39\
-    \\x2e\x0b\x44\x82\xa4\x84\x20\x04\x69\xc8\xf0\x4a\x9e\x1f\x9b\x5e\
-    \\x21\xc6\x68\x42\xf6\xe9\x6c\x9a\x67\x0c\x9c\x61\xab\xd3\x88\xf0\
-    \\x6a\x51\xa0\xd2\xd8\x54\x2f\x68\x96\x0f\xa7\x28\xab\x51\x33\xa3\
-    \\x6e\xef\x0b\x6c\x13\x7a\x3b\xe4\xba\x3b\xf0\x50\x7e\xfb\x2a\x98\
-    \\xa1\xf1\x65\x1d\x39\xaf\x01\x76\x66\xca\x59\x3e\x82\x43\x0e\x88\
-    \\x8c\xee\x86\x19\x45\x6f\x9f\xb4\x7d\x84\xa5\xc3\x3b\x8b\x5e\xbe\
-    \\xe0\x6f\x75\xd8\x85\xc1\x20\x73\x40\x1a\x44\x9f\x56\xc1\x6a\xa6\
-    \\x4e\xd3\xaa\x62\x36\x3f\x77\x06\x1b\xfe\xdf\x72\x42\x9b\x02\x3d\
-    \\x37\xd0\xd7\x24\xd0\x0a\x12\x48\xdb\x0f\xea\xd3\x49\xf1\xc0\x9b\
-    \\x07\x53\x72\xc9\x80\x99\x1b\x7b\x25\xd4\x79\xd8\xf6\xe8\xde\xf7\
-    \\xe3\xfe\x50\x1a\xb6\x79\x4c\x3b\x97\x6c\xe0\xbd\x04\xc0\x06\xba\
-    \\xc1\xa9\x4f\xb6\x40\x9f\x60\xc4\x5e\x5c\x9e\xc2\x19\x6a\x24\x63\
-    \\x68\xfb\x6f\xaf\x3e\x6c\x53\xb5\x13\x39\xb2\xeb\x3b\x52\xec\x6f\
-    \\x6d\xfc\x51\x1f\x9b\x30\x95\x2c\xcc\x81\x45\x44\xaf\x5e\xbd\x09\
-    \\xbe\xe3\xd0\x04\xde\x33\x4a\xfd\x66\x0f\x28\x07\x19\x2e\x4b\xb3\
-    \\xc0\xcb\xa8\x57\x45\xc8\x74\x0f\xd2\x0b\x5f\x39\xb9\xd3\xfb\xdb\
-    \\x55\x79\xc0\xbd\x1a\x60\x32\x0a\xd6\xa1\x00\xc6\x40\x2c\x72\x79\
-    \\x67\x9f\x25\xfe\xfb\x1f\xa3\xcc\x8e\xa5\xe9\xf8\xdb\x32\x22\xf8\
-    \\x3c\x75\x16\xdf\xfd\x61\x6b\x15\x2f\x50\x1e\xc8\xad\x05\x52\xab\
-    \\x32\x3d\xb5\xfa\xfd\x23\x87\x60\x53\x31\x7b\x48\x3e\x00\xdf\x82\
-    \\x9e\x5c\x57\xbb\xca\x6f\x8c\xa0\x1a\x87\x56\x2e\xdf\x17\x69\xdb\
-    \\xd5\x42\xa8\xf6\x28\x7e\xff\xc3\xac\x67\x32\xc6\x8c\x4f\x55\x73\
-    \\x69\x5b\x27\xb0\xbb\xca\x58\xc8\xe1\xff\xa3\x5d\xb8\xf0\x11\xa0\
-    \\x10\xfa\x3d\x98\xfd\x21\x83\xb8\x4a\xfc\xb5\x6c\x2d\xd1\xd3\x5b\
-    \\x9a\x53\xe4\x79\xb6\xf8\x45\x65\xd2\x8e\x49\xbc\x4b\xfb\x97\x90\
-    \\xe1\xdd\xf2\xda\xa4\xcb\x7e\x33\x62\xfb\x13\x41\xce\xe4\xc6\xe8\
-    \\xef\x20\xca\xda\x36\x77\x4c\x01\xd0\x7e\x9e\xfe\x2b\xf1\x1f\xb4\
-    \\x95\xdb\xda\x4d\xae\x90\x91\x98\xea\xad\x8e\x71\x6b\x93\xd5\xa0\
-    \\xd0\x8e\xd1\xd0\xaf\xc7\x25\xe0\x8e\x3c\x5b\x2f\x8e\x75\x94\xb7\
-    \\x8f\xf6\xe2\xfb\xf2\x12\x2b\x64\x88\x88\xb8\x12\x90\x0d\xf0\x1c\
-    \\x4f\xad\x5e\xa0\x68\x8f\xc3\x1c\xd1\xcf\xf1\x91\xb3\xa8\xc1\xad\
-    \\x2f\x2f\x22\x18\xbe\x0e\x17\x77\xea\x75\x2d\xfe\x8b\x02\x1f\xa1\
-    \\xe5\xa0\xcc\x0f\xb5\x6f\x74\xe8\x18\xac\xf3\xd6\xce\x89\xe2\x99\
-    \\xb4\xa8\x4f\xe0\xfd\x13\xe0\xb7\x7c\xc4\x3b\x81\xd2\xad\xa8\xd9\
-    \\x16\x5f\xa2\x66\x80\x95\x77\x05\x93\xcc\x73\x14\x21\x1a\x14\x77\
-    \\xe6\xad\x20\x65\x77\xb5\xfa\x86\xc7\x54\x42\xf5\xfb\x9d\x35\xcf\
-    \\xeb\xcd\xaf\x0c\x7b\x3e\x89\xa0\xd6\x41\x1b\xd3\xae\x1e\x7e\x49\
-    \\x00\x25\x0e\x2d\x20\x71\xb3\x5e\x22\x68\x00\xbb\x57\xb8\xe0\xaf\
-    \\x24\x64\x36\x9b\xf0\x09\xb9\x1e\x55\x63\x91\x1d\x59\xdf\xa6\xaa\
-    \\x78\xc1\x43\x89\xd9\x5a\x53\x7f\x20\x7d\x5b\xa2\x02\xe5\xb9\xc5\
-    \\x83\x26\x03\x76\x62\x95\xcf\xa9\x11\xc8\x19\x68\x4e\x73\x4a\x41\
-    \\xb3\x47\x2d\xca\x7b\x14\xa9\x4a\x1b\x51\x00\x52\x9a\x53\x29\x15\
-    \\xd6\x0f\x57\x3f\xbc\x9b\xc6\xe4\x2b\x60\xa4\x76\x81\xe6\x74\x00\
-    \\x08\xba\x6f\xb5\x57\x1b\xe9\x1f\xf2\x96\xec\x6b\x2a\x0d\xd9\x15\
-    \\xb6\x63\x65\x21\xe7\xb9\xf9\xb6\xff\x34\x05\x2e\xc5\x85\x56\x64\
-    \\x53\xb0\x2d\x5d\xa9\x9f\x8f\xa1\x08\xba\x47\x99\x6e\x85\x07\x6a\
-    \"
-
-iSbox1 :: Sbox
-iSbox1  = mkBox "\
-    \\x4b\x7a\x70\xe9\xb5\xb3\x29\x44\xdb\x75\x09\x2e\xc4\x19\x26\x23\
-    \\xad\x6e\xa6\xb0\x49\xa7\xdf\x7d\x9c\xee\x60\xb8\x8f\xed\xb2\x66\
-    \\xec\xaa\x8c\x71\x69\x9a\x17\xff\x56\x64\x52\x6c\xc2\xb1\x9e\xe1\
-    \\x19\x36\x02\xa5\x75\x09\x4c\x29\xa0\x59\x13\x40\xe4\x18\x3a\x3e\
-    \\x3f\x54\x98\x9a\x5b\x42\x9d\x65\x6b\x8f\xe4\xd6\x99\xf7\x3f\xd6\
-    \\xa1\xd2\x9c\x07\xef\xe8\x30\xf5\x4d\x2d\x38\xe6\xf0\x25\x5d\xc1\
-    \\x4c\xdd\x20\x86\x84\x70\xeb\x26\x63\x82\xe9\xc6\x02\x1e\xcc\x5e\
-    \\x09\x68\x6b\x3f\x3e\xba\xef\xc9\x3c\x97\x18\x14\x6b\x6a\x70\xa1\
-    \\x68\x7f\x35\x84\x52\xa0\xe2\x86\xb7\x9c\x53\x05\xaa\x50\x07\x37\
-    \\x3e\x07\x84\x1c\x7f\xde\xae\x5c\x8e\x7d\x44\xec\x57\x16\xf2\xb8\
-    \\xb0\x3a\xda\x37\xf0\x50\x0c\x0d\xf0\x1c\x1f\x04\x02\x00\xb3\xff\
-    \\xae\x0c\xf5\x1a\x3c\xb5\x74\xb2\x25\x83\x7a\x58\xdc\x09\x21\xbd\
-    \\xd1\x91\x13\xf9\x7c\xa9\x2f\xf6\x94\x32\x47\x73\x22\xf5\x47\x01\
-    \\x3a\xe5\xe5\x81\x37\xc2\xda\xdc\xc8\xb5\x76\x34\x9a\xf3\xdd\xa7\
-    \\xa9\x44\x61\x46\x0f\xd0\x03\x0e\xec\xc8\xc7\x3e\xa4\x75\x1e\x41\
-    \\xe2\x38\xcd\x99\x3b\xea\x0e\x2f\x32\x80\xbb\xa1\x18\x3e\xb3\x31\
-    \\x4e\x54\x8b\x38\x4f\x6d\xb9\x08\x6f\x42\x0d\x03\xf6\x0a\x04\xbf\
-    \\x2c\xb8\x12\x90\x24\x97\x7c\x79\x56\x79\xb0\x72\xbc\xaf\x89\xaf\
-    \\xde\x9a\x77\x1f\xd9\x93\x08\x10\xb3\x8b\xae\x12\xdc\xcf\x3f\x2e\
-    \\x55\x12\x72\x1f\x2e\x6b\x71\x24\x50\x1a\xdd\xe6\x9f\x84\xcd\x87\
-    \\x7a\x58\x47\x18\x74\x08\xda\x17\xbc\x9f\x9a\xbc\xe9\x4b\x7d\x8c\
-    \\xec\x7a\xec\x3a\xdb\x85\x1d\xfa\x63\x09\x43\x66\xc4\x64\xc3\xd2\
-    \\xef\x1c\x18\x47\x32\x15\xd9\x08\xdd\x43\x3b\x37\x24\xc2\xba\x16\
-    \\x12\xa1\x4d\x43\x2a\x65\xc4\x51\x50\x94\x00\x02\x13\x3a\xe4\xdd\
-    \\x71\xdf\xf8\x9e\x10\x31\x4e\x55\x81\xac\x77\xd6\x5f\x11\x19\x9b\
-    \\x04\x35\x56\xf1\xd7\xa3\xc7\x6b\x3c\x11\x18\x3b\x59\x24\xa5\x09\
-    \\xf2\x8f\xe6\xed\x97\xf1\xfb\xfa\x9e\xba\xbf\x2c\x1e\x15\x3c\x6e\
-    \\x86\xe3\x45\x70\xea\xe9\x6f\xb1\x86\x0e\x5e\x0a\x5a\x3e\x2a\xb3\
-    \\x77\x1f\xe7\x1c\x4e\x3d\x06\xfa\x29\x65\xdc\xb9\x99\xe7\x1d\x0f\
-    \\x80\x3e\x89\xd6\x52\x66\xc8\x25\x2e\x4c\xc9\x78\x9c\x10\xb3\x6a\
-    \\xc6\x15\x0e\xba\x94\xe2\xea\x78\xa5\xfc\x3c\x53\x1e\x0a\x2d\xf4\
-    \\xf2\xf7\x4e\xa7\x36\x1d\x2b\x3d\x19\x39\x26\x0f\x19\xc2\x79\x60\
-    \\x52\x23\xa7\x08\xf7\x13\x12\xb6\xeb\xad\xfe\x6e\xea\xc3\x1f\x66\
-    \\xe3\xbc\x45\x95\xa6\x7b\xc8\x83\xb1\x7f\x37\xd1\x01\x8c\xff\x28\
-    \\xc3\x32\xdd\xef\xbe\x6c\x5a\xa5\x65\x58\x21\x85\x68\xab\x98\x02\
-    \\xee\xce\xa5\x0f\xdb\x2f\x95\x3b\x2a\xef\x7d\xad\x5b\x6e\x2f\x84\
-    \\x15\x21\xb6\x28\x29\x07\x61\x70\xec\xdd\x47\x75\x61\x9f\x15\x10\
-    \\x13\xcc\xa8\x30\xeb\x61\xbd\x96\x03\x34\xfe\x1e\xaa\x03\x63\xcf\
-    \\xb5\x73\x5c\x90\x4c\x70\xa2\x39\xd5\x9e\x9e\x0b\xcb\xaa\xde\x14\
-    \\xee\xcc\x86\xbc\x60\x62\x2c\xa7\x9c\xab\x5c\xab\xb2\xf3\x84\x6e\
-    \\x64\x8b\x1e\xaf\x19\xbd\xf0\xca\xa0\x23\x69\xb9\x65\x5a\xbb\x50\
-    \\x40\x68\x5a\x32\x3c\x2a\xb4\xb3\x31\x9e\xe9\xd5\xc0\x21\xb8\xf7\
-    \\x9b\x54\x0b\x19\x87\x5f\xa0\x99\x95\xf7\x99\x7e\x62\x3d\x7d\xa8\
-    \\xf8\x37\x88\x9a\x97\xe3\x2d\x77\x11\xed\x93\x5f\x16\x68\x12\x81\
-    \\x0e\x35\x88\x29\xc7\xe6\x1f\xd6\x96\xde\xdf\xa1\x78\x58\xba\x99\
-    \\x57\xf5\x84\xa5\x1b\x22\x72\x63\x9b\x83\xc3\xff\x1a\xc2\x46\x96\
-    \\xcd\xb3\x0a\xeb\x53\x2e\x30\x54\x8f\xd9\x48\xe4\x6d\xbc\x31\x28\
-    \\x58\xeb\xf2\xef\x34\xc6\xff\xea\xfe\x28\xed\x61\xee\x7c\x3c\x73\
-    \\x5d\x4a\x14\xd9\xe8\x64\xb7\xe3\x42\x10\x5d\x14\x20\x3e\x13\xe0\
-    \\x45\xee\xe2\xb6\xa3\xaa\xab\xea\xdb\x6c\x4f\x15\xfa\xcb\x4f\xd0\
-    \\xc7\x42\xf4\x42\xef\x6a\xbb\xb5\x65\x4f\x3b\x1d\x41\xcd\x21\x05\
-    \\xd8\x1e\x79\x9e\x86\x85\x4d\xc7\xe4\x4b\x47\x6a\x3d\x81\x62\x50\
-    \\xcf\x62\xa1\xf2\x5b\x8d\x26\x46\xfc\x88\x83\xa0\xc1\xc7\xb6\xa3\
-    \\x7f\x15\x24\xc3\x69\xcb\x74\x92\x47\x84\x8a\x0b\x56\x92\xb2\x85\
-    \\x09\x5b\xbf\x00\xad\x19\x48\x9d\x14\x62\xb1\x74\x23\x82\x0e\x00\
-    \\x58\x42\x8d\x2a\x0c\x55\xf5\xea\x1d\xad\xf4\x3e\x23\x3f\x70\x61\
-    \\x33\x72\xf0\x92\x8d\x93\x7e\x41\xd6\x5f\xec\xf1\x6c\x22\x3b\xdb\
-    \\x7c\xde\x37\x59\xcb\xee\x74\x60\x40\x85\xf2\xa7\xce\x77\x32\x6e\
-    \\xa6\x07\x80\x84\x19\xf8\x50\x9e\xe8\xef\xd8\x55\x61\xd9\x97\x35\
-    \\xa9\x69\xa7\xaa\xc5\x0c\x06\xc2\x5a\x04\xab\xfc\x80\x0b\xca\xdc\
-    \\x9e\x44\x7a\x2e\xc3\x45\x34\x84\xfd\xd5\x67\x05\x0e\x1e\x9e\xc9\
-    \\xdb\x73\xdb\xd3\x10\x55\x88\xcd\x67\x5f\xda\x79\xe3\x67\x43\x40\
-    \\xc5\xc4\x34\x65\x71\x3e\x38\xd8\x3d\x28\xf8\x9e\xf1\x6d\xff\x20\
-    \\x15\x3e\x21\xe7\x8f\xb0\x3d\x4a\xe6\xe3\x9f\x2b\xdb\x83\xad\xf7\
-    \"
-
-iSbox2 :: Sbox
-iSbox2  = mkBox "\
-    \\xe9\x3d\x5a\x68\x94\x81\x40\xf7\xf6\x4c\x26\x1c\x94\x69\x29\x34\
-    \\x41\x15\x20\xf7\x76\x02\xd4\xf7\xbc\xf4\x6b\x2e\xd4\xa2\x00\x68\
-    \\xd4\x08\x24\x71\x33\x20\xf4\x6a\x43\xb7\xd4\xb7\x50\x00\x61\xaf\
-    \\x1e\x39\xf6\x2e\x97\x24\x45\x46\x14\x21\x4f\x74\xbf\x8b\x88\x40\
-    \\x4d\x95\xfc\x1d\x96\xb5\x91\xaf\x70\xf4\xdd\xd3\x66\xa0\x2f\x45\
-    \\xbf\xbc\x09\xec\x03\xbd\x97\x85\x7f\xac\x6d\xd0\x31\xcb\x85\x04\
-    \\x96\xeb\x27\xb3\x55\xfd\x39\x41\xda\x25\x47\xe6\xab\xca\x0a\x9a\
-    \\x28\x50\x78\x25\x53\x04\x29\xf4\x0a\x2c\x86\xda\xe9\xb6\x6d\xfb\
-    \\x68\xdc\x14\x62\xd7\x48\x69\x00\x68\x0e\xc0\xa4\x27\xa1\x8d\xee\
-    \\x4f\x3f\xfe\xa2\xe8\x87\xad\x8c\xb5\x8c\xe0\x06\x7a\xf4\xd6\xb6\
-    \\xaa\xce\x1e\x7c\xd3\x37\x5f\xec\xce\x78\xa3\x99\x40\x6b\x2a\x42\
-    \\x20\xfe\x9e\x35\xd9\xf3\x85\xb9\xee\x39\xd7\xab\x3b\x12\x4e\x8b\
-    \\x1d\xc9\xfa\xf7\x4b\x6d\x18\x56\x26\xa3\x66\x31\xea\xe3\x97\xb2\
-    \\x3a\x6e\xfa\x74\xdd\x5b\x43\x32\x68\x41\xe7\xf7\xca\x78\x20\xfb\
-    \\xfb\x0a\xf5\x4e\xd8\xfe\xb3\x97\x45\x40\x56\xac\xba\x48\x95\x27\
-    \\x55\x53\x3a\x3a\x20\x83\x8d\x87\xfe\x6b\xa9\xb7\xd0\x96\x95\x4b\
-    \\x55\xa8\x67\xbc\xa1\x15\x9a\x58\xcc\xa9\x29\x63\x99\xe1\xdb\x33\
-    \\xa6\x2a\x4a\x56\x3f\x31\x25\xf9\x5e\xf4\x7e\x1c\x90\x29\x31\x7c\
-    \\xfd\xf8\xe8\x02\x04\x27\x2f\x70\x80\xbb\x15\x5c\x05\x28\x2c\xe3\
-    \\x95\xc1\x15\x48\xe4\xc6\x6d\x22\x48\xc1\x13\x3f\xc7\x0f\x86\xdc\
-    \\x07\xf9\xc9\xee\x41\x04\x1f\x0f\x40\x47\x79\xa4\x5d\x88\x6e\x17\
-    \\x32\x5f\x51\xeb\xd5\x9b\xc0\xd1\xf2\xbc\xc1\x8f\x41\x11\x35\x64\
-    \\x25\x7b\x78\x34\x60\x2a\x9c\x60\xdf\xf8\xe8\xa3\x1f\x63\x6c\x1b\
-    \\x0e\x12\xb4\xc2\x02\xe1\x32\x9e\xaf\x66\x4f\xd1\xca\xd1\x81\x15\
-    \\x6b\x23\x95\xe0\x33\x3e\x92\xe1\x3b\x24\x0b\x62\xee\xbe\xb9\x22\
-    \\x85\xb2\xa2\x0e\xe6\xba\x0d\x99\xde\x72\x0c\x8c\x2d\xa2\xf7\x28\
-    \\xd0\x12\x78\x45\x95\xb7\x94\xfd\x64\x7d\x08\x62\xe7\xcc\xf5\xf0\
-    \\x54\x49\xa3\x6f\x87\x7d\x48\xfa\xc3\x9d\xfd\x27\xf3\x3e\x8d\x1e\
-    \\x0a\x47\x63\x41\x99\x2e\xff\x74\x3a\x6f\x6e\xab\xf4\xf8\xfd\x37\
-    \\xa8\x12\xdc\x60\xa1\xeb\xdd\xf8\x99\x1b\xe1\x4c\xdb\x6e\x6b\x0d\
-    \\xc6\x7b\x55\x10\x6d\x67\x2c\x37\x27\x65\xd4\x3b\xdc\xd0\xe8\x04\
-    \\xf1\x29\x0d\xc7\xcc\x00\xff\xa3\xb5\x39\x0f\x92\x69\x0f\xed\x0b\
-    \\x66\x7b\x9f\xfb\xce\xdb\x7d\x9c\xa0\x91\xcf\x0b\xd9\x15\x5e\xa3\
-    \\xbb\x13\x2f\x88\x51\x5b\xad\x24\x7b\x94\x79\xbf\x76\x3b\xd6\xeb\
-    \\x37\x39\x2e\xb3\xcc\x11\x59\x79\x80\x26\xe2\x97\xf4\x2e\x31\x2d\
-    \\x68\x42\xad\xa7\xc6\x6a\x2b\x3b\x12\x75\x4c\xcc\x78\x2e\xf1\x1c\
-    \\x6a\x12\x42\x37\xb7\x92\x51\xe7\x06\xa1\xbb\xe6\x4b\xfb\x63\x50\
-    \\x1a\x6b\x10\x18\x11\xca\xed\xfa\x3d\x25\xbd\xd8\xe2\xe1\xc3\xc9\
-    \\x44\x42\x16\x59\x0a\x12\x13\x86\xd9\x0c\xec\x6e\xd5\xab\xea\x2a\
-    \\x64\xaf\x67\x4e\xda\x86\xa8\x5f\xbe\xbf\xe9\x88\x64\xe4\xc3\xfe\
-    \\x9d\xbc\x80\x57\xf0\xf7\xc0\x86\x60\x78\x7b\xf8\x60\x03\x60\x4d\
-    \\xd1\xfd\x83\x46\xf6\x38\x1f\xb0\x77\x45\xae\x04\xd7\x36\xfc\xcc\
-    \\x83\x42\x6b\x33\xf0\x1e\xab\x71\xb0\x80\x41\x87\x3c\x00\x5e\x5f\
-    \\x77\xa0\x57\xbe\xbd\xe8\xae\x24\x55\x46\x42\x99\xbf\x58\x2e\x61\
-    \\x4e\x58\xf4\x8f\xf2\xdd\xfd\xa2\xf4\x74\xef\x38\x87\x89\xbd\xc2\
-    \\x53\x66\xf9\xc3\xc8\xb3\x8e\x74\xb4\x75\xf2\x55\x46\xfc\xd9\xb9\
-    \\x7a\xeb\x26\x61\x8b\x1d\xdf\x84\x84\x6a\x0e\x79\x91\x5f\x95\xe2\
-    \\x46\x6e\x59\x8e\x20\xb4\x57\x70\x8c\xd5\x55\x91\xc9\x02\xde\x4c\
-    \\xb9\x0b\xac\xe1\xbb\x82\x05\xd0\x11\xa8\x62\x48\x75\x74\xa9\x9e\
-    \\xb7\x7f\x19\xb6\xe0\xa9\xdc\x09\x66\x2d\x09\xa1\xc4\x32\x46\x33\
-    \\xe8\x5a\x1f\x02\x09\xf0\xbe\x8c\x4a\x99\xa0\x25\x1d\x6e\xfe\x10\
-    \\x1a\xb9\x3d\x1d\x0b\xa5\xa4\xdf\xa1\x86\xf2\x0f\x28\x68\xf1\x69\
-    \\xdc\xb7\xda\x83\x57\x39\x06\xfe\xa1\xe2\xce\x9b\x4f\xcd\x7f\x52\
-    \\x50\x11\x5e\x01\xa7\x06\x83\xfa\xa0\x02\xb5\xc4\x0d\xe6\xd0\x27\
-    \\x9a\xf8\x8c\x27\x77\x3f\x86\x41\xc3\x60\x4c\x06\x61\xa8\x06\xb5\
-    \\xf0\x17\x7a\x28\xc0\xf5\x86\xe0\x00\x60\x58\xaa\x30\xdc\x7d\x62\
-    \\x11\xe6\x9e\xd7\x23\x38\xea\x63\x53\xc2\xdd\x94\xc2\xc2\x16\x34\
-    \\xbb\xcb\xee\x56\x90\xbc\xb6\xde\xeb\xfc\x7d\xa1\xce\x59\x1d\x76\
-    \\x6f\x05\xe4\x09\x4b\x7c\x01\x88\x39\x72\x0a\x3d\x7c\x92\x7c\x24\
-    \\x86\xe3\x72\x5f\x72\x4d\x9d\xb9\x1a\xc1\x5b\xb4\xd3\x9e\xb8\xfc\
-    \\xed\x54\x55\x78\x08\xfc\xa5\xb5\xd8\x3d\x7c\xd3\x4d\xad\x0f\xc4\
-    \\x1e\x50\xef\x5e\xb1\x61\xe6\xf8\xa2\x85\x14\xd9\x6c\x51\x13\x3c\
-    \\x6f\xd5\xc7\xe7\x56\xe1\x4e\xc4\x36\x2a\xbf\xce\xdd\xc6\xc8\x37\
-    \\xd7\x9a\x32\x34\x92\x63\x82\x12\x67\x0e\xfa\x8e\x40\x60\x00\xe0\
-    \"
-  
-iSbox3 :: Sbox
-iSbox3  = mkBox "\
-    \\x3a\x39\xce\x37\xd3\xfa\xf5\xcf\xab\xc2\x77\x37\x5a\xc5\x2d\x1b\
-    \\x5c\xb0\x67\x9e\x4f\xa3\x37\x42\xd3\x82\x27\x40\x99\xbc\x9b\xbe\
-    \\xd5\x11\x8e\x9d\xbf\x0f\x73\x15\xd6\x2d\x1c\x7e\xc7\x00\xc4\x7b\
-    \\xb7\x8c\x1b\x6b\x21\xa1\x90\x45\xb2\x6e\xb1\xbe\x6a\x36\x6e\xb4\
-    \\x57\x48\xab\x2f\xbc\x94\x6e\x79\xc6\xa3\x76\xd2\x65\x49\xc2\xc8\
-    \\x53\x0f\xf8\xee\x46\x8d\xde\x7d\xd5\x73\x0a\x1d\x4c\xd0\x4d\xc6\
-    \\x29\x39\xbb\xdb\xa9\xba\x46\x50\xac\x95\x26\xe8\xbe\x5e\xe3\x04\
-    \\xa1\xfa\xd5\xf0\x6a\x2d\x51\x9a\x63\xef\x8c\xe2\x9a\x86\xee\x22\
-    \\xc0\x89\xc2\xb8\x43\x24\x2e\xf6\xa5\x1e\x03\xaa\x9c\xf2\xd0\xa4\
-    \\x83\xc0\x61\xba\x9b\xe9\x6a\x4d\x8f\xe5\x15\x50\xba\x64\x5b\xd6\
-    \\x28\x26\xa2\xf9\xa7\x3a\x3a\xe1\x4b\xa9\x95\x86\xef\x55\x62\xe9\
-    \\xc7\x2f\xef\xd3\xf7\x52\xf7\xda\x3f\x04\x6f\x69\x77\xfa\x0a\x59\
-    \\x80\xe4\xa9\x15\x87\xb0\x86\x01\x9b\x09\xe6\xad\x3b\x3e\xe5\x93\
-    \\xe9\x90\xfd\x5a\x9e\x34\xd7\x97\x2c\xf0\xb7\xd9\x02\x2b\x8b\x51\
-    \\x96\xd5\xac\x3a\x01\x7d\xa6\x7d\xd1\xcf\x3e\xd6\x7c\x7d\x2d\x28\
-    \\x1f\x9f\x25\xcf\xad\xf2\xb8\x9b\x5a\xd6\xb4\x72\x5a\x88\xf5\x4c\
-    \\xe0\x29\xac\x71\xe0\x19\xa5\xe6\x47\xb0\xac\xfd\xed\x93\xfa\x9b\
-    \\xe8\xd3\xc4\x8d\x28\x3b\x57\xcc\xf8\xd5\x66\x29\x79\x13\x2e\x28\
-    \\x78\x5f\x01\x91\xed\x75\x60\x55\xf7\x96\x0e\x44\xe3\xd3\x5e\x8c\
-    \\x15\x05\x6d\xd4\x88\xf4\x6d\xba\x03\xa1\x61\x25\x05\x64\xf0\xbd\
-    \\xc3\xeb\x9e\x15\x3c\x90\x57\xa2\x97\x27\x1a\xec\xa9\x3a\x07\x2a\
-    \\x1b\x3f\x6d\x9b\x1e\x63\x21\xf5\xf5\x9c\x66\xfb\x26\xdc\xf3\x19\
-    \\x75\x33\xd9\x28\xb1\x55\xfd\xf5\x03\x56\x34\x82\x8a\xba\x3c\xbb\
-    \\x28\x51\x77\x11\xc2\x0a\xd9\xf8\xab\xcc\x51\x67\xcc\xad\x92\x5f\
-    \\x4d\xe8\x17\x51\x38\x30\xdc\x8e\x37\x9d\x58\x62\x93\x20\xf9\x91\
-    \\xea\x7a\x90\xc2\xfb\x3e\x7b\xce\x51\x21\xce\x64\x77\x4f\xbe\x32\
-    \\xa8\xb6\xe3\x7e\xc3\x29\x3d\x46\x48\xde\x53\x69\x64\x13\xe6\x80\
-    \\xa2\xae\x08\x10\xdd\x6d\xb2\x24\x69\x85\x2d\xfd\x09\x07\x21\x66\
-    \\xb3\x9a\x46\x0a\x64\x45\xc0\xdd\x58\x6c\xde\xcf\x1c\x20\xc8\xae\
-    \\x5b\xbe\xf7\xdd\x1b\x58\x8d\x40\xcc\xd2\x01\x7f\x6b\xb4\xe3\xbb\
-    \\xdd\xa2\x6a\x7e\x3a\x59\xff\x45\x3e\x35\x0a\x44\xbc\xb4\xcd\xd5\
-    \\x72\xea\xce\xa8\xfa\x64\x84\xbb\x8d\x66\x12\xae\xbf\x3c\x6f\x47\
-    \\xd2\x9b\xe4\x63\x54\x2f\x5d\x9e\xae\xc2\x77\x1b\xf6\x4e\x63\x70\
-    \\x74\x0e\x0d\x8d\xe7\x5b\x13\x57\xf8\x72\x16\x71\xaf\x53\x7d\x5d\
-    \\x40\x40\xcb\x08\x4e\xb4\xe2\xcc\x34\xd2\x46\x6a\x01\x15\xaf\x84\
-    \\xe1\xb0\x04\x28\x95\x98\x3a\x1d\x06\xb8\x9f\xb4\xce\x6e\xa0\x48\
-    \\x6f\x3f\x3b\x82\x35\x20\xab\x82\x01\x1a\x1d\x4b\x27\x72\x27\xf8\
-    \\x61\x15\x60\xb1\xe7\x93\x3f\xdc\xbb\x3a\x79\x2b\x34\x45\x25\xbd\
-    \\xa0\x88\x39\xe1\x51\xce\x79\x4b\x2f\x32\xc9\xb7\xa0\x1f\xba\xc9\
-    \\xe0\x1c\xc8\x7e\xbc\xc7\xd1\xf6\xcf\x01\x11\xc3\xa1\xe8\xaa\xc7\
-    \\x1a\x90\x87\x49\xd4\x4f\xbd\x9a\xd0\xda\xde\xcb\xd5\x0a\xda\x38\
-    \\x03\x39\xc3\x2a\xc6\x91\x36\x67\x8d\xf9\x31\x7c\xe0\xb1\x2b\x4f\
-    \\xf7\x9e\x59\xb7\x43\xf5\xbb\x3a\xf2\xd5\x19\xff\x27\xd9\x45\x9c\
-    \\xbf\x97\x22\x2c\x15\xe6\xfc\x2a\x0f\x91\xfc\x71\x9b\x94\x15\x25\
-    \\xfa\xe5\x93\x61\xce\xb6\x9c\xeb\xc2\xa8\x64\x59\x12\xba\xa8\xd1\
-    \\xb6\xc1\x07\x5e\xe3\x05\x6a\x0c\x10\xd2\x50\x65\xcb\x03\xa4\x42\
-    \\xe0\xec\x6e\x0e\x16\x98\xdb\x3b\x4c\x98\xa0\xbe\x32\x78\xe9\x64\
-    \\x9f\x1f\x95\x32\xe0\xd3\x92\xdf\xd3\xa0\x34\x2b\x89\x71\xf2\x1e\
-    \\x1b\x0a\x74\x41\x4b\xa3\x34\x8c\xc5\xbe\x71\x20\xc3\x76\x32\xd8\
-    \\xdf\x35\x9f\x8d\x9b\x99\x2f\x2e\xe6\x0b\x6f\x47\x0f\xe3\xf1\x1d\
-    \\xe5\x4c\xda\x54\x1e\xda\xd8\x91\xce\x62\x79\xcf\xcd\x3e\x7e\x6f\
-    \\x16\x18\xb1\x66\xfd\x2c\x1d\x05\x84\x8f\xd2\xc5\xf6\xfb\x22\x99\
-    \\xf5\x23\xf3\x57\xa6\x32\x76\x23\x93\xa8\x35\x31\x56\xcc\xcd\x02\
-    \\xac\xf0\x81\x62\x5a\x75\xeb\xb5\x6e\x16\x36\x97\x88\xd2\x73\xcc\
-    \\xde\x96\x62\x92\x81\xb9\x49\xd0\x4c\x50\x90\x1b\x71\xc6\x56\x14\
-    \\xe6\xc6\xc7\xbd\x32\x7a\x14\x0a\x45\xe1\xd0\x06\xc3\xf2\x7b\x9a\
-    \\xc9\xaa\x53\xfd\x62\xa8\x0f\x00\xbb\x25\xbf\xe2\x35\xbd\xd2\xf6\
-    \\x71\x12\x69\x05\xb2\x04\x02\x22\xb6\xcb\xcf\x7c\xcd\x76\x9c\x2b\
-    \\x53\x11\x3e\xc0\x16\x40\xe3\xd3\x38\xab\xbd\x60\x25\x47\xad\xf0\
-    \\xba\x38\x20\x9c\xf7\x46\xce\x76\x77\xaf\xa1\xc5\x20\x75\x60\x60\
-    \\x85\xcb\xfe\x4e\x8a\xe8\x8d\xd8\x7a\xaa\xf9\xb0\x4c\xf9\xaa\x7e\
-    \\x19\x48\xc2\x5c\x02\xfb\x8a\x8c\x01\xc3\x6a\xe4\xd6\xeb\xe1\xf9\
-    \\x90\xd4\xf8\x69\xa6\x5c\xde\xa0\x3f\x09\x25\x2d\xc2\x08\xe6\x9f\
-    \\xb7\x4e\x61\x32\xce\x77\xe2\x5b\x57\x8f\xdf\xe3\x3a\xc3\x72\xe6\
-    \"
diff --git a/Crypto/Cipher/Camellia.hs b/Crypto/Cipher/Camellia.hs
deleted file mode 100644
--- a/Crypto/Cipher/Camellia.hs
+++ /dev/null
@@ -1,329 +0,0 @@
--- |
--- Module      : Crypto.Cipher.Camellia
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
--- this only cover Camellia 128 bits for now, API will change once
--- 192 and 256 mode are implemented too
-
-module Crypto.Cipher.Camellia
-	( Key(..)
-	, initKey128
-	, encrypt
-	, decrypt
-	) where
-
-import Data.Word
-import Data.Vector.Unboxed
-import Data.Bits
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Unsafe as B
-
-data Mode = Decrypt | Encrypt
-
--- should probably use crypto large word ?
-data Word128 = Word128 !Word64 !Word64 deriving (Show, Eq)
-
-w128tow64 :: Word128 -> (Word64, Word64)
-w128tow64 (Word128 w1 w2) = (w1, w2)
-
-w64tow128 :: (Word64, Word64) -> Word128
-w64tow128 (x1, x2) = Word128 x1 x2
-
-w64tow8 :: Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
-w64tow8 x = (t1, t2, t3, t4, t5, t6, t7, t8)
-	where
-		t1 = fromIntegral (x `shiftR` 56)
-		t2 = fromIntegral (x `shiftR` 48)
-		t3 = fromIntegral (x `shiftR` 40)
-		t4 = fromIntegral (x `shiftR` 32)
-		t5 = fromIntegral (x `shiftR` 24)
-		t6 = fromIntegral (x `shiftR` 16)
-		t7 = fromIntegral (x `shiftR` 8)
-		t8 = fromIntegral (x)
-
-w8tow64 :: B.ByteString -> Word64
-w8tow64 b = (sh t1 56 .|. sh t2 48 .|. sh t3 40 .|. sh t4 32 .|. sh t5 24 .|. sh t6 16 .|. sh t7 8 .|. sh t8 0)
-	where
-		t1     = B.unsafeIndex b 0
-		t2     = B.unsafeIndex b 1
-		t3     = B.unsafeIndex b 2
-		t4     = B.unsafeIndex b 3
-		t5     = B.unsafeIndex b 4
-		t6     = B.unsafeIndex b 5
-		t7     = B.unsafeIndex b 6
-		t8     = B.unsafeIndex b 7
-		sh i r = (fromIntegral i) `shiftL` r
-
-w64tow32 :: Word64 -> (Word32, Word32)
-w64tow32 w = (fromIntegral (w `shiftR` 32), fromIntegral (w .&. 0xffffffff))
-
-w32tow64 :: (Word32, Word32) -> Word64
-w32tow64 (x1, x2) = ((fromIntegral x1) `shiftL` 32) .|. (fromIntegral x2)
-
-w128tow8 :: Word128 -> [Word8]
-w128tow8 (Word128 x1 x2) = [t1,t2,t3,t4,t5,t6,t7,t8,u1,u2,u3,u4,u5,u6,u7,u8]
-	where
-		(t1, t2, t3, t4, t5, t6, t7, t8) = w64tow8 x1
-		(u1, u2, u3, u4, u5, u6, u7, u8) = w64tow8 x2
-
-getWord64 :: B.ByteString -> Word64
-getWord64 s = sh 0 56 .|. sh 1 48 .|. sh 2 40 .|. sh 3 32 .|. sh 4 24 .|. sh 5 16 .|. sh 6 8 .|. sh 7 0
-	where
-		sh i l = (fromIntegral (s `B.index` i) `shiftL` l)
-
-getWord128 :: B.ByteString -> Word128
-getWord128 s = Word128 (getWord64 s) (getWord64 (B.drop 8 s))
-
-putWord128 :: Word128 -> B.ByteString
-putWord128 = B.pack . w128tow8
-
-sbox :: Vector Word8
-sbox = fromList
-	[112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65
-	, 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189
-	,134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26
-	,166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77
-	,139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153
-	,223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215
-	, 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34
-	,254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80
-	,170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210
-	, 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148
-	,135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226
-	, 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46
-	,233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89
-	,120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250
-	,114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164
-	, 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
-	]
-
-sbox1 :: Word8 -> Word8
-sbox1 x = sbox ! (fromIntegral x)
-
-sbox2 :: Word8 -> Word8
-sbox2 x = sbox1 x `rotateL` 1;
-
-sbox3 :: Word8 -> Word8
-sbox3 x = sbox1 x `rotateL` 7;
-
-sbox4 :: Word8 -> Word8
-sbox4 x = sbox1 (x `rotateL` 1);
-
-sigma1 :: Word64
-sigma1 = 0xA09E667F3BCC908B
-
-sigma2 :: Word64
-sigma2 = 0xB67AE8584CAA73B2
-
-sigma3 :: Word64
-sigma3 = 0xC6EF372FE94F82BE
-
-sigma4 :: Word64
-sigma4 = 0x54FF53A5F1D36F1C
-
-sigma5 :: Word64
-sigma5 = 0x10E527FADE682D1D
-
-sigma6 :: Word64
-sigma6 = 0xB05688C2B3E6C1FD
-
-rotl128 :: Word128 -> Int -> Word128
-rotl128 v               0  = v
-rotl128 (Word128 x1 x2) 64 = Word128 x2 x1
-
-rotl128 v@(Word128 x1 x2) w
-	| w > 64    = (v `rotl128` 64) `rotl128` (w - 64)
-	| otherwise = Word128 (x1high .|. x2low) (x2high .|. x1low)
-		where
-			splitBits i = (i .&. complement x, i .&. x)
-				where x = 2 ^ w - 1
-			(x1high, x1low) = splitBits (x1 `rotateL` w)
-			(x2high, x2low) = splitBits (x2 `rotateL` w)
-
-data Key = Key
-	{ k :: Vector Word64
-	, kw :: Vector Word64
-	, ke :: Vector Word64 }
-	deriving (Show)
-
-setKeyInterim :: B.ByteString -> (Word128, Word128, Word128, Word128)
-setKeyInterim keyseed =
-	let kL = (w8tow64 $ B.take 8 keyseed, w8tow64 $ B.drop 8 keyseed) in
-	let kR = (0, 0) in
-
-	let kA =
-		let d1 = (fst kL `xor` fst kR) in
-		let d2 = (snd kL `xor` snd kR) in
-
-		let d3 = d2 `xor` feistel d1 sigma1 in
-		let d4 = d1 `xor` feistel d3 sigma2 in
-		let d5 = d4 `xor` (fst kL) in
-		let d6 = d3 `xor` (snd kL) in
-		let d7 = d6 `xor` feistel d5 sigma3 in
-		let d8 = d5 `xor` feistel d7 sigma4 in
-		(d8, d7)
-		in
-
-	let kB =
-		let d1 = (fst kA `xor` fst kR) in
-		let d2 = (snd kA `xor` snd kR) in
-
-		let d3 = d2 `xor` feistel d1 sigma5 in
-		let d4 = d1 `xor` feistel d3 sigma6 in
-		(d4, d3)
-		in
-	(w64tow128 kL, w64tow128 kR, w64tow128 kA, w64tow128 kB)
-
-initKey128 :: B.ByteString -> Either String Key
-initKey128 keyseed
-	| B.length keyseed /= 16 = Left "wrong key size"
-	| otherwise              =
-		let (kL, _, kA, _) = setKeyInterim keyseed in
-
-		let (kw1, kw2) = w128tow64 (kL `rotl128` 0) in
-		let (k1, k2)   = w128tow64 (kA `rotl128` 0) in
-		let (k3, k4)   = w128tow64 (kL `rotl128` 15) in
-		let (k5, k6)   = w128tow64 (kA `rotl128` 15) in
-		let (ke1, ke2) = w128tow64 (kA `rotl128` 30) in --ke1 = (KA <<<  30) >> 64; ke2 = (KA <<<  30) & MASK64;
-		let (k7, k8)   = w128tow64 (kL `rotl128` 45) in --k7  = (KL <<<  45) >> 64; k8  = (KL <<<  45) & MASK64;
-		let (k9, _)    = w128tow64 (kA `rotl128` 45) in --k9  = (KA <<<  45) >> 64;
-		let (_, k10)   = w128tow64 (kL `rotl128` 60) in
-		let (k11, k12) = w128tow64 (kA `rotl128` 60) in
-		let (ke3, ke4) = w128tow64 (kL `rotl128` 77) in
-		let (k13, k14) = w128tow64 (kL `rotl128` 94) in
-		let (k15, k16) = w128tow64 (kA `rotl128` 94) in
-		let (k17, k18) = w128tow64 (kL `rotl128` 111) in
-		let (kw3, kw4) = w128tow64 (kA `rotl128` 111) in
-
-		Right $ Key
-			{ kw = fromList [ kw1, kw2, kw3, kw4 ]
-			, ke = fromList [ ke1, ke2, ke3, ke4 ]
-			, k  = fromList [ k1, k2, k3, k4, k5, k6, k7, k8, k9,
-					  k10, k11, k12, k13, k14, k15, k16, k17, k18 ]
-			}
-
-feistel :: Word64 -> Word64 -> Word64
-feistel fin sk = 
-	let x = fin `xor` sk in
-	let (t1, t2, t3, t4, t5, t6, t7, t8) = w64tow8 x in
-	let t1' = sbox1 t1 in
-	let t2' = sbox2 t2 in
-	let t3' = sbox3 t3 in
-	let t4' = sbox4 t4 in
-	let t5' = sbox2 t5 in
-	let t6' = sbox3 t6 in
-	let t7' = sbox4 t7 in
-	let t8' = sbox1 t8 in
-	let y1 = t1' `xor` t3' `xor` t4' `xor` t6' `xor` t7' `xor` t8' in
-	let y2 = t1' `xor` t2' `xor` t4' `xor` t5' `xor` t7' `xor` t8' in
-	let y3 = t1' `xor` t2' `xor` t3' `xor` t5' `xor` t6' `xor` t8' in
-	let y4 = t2' `xor` t3' `xor` t4' `xor` t5' `xor` t6' `xor` t7' in
-	let y5 = t1' `xor` t2' `xor` t6' `xor` t7' `xor` t8' in
-	let y6 = t2' `xor` t3' `xor` t5' `xor` t7' `xor` t8' in
-	let y7 = t3' `xor` t4' `xor` t5' `xor` t6' `xor` t8' in
-	let y8 = t1' `xor` t4' `xor` t5' `xor` t6' `xor` t7' in
-	w8tow64 $ B.pack [y1, y2, y3, y4, y5, y6, y7, y8]
-
-fl :: Word64 -> Word64 -> Word64
-fl fin sk =
-	let (x1, x2) = w64tow32 fin in
-	let (k1, k2) = w64tow32 sk in
-	let y2 = x2 `xor` ((x1 .&. k1) `rotateL` 1) in
-	let y1 = x1 `xor` (y2 .|. k2) in
-	w32tow64 (y1, y2)
-
-flinv :: Word64 -> Word64 -> Word64
-flinv fin sk =
-	let (y1, y2) = w64tow32 fin in
-	let (k1, k2) = w64tow32 sk in
-	let x1 = y1 `xor` (y2 .|. k2) in
-	let x2 = y2 `xor` ((x1 .&. k1) `rotateL` 1) in
-	w32tow64 (x1, x2)
-
-{- in decrypt mode 0->17 1->16 ... -}
-getKeyK :: Mode -> Key -> Int -> Word64
-getKeyK Encrypt key i = k key ! i
-getKeyK Decrypt key i = k key ! (17 - i)
-
-{- in decrypt mode 0->3 1->2 2->1 3->0 -}
-getKeyKe :: Mode -> Key -> Int -> Word64
-getKeyKe Encrypt key i = ke key ! i
-getKeyKe Decrypt key i = ke key ! (3 - i)
-
-{- in decrypt mode 0->2 1->3 2->0 3->1 -}
-getKeyKw :: Mode -> Key -> Int -> Word64
-getKeyKw Encrypt key i = kw key ! i
-getKeyKw Decrypt key i = kw key ! ((i + 2) `mod` 4)
-
-{- perform the following
-	D2 = D2 ^ F(D1, k1);     // Round 1
-	D1 = D1 ^ F(D2, k2);     // Round 2
-	D2 = D2 ^ F(D1, k3);     // Round 3
-	D1 = D1 ^ F(D2, k4);     // Round 4
-	D2 = D2 ^ F(D1, k5);     // Round 5
-	D1 = D1 ^ F(D2, k6);     // Round 6
- -}
-doBlockRound :: Mode -> Key -> Word64 -> Word64 -> Int -> (Word64, Word64)
-doBlockRound mode key d1 d2 i =
-	let r1 = d2 `xor` feistel d1 (getKeyK mode key (0+i)) in     {- Round 1+i -}
-	let r2 = d1 `xor` feistel r1 (getKeyK mode key (1+i)) in     {- Round 2+i -}
-	let r3 = r1 `xor` feistel r2 (getKeyK mode key (2+i)) in     {- Round 3+i -}
-	let r4 = r2 `xor` feistel r3 (getKeyK mode key (3+i)) in     {- Round 4+i -}
-	let r5 = r3 `xor` feistel r4 (getKeyK mode key (4+i)) in     {- Round 5+i -}
-	let r6 = r4 `xor` feistel r5 (getKeyK mode key (5+i)) in     {- Round 6+i -}
-	(r6, r5)
-
-doBlock :: Mode -> Key -> Word128 -> Word128
-doBlock mode key m =
-	let (d1, d2) = w128tow64 m in
-
-	let d1a = d1 `xor` (getKeyKw mode key 0) in {- Prewhitening -}
-	let d2a = d2 `xor` (getKeyKw mode key 1) in
-
-	let (d1b, d2b) = doBlockRound mode key d1a d2a 0 in
-
-	let d1c = fl    d1b (getKeyKe mode key 0) in {- FL -}
-	let d2c = flinv d2b (getKeyKe mode key 1) in {- FLINV -}
-
-	let (d1d, d2d) = doBlockRound mode key d1c d2c 6 in
-
-	let d1e = fl    d1d (getKeyKe mode key 2) in {- FL -}
-	let d2e = flinv d2d (getKeyKe mode key 3) in {- FLINV -}
-
-	let (d1f, d2f) = doBlockRound mode key d1e d2e 12 in
-
-	let d2g = d2f `xor` (getKeyKw mode key 2) in {- Postwhitening -}
-	let d1g = d1f `xor` (getKeyKw mode key 3) in
-	w64tow128 (d2g, d1g)
-
-{- encryption for 128 bits blocks -}
-encryptBlock :: Key -> Word128 -> Word128
-encryptBlock = doBlock Encrypt
-
-{- decryption for 128 bits blocks -}
-decryptBlock :: Key -> Word128 -> Word128
-decryptBlock = doBlock Decrypt
-
-encryptChunk :: Key -> B.ByteString -> B.ByteString
-encryptChunk key b = putWord128 $ encryptBlock key $ getWord128 b
-
-decryptChunk :: Key -> B.ByteString -> B.ByteString
-decryptChunk key b = putWord128 $ decryptBlock key $ getWord128 b
-
-doChunks :: (B.ByteString -> B.ByteString) -> B.ByteString -> [B.ByteString]
-doChunks f b =
-	let (x, rest) = B.splitAt 16 b in
-	if B.length rest >= 16
-		then f x : doChunks f rest
-		else [ f x ]
-
-{- | encrypt with the key a bytestring and returns the encrypted bytestring -}
-encrypt :: Key -> B.ByteString -> B.ByteString
-encrypt key b = B.concat $ doChunks (encryptChunk key) b
-
-{- | decrypt with the key a bytestring and returns the encrypted bytestring -}
-decrypt :: Key -> B.ByteString -> B.ByteString
-decrypt key b = B.concat $ doChunks (decryptChunk key) b
diff --git a/Crypto/Cipher/DH.hs b/Crypto/Cipher/DH.hs
deleted file mode 100644
--- a/Crypto/Cipher/DH.hs
+++ /dev/null
@@ -1,46 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-
--- |
--- Module      : Crypto.Cipher.DH
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
-module Crypto.Cipher.DH
-	( Params
-	, PublicNumber
-	, PrivateNumber
-	, SharedKey
-	, generateParams
-	, generatePrivate
-	, generatePublic
-	, getShared
-	) where
-
-import Number.ModArithmetic (exponantiation)
-import Number.Prime (generateSafePrime)
-import Number.Generate (generateOfSize)
-import Crypto.Types.PubKey.DH
-import Crypto.Random
-import Control.Arrow (first)
-
--- | generate params from a specific generator (2 or 5 are common values)
--- we generate a safe prime (a prime number of the form 2p+1 where p is also prime)
-generateParams :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Params, g)
-generateParams rng bits generator =
-	either Left (Right . first (\p -> (p, generator))) $ generateSafePrime rng bits
-
--- | generate a private number with no specific property
--- this number is usually called X in DH text.
-generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)
-generatePrivate rng bits = either Left (Right . first PrivateNumber) $ generateOfSize rng bits
-
--- | generate a public number that is for the other party benefits.
--- this number is usually called Y in DH text.
-generatePublic :: Params -> PrivateNumber -> PublicNumber
-generatePublic (p,g) (PrivateNumber x) = PublicNumber $ exponantiation g x p
-
--- | generate a shared key using our private number and the other party public number
-getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
-getShared (p,_) (PrivateNumber x) (PublicNumber y) = SharedKey $ exponantiation y x p
diff --git a/Crypto/Cipher/DSA.hs b/Crypto/Cipher/DSA.hs
deleted file mode 100644
--- a/Crypto/Cipher/DSA.hs
+++ /dev/null
@@ -1,67 +0,0 @@
--- |
--- Module      : Crypto.Cipher.DSA
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
-
-module Crypto.Cipher.DSA
-	( Error(..)
-	, Params
-	, Signature
-	, PublicKey(..)
-	, PrivateKey(..)
-	, sign
-	, verify
-	) where
-
-import Crypto.Random
-import Data.Maybe
-import Data.ByteString (ByteString)
-import Number.ModArithmetic (exponantiation, inverse)
-import Number.Serialize
-import Number.Generate
-import Crypto.Types.PubKey.DSA
-
-data Error = 
-	  InvalidSignature          -- ^ signature is not valid r or s is not between the bound 0..q
-	| RandomGenFailure GenError -- ^ the random generator returns an error. give the opportunity to reseed for example.
-	deriving (Show,Eq)
-
-{-| sign message using the private key. -}
-sign :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> PrivateKey -> ByteString -> Either GenError (Signature, g)
-sign rng hash pk m =
-	-- Recalculate the signature in the unlikely case that r = 0 or s = 0
-	case generateMax rng q of
-		Left err        -> Left err
-		Right (k, rng') ->
-			let kinv = fromJust $ inverse k q in
-			let r    = expmod g k p `mod` q in
-			let s    = (kinv * (hm + x * r)) `mod` q in
-			if r == 0 || s == 0
-				then sign rng' hash pk m
-				else Right ((r, s), rng')
-	where
-		(p,g,q)   = private_params pk
-		x         = private_x pk
-		hm        = os2ip $ hash m
-
-{- | verify a bytestring using the public key. -}
-verify :: Signature -> (ByteString -> ByteString) -> PublicKey -> ByteString -> Either Error Bool
-verify (r,s) hash pk m
-	-- Reject the signature if either 0 < r <q or 0 < s < q is not satisfied.
-	| r <= 0 || r >= q || s <= 0 || s >= q = Left InvalidSignature
-	| otherwise                            = Right $ v == r
-	where
-		(p,g,q) = public_params pk
-		y       = public_y pk
-		hm      = os2ip $ hash m
-
-		w       = fromJust $ inverse s q
-		u1      = (hm*w) `mod` q
-		u2      = (r*w) `mod` q
-		v       = ((expmod g u1 p) * (expmod y u2 p)) `mod` p `mod` q
-
-expmod :: Integer -> Integer -> Integer -> Integer
-expmod = exponantiation
diff --git a/Crypto/Cipher/ElGamal.hs b/Crypto/Cipher/ElGamal.hs
deleted file mode 100644
--- a/Crypto/Cipher/ElGamal.hs
+++ /dev/null
@@ -1,73 +0,0 @@
--- |
--- Module      : Crypto.Cipher.ElGamal
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
--- This module is a work in progress. do not use:
--- it might eat your dog, your data or even both.
---
--- TODO: provide a mapping between integer and ciphertext
---       generate numbers correctly
---
-module Crypto.Cipher.ElGamal
-	( Params
-	, PublicNumber
-	, PrivateNumber
-	, SharedKey
-    , generatePrivate
-    , generatePublic
-    , encryptWith
-    , encrypt
-    , decrypt
-{-
-    , sign
-    , verify
--}
-    ) where
-
-import Number.ModArithmetic (exponantiation, inverse)
-import Number.Generate (generateOfSize)
-import Crypto.Types.PubKey.DH
-import Crypto.Random
-import Control.Arrow (first)
-import Control.Applicative ((<$>))
-import Data.Maybe (fromJust)
-
--- | generate a private number with no specific property
--- this number is usually called a.
--- 
--- FIXME replace generateOfSize by generateBetween [0, q-1]
-generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)
-generatePrivate rng bits = either Left (Right . first PrivateNumber) $ generateOfSize rng bits
-
--- | generate a public number that is for the other party benefits.
--- this number is usually called h=g^a
-generatePublic :: Params -> PrivateNumber -> PublicNumber
-generatePublic (p,g) (PrivateNumber a) = PublicNumber $ exponantiation g a p
-
--- | encrypt with a specified ephemeral key
--- do not reuse ephemeral key.
-encryptWith :: PrivateNumber -> Params -> PublicNumber -> Integer -> (Integer,Integer)
-encryptWith (PrivateNumber b) (p,g) (PublicNumber h) m = (c1,c2)
-    where s  = exponantiation h b p
-          c1 = exponantiation g b p
-          c2 = (s * m) `mod` p
-
--- | encrypt a message using params and public keys
--- will generate b (called the ephemeral key)
-encrypt :: CryptoRandomGen g => g -> Params -> PublicNumber -> Integer -> Either GenError ((Integer,Integer), g)
-encrypt rng params public m = (\(b,rng') -> (encryptWith b params public m,rng')) <$> generatePrivate rng 1024
-
--- | decrypt message
-decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> Integer
-decrypt (p,_) (PrivateNumber a) (c1,c2) = (c2 * sm1) `mod` p
-    where s   = exponantiation c1 a p
-          sm1 = fromJust $ inverse s p -- always inversible in Zp
-
-{-
-sign = undefined
-
-verify = undefined
--}
diff --git a/Crypto/Cipher/RC4.hs b/Crypto/Cipher/RC4.hs
deleted file mode 100644
--- a/Crypto/Cipher/RC4.hs
+++ /dev/null
@@ -1,82 +0,0 @@
--- |
--- Module      : Crypto.Cipher.RC4
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
-
-module Crypto.Cipher.RC4 (
-	Ctx,
-	initCtx,
-	encrypt,
-	decrypt,
-	encryptlazy,
-	decryptlazy
-	) where
-
-import Data.Vector.Unboxed
-import Data.Bits (xor)
-import Data.Word
-import Control.Arrow (second)
-import Data.Maybe (fromJust)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as L
-import Prelude hiding (length)
-
-type Ctx = (Vector Word8, Word8, Word8)
-
-swap :: Vector Word8 -> Int -> Int -> Vector Word8
-swap arr x y
-	| x == y    = arr
-	| otherwise = arr // [(x, arr ! y), (y, arr ! x)]
-
-setKey :: Vector Word8 -> Int -> Word8 -> Int -> Vector Word8 -> Vector Word8
-setKey _   _  _  256 arr = arr
-setKey key ki si i   arr = setKey key ki' si' (i + 1) (swap arr (fromIntegral si') i)
-	where
-		si' = si + (key ! ki) + (arr ! i)
-		ki' = (ki + 1) `mod` (length key)
-
-{- | initCtx initialize the Ctx with the key as parameter.
-   the key can be of any size but not empty -}
-initCtx :: [Word8] -> Ctx
-initCtx key = (setKey (fromList key) 0 0 0 initialArray, 0, 0)
-	where
-		initialArray = generate 256 (\i -> fromIntegral i)
-
-getNextChar :: Ctx -> (Word8, Ctx)
-getNextChar (arr, x, y) = (c, (na, x', y'))
-	where
-		na = swap arr (fromIntegral x') (fromIntegral y')
-		x' = x + 1
-		y' = sx + y
-		sx = arr ! (fromIntegral x')
-		c  = na ! (fromIntegral (sx + (arr ! (fromIntegral y'))))
-
-genstream :: Ctx -> Int -> (B.ByteString, Ctx)
-genstream ctx len = second fromJust $ B.unfoldrN len (\c -> Just $ getNextChar c) ctx
-
-{- | encrypt with the current context a bytestring and returns a new context
-   and the resulted encrypted bytestring -}
-encrypt :: Ctx -> B.ByteString -> (Ctx, B.ByteString)
-encrypt ctx d = (ctx', B.pack $ B.zipWith xor d rc4stream)
-	where
-		(rc4stream, ctx') = genstream ctx (B.length d)
-
-{- | decrypt with the current context a bytestring and returns a new context
-   and the resulted decrypted bytestring -}
-decrypt :: Ctx -> B.ByteString -> (Ctx, B.ByteString)
-decrypt = encrypt
-
-{- | encrypt with the current context a lazy bytestring and returns a new context
-   and the resulted lencrypted lazy bytestring -}
-encryptlazy :: Ctx -> L.ByteString -> (Ctx, L.ByteString)
-encryptlazy ctx d = (ctx', L.pack $ L.zipWith xor d (L.fromChunks [ rc4stream ]))
-	where
-		(rc4stream, ctx') = genstream ctx (fromIntegral $ L.length d)
-
-{- | decrypt with the current context a lazy bytestring and returns a new context
-   and the resulted decrypted lazy bytestring -}
-decryptlazy :: Ctx -> L.ByteString -> (Ctx, L.ByteString)
-decryptlazy = encryptlazy
diff --git a/Crypto/Cipher/RSA.hs b/Crypto/Cipher/RSA.hs
deleted file mode 100644
--- a/Crypto/Cipher/RSA.hs
+++ /dev/null
@@ -1,180 +0,0 @@
-{-# LANGUAGE FlexibleInstances, CPP #-}
-
--- |
--- Module      : Crypto.Cipher.RSA
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
---
-module Crypto.Cipher.RSA
-	( Error(..)
-	, PublicKey(..)
-	, PrivateKey(..)
-	, HashF
-	, HashASN1
-	, generate
-	, decrypt
-	, encrypt
-	, sign
-	, verify
-	) where
-
-import Control.Arrow (first)
-import Crypto.Random
-import Crypto.Types.PubKey.RSA
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import Number.ModArithmetic (exponantiation, inverse)
-import Number.Prime (generatePrime)
-import Number.Serialize
-import Data.Maybe (fromJust)
-
-data Error =
-	  MessageSizeIncorrect      -- ^ the message to decrypt is not of the correct size (need to be == private_size)
-	| MessageTooLong            -- ^ the message to encrypt is too long (>= private_size - 11)
-	| MessageNotRecognized      -- ^ the message decrypted doesn't have a PKCS15 structure (0 2 .. 0 msg)
-	| SignatureTooLong          -- ^ the signature generated through the hash is too long to process with this key
-	| RandomGenFailure GenError -- ^ the random generator returns an error. give the opportunity to reseed for example.
-	| KeyInternalError          -- ^ the whole key is probably not valid, since the message is bigger than the key size
-	deriving (Show,Eq)
-
-type HashF = ByteString -> ByteString
-type HashASN1 = ByteString
-
-#if ! (MIN_VERSION_base(4,3,0))
-instance Monad (Either Error) where
-	return          = Right
-	(Left x) >>= _  = Left x
-	(Right x) >>= f = f x
-#endif
-
-padPKCS1 :: CryptoRandomGen g => g -> Int -> ByteString -> Either Error (ByteString, g)
-padPKCS1 rng len m = do
-	(padding, rng') <- getRandomBytes rng (len - B.length m - 3)
-	return (B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ], rng')
-
-unpadPKCS1 :: ByteString -> Either Error ByteString
-unpadPKCS1 packed
-	| signal_error = Left MessageNotRecognized
-	| otherwise    = Right m
-	where
-		(zt, ps0m)   = B.splitAt 2 packed
-		(ps, zm)     = B.span (/= 0) ps0m
-		(z, m)       = B.splitAt 1 zm
-		signal_error = (B.unpack zt /= [0, 2]) || (B.unpack z /= [0]) || (B.length ps < 8)
-
-{- dpSlow computes the decrypted message not using any precomputed cache value.
-   only n and d need to valid. -}
-dpSlow :: PrivateKey -> ByteString -> Either Error ByteString
-dpSlow pk c = i2ospOf (private_size pk) $ expmod (os2ip c) (private_d pk) (private_n pk)
-
-{- dpFast computes the decrypted message more efficiently if the
-   precomputed private values are available. mod p and mod q are faster
-   to compute than mod pq -}
-dpFast :: PrivateKey -> ByteString -> Either Error ByteString
-dpFast pk c = i2ospOf (private_size pk) (m2 + h * (private_q pk))
-	where
-		iC = os2ip c
-		m1 = expmod iC (private_dP pk) (private_p pk)
-		m2 = expmod iC (private_dQ pk) (private_q pk)
-		h  = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk)
-
-{-| decrypt message using the private key. -}
-decrypt :: PrivateKey -> ByteString -> Either Error ByteString
-decrypt pk c
-	| B.length c /= (private_size pk) = Left MessageSizeIncorrect
-	| otherwise                       = dp pk c >>= unpadPKCS1
-		where dp = if private_p pk /= 0 && private_q pk /= 0 then dpFast else dpSlow
-
-{- | encrypt a bytestring using the public key and a CryptoRandomGen random generator.
- - the message need to be smaller than the key size - 11
- -}
-encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either Error (ByteString, g)
-encrypt rng pk m
-	| B.length m > public_size pk - 11 = Left MessageTooLong
-	| otherwise                        = do
-		(em, rng') <- padPKCS1 rng (public_size pk) m
-		c          <- i2ospOf (public_size pk) $ expmod (os2ip em) (public_e pk) (public_n pk)
-		return (c, rng')
-
-{-| sign message using private key, a hash and its ASN1 description -}
-sign :: HashF -> HashASN1 -> PrivateKey -> ByteString -> Either Error ByteString
-sign hash hashdesc pk m = makeSignature hash hashdesc (private_size pk) m >>= d pk
-	where d = if private_p pk /= 0 && private_q pk /= 0 then dpFast else dpSlow
-
-{-| verify message with the signed message -}
-verify :: HashF -> HashASN1 -> PublicKey -> ByteString -> ByteString -> Either Error Bool
-verify hash hashdesc pk m sm = do
-	s  <- makeSignature hash hashdesc (public_size pk) m
-	em <- i2ospOf (public_size pk) $ expmod (os2ip sm) (public_e pk) (public_n pk)
-	Right (s == em)
-
--- | generate a pair of (private, public) key of size in bytes.
-generate :: CryptoRandomGen g => g -> Int -> Integer -> Either Error ((PublicKey, PrivateKey), g)
-generate rng size e = do
-	((p,q), rng') <- generatePQ rng
-	let n   = p * q
-	let phi = (p-1)*(q-1)
-	case inverse e phi of
-		Nothing -> generate rng' size e
-		Just d  -> do
-			let pub = PublicKey
-				{ public_size = size
-				, public_n    = n
-				, public_e    = e
-				}
-			let priv = PrivateKey
-				{ private_pub  = pub
-				, private_d    = d
-				, private_p    = p
-				, private_q    = q
-				, private_dP   = d `mod` (p-1)
-				, private_dQ   = d `mod` (q-1)
-				, private_qinv = fromJust $ inverse q p -- q and p are coprime, so fromJust is safe.
-				}
-			Right ((pub, priv), rng')
-	where
-		generatePQ g = do
-			(p, g')  <- genPrime g (8 * (size `div` 2))
-			(q, g'') <- generateQ p g'
-			return ((p,q), g'')
-		generateQ p h = do
-			(q, h') <- genPrime h (8 * (size - (size `div` 2)))
-			if p == q then generateQ p h' else return (q, h')
-		genPrime g sz = either (Left . RandomGenFailure) Right $ generatePrime g sz
-
-{- makeSignature for sign and verify -}
-makeSignature :: HashF -> HashASN1 -> Int -> ByteString -> Either Error ByteString
-makeSignature hash descr klen m
-	| klen < siglen+1 = Left SignatureTooLong
-	| otherwise       = Right $ B.concat [B.singleton 0,B.singleton 1,padding,B.singleton 0,signature]
-	where
-		signature = descr `B.append` hash m
-		siglen    = B.length signature
-		padding   = B.replicate (klen - siglen - 3) 0xff
-
-{- get random non-null bytes for encryption padding. -}
-getRandomBytes :: CryptoRandomGen g => g -> Int -> Either Error (ByteString, g)
-getRandomBytes rng n = do
-	gend <- either (Left . RandomGenFailure) Right $ genBytes n rng
-	let (bytes, rng') = first (B.pack . filter (/= 0) . B.unpack) gend
-	let left          = (n - B.length bytes)
-	if left == 0
-		then return (bytes, rng')
-		else getRandomBytes rng' left >>= return . first (B.append bytes)
-
-{- convert a positive integer into a bytestring of specific size.
-   if the number is too big, this will returns an error, otherwise it will pad
-   the bytestring of 0 -}
-i2ospOf :: Int -> Integer -> Either Error ByteString
-i2ospOf len m 
-	| lenbytes < len  = Right $ B.replicate (len - lenbytes) 0 `B.append` bytes
-	| lenbytes == len = Right bytes
-	| otherwise       = Left KeyInternalError
-	where
-		lenbytes = B.length bytes
-		bytes    = i2osp m
-
-expmod :: Integer -> Integer -> Integer -> Integer
-expmod = exponantiation
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2011 Vincent Hanquez <vincent@snarc.org>
+Copyright (c) 2010-2013 Vincent Hanquez <vincent@snarc.org>
 
 All rights reserved.
 
diff --git a/Number/Basic.hs b/Number/Basic.hs
deleted file mode 100644
--- a/Number/Basic.hs
+++ /dev/null
@@ -1,88 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
--- |
--- Module      : Number.Basic
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Number.Basic
-	( sqrti
-	, gcde
-	, gcde_binary
-	, areEven
-	) where
-
-import Data.Bits
-
--- | sqrti returns two integer (l,b) so that l <= sqrt i <= b
--- the implementation is quite naive, use an approximation for the first number
--- and use a dichotomy algorithm to compute the bound relatively efficiently.
-sqrti :: Integer -> (Integer, Integer)
-sqrti i
-	| i < 0     = error "cannot compute negative square root"
-	| i == 0    = (0,0)
-	| i == 1    = (1,1)
-	| i == 2    = (1,2)
-	| otherwise = loop x0
-		where
-			nbdigits = length $ show i
-			x0n = (if even nbdigits then nbdigits - 2 else nbdigits - 1) `div` 2
-			x0  = if even nbdigits then 2 * 10 ^ x0n else 6 * 10 ^ x0n
-			loop x = case compare (sq x) i of
-				LT -> iterUp x
-				EQ -> (x, x)
-				GT -> iterDown x
-			iterUp lb = if sq ub >= i then iter lb ub else iterUp ub
-				where ub = lb * 2
-			iterDown ub = if sq lb >= i then iterDown lb else iter lb ub
-				where lb = ub `div` 2
-			iter lb ub
-				| lb == ub   = (lb, ub)
-				| lb+1 == ub = (lb, ub)
-				| otherwise  =
-					let d = (ub - lb) `div` 2 in
-					if sq (lb + d) >= i
-						then iter lb (ub-d)
-						else iter (lb+d) ub
-			sq a = a * a
-
--- | get the extended GCD of two integer using integer divMod
-gcde :: Integer -> Integer -> (Integer, Integer, Integer)
-gcde a b = if d < 0 then (-x,-y,-d) else (x,y,d) where
-	(d, x, y)                     = f (a,1,0) (b,0,1)
-	f t              (0, _, _)    = t
-	f (a', sa, ta) t@(b', sb, tb) =
-		let (q, r) = a' `divMod` b' in
-		f t (r, sa - (q * sb), ta - (q * tb))
-
--- | get the extended GCD of two integer using the extended binary algorithm (HAC 14.61)
--- get (x,y,d) where d = gcd(a,b) and x,y satisfying ax + by = d
-gcde_binary :: Integer -> Integer -> (Integer, Integer, Integer)
-gcde_binary a' b'
-	| b' == 0   = (1,0,a')
-	| a' >= b'  = compute a' b'
-	| otherwise = (\(x,y,d) -> (y,x,d)) $ compute b' a'
-	where
-		getEvenMultiplier !g !x !y
-			| areEven [x,y] = getEvenMultiplier (g `shiftL` 1) (x `shiftR` 1) (y `shiftR` 1)
-			| otherwise     = (x,y,g)
-		halfLoop !x !y !u !i !j
-			| areEven [u,i,j] = halfLoop x y (u `shiftR` 1) (i `shiftR` 1) (j `shiftR` 1)
-			| even u          = halfLoop x y (u `shiftR` 1) ((i + y) `shiftR` 1) ((j - x) `shiftR` 1)
-			| otherwise       = (u, i, j)
-		compute a b =
-			let (x,y,g) = getEvenMultiplier 1 a b in
-			loop g x y x y 1 0 0 1
-
-		loop g _ _ 0  !v _  _  !c !d = (c, d, g * v)
-		loop g x y !u !v !a !b !c !d =
-			let (u2,a2,b2) = halfLoop x y u a b in
-			let (v2,c2,d2) = halfLoop x y v c d in
-			if u2 >= v2
-				then loop g x y (u2 - v2) v2 (a2 - c2) (b2 - d2) c2 d2
-				else loop g x y u2 (v2 - u2) a2 b2 (c2 - a2) (d2 - b2)
-
--- | check if a list of integer are all even
-areEven :: [Integer] -> Bool
-areEven = and . map even
diff --git a/Number/Generate.hs b/Number/Generate.hs
deleted file mode 100644
--- a/Number/Generate.hs
+++ /dev/null
@@ -1,38 +0,0 @@
--- |
--- Module      : Number.Generate
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Number.Generate
-	( generateMax
-	, generateBetween
-	, generateOfSize
-	) where
-
-import Number.Serialize
-import Crypto.Random
-import qualified Data.ByteString as B
-import Data.Bits ((.|.))
-
--- | generate a positive integer between 0 and m.
--- using as many bytes as necessary to the same size as m, that are converted to integer.
-generateMax :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)
-generateMax rng m = case genBytes (lengthBytes m) rng of
-	Left err         -> Left err
-	Right (bs, rng') -> Right (os2ip bs `mod` m, rng')
-
--- | generate a number between the inclusive bound [low,high].
-generateBetween :: CryptoRandomGen g => g -> Integer -> Integer -> Either GenError (Integer, g)
-generateBetween rng low high = case generateMax rng (high - low + 1) of
-	Left err        -> Left err
-	Right (v, rng') -> Right (low + v, rng')
-
--- | generate a positive integer of a specific size in bits.
--- the number of bits need to be multiple of 8. It will always returns
--- an integer that is close 2^(1+bits/8) by setting the 2 highest bits to 1.
-generateOfSize :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)
-generateOfSize rng bits = case genBytes (bits `div` 8) rng of
-	Left err         -> Left err
-	Right (bs, rng') -> Right (os2ip $ snd $ B.mapAccumL (\acc w -> (0, w .|. acc)) 0xc0 bs, rng')
diff --git a/Number/ModArithmetic.hs b/Number/ModArithmetic.hs
deleted file mode 100644
--- a/Number/ModArithmetic.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
--- |
--- Module      : Number.ModArithmetic
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Number.ModArithmetic
-	( exponantiation_rtl_binary
-	, exponantiation
-	, inverse
-	) where
-
-import Number.Basic (gcde_binary)
-import Data.Bits
-
--- note on exponantiation: 0^0 is treated as 1 for mimicking the standard library;
--- the mathematic debate is still open on whether or not this is true, but pratically
--- in computer science it shouldn't be useful for anything anyway.
-
--- | exponantiation_rtl_binary computes modular exponantiation as b^e mod m
--- using the right-to-left binary exponentiation algorithm (HAC 14.79)
-exponantiation_rtl_binary :: Integer -> Integer -> Integer -> Integer
-exponantiation_rtl_binary 0 0 m = 1 `mod` m
-exponantiation_rtl_binary b e m = loop e b 1
-	where
-		sq x          = (x * x) `mod` m
-		loop !0 _  !a = a `mod` m
-		loop !i !s !a = loop (i `shiftR` 1) (sq s) (if odd i then a * s else a)
-
--- | exponantiation computes modular exponantiation as b^e mod m
--- using repetitive squaring.
-exponantiation :: Integer -> Integer -> Integer -> Integer
-exponantiation b e m
-             | e == 0    = 1
-             | e == 1    = b `mod` m
-             | even e    = let p = (exponantiation b (e `div` 2) m) `mod` m
-                           in  (p^(2::Integer)) `mod` m
-             | otherwise = (b * exponantiation b (e-1) m) `mod` m
-
--- | inverse computes the modular inverse as in g^(-1) mod m
-inverse :: Integer -> Integer -> Maybe Integer
-inverse g m = if d > 1 then Nothing else Just (x `mod` m)
-	where (x,_,d) = gcde_binary g m
diff --git a/Number/Polynomial.hs b/Number/Polynomial.hs
deleted file mode 100644
--- a/Number/Polynomial.hs
+++ /dev/null
@@ -1,133 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
--- |
--- Module      : Number.Polynomial
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Number.Polynomial
-	( Monomial(..)
-	-- * polynomial operations
-	, Polynomial
-	, toList
-	, fromList
-	, addPoly
-	, subPoly
-	, mulPoly
-	, squarePoly
-	, expPoly
-	, divPoly
-	, negPoly
-	) where
-
-import Data.List (intercalate, sort)
-import Data.Vector ((!), Vector)
-import qualified Data.Vector as V
-import Control.Arrow (first)
-
-data Monomial = Monomial {-# UNPACK #-} !Int !Integer
-	deriving (Eq)
-
-data Polynomial = Polynomial (Vector Monomial)
-	deriving (Eq)
-
-instance Ord Monomial where
-	compare (Monomial w1 v1) (Monomial w2 v2) =
-		case compare w1 w2 of
-			EQ -> compare v1 v2
-			r  -> r
-
-instance Show Monomial where
-	show (Monomial w v) = show v ++ "x^" ++ show w
-
-instance Show Polynomial where
-	show (Polynomial p) = intercalate "+" $ map show $ V.toList p
-
-toList :: Polynomial -> [Monomial]
-toList (Polynomial p) = V.toList p
-
-fromList :: [Monomial] -> Polynomial
-fromList = Polynomial . V.fromList . reverse . sort . filterZero
-	where
-		filterZero = filter (\(Monomial _ v) -> v /= 0)
-
-getWeight :: Polynomial -> Int -> Maybe Integer
-getWeight (Polynomial p) n = look 0
-	where
-		plen = V.length p
-		look !i
-			| i >= plen = Nothing
-			| otherwise =
-				let (Monomial w v) = p ! i in
-				case compare w n of
-					LT -> Nothing
-					EQ -> Just v
-					GT -> look (i+1)
-		
-
-mergePoly :: (Integer -> Integer -> Integer) -> Polynomial -> Polynomial -> Polynomial
-mergePoly f (Polynomial p1) (Polynomial p2) = fromList $ loop 0 0
-	where
-		l1 = V.length p1
-		l2 = V.length p2
-		loop !i1 !i2
-			| i1 == l1 && i2 == l2 = []
-			| i1 == l1             = (p2 ! i2) : loop i1 (i2+1)
-			| i2 == l2             = (p1 ! i1) : loop (i1+1) i2
-			| otherwise            =
-				let (coef, i1inc, i2inc) = addCoef (p1 ! i1) (p2 ! i2) in
-				coef : loop (i1+i1inc) (i2+i2inc)
-		addCoef m1@(Monomial w1 v1) (Monomial w2 v2) =
-			case compare w1 w2 of
-				LT -> (Monomial w2 (f 0 v2), 0, 1)
-				EQ -> (Monomial w1 (f v1 v2), 1, 1)
-				GT -> (m1, 1, 0)
-
-addPoly :: Polynomial -> Polynomial -> Polynomial
-addPoly = mergePoly (+)
-
-subPoly :: Polynomial -> Polynomial -> Polynomial
-subPoly = mergePoly (-)
-
-negPoly :: Polynomial -> Polynomial
-negPoly (Polynomial p) = Polynomial $ V.map negateMonomial p
-	where negateMonomial (Monomial w v) = Monomial w (-v)
-
-mulPoly :: Polynomial -> Polynomial -> Polynomial
-mulPoly p1@(Polynomial v1) p2@(Polynomial v2) =
-	fromList $ filter (\(Monomial _ v) -> v /= 0) $ map (\i -> Monomial i (c i)) $ reverse [0..(m+n)]
-	where
-		(Monomial m _) = v1 ! 0
-		(Monomial n _) = v2 ! 0
-		c r = foldl (\acc i -> (b $ r-i) * (a $ i) + acc) 0 [0..r]
-			where
-				a = maybe 0 id . getWeight p1
-				b = maybe 0 id . getWeight p2
-
-squarePoly :: Polynomial -> Polynomial
-squarePoly p = p `mulPoly` p
-
-expPoly :: Polynomial -> Integer -> Polynomial
-expPoly p e = loop p e
-	where
-		loop t 0 = t
-		loop t n = loop (squarePoly t) (n-1)
-
-divPoly :: Polynomial -> Polynomial -> (Polynomial, Polynomial)
-divPoly p1 p2@(Polynomial pp2) = first fromList $ divLoop p1
-	where divLoop d1@(Polynomial pp1)
-		| V.null pp1 = ([], d1)
-		| otherwise  =
-			let (Monomial w1 v1) = pp1 ! 0 in
-			let (Monomial w2 v2) = pp2 ! 0 in
-			let w = w1 - w2 in
-			let (v,r) = v1 `divMod` v2 in
-			if w >= 0 && r == 0
-				then
-					let mono = (Monomial w v) in
-					let remain = d1 `subPoly` (p2 `mulPoly` (fromList [mono])) in
-					let (l, finalRem) = divLoop remain in
-					(mono : l, finalRem)
-				else
-					([], d1)
diff --git a/Number/Prime.hs b/Number/Prime.hs
deleted file mode 100644
--- a/Number/Prime.hs
+++ /dev/null
@@ -1,180 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
--- |
--- Module      : Number.Prime
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : Good
-
-module Number.Prime
-	( generatePrime
-	, generateSafePrime
-	, isProbablyPrime
-	, findPrimeFrom
-	, findPrimeFromWith
-	, primalityTestNaive
-	, primalityTestMillerRabin
-	, primalityTestFermat
-	, isCoprime
-	) where
-
-import Crypto.Random
-import Data.Bits
-import Number.Generate
-import Number.Basic (sqrti, gcde_binary)
-import Number.ModArithmetic (exponantiation)
-
--- | returns if the number is probably prime.
--- first a list of small primes are implicitely tested for divisibility,
--- then a fermat primality test is used with arbitrary numbers and
--- then the Miller Rabin algorithm is used with an accuracy of 30 recursions
-isProbablyPrime :: CryptoRandomGen g => g -> Integer -> Either GenError (Bool, g)
-isProbablyPrime rng !n
-	| any (\p -> p `divides` n) (filter (< n) smallPrimes) = Right (False, rng)
-	| primalityTestFermat 50 (n`div`2) n                   = primalityTestMillerRabin rng 30 n
-	| otherwise                                            = Right (False, rng)
-
--- | generate a prime number of the required bitsize
-generatePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)
-generatePrime rng bits = case generateOfSize rng bits of
-	Left err         -> Left err
-	Right (sp, rng') -> findPrimeFrom rng' sp
-
--- | generate a prime number of the form 2p+1 where p is also prime.
--- it is also knowed as a Sophie Germaine prime or safe prime.
---
--- The number of safe prime is significantly smaller to the number of prime,
--- as such it shouldn't be used if this number is supposed to be kept safe.
-generateSafePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)
-generateSafePrime rng bits = case generateOfSize rng bits of
-	Left err         -> Left err
-	Right (sp, rng') -> case findPrimeFromWith rng' (\g i -> isProbablyPrime g (2*i+1)) (sp `div` 2) of
-		Left err         -> Left err
-		Right (p, rng'') -> Right (2*p+1, rng'')
-
--- | find a prime from a starting point where the property hold.
-findPrimeFromWith :: CryptoRandomGen g => g -> (g -> Integer -> Either GenError (Bool,g)) -> Integer -> Either GenError (Integer, g)
-findPrimeFromWith rng prop !n
-	| even n        = findPrimeFromWith rng prop (n+1)
-	| otherwise     = case isProbablyPrime rng n of
-		Left err               -> Left err
-		Right (False, rng')    -> findPrimeFromWith rng' prop (n+2)
-		Right (True, rng')     ->
-			case prop rng' n of
-				Left err             -> Left err
-				Right (False, rng'') -> findPrimeFromWith rng'' prop (n+2)
-				Right (True, rng'')  -> Right (n, rng'')
-
--- | find a prime from a starting point with no specific property.
-findPrimeFrom :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)
-findPrimeFrom rng n = findPrimeFromWith rng (\g _ -> Right (True, g)) n
-
--- | Miller Rabin algorithm return if the number is probably prime or composite.
--- the tries parameter is the number of recursion, that determines the accuracy of the test.
-primalityTestMillerRabin :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Bool, g)
-primalityTestMillerRabin rng tries !n
-	| n <= 3     = error "Miller-Rabin requires tested value to be > 3"
-	| even n     = Right (False, rng)
-	| tries <= 0 = error "Miller-Rabin tries need to be > 0"
-	| otherwise  = loop rng (factorise 0 (n-1)) tries where
-		-- factorise n-1 into the form 2^s*d
-		factorise :: Integer -> Integer -> (Integer, Integer)
-		factorise !s !v
-			| v `testBit` 0 = (s, v)
-			| otherwise     = factorise (s+1) (v `shiftR` 1)
-		expmod = exponantiation
-		-- when iteration reach zero, we have a probable prime
-		loop g _       0 = Right (True, g)
-		loop g t@(_,d) k = case generateBetween g 2 (n-2) of
-			Left err      -> Left err
-			Right (a, g') ->
-				let x = expmod a d n in
-				if x == (1 :: Integer) || x == (n-1)
-					then loop g' t (k-1)
-					else loop' g' t (k-1) ((x*x) `mod` n) 1
-		-- loop from 1 to s-1. if we reach the end then it's composite
-		loop' g t@(s,_) km1 !x2 !r
-			| r == s      = Right (False, g)
-			| x2 == 1     = Right (False, g)
-			| x2 /= (n-1) = loop' g t km1 ((x2*x2) `mod` n) (r+1)
-			| otherwise   = loop g t km1
-
--- | Probabilitic Test using Fermat primility test.
--- Beware of Carmichael numbers that are Fermat liars, i.e. this test
--- is useless for them. always combines with some other test.
-primalityTestFermat :: Int -- ^ number of iterations of the algorithm
-                    -> Integer -- ^ starting a
-                    -> Integer -- ^ number to test for primality
-                    -> Bool
-primalityTestFermat n a p = and $ map expTest [a..(a+fromIntegral n)]
-    where !pm1 = p-1
-          expTest i = exponantiation i pm1 p == 1
-
--- | Test naively is integer is prime.
--- while naive, we skip even number and stop iteration at i > sqrt(n)
-primalityTestNaive :: Integer -> Bool
-primalityTestNaive n
-	| n <= 1    = False
-	| n == 2    = True
-	| even n    = False
-	| otherwise = loop 3 where
-		ubound = snd $ sqrti n
-		loop i
-			| i > ubound    = True
-			| i `divides` n = False
-			| otherwise     = loop (i+2)
-
--- | Test is two integer are coprime to each other
-isCoprime :: Integer -> Integer -> Bool
-isCoprime m n = case gcde_binary m n of (_,_,d) -> d == 1
-
--- | list of the first primes till 2903..
-smallPrimes :: [Integer]
-smallPrimes =
-	[ 2    , 3    , 5    , 7    , 11   , 13   , 17   , 19   , 23   , 29
-	, 31   , 37   , 41   , 43   , 47   , 53   , 59   , 61   , 67   , 71
-	, 73   , 79   , 83   , 89   , 97   , 101  , 103  , 107  , 109  , 113
-	, 127  , 131  , 137  , 139  , 149  , 151  , 157  , 163  , 167  , 173
-	, 179  , 181  , 191  , 193  , 197  , 199  , 211  , 223  , 227  , 229
-	, 233  , 239  , 241  , 251  , 257  , 263  , 269  , 271  , 277  , 281
-	, 283  , 293  , 307  , 311  , 313  , 317  , 331  , 337  , 347  , 349
-	, 353  , 359  , 367  , 373  , 379  , 383  , 389  , 397  , 401  , 409
-	, 419  , 421  , 431  , 433  , 439  , 443  , 449  , 457  , 461  , 463
-	, 467  , 479  , 487  , 491  , 499  , 503  , 509  , 521  , 523  , 541
-	, 547  , 557  , 563  , 569  , 571  , 577  , 587  , 593  , 599  , 601
-	, 607  , 613  , 617  , 619  , 631  , 641  , 643  , 647  , 653  , 659
-	, 661  , 673  , 677  , 683  , 691  , 701  , 709  , 719  , 727  , 733
-	, 739  , 743  , 751  , 757  , 761  , 769  , 773  , 787  , 797  , 809
-	, 811  , 821  , 823  , 827  , 829  , 839  , 853  , 857  , 859  , 863
-	, 877  , 881  , 883  , 887  , 907  , 911  , 919  , 929  , 937  , 941
-	, 947  , 953  , 967  , 971  , 977  , 983  , 991  , 997  , 1009 , 1013
-	, 1019 , 1021 , 1031 , 1033 , 1039 , 1049 , 1051 , 1061 , 1063 , 1069
-	, 1087 , 1091 , 1093 , 1097 , 1103 , 1109 , 1117 , 1123 , 1129 , 1151
-	, 1153 , 1163 , 1171 , 1181 , 1187 , 1193 , 1201 , 1213 , 1217 , 1223
-	, 1229 , 1231 , 1237 , 1249 , 1259 , 1277 , 1279 , 1283 , 1289 , 1291
-	, 1297 , 1301 , 1303 , 1307 , 1319 , 1321 , 1327 , 1361 , 1367 , 1373
-	, 1381 , 1399 , 1409 , 1423 , 1427 , 1429 , 1433 , 1439 , 1447 , 1451
-	, 1453 , 1459 , 1471 , 1481 , 1483 , 1487 , 1489 , 1493 , 1499 , 1511
-	, 1523 , 1531 , 1543 , 1549 , 1553 , 1559 , 1567 , 1571 , 1579 , 1583
-	, 1597 , 1601 , 1607 , 1609 , 1613 , 1619 , 1621 , 1627 , 1637 , 1657
-	, 1663 , 1667 , 1669 , 1693 , 1697 , 1699 , 1709 , 1721 , 1723 , 1733
-	, 1741 , 1747 , 1753 , 1759 , 1777 , 1783 , 1787 , 1789 , 1801 , 1811
-	, 1823 , 1831 , 1847 , 1861 , 1867 , 1871 , 1873 , 1877 , 1879 , 1889
-	, 1901 , 1907 , 1913 , 1931 , 1933 , 1949 , 1951 , 1973 , 1979 , 1987
-	, 1993 , 1997 , 1999 , 2003 , 2011 , 2017 , 2027 , 2029 , 2039 , 2053
-	, 2063 , 2069 , 2081 , 2083 , 2087 , 2089 , 2099 , 2111 , 2113 , 2129
-	, 2131 , 2137 , 2141 , 2143 , 2153 , 2161 , 2179 , 2203 , 2207 , 2213
-	, 2221 , 2237 , 2239 , 2243 , 2251 , 2267 , 2269 , 2273 , 2281 , 2287
-	, 2293 , 2297 , 2309 , 2311 , 2333 , 2339 , 2341 , 2347 , 2351 , 2357
-	, 2371 , 2377 , 2381 , 2383 , 2389 , 2393 , 2399 , 2411 , 2417 , 2423
-	, 2437 , 2441 , 2447 , 2459 , 2467 , 2473 , 2477 , 2503 , 2521 , 2531
-	, 2539 , 2543 , 2549 , 2551 , 2557 , 2579 , 2591 , 2593 , 2609 , 2617
-	, 2621 , 2633 , 2647 , 2657 , 2659 , 2663 , 2671 , 2677 , 2683 , 2687
-	, 2689 , 2693 , 2699 , 2707 , 2711 , 2713 , 2719 , 2729 , 2731 , 2741
-	, 2749 , 2753 , 2767 , 2777 , 2789 , 2791 , 2797 , 2801 , 2803 , 2819
-	, 2833 , 2837 , 2843 , 2851 , 2857 , 2861 , 2879 , 2887 , 2897 , 2903
-	]
-
-{-# INLINE divides #-}
-divides :: Integer -> Integer -> Bool
-divides i n = n `mod` i == 0
diff --git a/Number/Serialize.hs b/Number/Serialize.hs
deleted file mode 100644
--- a/Number/Serialize.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-module Number.Serialize
-	( i2osp
-	, os2ip
-	, lengthBytes
-	) where
-
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import Data.Bits
-
--- | os2ip converts a byte string into a positive integer
-os2ip :: ByteString -> Integer
-os2ip = B.foldl' (\a b -> (256 * a) .|. (fromIntegral b)) 0
-
--- | i2osp converts a positive integer into a byte string
-i2osp :: Integer -> ByteString
-i2osp m = B.reverse $ B.unfoldr divMod256 m
-	where
-		divMod256 0 = Nothing
-		divMod256 n = Just (fromIntegral a,b) where (b,a) = n `divMod` 256
-
--- | returns the number of bytes to store an integer with i2osp
-lengthBytes :: Integer -> Int
-lengthBytes n
-	| n < 256   = 1
-	| otherwise = 1 + lengthBytes (n `div` 256)
diff --git a/Tests/AES.hs b/Tests/AES.hs
deleted file mode 100644
--- a/Tests/AES.hs
+++ /dev/null
@@ -1,75 +0,0 @@
-{-# LANGUAGE CPP #-}
-module AES (aesTests) where
-
--- unfortunately due to a bug in some version of cabal
--- there's no way to have a condition cpp-options in the cabal file
--- for test suite. to run test with AESni, uncomment the following
--- #define HAVE_AESNI
-
-import qualified Crypto.Cipher.AES.Haskell as AESHs
-#ifdef HAVE_AESNI
-import qualified Crypto.Cipher.AES.X86NI as AESNI
-#endif
-
-import Crypto.Classes
-import qualified Crypto.Modes as CAPI
-
-import Data.Word
-import Data.List
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import Control.Monad
-import Control.Applicative
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-import Test.QuickCheck
-
-newtype IV = IV ByteString
-    deriving (Show,Eq)
-newtype Key128 = Key128 ByteString
-    deriving (Show,Eq)
-newtype Message = Message ByteString
-    deriving (Show,Eq)
-
-arbitraryBS sz = B.pack <$> replicateM sz (choose (0,255) :: Gen Word8)
-
-instance Arbitrary IV where
-    arbitrary = IV <$> arbitraryBS 16
-
-instance Arbitrary Key128 where
-    arbitrary = Key128 <$> arbitraryBS 16
-
-instance Arbitrary Message where
-    arbitrary = choose (1,102) >>= \sz -> Message <$> arbitraryBS (16*sz)
-
-ecbTests l (Key128 k, Message m) = (== 1) $ length $ nub $ map (\f -> f k m) l
-cbcTests l (IV iv, Key128 k, Message m) = (== 1) $ length $ nub $ map (\f -> f k iv m) l
-
-unright (Right r) = r
-unright (Left e) = error e
-
-aesTests =
-    [ testProperty "ECB Encryption Equivalent" $ ecbTests
-        [ (\k m -> AESHs.encrypt (unright $ AESHs.initKey128 k) m)
-#ifdef HAVE_AESNI
-        , (\k m -> AESNI.encrypt (AESNI.initKey128 k) m)
-#endif
-        ]
-    , testProperty "CBC Encryption Equivalent" $ cbcTests
-        [ (\k iv m -> AESHs.encryptCBC (unright $ AESHs.initKey128 k) iv m)
-#ifdef HAVE_AESNI
-        , (\k iv m -> AESNI.encryptCBC (AESNI.initKey128 k) iv m)
-#endif
-        ]
-    , testProperty "ECB Decryption Equivalent" $ ecbTests
-        [ (\k m -> AESHs.decrypt (unright $ AESHs.initKey128 k) m)
-#ifdef HAVE_AESNI
-        , (\k m -> AESNI.decrypt (AESNI.initKey128 k) m)
-#endif
-        ]
-    , testProperty "CBC Decryption Equivalent" $ cbcTests
-        [ (\k iv m -> AESHs.decryptCBC (unright $ AESHs.initKey128 k) iv m)
-#ifdef HAVE_AESNI
-        , (\k iv m -> AESNI.decryptCBC (AESNI.initKey128 k) iv m)
-#endif
-        ]
-    ]
diff --git a/Tests/KAT.hs b/Tests/KAT.hs
deleted file mode 100644
--- a/Tests/KAT.hs
+++ /dev/null
@@ -1,260 +0,0 @@
-{-# LANGUAGE OverloadedStrings, CPP #-}
-module KAT (katTests) where
-
--- unfortunately due to a bug in some version of cabal
--- there's no way to have a condition cpp-options in the cabal file
--- for test suite. to run test with AESni, uncomment the following
--- #define HAVE_AESNI
-
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as BC
-
-import Data.Word
-
-import qualified Crypto.Cipher.AES.Haskell as AES
-#ifdef HAVE_AESNI
-import qualified Crypto.Cipher.AES.X86NI as AESNI
-#endif
-import qualified Crypto.Cipher.Blowfish as Blowfish
-import qualified Crypto.Cipher.Camellia as Camellia
-import qualified Crypto.Cipher.RC4 as RC4
-
-encryptStream fi fc key plaintext = B.unpack $ snd $ fc (fi key) plaintext
-
-encryptBlock fi fc key plaintext =
-	let e = fi (B.pack key) in
-	case e of
-		Right k -> B.unpack $ fc k plaintext
-		Left  e -> error e
-
-wordify :: [Char] -> [Word8]
-wordify = map (toEnum . fromEnum)
-
-vectors_aes128_enc =
-	[
-	  ( [0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,0x74,0xcf,0x86,0x7c,0xfb,0x47,0x38,0x59]
-	  , B.replicate 16 0
-	  , [0x6d,0x25,0x1e,0x69,0x44,0xb0,0x51,0xe0,0x4e,0xaa,0x6f,0xb4,0xdb,0xf7,0x84,0x65]
-	  )
-	, ( replicate 16 0
-	  , B.replicate 16 0
-	  , [0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b,0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e]
-	  )
-	, ( replicate 16 0
-	  , B.replicate 16 1
-	  , [0xe1,0x4d,0x5d,0x0e,0xe2,0x77,0x15,0xdf,0x08,0xb4,0x15,0x2b,0xa2,0x3d,0xa8,0xe0]
-	  )
-	, ( replicate 16 1
-	  , B.replicate 16 2
-	  , [0x17,0xd6,0x14,0xf3,0x79,0xa9,0x35,0x90,0x77,0xe9,0x55,0x77,0xfd,0x31,0xc2,0x0a]
-	  )
-	, ( replicate 16 2
-	  , B.replicate 16 1
-	  , [0x8f,0x42,0xc2,0x4b,0xee,0x6e,0x63,0x47,0x2b,0x16,0x5a,0xa9,0x41,0x31,0x2f,0x7c]
-	  )
-	, ( replicate 16 3
-	  , B.replicate 16 2
-	  , [0x90,0x98,0x85,0xe4,0x77,0xbc,0x20,0xf5,0x8a,0x66,0x97,0x1d,0xa0,0xbc,0x75,0xe3]
-	  )
-	]
-
-vectors_aes192_enc =
-	[
-	  ( replicate 24 0
-	  , B.replicate 16 0
-	  , [0xaa,0xe0,0x69,0x92,0xac,0xbf,0x52,0xa3,0xe8,0xf4,0xa9,0x6e,0xc9,0x30,0x0b,0xd7]
-	  )
-	, ( replicate 24 0
-	  , B.replicate 16 1
-	  , [0xcf,0x1e,0xce,0x3c,0x44,0xb0,0x78,0xfb,0x27,0xcb,0x0a,0x3e,0x07,0x1b,0x08,0x20]
-	  )
-	, ( replicate 24 1
-	  , B.replicate 16 2
-	  , [0xeb,0x8c,0x17,0x30,0x90,0xc7,0x5b,0x77,0xd6,0x72,0xb4,0x57,0xa7,0x78,0xd9,0xd0]
-	  )
-	, ( replicate 24 2
-	  , B.replicate 16 1
-	  , [0xf2,0xf0,0xae,0xd8,0xcd,0xc9,0x21,0xca,0x4b,0x55,0x84,0x5d,0xa4,0x15,0x21,0xc2]
-	  )
-	, ( replicate 24 3
-	  , B.replicate 16 2
-	  , [0xca,0xcc,0x30,0x79,0xe4,0xb7,0x95,0x27,0x63,0xd2,0x55,0xd6,0x34,0x10,0x46,0x14]
-	  )
-	]
-
-vectors_aes256_enc =
-	[ ( replicate 32 0
-	  , B.replicate 16 0
-	  , [0xdc,0x95,0xc0,0x78,0xa2,0x40,0x89,0x89,0xad,0x48,0xa2,0x14,0x92,0x84,0x20,0x87]
-	  )
-	, ( replicate 32 0
-	  , B.replicate 16 1
-	  , [0x7b,0xc3,0x02,0x6c,0xd7,0x37,0x10,0x3e,0x62,0x90,0x2b,0xcd,0x18,0xfb,0x01,0x63]
-	  )
-	, ( replicate 32 1
-	  , B.replicate 16 2
-	  , [0x62,0xae,0x12,0xf3,0x24,0xbf,0xea,0x08,0xd5,0xf6,0x75,0xb5,0x13,0x02,0x6b,0xbf]
-	  )
-	, ( replicate 32 2
-	  , B.replicate 16 1
-	  , [0x00,0xf9,0xc7,0x44,0x4b,0xb0,0xcc,0x80,0x6c,0x7c,0x39,0xee,0x22,0x11,0xf1,0x46]
-	  )
-	, ( replicate 32 3
-	  , B.replicate 16 2
-	  , [0xb4,0x05,0x87,0x3e,0xa0,0x76,0x1b,0x9c,0xa9,0x9f,0x70,0xb0,0x16,0x16,0xce,0xb1]
-	  )
-	]
-
-vectors_aes128_dec =
-	[ ( replicate 16 0
-	  , B.replicate 16 0
-	  , [0x14,0x0f,0x0f,0x10,0x11,0xb5,0x22,0x3d,0x79,0x58,0x77,0x17,0xff,0xd9,0xec,0x3a]
-	  )
-	, ( replicate 16 0
-	  , B.replicate 16 1
-	  , [0x15,0x6d,0x0f,0x85,0x75,0xd5,0x33,0x07,0x52,0xf8,0x4a,0xf2,0x72,0xff,0x30,0x50]
-	  )
-	, ( replicate 16 1
-	  , B.replicate 16 2
-	  , [0x34,0x37,0xd6,0xe2,0x31,0xd7,0x02,0x41,0x9b,0x51,0xb4,0x94,0x72,0x71,0xb6,0x11]
-	  )
-	, ( replicate 16 2
-	  , B.replicate 16 1
-	  , [0xe3,0xcd,0xe2,0x37,0xc8,0xf2,0xd9,0x7b,0x8d,0x79,0xf9,0x17,0x1d,0x4b,0xda,0xc1]
-	  )
-	, ( replicate 16 3
-	  , B.replicate 16 2
-	  , [0x5b,0x94,0xaa,0xed,0xd7,0x83,0x99,0x8c,0xd5,0x15,0x35,0x35,0x18,0xcc,0x45,0xe2]
-	  )
-	]
-
-vectors_aes192_dec =
-	[
-	  ( replicate 24 0
-	  , B.replicate 16 0
-	  , [0x13,0x46,0x0e,0x87,0xa8,0xfc,0x02,0x3e,0xf2,0x50,0x1a,0xfe,0x7f,0xf5,0x1c,0x51]
-	  )
-	, ( replicate 24 0
-	  , B.replicate 16 1
-	  , [0x92,0x17,0x07,0xc3,0x3d,0x1c,0xc5,0x96,0x7d,0xa5,0x1d,0xbb,0xb0,0x66,0xb2,0x6c]
-	  )
-	, ( replicate 24 1
-	  , B.replicate 16 2
-	  , [0xee,0x92,0x97,0xc6,0xba,0xe8,0x26,0x4d,0xff,0x08,0x0e,0xbb,0x1e,0x74,0x11,0xc1]
-	  )
-	, ( replicate 24 2
-	  , B.replicate 16 1
-	  , [0x49,0x67,0xdf,0x70,0xd2,0x9e,0x9a,0x7f,0x5d,0x7c,0xb9,0xc1,0x20,0xc3,0x8a,0x71]
-	  )
-	, ( replicate 24 3
-	  , B.replicate 16 2
-	  , [0x74,0x38,0x62,0x42,0x6b,0x56,0x7f,0xd5,0xf0,0x1d,0x1b,0x59,0x56,0x01,0x26,0x29]
-	  )
-	]
-
-vectors_aes256_dec =
-	[ ( replicate 32 0
-	  , B.replicate 16 0
-	  , [0x67,0x67,0x1c,0xe1,0xfa,0x91,0xdd,0xeb,0x0f,0x8f,0xbb,0xb3,0x66,0xb5,0x31,0xb4]
-	  )
-	, ( replicate 32 0
-	  , B.replicate 16 1
-	  , [0xcc,0x09,0x21,0xa3,0xc5,0xca,0x17,0xf7,0x48,0xb7,0xc2,0x7b,0x73,0xba,0x87,0xa2]
-	  )
-	, ( replicate 32 1
-	  , B.replicate 16 2
-	  , [0xc0,0x4b,0x27,0x90,0x1a,0x50,0xcf,0xfa,0xf1,0xbb,0x88,0x9f,0xc0,0x92,0x5e,0x14]
-	  )
-	, ( replicate 32 2
-	  , B.replicate 16 1
-	  , [0x24,0x61,0x53,0x5d,0x16,0x1c,0x15,0x39,0x88,0x32,0x77,0x29,0xc5,0x8c,0xc0,0x3a]
-	  )
-	, ( replicate 32 3
-	  , B.replicate 16 2
-	  , [0x30,0xc9,0x1c,0xce,0xfe,0x89,0x30,0xcf,0xff,0x31,0xdb,0xcc,0xfc,0x11,0xc5,0x23]
-	  )
-	]
-
-aes128InitKey = AES.initKey128
-aes192InitKey = AES.initKey192
-aes256InitKey = AES.initKey256
-
-vectors_rc4 =
-	[ (wordify "Key", "Plaintext", [ 0xBB,0xF3,0x16,0xE8,0xD9,0x40,0xAF,0x0A,0xD3 ])
-	, (wordify "Wiki", "pedia", [ 0x10,0x21,0xBF,0x04,0x20 ])
-	, (wordify "Secret", "Attack at dawn", [ 0x45,0xA0,0x1F,0x64,0x5F,0xC3,0x5B,0x38,0x35,0x52,0x54,0x4B,0x9B,0xF5 ])
-	]
-
-vectors_camellia128 =
-	[ 
-	  ( replicate 16 0
-	  , B.replicate 16 0
-	  , [0x3d,0x02,0x80,0x25,0xb1,0x56,0x32,0x7c,0x17,0xf7,0x62,0xc1,0xf2,0xcb,0xca,0x71]
-	  )
-	, ( [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]
-	  , B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]
-	  , [0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43]
-	  )
-	]
-
-vectors_camellia192 =
-	[
-	  ( [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77]
-	  , B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]
-	  ,[0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9]
-	  )
-	]
-
-vectors_camellia256 =
-	[
-	  ( [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
-	    ,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff]
-	  , B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]
-	  , [0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09]
-	  )
-	]
-
-vectors_blowfish =
-    [
-      ( replicate 8 0
-      , B.replicate 8 0
-      , [0x4e,0xf9,0x97,0x45,0x61,0x98,0xDD,0x78]
-      )
-    , ( replicate 8 255
-      , B.replicate 8 255
-      , [0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A]
-      )
-    , ( [0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57]
-      , B.pack [0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42]
-      , [0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B]
-      )
-    ]
-
-vectors =
-	[ ("RC4",        vectors_rc4,         encryptStream RC4.initCtx RC4.encrypt)
-	-- AES haskell implementation
-	, ("AES 128 Enc", vectors_aes128_enc,  encryptBlock aes128InitKey AES.encrypt)
-	, ("AES 192 Enc", vectors_aes192_enc,  encryptBlock aes192InitKey AES.encrypt)
-	, ("AES 256 Enc", vectors_aes256_enc,  encryptBlock aes256InitKey AES.encrypt)
-	, ("AES 128 Dec", vectors_aes128_dec,  encryptBlock aes128InitKey AES.decrypt)
-	, ("AES 192 Dec", vectors_aes192_dec,  encryptBlock aes192InitKey AES.decrypt)
-	, ("AES 256 Dec", vectors_aes256_dec,  encryptBlock aes256InitKey AES.decrypt)
-#ifdef HAVE_AESNI
-	-- AES ni implementation
-	, ("AESNI 128 Enc", vectors_aes128_enc,  encryptBlock (Right . AESNI.initKey128) AESNI.encrypt)
-	, ("AESNI 128 Dec", vectors_aes128_dec,  encryptBlock (Right . AESNI.initKey128) AESNI.decrypt)
-#endif
-    -- Blowfish implementation
-    , ("Blowfish",   vectors_blowfish,    encryptBlock Blowfish.initKey Blowfish.encrypt)
-	-- Camellia implementation
-	, ("Camellia",   vectors_camellia128, encryptBlock Camellia.initKey128 Camellia.encrypt)
-	]
-
-katTests = map makeTests vectors
-	where makeTests (name, v, f) = testProperty name (and $ map makeTest v)
-		where makeTest (key,plaintext,expected) = assertEq expected $ f key plaintext
-
-assertEq expected got
-	| expected == got = True
-	| otherwise       = error ("expected: " ++ show expected ++ " got: " ++ show got)
diff --git a/Tests/tests.hs b/Tests/tests.hs
deleted file mode 100644
--- a/Tests/tests.hs
+++ /dev/null
@@ -1,320 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-
-import Test.QuickCheck
-import Test.QuickCheck.Test
-import System.IO (hFlush, stdout)
-
-import Control.Monad
-import Control.Arrow (first)
-import Control.Applicative ((<$>))
-
-import Data.List (intercalate)
-import Data.Char
-import Data.Bits
-import Data.Word
-import qualified Data.Vector.Unboxed as V
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Char8 as BC
--- for DSA
-import qualified Crypto.Hash.SHA1 as SHA1
-
--- numbers
-{-
-import Number.ModArithmetic
-import Number.Basic
-import Number.Prime
-import Number.Serialize
--}
--- ciphers/Kexch
-import AES (aesTests)
-import qualified Crypto.Cipher.AES.Haskell as AES
-import qualified Crypto.Cipher.RSA as RSA
-import qualified Crypto.Cipher.DSA as DSA
-import qualified Crypto.Cipher.DH as DH
-import Crypto.Random
-import KAT
-
-{-
-prop_gcde_binary_valid (Positive a, Positive b) =
-	let (x,y,v)    = gcde_binary a b in
-	let (x',y',v') = gcde a b in
-	and [v==v', a*x' + b*y' == v', a*x + b*y == v, gcd a b == v]
-
-prop_modexp_rtl_valid (NonNegative a, NonNegative b, Positive m) =
-	exponantiation_rtl_binary a b m == ((a ^ b) `mod` m)
-
-prop_modinv_valid (Positive a, Positive m)
-	| m > 1 =
-		case inverse a m of
-			Just ainv -> (ainv * a) `mod` m == 1
-			Nothing   -> True
-	| otherwise       = True
-
-prop_sqrti_valid (Positive i) = l*l <= i && i <= u*u where (l, u) = sqrti i
-
-prop_generate_prime_valid i =
-	-- becuase of the next naive test, we can't generate easily number above 32 bits
-	-- otherwise it slows down the tests to uselessness. when AKS or ECPP is implemented
-	-- we can revisit the number here
-	let p = withAleasInteger rng i (\g -> generatePrime g 32) in
-	-- FIXME test if p is around 32 bits
-	primalityTestNaive p
-
-prop_miller_rabin_valid i
-	| i <= 3    = True
-	| otherwise =
-		-- miller rabin only returns with certitude that the integer is composite.
-		let b = withAleasInteger rng i (\g -> isProbablyPrime g i) in
-		(b == False && primalityTestNaive i == False) || b == True
-
-withAleasInteger rng i f = case reseed (i2osp (if i < 0 then -i else i)) rng of
-	Left _     -> error "impossible"
-	Right rng' -> case f rng' of
-		Left _  -> error "impossible"
-		Right v -> fst v
--}
-
-newtype RSAMessage = RSAMessage B.ByteString deriving (Show, Eq)
-
-instance Arbitrary RSAMessage where
-	arbitrary = do
-		sz <- choose (0, 128 - 11)
-		ws <- replicateM sz (choose (0,255) :: Gen Int)
-		return $ RSAMessage $ B.pack $ map fromIntegral ws
-
-{- this is a just test rng. this is absolutely not a serious RNG. DO NOT use elsewhere -}
-data Rng = Rng (Int, Int)
-
-getByte :: Rng -> (Word8, Rng)
-getByte (Rng (mz, mw)) =
-	let mz2 = 36969 * (mz `mod` 65536) in
-	let mw2 = 18070 * (mw `mod` 65536) in
-	(fromIntegral (mz2 + mw2), Rng (mz2, mw2))
-
-getBytes 0 rng = ([], rng)
-getBytes n rng =
-	let (b, rng')  = getByte rng in
-	let (l, rng'') = getBytes (n-1) rng' in
-	(b:l, rng'')
-
-instance CryptoRandomGen Rng where
-	newGen _       = Right (Rng (2,3))
-	genSeedLength  = 0
-	genBytes len g = Right $ first B.pack $ getBytes len g
-	reseed bs (Rng (a,b)) = Right $ Rng (fromIntegral a', b) where
-		a' = ((fromIntegral a) + i * 36969) `mod` 65536
-		i = B.head bs
-
-rng = Rng (1,2) 
-
-{-----------------------------------------------------------------------------------------------}
-{- testing RSA -}
-{-----------------------------------------------------------------------------------------------}
-
-{-
-prop_rsa_generate_valid (Positive i, RSAMessage msgz) =
-	let keysz = 64 in
-	let (pub,priv) = withAleasInteger rng i (\g -> RSA.generate g keysz 65537) in
-	let msg = B.take (keysz - 11) msgz in
-	(RSA.private_p priv * RSA.private_q priv == RSA.private_n priv) &&
-	((RSA.private_d priv * RSA.public_e pub) `mod` ((RSA.private_p priv - 1) * (RSA.private_q priv - 1)) == 1) &&
-	(either Left (RSA.decrypt priv . fst) $ RSA.encrypt rng pub msg) == Right msg
--}
-
-prop_rsa_valid fast (RSAMessage msg) =
-	(either Left (RSA.decrypt pk . fst) $ RSA.encrypt rng rsaPublickey msg) == Right msg
-	where pk       = if fast then rsaPrivatekey else rsaPrivatekey { RSA.private_p = 0, RSA.private_q = 0 }
-
-prop_rsa_fast_valid  = prop_rsa_valid True
-prop_rsa_slow_valid  = prop_rsa_valid False
-
-prop_rsa_sign_valid fast (RSAMessage msg) = (either Left (\smsg -> verify msg smsg) $ sign msg) == Right True
-	where
-		verify   = RSA.verify (SHA1.hash) sha1desc rsaPublickey
-		sign     = RSA.sign (SHA1.hash) sha1desc pk
-		sha1desc = B.pack [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03, 0x02,0x1a,0x05,0x00,0x04,0x14]
-		pk       = if fast then rsaPrivatekey else rsaPrivatekey { RSA.private_p = 0, RSA.private_q = 0 }
-
-prop_rsa_sign_fast_valid = prop_rsa_sign_valid True
-prop_rsa_sign_slow_valid = prop_rsa_sign_valid False
-
-rsaPrivatekey = RSA.PrivateKey
-	{ RSA.private_pub  = rsaPublickey
-	, RSA.private_d    = 133764127300370985476360382258931504810339098611363623122953018301285450176037234703101635770582297431466449863745848961134143024057267778947569638425565153896020107107895924597628599677345887446144410702679470631826418774397895304952287674790343620803686034122942606764275835668353720152078674967983573326257
-	, RSA.private_p    = 12909745499610419492560645699977670082358944785082915010582495768046269235061708286800087976003942261296869875915181420265794156699308840835123749375331319
-	, RSA.private_q    = 10860278066550210927914375228722265675263011756304443428318337179619069537063135098400347475029673115805419186390580990519363257108008103841271008948795129
-	, RSA.private_dP   = 5014229697614831746694710412330921341325464081424013940131184365711243776469716106024020620858146547161326009604054855316321928968077674343623831428796843
-	, RSA.private_dQ   = 3095337504083058271243917403868092841421453478127022884745383831699720766632624326762288333095492075165622853999872779070009098364595318242383709601515849
-	, RSA.private_qinv = 11136639099661288633118187183300604127717437440459572124866697429021958115062007251843236337586667012492941414990095176435990146486852255802952814505784196
-	}
-
-rsaPublickey = RSA.PublicKey
-	{ RSA.public_size = 128
-	, RSA.public_n    = 140203425894164333410594309212077886844966070748523642084363106504571537866632850620326769291612455847330220940078873180639537021888802572151020701352955762744921926221566899281852945861389488419179600933178716009889963150132778947506523961974222282461654256451508762805133855866018054403911588630700228345151
-	, RSA.public_e    = 65537
-	}
-
-{-----------------------------------------------------------------------------------------------}
-{- testing DSA -}
-{-----------------------------------------------------------------------------------------------}
-
-
-dsaParams = (p,g,q)
-	where
-		p = 0x00a8c44d7d0bbce69a39008948604b9c7b11951993a5a1a1fa995968da8bb27ad9101c5184bcde7c14fb79f7562a45791c3d80396cefb328e3e291932a17e22edd
-		g = 0x0bf9fe6c75d2367b88912b2252d20fdcad06b3f3a234b92863a1e30a96a123afd8e8a4b1dd953e6f5583ef8e48fc7f47a6a1c8f24184c76dba577f0fec2fcd1c
-		q = 0x0096674b70ef58beaaab6743d6af16bb862d18d119
-
-dsaPrivatekey = DSA.PrivateKey
-	{ DSA.private_params = dsaParams
-	, DSA.private_x      = 0x229bac7aa1c7db8121bfc050a3426eceae23fae8
-	}
-
-dsaPublickey = DSA.PublicKey
-	{ DSA.public_params = dsaParams
-	, DSA.public_y      = 0x4fa505e86e32922f1fa1702a120abdba088bb4be801d4c44f7fc6b9094d85cd52c429cbc2b39514e30909b31e2e2e0752b0fc05c1a7d9c05c3e52e49e6edef4c
-	}
-
-prop_dsa_valid (RSAMessage msg) =
-	case DSA.verify signature (SHA1.hash) dsaPublickey msg of
-		Left err -> False
-		Right b  -> b
-	where
-		Right (signature, rng') = DSA.sign rng (SHA1.hash) dsaPrivatekey msg
-
-{-----------------------------------------------------------------------------------------------}
-{- testing DH -}
-{-----------------------------------------------------------------------------------------------}
-instance Arbitrary DH.PrivateNumber where
-	arbitrary = fromIntegral <$> (suchThat (arbitrary :: Gen Integer) (\x -> x >= 1))
-
-prop_dh_valid (xa, xb) = sa == sb
-	where
-		sa = DH.getShared dhparams xa yb
-		sb = DH.getShared dhparams xb ya
-		yb = DH.generatePublic dhparams xb
-		ya = DH.generatePublic dhparams xa
-		dhparams = (11, 7)
-
-{-----------------------------------------------------------------------------------------------}
-{- testing AES -}
-{-----------------------------------------------------------------------------------------------}
-data AES128Message = AES128Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
-data AES192Message = AES192Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
-data AES256Message = AES256Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
-
-arbitraryAES keysize = do
-	sz <- choose (1, 12)
-	ws <- replicateM (sz*16) (choose (0,255) :: Gen Int)
-	key <- replicateM keysize (choose (0,255) :: Gen Int)
-	iv  <- replicateM 16 (choose (0,255) :: Gen Int)
-	return (ws, key, iv)
-
-instance Arbitrary AES128Message where
-	arbitrary = do
-		(ws, key, iv) <- arbitraryAES 16
-		return $ AES128Message (B.pack $ map fromIntegral key)
-		                       (B.pack $ map fromIntegral iv)
-		                       (B.pack $ map fromIntegral ws)
-
-instance Arbitrary AES192Message where
-	arbitrary = do
-		(ws, key, iv) <- arbitraryAES 24
-		return $ AES192Message (B.pack $ map fromIntegral key)
-		                       (B.pack $ map fromIntegral iv)
-		                       (B.pack $ map fromIntegral ws)
-
-instance Arbitrary AES256Message where
-	arbitrary = do
-		(ws, key, iv) <- arbitraryAES 32
-		return $ AES256Message (B.pack $ map fromIntegral key)
-		                       (B.pack $ map fromIntegral iv)
-		                       (B.pack $ map fromIntegral ws)
-
-
-prop_ecb_valid k msg = AES.decrypt k (AES.encrypt k msg) == msg
-prop_cbc_valid k iv msg = AES.decryptCBC k iv (AES.encryptCBC k iv msg) == msg
-
-prop_aes128_ecb_valid (AES128Message key _ msg) =
-	let (Right k) = AES.initKey128 key in
-	prop_ecb_valid k msg
-
-prop_aes192_ecb_valid (AES192Message key _ msg) =
-	let (Right k) = AES.initKey192 key in
-	prop_ecb_valid k msg
-
-prop_aes256_ecb_valid (AES256Message key _ msg) =
-	let (Right k) = AES.initKey256 key in
-	prop_ecb_valid k msg
-
-prop_aes128_cbc_valid (AES128Message key iv msg) =
-	let (Right k) = AES.initKey128 key in
-	prop_cbc_valid k iv msg
-
-prop_aes192_cbc_valid (AES192Message key iv msg) =
-	let (Right k) = AES.initKey192 key in
-	prop_cbc_valid k iv msg
-
-prop_aes256_cbc_valid (AES256Message key iv msg) =
-	let (Right k) = AES.initKey256 key in
-	prop_cbc_valid k iv msg
-
-{-----------------------------------------------------------------------------------------------}
-{- main -}
-{-----------------------------------------------------------------------------------------------}
-
-symCipherExpectedTests = testGroup "symmetric cipher KAT" katTests
-
-symCipherMarshallTests = testGroup "symmetric cipher marshall"
-	[ testProperty "AES128 (ECB)" prop_aes128_ecb_valid
-	, testProperty "AES128 (CBC)" prop_aes128_cbc_valid
-	, testProperty "AES192 (ECB)" prop_aes192_ecb_valid
-	, testProperty "AES192 (CBC)" prop_aes192_cbc_valid
-	, testProperty "AES256 (ECB)" prop_aes256_ecb_valid
-	, testProperty "AES256 (CBC)" prop_aes256_cbc_valid
-	]
-
-asymEncryptionTests = testGroup "assymmetric cipher encryption"
-	[ testProperty "RSA (slow)" prop_rsa_slow_valid
-	, testProperty "RSA (fast)" prop_rsa_fast_valid
-	]
-
-asymSignatureTests = testGroup "assymmetric cipher signature"
-	[ testProperty "RSA (slow)" prop_rsa_sign_slow_valid
-	, testProperty "RSA (fast)" prop_rsa_sign_fast_valid
-	, testProperty "DSA" prop_dsa_valid
-	]
-
-asymOtherTests = testGroup "assymetric other tests"
-	[ testProperty "DH valid" prop_dh_valid
-	]
-
-arithmeticTests = testGroup "arithmetic"
-	[]
-
-{- run_test "RSA generate" prop_rsa_generate_valid -}
-
-tests :: [Test]
-tests =
-	[ symCipherExpectedTests
-	, symCipherMarshallTests
-	, testGroup "AES" aesTests
-	, arithmeticTests
-	, asymEncryptionTests
-	, asymSignatureTests
-	, asymOtherTests
-	]
-
-main = defaultMain tests
-{-
-	-- Number Tests
-	run_test "gcde binary valid" prop_gcde_binary_valid
-	run_test "exponantiation RTL valid" prop_modexp_rtl_valid
-	run_test "inverse valid" prop_modinv_valid
-	run_test "sqrt integer valid" prop_sqrti_valid
-	run_test "primality test Miller Rabin" prop_miller_rabin_valid
-	run_test "Generate prime" prop_generate_prime_valid
-	-}
diff --git a/cbits/aes/aes.h b/cbits/aes/aes.h
deleted file mode 100644
--- a/cbits/aes/aes.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Vincent Hanquez <vincent@snarc.org>
- * 
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of his contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef CRYPTOCIPHER_AES_H
-#define CRYPTOCIPHER_AES_H
-
-#define AES128_NB_ROUNDS 10
-
-#include <stdint.h>
-
-/* aes_key128 need to be 16 aligned by higher layer using the code. */
-typedef struct { uint8_t _data[20]; } aes_key128;
-
-void aes_generate_key128(aes_key128 *key, uint8_t *ikey);
-
-/* ECB mode */
-void aes_encrypt(uint8_t *out, aes_key128 *key, uint8_t *in, uint32_t blocks);
-void aes_decrypt(uint8_t *out, aes_key128 *key, uint8_t *in, uint32_t blocks);
-
-/* CBC mode */
-void aes_encrypt_cbc(uint8_t *out, aes_key128 *key, uint8_t *iv, uint8_t *in, uint32_t blocks);
-void aes_decrypt_cbc(uint8_t *out, aes_key128 *key, uint8_t *iv, uint8_t *in, uint32_t blocks);
-
-#endif
diff --git a/cryptocipher.cabal b/cryptocipher.cabal
--- a/cryptocipher.cabal
+++ b/cryptocipher.cabal
@@ -1,84 +1,29 @@
 Name:                cryptocipher
-Version:             0.3.7
-Description:         Symmetrical Block, Stream and PubKey Ciphers
+Version:             0.6.2
+Description:         Symmetrical block and stream ciphers.
 License:             BSD3
 License-file:        LICENSE
 Copyright:           Vincent Hanquez <vincent@snarc.org>
 Author:              Vincent Hanquez <vincent@snarc.org>
 Maintainer:          Vincent Hanquez <vincent@snarc.org>
-Synopsis:            Symmetrical Block, Stream and PubKey Ciphers
+Synopsis:            Symmetrical block and stream ciphers.
 Category:            Cryptography
 Build-Type:          Simple
-Homepage:            http://github.com/vincenthz/hs-cryptocipher
+Homepage:            http://github.com/vincenthz/hs-crypto-cipher
 Cabal-Version:       >=1.8
-Extra-Source-Files:  Tests/*.hs
-                     cbits/aes/aes.h
 
-Flag benchmark
-  Description:       Build benchmarks
-  Default:           False
-
-Flag aesni
-  Description:       Use fast aesni operations that are cpu dependant
-  Default:           False
-
 Library
   Build-Depends:     base >= 4 && < 5
-                   , bytestring
-                   , vector >= 0.7
-                   , cpu >= 0.1 && < 0.2
-                   , ghc-prim
-                   , primitive
-                   , crypto-api >= 0.5
-                   , crypto-pubkey-types >= 0.2 && < 0.3
-                   , tagged
-                   , cereal
-  Exposed-modules:   Crypto.Cipher.RC4
-                     Crypto.Cipher.AES
-                     Crypto.Cipher.AES.Haskell
-                     Crypto.Cipher.Blowfish
-                     Crypto.Cipher.Camellia
-                     Crypto.Cipher.RSA
-                     Crypto.Cipher.DSA
-                     Crypto.Cipher.DH
-  other-modules:     Number.ModArithmetic
-                     Number.Serialize
-                     Number.Generate
-                     Number.Basic
-                     Number.Polynomial
-                     Number.Prime
-                     Crypto.Cipher.ElGamal
+                   , crypto-cipher-types >= 0.0.8 && < 0.1
+                   , cipher-aes >= 0.2.3 && < 0.3
+                   , cipher-rc4 >= 0.1.3 && < 0.2
+                   , cipher-des >= 0.0 && < 0.1
+                   , cipher-blowfish >= 0.0 && < 0.1
+                   , cipher-camellia >= 0.0 && < 0.1
+  Exposed-modules:   Crypto.Cipher
   ghc-options:       -Wall
 
-Test-Suite test-cryptocipher
-  type:              exitcode-stdio-1.0
-  hs-source-dirs:    Tests
-  Main-Is:           tests.hs
-  Build-depends:     base >= 4 && < 5
-                   , crypto-api >= 0.5
-                   , cryptocipher
-                   , bytestring
-                   , cryptohash
-                   , vector
-                   , entropy
-                   , QuickCheck >= 2
-                   , test-framework >= 0.3.3
-                   , test-framework-quickcheck2 >= 0.2.9
-
-Executable           Benchmarks
-  hs-source-dirs:    Benchmarks
-  Main-Is:           Benchmarks.hs
-  if flag(benchmark)
-    Buildable:       True
-    Build-depends:   base >= 4 && < 5
-                   , bytestring
-                   , crypto-api
-                   , cryptocipher
-                   , criterion
-                   , mtl
-  else
-    Buildable:       False
-
 source-repository head
   type:     git
-  location: git://github.com/vincenthz/hs-cryptocipher
+  location: git://github.com/vincenthz/hs-crypto-cipher
+  subdir:   cryptocipher
