-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Deterministic random bit generator (aka RNG, PRNG) based
--   HMACs, Hashes, and Ciphers.
--   
--   Cryptographically secure RNGs
@package DRBG
@version 0.5.5

module Crypto.Random.DRBG.Types
type BitLen = Int
type Entropy = ByteString
type PersonalizationString = ByteString
type Nonce = ByteString
type AdditionalInput = ByteString
type RandomBits = ByteString

module Crypto.Random.DRBG.Hash
data State d
counter :: State d -> Word64
reseedInterval :: Word64
class SeedLength h
seedlen :: SeedLength h => Tagged h Int
instantiate :: (Hash c d, SeedLength d) => Entropy -> Nonce -> PersonalizationString -> State d
reseed :: (SeedLength d, Hash c d) => State d -> Entropy -> AdditionalInput -> State d
generate :: (Hash c d, SeedLength d) => State d -> BitLen -> AdditionalInput -> Maybe (RandomBits, State d)

module Crypto.Random.DRBG.HMAC
data State d
counter :: State d -> Word64
reseedInterval :: Word64
instantiate :: (Hash c d) => Entropy -> Nonce -> PersonalizationString -> State d
reseed :: (Hash c d) => State d -> Entropy -> AdditionalInput -> State d
generate :: (Hash c d) => State d -> BitLength -> AdditionalInput -> Maybe (RandomBits, State d)

module Crypto.Random.DRBG.CTR
data State a

-- | Get a count of how many times this generator has been used since
--   instantiation or reseed.
getCounter :: State a -> Word64

-- | The reseed interval
reseedInterval :: Word64

-- | Update the RNG
update :: BlockCipher a => ByteString -> State a -> Maybe (State a)

-- | Instantiate a new CTR based counter. This assumes the block cipher is
--   safe for generating 2^48 seperate bitstrings (e.g. For SP800-90 we
--   assume AES and not 3DES)
instantiate :: BlockCipher a => Entropy -> PersonalizationString -> Maybe (State a)

-- | <pre>
--   reseed oldRNG entropy additionalInfo
--   </pre>
--   
--   Reseed a DRBG with some entropy (<tt>ent</tt> must be at least
--   seedlength, which is the block length plus the key length)
reseed :: BlockCipher a => State a -> Entropy -> AdditionalInput -> Maybe (State a)

-- | Generate new bytes of data, stepping the generator.
generate :: BlockCipher a => State a -> ByteLength -> AdditionalInput -> Maybe (RandomBits, State a)
instance Data.Serialize.Serialize a => Data.Serialize.Serialize (Crypto.Random.DRBG.CTR.State a)


