diff --git a/Benchmarks/Benchmarks.hs b/Benchmarks/Benchmarks.hs
--- a/Benchmarks/Benchmarks.hs
+++ b/Benchmarks/Benchmarks.hs
@@ -13,25 +13,12 @@
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 
-import qualified Crypto.Cipher.AES as AES
 import qualified Crypto.Cipher.RC4 as RC4
 import qualified Crypto.Cipher.Blowfish as Blowfish
 import qualified Crypto.Cipher.Camellia as Camellia
 
 import Crypto.Classes
 
-key128 = AES.initKey $ B.replicate 16 0
-aesEncrypt128 = AES.encryptECB key128
-aesEncrypt128CBC = AES.encryptCBC key128 (AES.IV $ B.replicate 16 0)
-
-key192 = AES.initKey $ B.replicate 24 0
-aesEncrypt192 = AES.encryptECB key192
-aesEncrypt192CBC = AES.encryptCBC key192 (AES.IV $ B.replicate 16 0)
-
-key256 = AES.initKey $ B.replicate 32 0
-aesEncrypt256 = AES.encryptECB key256
-aesEncrypt256CBC = AES.encryptCBC key256 (AES.IV $ B.replicate 16 0)
-
 (Right blowfishKey) = Blowfish.initKey $ B.empty
 blowfishEncrypt = Blowfish.encrypt blowfishKey
 
