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


-- | A monad for using CryptoRandomGen
--   
--   A monad for using CryptoRandomGen
@package monadcryptorandom
@version 0.7.2.1


-- | Much like the <a>MonadRandom</a> package
--   (<a>Control.Monad.Random</a>), this module provides plumbing for the
--   CryptoRandomGen generators.
module Control.Monad.CryptoRandom

-- | <tt>CRandom a</tt> is much like the <tt>Random</tt> class from the
--   <a>System.Random</a> module in the "random" package. The main
--   difference is CRandom builds on "crypto-api"'s <a>CryptoRandomGen</a>,
--   so it allows explicit failure.
--   
--   <tt>crandomR (low,high) g</tt> as typically instantiated will generate
--   a value between [low, high] inclusively, swapping the pair if high
--   &lt; low.
--   
--   Provided instances for <tt>crandom g</tt> generates randoms between
--   the bounds and between +/- 2^256 for Integer.
--   
--   The <a>crandomR</a> function has degraded (theoretically unbounded,
--   probabilistically decent) performance the closer your range size (high
--   - low) is to 2^n (from the top).
class CRandom a
crandom :: (CRandom a, CryptoRandomGen g) => g -> Either GenError (a, g)
crandoms :: (CRandom a, CryptoRandomGen g) => g -> [a]
class CRandomR a
crandomR :: (CRandomR a, CryptoRandomGen g) => (a, a) -> g -> Either GenError (a, g)
crandomRs :: (CRandomR a, CryptoRandomGen g) => (a, a) -> g -> [a]

-- | <tt>MonadCRandom m</tt> represents a monad that can produce random
--   values (or fail with a <a>GenError</a>). It is suggested you use the
--   <a>CRandT</a> transformer in your monad stack.
class (ContainsGenError e, MonadError e m) => MonadCRandom e m
getCRandom :: (MonadCRandom e m, CRandom a) => m a
getBytes :: MonadCRandom e m => Int -> m ByteString
getBytesWithEntropy :: MonadCRandom e m => Int -> ByteString -> m ByteString
doReseed :: MonadCRandom e m => ByteString -> m ()
class (ContainsGenError e, MonadError e m) => MonadCRandomR e m
getCRandomR :: (MonadCRandomR e m, CRandomR a) => (a, a) -> m a
class ContainsGenError e
toGenError :: ContainsGenError e => e -> Maybe GenError
fromGenError :: ContainsGenError e => GenError -> e

-- | CRandT is the transformer suggested for MonadCRandom.
newtype CRandT g e m a
CRandT :: StateT g (ExceptT e m) a -> CRandT g e m a
[unCRandT] :: CRandT g e m a -> StateT g (ExceptT e m) a

