cprng-aes 0.2.3 → 0.2.4
raw patch · 2 files changed
+44/−21 lines, 2 filesdep +cipher-aesdep ~cryptocipherPVP ok
version bump matches the API change (PVP)
Dependencies added: cipher-aes
Dependency ranges changed: cryptocipher
API changes (from Hackage documentation)
Files
- Crypto/Random/AESCtr.hs +34/−19
- cprng-aes.cabal +10/−2
Crypto/Random/AESCtr.hs view
@@ -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')
cprng-aes.cabal view
@@ -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