@@ -82,13 +69,6 @@
 		[ ("RC4"        , rc4Encrypt)
 		, ("Blowfish"   , blowfishEncrypt)
 		, ("Camellia128", camelliaEncrypt128)
-		, ("AES128"     , aesEncrypt128)
-		, ("AES128-CBC" , aesEncrypt128CBC)
-		-- , ("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"
diff --git a/Crypto/Cipher/DES.hs b/Crypto/Cipher/DES.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/Cipher/DES.hs
@@ -0,0 +1,202 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Crypto.Cipher.DES
+-- License     :  BSD-style
+--
+-- This module is copy of DES module from Crypto package.
+-- http://hackage.haskell.org/package/Crypto
+--
+-----------------------------------------------------------------------------
+
+
+module Crypto.Cipher.DES (encrypt, decrypt) where
+
+import Data.Word
+import Data.Bits
+
+type Rotation = Int
+type Key     = Word64
+type Message = Word64
+type Enc     = Word64
+
+type BitsX  = [Bool]
+type Bits4  = [Bool]
+type Bits6  = [Bool]
+type Bits32 = [Bool]
+type Bits48 = [Bool]
+type Bits56 = [Bool]
+type Bits64 = [Bool]
+
+instance Num [Bool]
+
+instance Bits [Bool] where
+ a `xor` b = (zipWith (\x y -> (not x && y) || (x && not y)) a b)
+ rotate bits rot = drop rot' bits ++ take rot' bits
+  where rot' = rot `mod` (length bits)
+
+bitify :: Word64 -> Bits64
+bitify w = map (\b -> w .&. (shiftL 1 b) /= 0) [63,62..0]
+
+unbitify :: Bits64 -> Word64
+unbitify bs = foldl (\i b -> if b then 1 + shiftL i 1 else shiftL i 1) 0 bs
+
+initial_permutation :: Bits64 -> Bits64
+initial_permutation mb = map ((!!) mb) i
+ where i = [57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+            61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,
+            56, 48, 40, 32, 24, 16,  8, 0, 58, 50, 42, 34, 26, 18, 10, 2,
+            60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6]
+
+key_transformation :: Bits64 -> Bits56
+key_transformation kb = map ((!!) kb) i
+ where i = [56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
+             9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
+            62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
+            13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3]
+
+des_enc :: Message -> Key -> Enc
+des_enc = do_des [1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28]
+
+des_dec :: Message -> Key -> Enc
+des_dec = do_des [28,27,25,23,21,19,17,15,14,12,10,8,6,4,2,1]
+
+do_des :: [Rotation] -> Message -> Key -> Enc
+do_des rots m k = des_work rots (takeDrop 32 mb) kb
+ where kb = key_transformation $ bitify k
+       mb = initial_permutation $ bitify m
+
+des_work :: [Rotation] -> (Bits32, Bits32) -> Bits56 -> Enc
+des_work [] (ml, mr) _ = unbitify $ final_perm $ (mr ++ ml)
+des_work (r:rs) mb kb = des_work rs mb' kb
+ where mb' = do_round r mb kb
+
+do_round :: Rotation -> (Bits32, Bits32) -> Bits56 -> (Bits32, Bits32)
+do_round r (ml, mr) kb = (mr, m')
+ where kb' = get_key kb r
+       comp_kb = compression_permutation kb'
+       expa_mr = expansion_permutation mr
+       res = comp_kb `xor` expa_mr
+       res' = tail $ iterate (trans 6) ([], res)
+       trans n (_, b) = (take n b, drop n b)
+       res_s = concat $ zipWith (\f (x,_) -> f x) [s_box_1, s_box_2,
+                                                   s_box_3, s_box_4,
+                                                   s_box_5, s_box_6,
+                                                   s_box_7, s_box_8] res'
+       res_p = p_box res_s
+       m' = res_p `xor` ml
+
+get_key :: Bits56 -> Rotation -> Bits56
+get_key kb r = kb'
+ where (kl, kr) = takeDrop 28 kb
+       kb' = rotateL kl r ++ rotateL kr r
+
+compression_permutation :: Bits56 -> Bits48
+compression_permutation kb = map ((!!) kb) i
+ where i = [13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
+            22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
+            40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+            43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31]
+
+expansion_permutation :: Bits32 -> Bits48
+expansion_permutation mb = map ((!!) mb) i
+ where i = [31,  0,  1,  2,  3,  4,  3,  4,  5,  6,  7,  8,
+             7,  8,  9, 10, 11, 12, 11, 12, 13, 14, 15, 16,
+            15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24,
+            23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31,  0]
+
+s_box :: [[Word8]] -> Bits6 -> Bits4
+s_box s [a,b,c,d,e,f] = to_bool 4 $ (s !! row) !! col
+ where row = sum $ zipWith numericise [a,f]     [1, 0]
+       col = sum $ zipWith numericise [b,c,d,e] [3, 2, 1, 0]
+       numericise = (\x y -> if x then 2^y else 0)
+       to_bool 0 _ = []
+       to_bool n i = ((i .&. 8) == 8):to_bool (n-1) (shiftL i 1)
+
+s_box_1 :: Bits6 -> Bits4
+s_box_1 = s_box i
+ where i = [[14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7],
+            [ 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8],
+            [ 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0],
+            [15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13]]
+
+s_box_2 :: Bits6 -> Bits4
+s_box_2 = s_box i
+ where i = [[15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10],
+            [3,  13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9,  11, 5],
+            [0,  14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15],
+            [13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5,  14, 9]]
+
+s_box_3 :: Bits6 -> Bits4
+s_box_3 = s_box i
+ where i = [[10,  0,  9, 14 , 6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8],
+            [13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1],
+            [13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7],
+            [1,  10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12]]
+
+s_box_4 :: Bits6 -> Bits4
+s_box_4 = s_box i
+ where i = [[7,  13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15],
+            [13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9],
+            [10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4],
+            [3,  15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14]]
+
+s_box_5 :: Bits6 -> Bits4
+s_box_5 = s_box i
+ where i = [[2,  12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9],
+            [14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6],
+            [4,   2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14],
+            [11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3]]
+
+s_box_6 :: Bits6 -> Bits4
+s_box_6 = s_box i
+ where i = [[12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11],
+            [10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8],
+            [9,  14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6],
+            [4,  3,   2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13]]
+
+s_box_7 :: Bits6 -> Bits4
+s_box_7 = s_box i
+ where i = [[4,  11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1],
+            [13, 0,  11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6],
+            [1,  4,  11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2],
+            [6,  11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12]]
+
+s_box_8 :: Bits6 -> Bits4
+s_box_8 = s_box i
+ where i = [[13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7],
+            [1,  15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2],
+            [7,  11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8],
+            [2,   1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11]]
+
+p_box :: Bits32 -> Bits32
+p_box kb = map ((!!) kb) i
+ where i = [15, 6, 19, 20, 28, 11, 27, 16,  0, 14, 22, 25,  4, 17, 30,  9,
+             1, 7, 23, 13, 31, 26,  2,  8, 18, 12, 29,  5, 21, 10,  3, 24]
+
+final_perm :: Bits64 -> Bits64
+final_perm kb = map ((!!) kb) i
+ where i = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30,
+            37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28,
+            35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26,
+            33, 1, 41,  9, 49, 17, 57, 25, 32, 0, 40 , 8, 48, 16, 56, 24]
+
+takeDrop :: Int -> [a] -> ([a], [a])
+takeDrop _ [] = ([], [])
+takeDrop 0 xs = ([], xs)
+takeDrop n (x:xs) = (x:ys, zs)
+ where (ys, zs) = takeDrop (n-1) xs
+
+
+-- | Basic DES encryption which takes a key and a block of plaintext
+-- and returns the encrypted block of ciphertext according to the standard.
+
+encrypt :: Word64 -> Word64 -> Word64
+encrypt = flip des_enc
+
+-- | Basic DES decryption which takes a key and a block of ciphertext and
+-- returns the decrypted block of plaintext according to the standard.
+
+decrypt :: Word64 -> Word64 -> Word64
+decrypt = flip des_dec
diff --git a/Crypto/Cipher/TripleDES.hs b/Crypto/Cipher/TripleDES.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/Cipher/TripleDES.hs
@@ -0,0 +1,134 @@
+-- |
+-- Module      : Crypto.Cipher.TripleDES
+-- License     : BSD-style
+-- Stability   : experimental
+-- Portability : ???
+
+module Crypto.Cipher.TripleDES
+    ( DesEee3Key(..)
+    , DesEde3Key(..)
+    , DesEee2Key(..)
+    , DesEde2Key(..)
+    ) where
+
+import Control.Applicative ((<$>))
+import Data.Serialize (Get, Put, Serialize(..), runGet, runPut,
+                       getWord8, putWord64le)
+import Data.Word (Word8, Word64)
+import Foreign (castPtr, peek)
+import System.IO.Unsafe (unsafePerformIO)
+import Data.ByteString.Unsafe (unsafeUseAsCString)
+import qualified Data.ByteString as B
+import qualified Data.Bits as Bits
+
+import Crypto.Classes (BlockCipher(..))
+import qualified Crypto.Cipher.DES as DES
+
+data DesEee3Key = DesEee3Key Word64 Word64 Word64 -- three different keys
+    deriving (Show, Eq)
+
+data DesEde3Key = DesEde3Key Word64 Word64 Word64 -- three different keys
+    deriving (Show, Eq)
+
+data DesEee2Key = DesEee2Key Word64 Word64 -- key1 and key3 are equal
+    deriving (Show, Eq)
+
+data DesEde2Key = DesEde2Key Word64 Word64 -- key1 and key3 are equal
+    deriving (Show, Eq)
+
+triplePut :: Word64 -> Word64 -> Word64 -> Put
+triplePut f s t = putWord64le f >> putWord64le s >> putWord64le t
+
+doublePut :: Word64 -> Word64 -> Put
+doublePut f s = putWord64le f >> putWord64le s
+
+getFixedParityByte :: Get Word8
+getFixedParityByte = do
+    sourceWord <- getWord8
+    return $ case odd(Bits.popCount sourceWord) of
+        True  -> Bits.clearBit sourceWord lsb
+        False -> sourceWord
+  where
+    lsb = 0
+
+getFixedParityWord64le :: Get Word64
+getFixedParityWord64le =
+    sum <$> sequence [ shiftWord8Toword64 pos <$> getFixedParityByte
+                     | pos <- [7,6..0] ]
+  where
+    shiftWord8Toword64 :: Int -> Word8 -> Word64
+    shiftWord8Toword64 pos = flip Bits.shiftL (pos * 8) . fromIntegral
+
+tripleGet :: Get (Word64, Word64, Word64)
+tripleGet = do
+    f <- getFixedParityWord64le
+    s <- getFixedParityWord64le
+    t <- getFixedParityWord64le
+    return (f, s, t)
+
+doubleGet :: Get (Word64, Word64)
+doubleGet = do
+    f <- getFixedParityWord64le
+    s <- getFixedParityWord64le
+    return (f, s)
+
+uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
+uncurry3 f (x, y, z) = f x y z
+
+instance Serialize DesEee3Key where
+    put (DesEee3Key f s t) = triplePut f s t
+    get = uncurry3 DesEee3Key <$> tripleGet
+
+instance Serialize DesEde3Key where
+    put (DesEde3Key f s t) = triplePut f s t
+    get = uncurry3 DesEde3Key <$> tripleGet
+
+instance Serialize DesEee2Key where
+    put (DesEee2Key f s) = doublePut f s
+    get = uncurry DesEee2Key <$> doubleGet
+
+instance Serialize DesEde2Key where
+    put (DesEde2Key f s) = doublePut f s
+    get = uncurry DesEde2Key <$> doubleGet
+
+bsToWord64 :: B.ByteString -> Word64
+bsToWord64 bs = unsafePerformIO $ unsafeUseAsCString bs $ peek . castPtr
+
+word64ToBs :: Word64 -> B.ByteString
+word64ToBs = runPut . putWord64le
+
+instance BlockCipher DesEee3Key where
+    blockSize = 64
+    encryptBlock (DesEee3Key f s t) = word64ToBs .
+        DES.encrypt f . DES.encrypt s . DES.encrypt t . bsToWord64
+    decryptBlock (DesEee3Key f s t) = word64ToBs .
+        DES.decrypt t . DES.decrypt s . DES.decrypt f . bsToWord64
+    buildKey = either (const Nothing) Just . runGet get
+    keyLength = 64 * 3
+
+instance BlockCipher DesEde3Key where
+    blockSize = 64
+    encryptBlock (DesEde3Key f s t) = word64ToBs .
+        DES.encrypt f . DES.decrypt s . DES.encrypt t . bsToWord64
+    decryptBlock (DesEde3Key f s t) = word64ToBs .
+        DES.decrypt t . DES.encrypt s . DES.decrypt f . bsToWord64
+    buildKey = either (const Nothing) Just . runGet get
+    keyLength = 64 * 3
+
+instance BlockCipher DesEee2Key where
+    blockSize = 64
+    encryptBlock (DesEee2Key f s) = word64ToBs .
+        DES.encrypt f . DES.encrypt s . DES.encrypt f . bsToWord64
+    decryptBlock (DesEee2Key f s) = word64ToBs .
+        DES.decrypt f . DES.decrypt s . DES.decrypt f . bsToWord64
+    buildKey = either (const Nothing) Just . runGet get
+    keyLength = 64 * 2
+
+instance BlockCipher DesEde2Key where
+    blockSize = 64
+    encryptBlock (DesEde2Key f s) = word64ToBs .
+        DES.encrypt f . DES.decrypt s . DES.encrypt f . bsToWord64
+    decryptBlock (DesEde2Key f s) = word64ToBs .
+        DES.decrypt f . DES.encrypt s . DES.decrypt f . bsToWord64
+    buildKey = either (const Nothing) Just . runGet get
+    keyLength = 64 * 2
diff --git a/Tests/tests.hs b/Tests/tests.hs
--- a/Tests/tests.hs
+++ b/Tests/tests.hs
@@ -15,6 +15,7 @@
 import Data.Char
 import Data.Bits
 import Data.Word
+import Data.Maybe (fromJust)
 import qualified Data.Vector.Unboxed as V
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Char8 as BC
@@ -22,74 +23,196 @@
 import qualified Crypto.Hash.SHA1 as SHA1
 
 -- ciphers/Kexch
-import AES (aesTests)
-import qualified Crypto.Cipher.AES as AES
+import qualified Crypto.Cipher.TripleDES as TripleDES
+import qualified Crypto.Classes as CryptoAPI
+import qualified Crypto.Types as CryptoTypes
 import Crypto.Random
 import KAT
 
+prop_ecb_valid encrypt decrypt k msg = decrypt k (encrypt k msg) == msg
+
 {-----------------------------------------------------------------------------------------------}
-{- testing AES -}
+{- testing 3DES -}
 {-----------------------------------------------------------------------------------------------}
-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)
+data DESEEE3Message = DESEEE3Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
+data DESEDE3Message = DESEDE3Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
+data DESEEE2Message = DESEEE2Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
+data DESEDE2Message = DESEDE2Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)
 
