1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
-- |
-- Module : Crypto.Random.Types
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : Good
--
module Crypto.Random.Types
(
MonadRandom(..)
, MonadPseudoRandom
, DRG(..)
, withDRG
) where
import Crypto.Random.Entropy
import Crypto.Internal.ByteArray
-- | A monad constraint that allows to generate random bytes
class Monad m => MonadRandom m where
getRandomBytes :: ByteArray byteArray => Int -> m byteArray
-- | A Deterministic Random Generator (DRG) class
class DRG gen where
-- | Generate N bytes of randomness from a DRG
randomBytesGenerate :: ByteArray byteArray => Int -> gen -> (byteArray, gen)
instance MonadRandom IO where
getRandomBytes = getEntropy
-- | A simple Monad class very similar to a State Monad
-- with the state being a DRG.
newtype MonadPseudoRandom gen a = MonadPseudoRandom
{ runPseudoRandom :: gen -> (a, gen)
}
instance DRG gen => Functor (MonadPseudoRandom gen) where
fmap f m = MonadPseudoRandom $ \g1 ->
let (a, g2) = runPseudoRandom m g1 in (f a, g2)
instance DRG gen => Applicative (MonadPseudoRandom gen) where
pure a = MonadPseudoRandom $ \g -> (a, g)
(<*>) fm m = MonadPseudoRandom $ \g1 ->
let (f, g2) = runPseudoRandom fm g1
(a, g3) = runPseudoRandom m g2
in (f a, g3)
instance DRG gen => Monad (MonadPseudoRandom gen) where
return = pure
(>>=) m1 m2 = MonadPseudoRandom $ \g1 ->
let (a, g2) = runPseudoRandom m1 g1
in runPseudoRandom (m2 a) g2
instance DRG gen => MonadRandom (MonadPseudoRandom gen) where
getRandomBytes n = MonadPseudoRandom (randomBytesGenerate n)
-- | Run a pure computation with a Deterministic Random Generator
-- in the 'MonadPseudoRandom'
withDRG :: DRG gen => gen -> MonadPseudoRandom gen a -> (a, gen)
withDRG gen m = runPseudoRandom m gen
|