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