-- | This module is the convenience interface for the DRBG (NIST
--   standardized number-theoretically secure random number generator).
--   Everything is setup for using the "crypto-api" <a>CryptoRandomGen</a>
--   type class.
--   
--   To instantiate the base types of <a>HmacDRBG</a>, <a>HashDRBG</a>, or
--   <a>CtrDRBG</a> just use the <a>CryptoRandomGen</a> primitives of
--   <a>newGen</a> or <a>newGenIO</a>.
--   
--   For example, to seed a new generator with the system secure random
--   (<a>Entropy</a>) and generate some bytes (stepping the generator along
--   the way) one would do:
--   
--   <pre>
--   gen &lt;- newGenIO :: IO CtrDRBG
--   let Right (randomBytes, newGen) = genBytes 1024 gen
--   </pre>
--   
--   or the same thing with your own entropy (throwing exceptions instead
--   of dealing with <a>Either</a> this time):
--   
--   <pre>
--   let gen = throwLeft (newGen entropy)
--       (bytes,gen') = throwLeft (genBytes 1024 gen)
--   in ...
--   </pre>
--   
--   There are several modifiers that allow you to compose generators
--   together, producing generators with modified security, reseed, and
--   performance properties. <a>GenXor</a> will xor the random bytes of two
--   generators. <a>GenBuffered</a> will spark off work to generate several
--   megabytes of random data and keep that data buffered for quick use.
--   <a>GenAutoReseed</a> will use one generator to automatically reseed
--   another after every 32 kilobytes of requested randoms.
--   
--   Most likely you will want to automatically reseed using system
--   randomness (via lazy IO). Thus, you are left with a generator that is
--   random, not pseudo random but without the dangerously unsafe IO found
--   in some other RNGs:
--   
--   <pre>
--   import Crypto.Random.DRBG hiding (genBytes)
--   import Crypto.Classes.Exceptions (genBytes)
--   
--   -- An AES CTR generator that automatically reseeds.
--   getCtrGen :: IO (GenAutoReseed CtrDRBG SystemEntropy)
--   getCtrGen = newGenAutoReseedIO
--   
--   f = do g1 &lt;- getCtrGen
--          let (bytes, g2) = getBytes 1024 g1
--          g bytes g2
--   </pre>
--   
--   For a complex example, here is a generator that buffers several
--   megabytes of random values which are an Xor of AES with a SHA384 hash
--   that are each reseeded every 32kb with the output of a SHA512 HMAC
--   generator (not to claim this has any enhanced security properties, but
--   just to show the composition can be nested).
--   
--   <pre>
--   gen &lt;- newGenIO :: IO (GenBuffered (GenAutoReseed (GenXor AesCntDRBG (HashDRBGWith SHA384)) HmacDRBG))
--   </pre>
module Crypto.Random.DRBG

-- | An alias for an HMAC DRBG generator using SHA512.
type HmacDRBG = State SHA512

-- | An Alias for a Hash DRBG generator using SHA512.
--   
--   As of 1July2014 this remains the fastest cryptographic RNG on hackage
--   that has been ran against known answer tests.
type HashDRBG = State SHA512

-- | The recommended generator which uses AES-128 in counter mode.
--   
--   This is an alias for a Counter DRBG generator using AES 128.
type CtrDRBG = State AESKey128

-- | The HMAC DRBG state (of kind * -&gt; *) allowing selection of the
--   underlying hash algorithm (SHA1, SHA224 ... SHA512)
type HmacDRBGWith = State

-- | The Hash DRBG state (of kind * -&gt; *) allowing selection of the
--   underlying hash algorithm.
type HashDRBGWith = State

-- | The AES CTR DRBG state (of kind * -&gt; *) allowing selection of the
--   underlying cipher algorithm.
type CtrDRBGWith = State

-- | <tt>g :: GenXor a b</tt> generates bytes with sub-generators a and b
--   and exclusive-or's the outputs to produce the resulting bytes.
data GenXor a b
GenXor :: !a -> !b -> GenXor a b

-- | <tt>g :: GenBuffered a</tt> is a generator of type <tt>a</tt> that
--   attempts to maintain a buffer of random values size &gt;= 1MB and
--   &lt;= 5MB at any time.
data GenBuffered g

-- | <tt>g :: GenAutoReseed a b</tt> is a generator of type a that gets
--   automatically reseeded by generator b upon every 32kB generated.
--   
--   <tt>reseed g ent</tt> will reseed both the component generators by
--   breaking ent up into two parts determined by the genSeedLength of each
--   generator.
--   
--   <tt>genBytes</tt> will generate the requested bytes with generator
--   <tt>a</tt> and reseed <tt>a</tt> using generator <tt>b</tt> if there
--   has been 32KB of generated data since the last reseed. Note a request
--   for &gt; 32KB of data will be filled in one request to generator
--   <tt>a</tt> before <tt>a</tt> is reseeded by <tt>b</tt>.
--   
--   <tt>genBytesWithEntropy</tt> is lifted into the same call for
--   generator <tt>a</tt>, but it will still reseed from generator
--   <tt>b</tt> if the limit is hit.
--   
--   Reseed interval: If generator <tt>a</tt> needs a <tt>genSeedLength a =
--   a'</tt> and generator B needs reseeded every <tt>2^b</tt> bytes then a
--   <tt>GenAutoReseed a b</tt> will need reseeded every <tt>2^15 * (2^b /
--   a')</tt> bytes. For the common values of <tt>a' = 128</tt> and <tt>2^b
--   = 2^48</tt> this means reseeding every 2^56 byte. For the example
--   numbers this translates to about 200 years of continually generating
--   random values at a rate of 10MB/s.
data GenAutoReseed a b

-- | <tt>newGenAutoReseed bs i</tt> creates a new <a>GenAutoReseed</a> with
--   a custom interval of <tt>i</tt> bytes using the provided entropy in
--   <tt>bs</tt>.
--   
--   This is for extremely long running uses of <a>CryptoRandomGen</a>
--   instances that can't explicitly reseed as often as a single underlying
--   generator would need (usually every 2^48 bytes).
--   
--   For example:
--   
--   <pre>
--   newGenAutoReseedIO (2^48) :: IO (Either GenError (GenAutoReseed HashDRBG HashDRBG))
--   </pre>
--   
--   Will last for <tt>2^48 * 2^41</tt> bytes of randomly generated data.
--   That's 2^49 terabytes of random values (128 byte reseeds every 2^48
--   bytes generated).
newGenAutoReseed :: (CryptoRandomGen a, CryptoRandomGen b) => ByteString -> Word64 -> Either GenError (GenAutoReseed a b)

-- | <tt>newGenAutoReseedIO i</tt> creates a new <a>GenAutoReseed</a> with
--   a custom interval of <tt>i</tt> bytes, using the system random number
--   generator as a seed.
--   
--   See <a>newGenAutoReseed</a>.
newGenAutoReseedIO :: (CryptoRandomGen a, CryptoRandomGen b) => Word64 -> IO (GenAutoReseed a b)
instance Crypto.Random.DRBG.Hash.SeedLength Crypto.Hash.CryptoAPI.SHA512
instance Crypto.Random.DRBG.Hash.SeedLength Crypto.Hash.CryptoAPI.SHA384
instance Crypto.Random.DRBG.Hash.SeedLength Crypto.Hash.CryptoAPI.SHA256
instance Crypto.Random.DRBG.Hash.SeedLength Crypto.Hash.CryptoAPI.SHA224
instance Crypto.Random.DRBG.Hash.SeedLength Crypto.Hash.CryptoAPI.SHA1
instance Crypto.Random.CryptoRandomGen Crypto.Random.DRBG.HmacDRBG
instance Crypto.Random.CryptoRandomGen Crypto.Random.DRBG.HashDRBG
instance (Crypto.Random.CryptoRandomGen a, Crypto.Random.CryptoRandomGen b) => Crypto.Random.CryptoRandomGen (Crypto.Random.DRBG.GenAutoReseed a b)
instance (Crypto.Random.CryptoRandomGen a, Crypto.Random.CryptoRandomGen b) => Crypto.Random.CryptoRandomGen (Crypto.Random.DRBG.GenXor a b)
instance Crypto.Random.CryptoRandomGen g => Crypto.Random.CryptoRandomGen (Crypto.Random.DRBG.GenBuffered g)
instance Crypto.Classes.BlockCipher x => Crypto.Random.CryptoRandomGen (Crypto.Random.DRBG.CtrDRBGWith x)
