cprng-aes-0.6.1: Crypto/Random/AESCtr/Internal.hs
-- |
-- Module : Crypto.Random.AESCtr.Internal
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : stable
-- Portability : unknown
--
{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
module Crypto.Random.AESCtr.Internal where
import qualified Crypto.Cipher.AES as AES
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
{-| An opaque object containing an AES CPRNG -}
data RNG = RNG !AES.AESIV !Int !AES.AES
getNbChunksGenerated :: RNG -> Int
getNbChunksGenerated (RNG _ c _) = c
makeParams :: ByteString -> (AES.AES, AES.AESIV)
makeParams b = key `seq` iv `seq` (key, iv)
where (keyBS, r1) = B.splitAt 32 b
(cnt, _) = B.splitAt 16 r1
!key = AES.initAES keyBS
!iv = AES.aesIV_ $ B.copy cnt
makeRNG :: ByteString -> RNG
makeRNG b = RNG iv 0 key
where (key,iv) = makeParams b
chunkSize :: Int
chunkSize = 1024
genNextChunk :: RNG -> (ByteString, RNG)
genNextChunk (RNG counter nbChunks key) =
chunk `seq` newrng `seq` (chunk, newrng)
where
newrng = RNG newCounter (nbChunks+1) key
(chunk,newCounter) = AES.genCounter key counter chunkSize