-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)
+commonTripleDesMessage construct keysNumber = do
+                key <- replicateM (8 * keysNumber) (choose (0, 255) :: Gen Int)
+                sz <- choose (1, 12)
+                ws <- replicateM (sz * 16) (choose (0, 255) :: Gen Int)
+                iv  <- replicateM 8 (choose (0,255) :: Gen Int)
+                return $ construct (B.pack $ map fromIntegral key)
+                                   (B.pack $ map fromIntegral ws)
+                                   (B.pack $ map fromIntegral iv)
 
-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 DESEEE3Message where
+        arbitrary = commonTripleDesMessage DESEEE3Message 3
 
-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)
+instance Arbitrary DESEDE3Message where
+        arbitrary = commonTripleDesMessage DESEDE3Message 3
 
+instance Arbitrary DESEEE2Message where
+        arbitrary = commonTripleDesMessage DESEEE2Message 2
 
-prop_ecb_valid k msg = AES.decryptECB k (AES.encryptECB k msg) == msg
-prop_cbc_valid k iv msg = AES.decryptCBC k (AES.IV iv) (AES.encryptCBC k (AES.IV iv) msg) == msg
+instance Arbitrary DESEDE2Message where
+        arbitrary = commonTripleDesMessage DESEDE2Message 2
 
