1-- | 2-- Module : Crypto.Random.AESCtr.Internal 3-- License : BSD-style 4-- Maintainer : Vincent Hanquez <vincent@snarc.org> 5-- Stability : stable 6-- Portability : unknown 7-- 8{-# LANGUAGE CPP #-} 9{-# LANGUAGE BangPatterns #-} 10module Crypto.Random.AESCtr.Internal where 11 12import qualified Crypto.Cipher.AES as AES 13 14import Data.ByteString (ByteString) 15import qualified Data.ByteString as B 16 17{-| An opaque object containing an AES CPRNG -} 18data RNG = RNG !AES.AESIV !Int !AES.AES 19 20getNbChunksGenerated :: RNG -> Int 21getNbChunksGenerated (RNG _ c _) = c 22 23makeParams :: ByteString -> (AES.AES, AES.AESIV) 24makeParams b = key `seq` iv `seq` (key, iv) 25 where (keyBS, r1) = B.splitAt 32 b 26 (cnt, _) = B.splitAt 16 r1 27 !key = AES.initAES keyBS 28 !iv = AES.aesIV_ $ B.copy cnt 29 30makeRNG :: ByteString -> RNG 31makeRNG b = RNG iv 0 key 32 where (key,iv) = makeParams b 33 34chunkSize :: Int 35chunkSize = 1024 36 37genNextChunk :: RNG -> (ByteString, RNG) 38genNextChunk (RNG counter nbChunks key) = 39 chunk `seq` newrng `seq` (chunk, newrng) 40 where 41 newrng = RNG newCounter (nbChunks+1) key 42 (chunk,newCounter) = AES.genCounter key counter chunkSize 43