diff --git a/Crypto/Random/AESCtr.hs b/Crypto/Random/AESCtr.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/Random/AESCtr.hs
@@ -0,0 +1,114 @@
+-- |
+-- Module      : Crypto.Random.AESCtr
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : stable
+-- Portability : unknown
+--
+-- this CPRNG is an AES cbc based counter system.
+--
+-- the internal size of fields are: 16 bytes IV, 16 bytes counter, 32 bytes key
+--
+-- each block are generated the following way:
+--   (IV `xor` counter) `aes` key -> 16 bytes output
+--
+
+module Crypto.Random.AESCtr
+	( AESRNG
+	, make
+	, makeSystem
+	, getRandomBytes
+	) where
+
+import Control.Applicative ((<$>))
+
+import Crypto.Random
+import System.Crypto.Random (getEntropy)
+import qualified Crypto.Cipher.AES as AES
+
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+
+import Data.Word
+import Data.Bits (xor)
+import Data.Serialize
+
+data Word128 = Word128 !Word64 !Word64
+
+{-| An opaque object containing an AES CPRNG -}
+data AESRNG = RNG !ByteString !Word128 !AES.Key
+
+instance Show AESRNG where
+	show _ = "aesrng[..]"
+
+put128 :: Word128 -> ByteString
+put128 (Word128 a b) = runPut (putWord64host a >> putWord64host b)
+
+get128 :: ByteString -> Word128
+get128 = either (\_ -> Word128 0 0) id . runGet (getWord64host >>= \a -> (getWord64host >>= \b -> return $ Word128 a b))
+
+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
+		(Right key)  = AES.initKey256 $ B.take 32 left2
+		(cnt, left2) = B.splitAt 16 left1
+		(iv, left1)  = B.splitAt 16 b
+
+-- | make an AESRNG from a bytestring. the bytestring need to be at least 64 bytes.
+-- if the bytestring is longer, the extra bytes will be ignored and will not take part in
+-- the initialization.
+make :: B.ByteString -> Either GenError AESRNG
+make b
+	| B.length b < 64 = Left NotEnoughEntropy
+	| otherwise       = Right $ RNG 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)
+	where
+		newrng = RNG chunk (add1 counter) key
+		chunk  = AES.encryptCBC key iv bytes
+		bytes  = iv `bxor` (put128 counter)
+
+-- | Initialize a new AESRng using the system entropy.
+makeSystem :: IO AESRNG
+makeSystem = ofRight . make <$> getEntropy 64
+	where
+		ofRight (Left _)  = error "ofRight on a Left value"
+		ofRight (Right x) = x
+
+-- | get a Random number of bytes from the RNG.
+-- for efficienty and not wasted any randomness, it's better to generate
+-- bytes on multiple of 16, however it will works for any size.
+getRandomBytes :: AESRNG -> Int -> (ByteString, AESRNG)
+getRandomBytes rng n =
+	let list = helper rng n in
+	(B.concat $ map fst list, snd $ last list)
+	where
+		helper _ 0 = []
+		helper g i =
+			let (b, g') = nextChunk g in
+			if chunkSize >= i
+				then [ (B.take i b, g') ]
+				else (b, g') : helper g' (i-chunkSize)
+
+instance CryptoRandomGen AESRNG where
+	newGen           = make
+	genSeedLength    = 64
+	genBytes len rng = Right $ getRandomBytes 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
+			where
+				(r16, _)          = nextChunk rng
+				(key2, cnt2, iv2) = makeParams b
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2010-2011 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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+CPRNG-AES
+=========
+
+This module provides a crypto pseudo random number generator using AES in counter mode.
+
+to import:
+
+    import Crypto.Random.AESCtr
+
+to use:
+
+    rng <- makeSystem
+    let (ran, rng') = getRandomBytes rng 1024
+
+it's also an instance of CryptoRandomGen from the crypto-api package.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cprng-aes.cabal b/cprng-aes.cabal
new file mode 100644
--- /dev/null
+++ b/cprng-aes.cabal
@@ -0,0 +1,44 @@
+Name:                cprng-aes
+Version:             0.1.0
+Description:         
+    Simple crypto pseudo-random-number-generator with really good randomness property.
+    .
+    Using ent, a randomness property maker on one 1Mb sample:
+       Entropy = 7.999837 bits per byte.
+       Optimum compression would reduce the size of this 1048576 byte file by 0 percent.
+       Chi square distribution for 1048576 samples is 237.02
+       Arithmetic mean value of data bytes is 127.3422 (127.5 = random)
+       Monte Carlo value for Pi is 3.143589568 (error 0.06 percent)
+    .
+    Compared to urandom with the same sampling:
+       Entropy = 7.999831 bits per byte.
+       Optimum compression would reduce the size of this 1048576 byte file by 0 percent.
+       Chi square distribution for 1048576 samples is 246.63 
+       Arithmetic mean value of data bytes is 127.6347 (127.5 = random).
+       Monte Carlo value for Pi is 3.132465868 (error 0.29 percent).
+
+License:             BSD3
+License-file:        LICENSE
+Copyright:           Vincent Hanquez <vincent@snarc.org>
+Author:              Vincent Hanquez <vincent@snarc.org>
+Maintainer:          Vincent Hanquez <vincent@snarc.org>
+Synopsis:            Crypto Pseudo Random Number Generator using AES in counter mode.
+Build-Type:          Simple
+Category:            Cryptography
+stability:           experimental
+Cabal-Version:       >=1.6
+Homepage:            http://github.com/vincenthz/hs-cprng-aes
+data-files:          README.md
+
+Library
+  Build-Depends:     base >= 3 && < 5
+                   , bytestring
+                   , crypto-api >= 0.5
+                   , cryptocipher >= 0.2.5 && < 0.3.0
+                   , cereal >= 0.3.0 && < 0.4.0
+  Exposed-modules:   Crypto.Random.AESCtr
+  ghc-options:       -Wall
+
+source-repository head
+  type: git
+  location: git://github.com/vincenthz/hs-cprng-aes