-prop_aes128_ecb_valid (AES128Message key _ msg) =
-	let k = AES.initKey key in
-	prop_ecb_valid k msg
+prop_3des_valid encrypt decrypt key iv msg =
+    (fst $ decrypt key (CryptoTypes.IV iv) (fst $ encrypt key (CryptoTypes.IV iv) msg)) == msg
 
-prop_aes192_ecb_valid (AES192Message key _ msg) =
-	let k = AES.initKey key in
-	prop_ecb_valid k msg
+tripleDesCipherKey :: (CryptoAPI.BlockCipher c) => B.ByteString -> c
+tripleDesCipherKey = fromJust . CryptoAPI.buildKey
 
-prop_aes256_ecb_valid (AES256Message key _ msg) =
-	let k = AES.initKey key in
-	prop_ecb_valid k msg
+-- 3DES ECB section
 
-prop_aes128_cbc_valid (AES128Message key iv msg) =
-	let k = AES.initKey key in
-	prop_cbc_valid k iv msg
+prop_des_eee3_ecb_valid (DESEEE3Message key _ msg) =
+        prop_ecb_valid CryptoAPI.ecb
+                       CryptoAPI.unEcb
+                       (tripleDesCipherKey key :: TripleDES.DesEee3Key)
+                       msg
 
