packages feed

cprng-aes (empty) → 0.1.0

raw patch · 5 files changed

+202/−0 lines, 5 filesdep +basedep +bytestringdep +cerealsetup-changed

Dependencies added: base, bytestring, cereal, crypto-api, cryptocipher

Files

+ Crypto/Random/AESCtr.hs view
@@ -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
+ LICENSE view
@@ -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.
+ README.md view
@@ -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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cprng-aes.cabal view
@@ -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