packages feed

cprng-aes 0.2.5 → 0.3.0

raw patch · 2 files changed

+52/−26 lines, 2 filesdep +crypto-random-apidep ~bytestringdep ~cryptocipherdep ~randomPVP ok

version bump matches the API change (PVP)

Dependencies added: crypto-random-api

Dependency ranges changed: bytestring, cryptocipher, random

API changes (from Hackage documentation)

+ Crypto.Random.AESCtr: instance CPRG AESRNG
- Crypto.Random.AESCtr: genRandomBytes :: AESRNG -> Int -> (ByteString, AESRNG)
+ Crypto.Random.AESCtr: genRandomBytes :: CPRG g => g -> Int -> (ByteString, g)
- Crypto.Random.AESCtr: make :: ByteString -> Either GenError AESRNG
+ Crypto.Random.AESCtr: make :: ByteString -> Maybe AESRNG

Files

Crypto/Random/AESCtr.hs view
@@ -22,7 +22,11 @@  import Control.Applicative ((<$>)) -import Crypto.Random+#ifdef USE_CRYPTOAPI+import qualified Crypto.Random as CAPI+#endif+import Crypto.Random.API+ import System.Random (RandomGen(..)) import System.Entropy (getEntropy) #ifdef CIPHER_AES@@ -34,6 +38,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as B +import Data.Maybe (fromJust) import Data.Word import Data.Bits (xor, (.&.)) @@ -52,6 +57,7 @@ data RNG = RNG     {-# UNPACK #-} !Word128     {-# UNPACK #-} !Word128+    {-# UNPACK #-} !Word64     {-# UNPACK #-} !AES.Key  data AESRNG = AESRNG { aesrngState :: RNG@@ -112,12 +118,12 @@ -- the initialization. -- -- use `makeSystem` to not have to deal with the generator seed.-make :: B.ByteString -> Either GenError AESRNG+make :: B.ByteString -> Maybe AESRNG make b-    | B.length b < 64 = Left NotEnoughEntropy-    | otherwise       = Right $ AESRNG { aesrngState = rng, aesrngCache = B.empty }+    | B.length b < 64 = Nothing+    | otherwise       = Just $ AESRNG { aesrngState = rng, aesrngCache = B.empty }         where-            rng            = RNG (get128 iv) (get128 cnt) key+            rng            = RNG (get128 iv) (get128 cnt) 0 key             (key, cnt, iv) = makeParams b  #ifdef CIPHER_AES@@ -125,9 +131,9 @@ chunkSize = 1024  genNextChunk :: RNG -> (ByteString, RNG)-genNextChunk (RNG iv counter key) = (chunk, newrng)+genNextChunk (RNG iv counter sz key) = (chunk, newrng)     where-        newrng = RNG (get128 chunk) (add64 counter) key+        newrng = RNG (get128 chunk) (add64 counter) (sz+fromIntegral chunkSize) key         chunk  = AES.genCTR key (AES.IV bytes) 1024         bytes  = put128 (iv `xor128` counter) #else@@ -135,19 +141,22 @@ chunkSize = 16  genNextChunk :: RNG -> (ByteString, RNG)-genNextChunk (RNG iv counter key) = (chunk, newrng)+genNextChunk (RNG iv counter sz key) = (chunk, newrng)     where-        newrng = RNG (get128 chunk) (add1 counter) key+        newrng = RNG (get128 chunk) (add1 counter) (sz+fromIntegral chunkSize) key         chunk  = AES.encrypt key bytes         bytes  = put128 (iv `xor128` counter) #endif +getRNGReseedLimit :: RNG -> Int+getRNGReseedLimit (RNG _ _ sz _)+    | sz >= limit = 0+    | otherwise   = fromIntegral (limit - sz)+    where limit = 2^(24 :: Int)+ -- | Initialize a new AES RNG 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+makeSystem = fromJust . make <$> getEntropy 64  -- | get a Random number of bytes from the RNG. -- it generate randomness by block of chunkSize bytes and will returns@@ -163,8 +172,8 @@             | otherwise          = let (b, g') = genNextChunk g                                     in acc (l+1) (b:bs) g' -genRandomBytes :: AESRNG -> Int -> (ByteString, AESRNG)-genRandomBytes rng n+genRanBytes :: AESRNG -> Int -> (ByteString, AESRNG)+genRanBytes rng n     | B.length (aesrngCache rng) >= n = let (b1,b2) = B.splitAt n (aesrngCache rng)                                          in (b1, rng { aesrngCache = b2 })     | otherwise                       =@@ -172,27 +181,36 @@                 (b1, b2)  = B.splitAt n b              in (b1, rng { aesrngState = rng', aesrngCache = b2 }) -reseedState b rng@(RNG _ cnt1 _) = RNG (get128 r16 `xor128` get128 iv2) (cnt1 `xor128` get128 cnt2) key2+reseedState :: ByteString -> RNG -> RNG+reseedState b rng@(RNG _ cnt1 _ _) = RNG (get128 r16 `xor128` get128 iv2) (cnt1 `xor128` get128 cnt2) 0 key2     where (r16, _)          = genNextChunk rng           (key2, cnt2, iv2) = makeParams b -instance CryptoRandomGen AESRNG where-    newGen           = make+#ifdef USE_CRYPTOAPI+-- going away in 0.4.0. use the CPRG instance.+instance CAPI.CryptoRandomGen AESRNG where+    newGen b         = maybe (Left CAPI.NotEnoughEntropy) Right $ make b     genSeedLength    = 64-    genBytes len rng = Right $ genRandomBytes rng len+    genBytes len rng = Right $ genRanBytes rng len     reseed b rng-        | B.length b < 64 = Left NotEnoughEntropy+        | B.length b < 64 = Left CAPI.NotEnoughEntropy         | otherwise       = Right $ rng { aesrngState = reseedState b (aesrngState rng) }+#endif +instance CPRG AESRNG where+    cprgGenBytes rng len          = genRanBytes rng len+    cprgSupplyEntropy rng entropy = rng { aesrngState = reseedState entropy (aesrngState rng) }+    cprgNeedReseed rng            = getRNGReseedLimit (aesrngState rng)+ instance RandomGen AESRNG where     next rng =-        let (bs, rng') = genRandomBytes rng 16 in+        let (bs, rng') = genRanBytes rng 16 in         let (Word128 a _) = get128 bs in         let n = fromIntegral (a .&. 0x7fffffff) in         (n, rng')     split rng =-        let (bs, rng') = genRandomBytes rng 64 in+        let (bs, rng') = genRanBytes rng 64 in         case make bs of-            Left _      -> error "assert"-            Right rng'' -> (rng', rng'')+            Nothing    -> error "assert"+            Just rng'' -> (rng', rng'')     genRange _ = (0, 0x7fffffff)
cprng-aes.cabal view
@@ -1,5 +1,5 @@ Name:                cprng-aes-Version:             0.2.5+Version:             0.3.0 Description:              Simple crypto pseudo-random-number-generator with really good randomness property.     .@@ -38,11 +38,15 @@   Description:       Use cereal   Default:           False +Flag cryptoapi+  Description:       Use cereal+  Default:           True+ Library   Build-Depends:     base >= 3 && < 5                    , bytestring                    , random-                   , crypto-api >= 0.8+                   , crypto-random-api                    , entropy >= 0.2   Exposed-modules:   Crypto.Random.AESCtr   ghc-options:       -Wall@@ -54,6 +58,10 @@     Build-Depends:   cryptocipher   if flag(cereal)     Build-Depends:   cereal >= 0.3.0 && < 0.4.0+    cpp-options:     -DUSE_CEREAL+  if flag(cryptoapi)+    Build-Depends:   crypto-api >= 0.8+    cpp-options:     -DUSE_CRYPTOAPI  Benchmark bench-cprng-aes   hs-source-dirs:    Benchmarks