-prop_aes192_cbc_valid (AES192Message key iv msg) =
-	let k = AES.initKey key in
-	prop_cbc_valid k iv msg
+prop_des_ede3_ecb_valid (DESEDE3Message key _ msg) =
+        prop_ecb_valid CryptoAPI.ecb
+                       CryptoAPI.unEcb
+                       (tripleDesCipherKey key :: TripleDES.DesEde3Key)
+                       msg
 
-prop_aes256_cbc_valid (AES256Message key iv msg) =
-	let k = AES.initKey key in
-	prop_cbc_valid k iv msg
+prop_des_eee2_ecb_valid (DESEEE2Message key _ msg) =
+        prop_ecb_valid CryptoAPI.ecb
+                       CryptoAPI.unEcb
+                       (tripleDesCipherKey key :: TripleDES.DesEee2Key)
+                       msg
 
+prop_des_ede2_ecb_valid (DESEDE2Message key _ msg) =
+        prop_ecb_valid CryptoAPI.ecb
+                       CryptoAPI.unEcb
+                       (tripleDesCipherKey key :: TripleDES.DesEde2Key)
+                       msg
+
+-- 3DES CBC section
+
+prop_des_eee3_cbc_valid (DESEEE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.cbc
+                        CryptoAPI.unCbc
+                        (tripleDesCipherKey key :: TripleDES.DesEee3Key)
+                        iv
+                        msg
+
+prop_des_ede3_cbc_valid (DESEDE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.cbc
+                        CryptoAPI.unCbc
+                        (tripleDesCipherKey key :: TripleDES.DesEde3Key)
+                        iv
+                        msg
+
+prop_des_eee2_cbc_valid (DESEEE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.cbc
+                        CryptoAPI.unCbc
+                        (tripleDesCipherKey key :: TripleDES.DesEee2Key)
+                        iv
+                        msg
+
+prop_des_ede2_cbc_valid (DESEDE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.cbc
+                        CryptoAPI.unCbc
+                        (tripleDesCipherKey key :: TripleDES.DesEde2Key)
+                        iv
+                        msg
+
+-- 3DES CTR section
+
+prop_des_eee3_ctr_valid (DESEEE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.ctr
+                        CryptoAPI.unCtr
+                        (tripleDesCipherKey key :: TripleDES.DesEee3Key)
+                        iv
+                        msg
+
+prop_des_ede3_ctr_valid (DESEDE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.ctr
+                        CryptoAPI.unCtr
+                        (tripleDesCipherKey key :: TripleDES.DesEde3Key)
+                        iv
+                        msg
+
+prop_des_eee2_ctr_valid (DESEEE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.ctr
+                        CryptoAPI.unCtr
+                        (tripleDesCipherKey key :: TripleDES.DesEee2Key)
+                        iv
+                        msg
+
+prop_des_ede2_ctr_valid (DESEDE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.ctr
+                        CryptoAPI.unCtr
+                        (tripleDesCipherKey key :: TripleDES.DesEde2Key)
+                        iv
+                        msg
+
+-- 3DES CFB section
+
+prop_des_eee3_cfb_valid (DESEEE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.cfb
+                        CryptoAPI.unCfb
+                        (tripleDesCipherKey key :: TripleDES.DesEee3Key)
+                        iv
+                        msg
+
+prop_des_ede3_cfb_valid (DESEDE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.cfb
+                        CryptoAPI.unCfb
+                        (tripleDesCipherKey key :: TripleDES.DesEde3Key)
+                        iv
+                        msg
+
+prop_des_eee2_cfb_valid (DESEEE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.cfb
+                        CryptoAPI.unCfb
+                        (tripleDesCipherKey key :: TripleDES.DesEee2Key)
+                        iv
+                        msg
+
+prop_des_ede2_cfb_valid (DESEDE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.cfb
+                        CryptoAPI.unCfb
+                        (tripleDesCipherKey key :: TripleDES.DesEde2Key)
+                        iv
+                        msg
+
+-- 3DES OFB section
+
+prop_des_eee3_ofb_valid (DESEEE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.ofb
+                        CryptoAPI.unOfb
+                        (tripleDesCipherKey key :: TripleDES.DesEee3Key)
+                        iv
+                        msg
+
+prop_des_ede3_ofb_valid (DESEDE3Message key iv msg) =
+        prop_3des_valid CryptoAPI.ofb
+                        CryptoAPI.unOfb
+                        (tripleDesCipherKey key :: TripleDES.DesEde3Key)
+                        iv
+                        msg
+
+prop_des_eee2_ofb_valid (DESEEE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.ofb
+                        CryptoAPI.unOfb
+                        (tripleDesCipherKey key :: TripleDES.DesEee2Key)
+                        iv
+                        msg
+
+prop_des_ede2_ofb_valid (DESEDE2Message key iv msg) =
+        prop_3des_valid CryptoAPI.ofb
+                        CryptoAPI.unOfb
+                        (tripleDesCipherKey key :: TripleDES.DesEde2Key)
+                        iv
+                        msg
+
 {-----------------------------------------------------------------------------------------------}
 {- main -}
 {-----------------------------------------------------------------------------------------------}
@@ -97,28 +220,32 @@
 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
+	[ testProperty "DES-EEE3 (ECB)" prop_des_eee3_ecb_valid
+	, testProperty "DES-EEE3 (CBC)" prop_des_eee3_cbc_valid
+	, testProperty "DES-EEE3 (CTR)" prop_des_eee3_ctr_valid
+	, testProperty "DES-EEE3 (CFB)" prop_des_eee3_cfb_valid
+	, testProperty "DES-EEE3 (OFB)" prop_des_eee3_ofb_valid
+	, testProperty "DES-EDE3 (ECB)" prop_des_ede3_ecb_valid
+	, testProperty "DES-EDE3 (CBC)" prop_des_ede3_cbc_valid
+	, testProperty "DES-EDE3 (CTR)" prop_des_ede3_ctr_valid
+	, testProperty "DES-EDE3 (CFB)" prop_des_ede3_cfb_valid
+	, testProperty "DES-EDE3 (OFB)" prop_des_ede3_ofb_valid
+	, testProperty "DES-EEE2 (ECB)" prop_des_eee2_ecb_valid
+	, testProperty "DES-EEE2 (CBC)" prop_des_eee2_cbc_valid
+	, testProperty "DES-EEE2 (CTR)" prop_des_eee2_ctr_valid
+	, testProperty "DES-EEE2 (CFB)" prop_des_eee2_cfb_valid
+	, testProperty "DES-EEE2 (OFB)" prop_des_eee2_ofb_valid
+	, testProperty "DES-EDE2 (ECB)" prop_des_ede2_ecb_valid
+	, testProperty "DES-EDE2 (CBC)" prop_des_ede2_cbc_valid
+	, testProperty "DES-EDE2 (CTR)" prop_des_ede2_ctr_valid
+	, testProperty "DES-EDE2 (CFB)" prop_des_ede2_cfb_valid
+	, testProperty "DES-EDE2 (OFB)" prop_des_ede2_ofb_valid
 	]
 
 tests :: [Test]
 tests =
 	[ symCipherExpectedTests
 	, symCipherMarshallTests
-	, testGroup "AES" aesTests
 	]
 
 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,6 +1,11 @@
 Name:                cryptocipher
-Version:             0.5.0
-Description:         Symmetrical block and stream ciphers.
+Version:             0.5.1
+Description:
+    Symmetrical block and stream ciphers.
+    .
+    This package is eventually going away in this form, and should be considered deprecated.
+    use 'cipher-aes' for AES. For blowfish, camellia, DES/3DES, the package is still maintained,
+    but eventually each cipher will be available in another package.
 License:             BSD3
 License-file:        LICENSE
 Copyright:           Vincent Hanquez <vincent@snarc.org>
@@ -9,10 +14,9 @@
 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
@@ -33,6 +37,8 @@
                      Crypto.Cipher.AES
                      Crypto.Cipher.Blowfish
                      Crypto.Cipher.Camellia
+                     Crypto.Cipher.TripleDES
+                     Crypto.Cipher.DES
   ghc-options:       -Wall
 
 Test-Suite test-cryptocipher
@@ -66,4 +72,5 @@
 
 source-repository head
   type:     git
-  location: git://github.com/vincenthz/hs-cryptocipher
+  location: git://github.com/vincenthz/hs-crypto-cipher
+  subdir:   cryptocipher
