diff --git a/Benchmarks.hs b/Benchmarks.hs
--- a/Benchmarks.hs
+++ b/Benchmarks.hs
@@ -14,14 +14,21 @@
 
 import qualified Crypto.Cipher.AES as AES
 import qualified Crypto.Cipher.RC4 as RC4
+import qualified Crypto.Cipher.Camellia as Camellia
 
 (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)
 
+(Right camelliaKey128) = Camellia.initKey $ B.replicate 16 0
+camelliaEncrypt128 = Camellia.encrypt camelliaKey128
+
 rc4Key = RC4.initCtx $ replicate 16 0
 rc4Encrypt = snd . RC4.encrypt rc4Key 
 
@@ -52,7 +59,7 @@
 
 doOne env (cipherName, f) = do
 	(mean16, mean32, mean128, mean512, mean1024, mean4096) <- doCipher env f
-	let s = printf "%8s: %12s %12s %12s %12s %12s %12s\n          %12s %12s %12s %12s %12s %12s"
+	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)
@@ -63,12 +70,16 @@
 main = withConfig defaultConfig $ do
 	env <- measureEnvironment
 	l   <- mapM (doOne env)
-		[ ("RC4"   , rc4Encrypt)
-		, ("AES128", aesEncrypt128)
-		, ("AES192", aesEncrypt192)
-		, ("AES256", aesEncrypt256)
+		[ ("RC4"        , rc4Encrypt)
+		, ("Camellia128", camelliaEncrypt128)
+		, ("AES128"     , aesEncrypt128)
+		, ("AES128-CBC" , aesEncrypt128CBC)
+		, ("AES192"     , aesEncrypt192)
+		, ("AES192-CBC" , aesEncrypt192CBC)
+		, ("AES256"     , aesEncrypt256)
+		, ("AES256-CBC" , aesEncrypt256CBC)
 		]
-	liftIO $ printf "%8s| %12s %12s %12s %12s %12s %12s\n"
+	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"
+	liftIO $ printf "=============================================================================================\n"
 	mapM_ (liftIO . putStrLn) l
diff --git a/Crypto/Cipher/AES.hs b/Crypto/Cipher/AES.hs
--- a/Crypto/Cipher/AES.hs
+++ b/Crypto/Cipher/AES.hs
@@ -123,8 +123,8 @@
 {- | encrypt using simple EBC mode -}
 encrypt :: Key -> B.ByteString -> B.ByteString
 encrypt key b
-	| B.length b `mod` 16 == 0 = B.concat $ doChunks (coreEncrypt key) b
-	| otherwise                = error "invalid data length"
+	| 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 -}
@@ -142,8 +142,8 @@
 {- | decrypt using simple EBC mode -}
 decrypt :: Key -> B.ByteString -> B.ByteString
 decrypt key b
-	| B.length b `mod` 16 == 0 = B.concat $ doChunks (coreDecrypt key) b
-	| otherwise                = error "invalid data length"
+	| 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 =
@@ -203,12 +203,25 @@
 		shiftRowsInv blk >> addRoundKey key i blk >> mixColumnsInv blk
 	shiftRowsInv blk >> addRoundKey key 0 blk
 
-{- 0 -> 0, 1 -> 4, ... -}
-swapIndexes :: Vector Int
-swapIndexes = V.fromList [ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 ]
 {-# INLINE swapIndex #-}
 swapIndex :: Int -> Int
-swapIndex i = V.unsafeIndex swapIndexes i
+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
diff --git a/Crypto/Cipher/Camellia.hs b/Crypto/Cipher/Camellia.hs
--- a/Crypto/Cipher/Camellia.hs
+++ b/Crypto/Cipher/Camellia.hs
@@ -8,17 +8,18 @@
 -- this only cover Camellia 128 bits for now, API will change once
 -- 192 and 256 mode are implemented too
 
-module Crypto.Cipher.Camellia (
-	Key(..),
-	initKey,
-	encrypt,
-	decrypt
+module Crypto.Cipher.Camellia
+	( Key(..)
+	, initKey
+	, 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
 
@@ -43,10 +44,18 @@
 		t7 = fromIntegral (x `shiftR` 8)
 		t8 = fromIntegral (x)
 
-w8tow64 :: (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8) -> Word64
-w8tow64 (t1, t2, t3, t4, t5, t6, t7, t8) =
-	(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 sh i r = (fromIntegral i) `shiftL` r
+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))
@@ -140,9 +149,9 @@
 	, ke :: Vector Word64 }
 	deriving (Show)
 
-setKeyInterim :: [Word8] -> (Word128, Word128, Word128, Word128)
-setKeyInterim [a0,a1,a2,a3,a4,a5,a6,a7,b0,b1,b2,b3,b4,b5,b6,b7] =
-	let kL = (w8tow64 (a0,a1,a2,a3,a4,a5,a6,a7), w8tow64 (b0,b1,b2,b3,b4,b5,b6,b7)) in
+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 =
@@ -168,33 +177,33 @@
 		in
 	(w64tow128 kL, w64tow128 kR, w64tow128 kA, w64tow128 kB)
 
-setKeyInterim _ = error "wrong size key"
-
-initKey :: [Word8] -> Either String Key
-initKey l =
-	let (kL, _, kA, _) = setKeyInterim l in
+initKey :: B.ByteString -> Either String Key
+initKey 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
+		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 ]
-		}
+		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 = 
@@ -216,7 +225,7 @@
 	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 (y1, y2, y3, y4, y5, y6, y7, y8)
+	w8tow64 $ B.pack [y1, y2, y3, y4, y5, y6, y7, y8]
 
 fl :: Word64 -> Word64 -> Word64
 fl fin sk =
diff --git a/Tests.hs b/Tests.hs
--- a/Tests.hs
+++ b/Tests.hs
@@ -33,7 +33,7 @@
 encryptStream fi fc key plaintext = B.unpack $ snd $ fc (fi key) plaintext
 
 encryptBlock fi fc key plaintext =
-	let e = fi key in
+	let e = fi (B.pack key) in
 	case e of
 		Right k -> B.unpack $ fc k plaintext
 		Left  e -> error e
@@ -186,9 +186,9 @@
 	  )
 	]
 
-aes128InitKey = AES.initKey128 . B.pack
-aes192InitKey = AES.initKey192 . B.pack
-aes256InitKey = AES.initKey256 . B.pack
+aes128InitKey = AES.initKey128
+aes192InitKey = AES.initKey192
+aes256InitKey = AES.initKey256
 
 vectors_rc4 =
 	[ (wordify "Key", "Plaintext", [ 0xBB,0xF3,0x16,0xE8,0xD9,0x40,0xAF,0x0A,0xD3 ])
diff --git a/cryptocipher.cabal b/cryptocipher.cabal
--- a/cryptocipher.cabal
+++ b/cryptocipher.cabal
@@ -1,5 +1,5 @@
 Name:                cryptocipher
-Version:             0.2.6
+Version:             0.2.7
 Description:         Symmetrical Block, Stream and PubKey Ciphers
 License:             BSD3
 License-file:        LICENSE