-- | Simple users of generators can use CRand for quick and easy generation
--   of randoms. See below for a simple use of <a>newGenIO</a> (from
--   "crypto-api"), <a>getCRandom</a>, <a>getBytes</a>, and
--   <tt>runCRandom</tt>.
--   
--   <pre>
--   getRandPair = do
--     int &lt;- getCRandom
--     bytes &lt;- getBytes 100
--     return (int, bytes)
--   
--   func = do
--     g &lt;- newGenIO
--     case runCRand getRandPair g of
--       Right ((int,bytes), g') -&gt; useRandomVals (int,bytes)
--       Left x -&gt; handleGenError x
--   </pre>
type CRand g e = CRandT g e Identity
runCRandT :: ContainsGenError e => CRandT g e m a -> g -> m (Either e (a, g))
evalCRandT :: (ContainsGenError e, Monad m) => CRandT g e m a -> g -> m (Either e a)
runCRand :: ContainsGenError e => CRand g e a -> g -> Either e (a, g)
evalCRand :: CRand g GenError a -> g -> Either GenError a
newGenCRand :: (CryptoRandomGen g, MonadCRandom GenError m, Functor m) => m g
liftCRand :: (g -> Either e (a, g)) -> CRand g e a
liftCRandT :: Monad m => (g -> Either e (a, g)) -> CRandT g e m a

-- | Generator failures should always return the appropriate GenError. Note
--   <a>GenError</a> in an instance of exception but wether or not an
--   exception is thrown depends on if the selected generator (read: if you
--   don't want execptions from code that uses <a>throw</a> then pass in a
--   generator that never has an error for the used functions)
data GenError

-- | Misc
GenErrorOther :: String -> GenError

-- | Requested more bytes than a single pass can generate (The maximum
--   request is generator dependent)
RequestedTooManyBytes :: GenError

-- | When using <tt>genInteger g (l,h)</tt> and <tt>logBase 2 (h - l) &gt;
--   (maxBound :: Int)</tt>.
RangeInvalid :: GenError

-- | Some generators cease operation after too high a count without a
--   reseed (ex: NIST SP 800-90)
NeedReseed :: GenError

-- | For instantiating new generators (or reseeding)
NotEnoughEntropy :: GenError

-- | This generator can not be instantiated or reseeded with a finite seed
--   (ex: <a>SystemRandom</a>)
NeedsInfiniteSeed :: GenError

-- | A class of random bit generators that allows for the possibility of
--   failure, reseeding, providing entropy at the same time as requesting
--   bytes
--   
--   Minimum complete definition: <a>newGen</a>, <a>genSeedLength</a>,
--   <a>genBytes</a>, <a>reseed</a>, <a>reseedInfo</a>,
--   <a>reseedPeriod</a>.
class CryptoRandomGen g

-- | Instantiate a new random bit generator. The provided bytestring should
--   be of length &gt;= genSeedLength. If the bytestring is shorter then
--   the call may fail (suggested error: <a>NotEnoughEntropy</a>). If the
--   bytestring is of sufficent length the call should always succeed.
newGen :: CryptoRandomGen g => ByteString -> Either GenError g

-- | Length of input entropy necessary to instantiate or reseed a generator
genSeedLength :: CryptoRandomGen g => Tagged g ByteLength

-- | <tt>genBytes len g</tt> generates a random ByteString of length
--   <tt>len</tt> and new generator. The <a>MonadCryptoRandom</a> package
--   has routines useful for converting the ByteString to commonly needed
--   values (but "cereal" or other deserialization libraries would also
--   work).
--   
--   This routine can fail if the generator has gone too long without a
--   reseed (usually this is in the ball-park of 2^48 requests). Suggested
--   error in this cases is <a>NeedReseed</a>
genBytes :: CryptoRandomGen g => ByteLength -> g -> Either GenError (ByteString, g)

-- | Indicates how soon a reseed is needed
reseedInfo :: CryptoRandomGen g => g -> ReseedInfo

-- | Indicates the period between reseeds (constant for most generators).
reseedPeriod :: CryptoRandomGen g => g -> ReseedInfo

-- | <tt>genBytesWithEntropy g i entropy</tt> generates <tt>i</tt> random
--   bytes and use the additional input <tt>entropy</tt> in the generation
--   of the requested data to increase the confidence our generated data is
--   a secure random stream.
--   
--   Some generators use <tt>entropy</tt> to perturb the state of the
--   generator, meaning:
--   
--   <pre>
--   (_,g2') &lt;- genBytesWithEntropy len g1 ent
--   (_,g2 ) &lt;- genBytes len g1
--   g2 /= g2'
--   </pre>
--   
--   But this is not required.
--   
--   Default:
--   
--   <pre>
--   genBytesWithEntropy g bytes entropy = xor entropy (genBytes g bytes)
--   </pre>
genBytesWithEntropy :: CryptoRandomGen g => ByteLength -> ByteString -> g -> Either GenError (ByteString, g)

-- | If the generator has produced too many random bytes on its existing
--   seed it will return <a>NeedReseed</a>. In that case, reseed the
--   generator using this function and a new high-entropy seed of length
--   &gt;= <a>genSeedLength</a>. Using bytestrings that are too short can
--   result in an error (<a>NotEnoughEntropy</a>).
reseed :: CryptoRandomGen g => ByteString -> g -> Either GenError g

-- | By default this uses <a>System.Entropy</a> to obtain entropy for
--   <a>newGen</a>. WARNING: The default implementation opens a file handle
--   which will never be closed!
newGenIO :: CryptoRandomGen g => IO g
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.CryptoRandom.CRandT g e m)
instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError e (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.CryptoRandom.CRandT g e m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.CryptoRandom.CRandT g e m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.CryptoRandom.CRandT g e m)
instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.CryptoRandom.CRandT g e)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Control.Monad.CryptoRandom.CRandT g e m)
instance (Control.Monad.CryptoRandom.ContainsGenError e, GHC.Base.Monad m, Crypto.Random.CryptoRandomGen g) => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.CryptoRandom.CRandT g e m)
instance (Control.Monad.CryptoRandom.ContainsGenError e, GHC.Base.Monad m, Crypto.Random.CryptoRandomGen g) => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.CryptoRandom.CRandT g e m)
instance Control.Monad.CryptoRandom.MonadCRandomR e m => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.CryptoRandom.MonadCRandomR e m => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.State.Strict.StateT s m)
instance (Control.Monad.CryptoRandom.MonadCRandomR e m, GHC.Base.Monoid w) => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (Control.Monad.CryptoRandom.MonadCRandomR e m, GHC.Base.Monoid w) => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance Control.Monad.CryptoRandom.MonadCRandomR e m => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.Reader.ReaderT r m)
instance (Control.Monad.CryptoRandom.MonadCRandomR e m, GHC.Base.Monoid w) => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (Control.Monad.CryptoRandom.MonadCRandomR e m, GHC.Base.Monoid w) => Control.Monad.CryptoRandom.MonadCRandomR e (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Control.Monad.CryptoRandom.CRandomR GHC.Integer.Type.Integer
instance Control.Monad.CryptoRandom.CRandom GHC.Types.Int
instance Control.Monad.CryptoRandom.CRandomR GHC.Types.Int
instance Control.Monad.CryptoRandom.CRandom GHC.Word.Word8
instance Control.Monad.CryptoRandom.CRandomR GHC.Word.Word8
instance Control.Monad.CryptoRandom.CRandom GHC.Word.Word16
instance Control.Monad.CryptoRandom.CRandomR GHC.Word.Word16
instance Control.Monad.CryptoRandom.CRandom GHC.Word.Word32
instance Control.Monad.CryptoRandom.CRandomR GHC.Word.Word32
instance Control.Monad.CryptoRandom.CRandom GHC.Word.Word64
instance Control.Monad.CryptoRandom.CRandomR GHC.Word.Word64
instance Control.Monad.CryptoRandom.CRandom GHC.Int.Int8
instance Control.Monad.CryptoRandom.CRandomR GHC.Int.Int8
instance Control.Monad.CryptoRandom.CRandom GHC.Int.Int16
instance Control.Monad.CryptoRandom.CRandomR GHC.Int.Int16
instance Control.Monad.CryptoRandom.CRandom GHC.Int.Int32
instance Control.Monad.CryptoRandom.CRandomR GHC.Int.Int32
instance Control.Monad.CryptoRandom.CRandom GHC.Int.Int64
instance Control.Monad.CryptoRandom.CRandomR GHC.Int.Int64
instance Control.Monad.CryptoRandom.CRandom GHC.Types.Bool
instance Control.Monad.CryptoRandom.MonadCRandom e m => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.CryptoRandom.MonadCRandom e m => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.CryptoRandom.MonadCRandom e m) => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.CryptoRandom.MonadCRandom e m) => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance Control.Monad.CryptoRandom.MonadCRandom e m => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.Reader.ReaderT r m)
instance (GHC.Base.Monoid w, Control.Monad.CryptoRandom.MonadCRandom e m) => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.CryptoRandom.MonadCRandom e m) => Control.Monad.CryptoRandom.MonadCRandom e (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance Control.Monad.CryptoRandom.ContainsGenError Crypto.Random.GenError
