diff --git a/Crypto/Random/AESCtr.hs b/Crypto/Random/AESCtr.hs
--- a/Crypto/Random/AESCtr.hs
+++ b/Crypto/Random/AESCtr.hs
@@ -12,7 +12,7 @@
 -- each block are generated the following way:
 --   aes (IV `xor` counter) -> 16 bytes output
 --
-
+{-# LANGUAGE CPP, PackageImports #-}
 module Crypto.Random.AESCtr
 	( AESRNG
 	, make
@@ -25,7 +25,11 @@
 import Crypto.Random
 import System.Random (RandomGen(..))
 import System.Entropy (getEntropy)
-import qualified Crypto.Cipher.AES as AES
+#ifdef CIPHER_AES
+import qualified "cipher-aes" Crypto.Cipher.AES as AES
+#else
+import qualified "cryptocipher" Crypto.Cipher.AES as AES
+#endif
 
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as B
@@ -34,10 +38,13 @@
 import Data.Bits (xor, (.&.))
 import Data.Serialize
 
-data Word128 = Word128 !Word64 !Word64
+data Word128 = Word128 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64
 
 {-| An opaque object containing an AES CPRNG -}
-data AESRNG = RNG !ByteString !Word128 !AES.Key
+data AESRNG = RNG
+	{-# UNPACK #-} !Word128
+	{-# UNPACK #-} !Word128
+	{-# UNPACK #-} !AES.Key
 
 instance Show AESRNG where
 	show _ = "aesrng[..]"
@@ -48,13 +55,20 @@
 get128 :: ByteString -> Word128
 get128 = either (\_ -> Word128 0 0) id . runGet (getWord64host >>= \a -> (getWord64host >>= \b -> return $ Word128 a b))
 
+xor128 :: Word128 -> Word128 -> Word128
+xor128 (Word128 a1 b1) (Word128 a2 b2) = Word128 (a1 `xor` a2) (b1 `xor` b2)
+
 add1 :: Word128 -> Word128
 add1 (Word128 a b) = if b == 0xffffffffffffffff then Word128 (a+1) 0 else Word128 a (b+1)
 
 makeParams :: ByteString -> (AES.Key, ByteString, ByteString)
 makeParams b = (key, cnt, iv)
 	where
+#ifdef CIPHER_AES
+		key          = AES.initKey $ B.take 32 left2
+#else
 		(Right key)  = AES.initKey256 $ B.take 32 left2
+#endif
 		(cnt, left2) = B.splitAt 16 left1
 		(iv, left1)  = B.splitAt 16 b
 
@@ -66,22 +80,23 @@
 make :: B.ByteString -> Either GenError AESRNG
 make b
 	| B.length b < 64 = Left NotEnoughEntropy
-	| otherwise       = Right $ RNG iv (get128 cnt) key
+	| otherwise       = Right $ RNG (get128 iv) (get128 cnt) key
 		where
 			(key, cnt, iv) = makeParams b
 
 chunkSize :: Int
 chunkSize = 16
 
-bxor :: ByteString -> ByteString -> ByteString
-bxor a b = B.pack $ B.zipWith xor a b
-
-nextChunk :: AESRNG -> (ByteString, AESRNG)
-nextChunk (RNG iv counter key) = (chunk, newrng)
+genNextChunk :: AESRNG -> (ByteString, AESRNG)
+genNextChunk (RNG iv counter key) = (chunk, newrng)
 	where
-		newrng = RNG chunk (add1 counter) key
+		newrng = RNG (get128 chunk) (add1 counter) key
+#ifdef CIPHER_AES
+		chunk  = AES.encryptECB key bytes
+#else
 		chunk  = AES.encrypt key bytes
-		bytes  = iv `bxor` (put128 counter)
+#endif
+		bytes  = put128 (iv `xor128` counter)
 
 -- | Initialize a new AES RNG using the system entropy.
 makeSystem :: IO AESRNG
@@ -94,13 +109,13 @@
 -- it generate randomness by block of 16 bytes, but will truncate
 -- to the number of bytes required, and lose the truncated bytes.
 genRandomBytes :: AESRNG -> Int -> (ByteString, AESRNG)
-genRandomBytes rng n =
-	let list = helper rng n in
-	(B.concat $ map fst list, snd $ last list)
+genRandomBytes rng 16 = genNextChunk rng
+genRandomBytes rng n  = (B.concat $ map fst list, snd $ last list)
 	where
+		list = helper rng n
 		helper _ 0 = []
 		helper g i =
-			let (b, g') = nextChunk g in
+			let (b, g') = genNextChunk g in
 			if chunkSize >= i
 				then [ (B.take i b, g') ]
 				else (b, g') : helper g' (i-chunkSize)
@@ -111,14 +126,14 @@
 	genBytes len rng = Right $ genRandomBytes rng len
 	reseed b rng@(RNG _ cnt1 _)
 		| B.length b < 64 = Left NotEnoughEntropy
-		| otherwise       = Right $ RNG (r16 `bxor` iv2) (get128 (put128 cnt1 `bxor` cnt2)) key2
+		| otherwise       = Right $ RNG (get128 r16 `xor128` get128 iv2) (cnt1 `xor128` get128 cnt2) key2
 			where
-				(r16, _)          = nextChunk rng
+				(r16, _)          = genNextChunk rng
 				(key2, cnt2, iv2) = makeParams b
 
 instance RandomGen AESRNG where
 	next rng =
-		let (bs, rng') = nextChunk rng in
+		let (bs, rng') = genNextChunk rng in
 		let (Word128 a _) = get128 bs in
 		let n = fromIntegral (a .&. 0x7fffffff) in
 		(n, rng')
diff --git a/cprng-aes.cabal b/cprng-aes.cabal
--- a/cprng-aes.cabal
+++ b/cprng-aes.cabal
@@ -1,5 +1,5 @@
 Name:                cprng-aes
-Version:             0.2.3
+Version:             0.2.4
 Description:         
     Simple crypto pseudo-random-number-generator with really good randomness property.
     .
@@ -30,16 +30,24 @@
 Homepage:            http://github.com/vincenthz/hs-cprng-aes
 data-files:          README.md
 
+Flag fastaes
+  Description:       Use fast AES if available
+  Default:           True
+
 Library
   Build-Depends:     base >= 3 && < 5
                    , bytestring
                    , random
                    , crypto-api >= 0.8
                    , entropy >= 0.2
-                   , cryptocipher >= 0.2.5 && < 0.4.0
+                   , cryptocipher
                    , cereal >= 0.3.0 && < 0.4.0
   Exposed-modules:   Crypto.Random.AESCtr
   ghc-options:       -Wall
+
+  if os(linux) && flag(fastaes) && (arch(i386) || arch(x86_64))
+    cpp-options:     -DCIPHER_AES
+    Build-Depends:   cipher-aes >= 0.1 && < 0.2
 
 source-repository head
   type: git
