{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE RecordWildCards #-}
module Raaz.Random
(
RandomState
, withRandomState
, randomByteString
, Random(..)
, randomiseMemory
, withRandomisedMemory
, withSecureRandomisedMemory
, withSecureRandomState
, fillRandomBytes
, RandomStorable(..)
, fillRandom
, unsafeFillRandomElements
, reseed
, entropySource
, csprgName, csprgDescription
) where
import Control.Applicative
import Control.Monad
import Data.ByteString ( ByteString )
import Data.Int
import Data.Vector.Unboxed ( Unbox )
import Data.Word
import Foreign.Ptr ( castPtr )
import Foreign.Storable ( Storable )
import Prelude
import Raaz.Core
import Raaz.Core.Memory( Access(..) )
import PRGenerator ( entropySource, csprgName, csprgDescription, RandomState
, fillRandomBytes
, reseed
)
import qualified Raaz.Primitive.ChaCha20.Internal as ChaCha20
import qualified Raaz.Primitive.Poly1305.Internal as Poly1305
import Raaz.Primitive.Keyed.Internal ( Keyed )
import Raaz.Verse.Poly1305.C.Portable ( verse_poly1305_c_portable_clamp)
class Storable a => RandomStorable a where
fillRandomElements :: Int
-> Ptr a
-> RandomState
-> IO ()
fillRandom :: (RandomStorable a, Pointer ptr)
=> Int
-> ptr a
-> RandomState
-> IO ()
fillRandom :: forall a (ptr :: * -> *).
(RandomStorable a, Pointer ptr) =>
Int -> ptr a -> RandomState -> IO ()
fillRandom Int
n ptr a
ptr RandomState
rstate = forall (ptr :: * -> *) a b.
Pointer ptr =>
(Ptr a -> b) -> ptr a -> b
unsafeWithPointer (\ Ptr a
rawPtr -> forall a. RandomStorable a => Int -> Ptr a -> RandomState -> IO ()
fillRandomElements Int
n Ptr a
rawPtr RandomState
rstate) ptr a
ptr
withRandomState :: (RandomState -> IO a)
-> IO a
withRandomState :: forall a. (RandomState -> IO a) -> IO a
withRandomState RandomState -> IO a
action = forall mem a. Memory mem => (mem -> IO a) -> IO a
withMemory RandomState -> IO a
actionP
where actionP :: RandomState -> IO a
actionP RandomState
rstate = do RandomState -> IO ()
reseed RandomState
rstate
RandomState -> IO a
action RandomState
rstate
withSecureRandomState :: Memory mem
=> (mem -> RandomState -> IO a)
-> IO a
withSecureRandomState :: forall mem a. Memory mem => (mem -> RandomState -> IO a) -> IO a
withSecureRandomState mem -> RandomState -> IO a
action = forall mem a. Memory mem => (mem -> IO a) -> IO a
withSecureMemory (mem, RandomState) -> IO a
actionP
where actionP :: (mem, RandomState) -> IO a
actionP (mem
mem,RandomState
rstate) = do RandomState -> IO ()
reseed RandomState
rstate
mem -> RandomState -> IO a
action mem
mem RandomState
rstate
randomiseMemory :: WriteAccessible mem => mem -> RandomState -> IO ()
randomiseMemory :: forall mem. WriteAccessible mem => mem -> RandomState -> IO ()
randomiseMemory mem
mem RandomState
rstate = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Access -> IO ()
randomise forall a b. (a -> b) -> a -> b
$ forall mem. WriteAccessible mem => mem -> [Access]
writeAccess mem
mem
where randomise :: Access -> IO ()
randomise Access{Ptr Word8
BYTES Int
accessSize :: Access -> BYTES Int
accessPtr :: Access -> Ptr Word8
accessSize :: BYTES Int
accessPtr :: Ptr Word8
..} = forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
l -> Dest (ptr a) -> RandomState -> IO ()
fillRandomBytes BYTES Int
accessSize (forall a. a -> Dest a
destination Ptr Word8
accessPtr) RandomState
rstate
withRandomisedMemory :: WriteAccessible mem
=> (mem -> IO a)
-> IO a
withRandomisedMemory :: forall mem a. WriteAccessible mem => (mem -> IO a) -> IO a
withRandomisedMemory mem -> IO a
action = forall mem a. Memory mem => (mem -> IO a) -> IO a
withMemory (mem, RandomState) -> IO a
actionP
where actionP :: (mem, RandomState) -> IO a
actionP (mem
mem,RandomState
rstate) = do
RandomState -> IO ()
reseed RandomState
rstate
forall mem. WriteAccessible mem => mem -> RandomState -> IO ()
randomiseMemory mem
mem RandomState
rstate
mem -> IO a
action mem
mem
withSecureRandomisedMemory :: WriteAccessible mem
=> (mem -> IO a)
-> IO a
withSecureRandomisedMemory :: forall mem a. WriteAccessible mem => (mem -> IO a) -> IO a
withSecureRandomisedMemory mem -> IO a
action = forall mem a. Memory mem => (mem -> RandomState -> IO a) -> IO a
withSecureRandomState mem -> RandomState -> IO a
actionP
where actionP :: mem -> RandomState -> IO a
actionP mem
mem RandomState
rstate = do forall mem. WriteAccessible mem => mem -> RandomState -> IO ()
randomiseMemory mem
mem RandomState
rstate
mem -> IO a
action mem
mem
unsafeFillRandomElements :: Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements :: forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements Int
n Ptr a
ptr = forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
l -> Dest (ptr a) -> RandomState -> IO ()
fillRandomBytes BYTES Int
totalSz forall a b. (a -> b) -> a -> b
$ forall a. a -> Dest a
destination forall a b. (a -> b) -> a -> b
$ forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr
where totalSz :: BYTES Int
totalSz = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall a. Num a => a -> a -> a
* forall a. Storable a => Proxy a -> BYTES Int
sizeOf (forall a. Ptr a -> Proxy a
getProxy Ptr a
ptr)
getProxy :: Ptr a -> Proxy a
getProxy :: forall a. Ptr a -> Proxy a
getProxy = forall a b. a -> b -> a
const forall {k} (t :: k). Proxy t
Proxy
randomByteString ::LengthUnit l
=> l
-> RandomState
-> IO ByteString
randomByteString :: forall l. LengthUnit l => l -> RandomState -> IO ByteString
randomByteString l
l RandomState
rstate = forall l a. LengthUnit l => l -> (Ptr a -> IO ()) -> IO ByteString
create l
l forall {ptr :: * -> *} {a}. Pointer ptr => ptr a -> IO ()
genBS
where genBS :: ptr a -> IO ()
genBS ptr a
ptr = forall l (ptr :: * -> *) a.
(LengthUnit l, Pointer ptr) =>
l -> Dest (ptr a) -> RandomState -> IO ()
fillRandomBytes l
l (forall a. a -> Dest a
destination ptr a
ptr) RandomState
rstate
instance RandomStorable Word8 where
fillRandomElements :: Int -> Ptr Word8 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Word16 where
fillRandomElements :: Int -> Ptr Word16 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Word32 where
fillRandomElements :: Int -> Ptr Word32 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Word64 where
fillRandomElements :: Int -> Ptr Word64 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Word where
fillRandomElements :: Int -> Ptr Word -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Int8 where
fillRandomElements :: Int -> Ptr Int8 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Int16 where
fillRandomElements :: Int -> Ptr Int16 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Int32 where
fillRandomElements :: Int -> Ptr Int32 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Int64 where
fillRandomElements :: Int -> Ptr Int64 -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Int where
fillRandomElements :: Int -> Ptr Int -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable (Key ChaCha20.ChaCha20) where
fillRandomElements :: Int -> Ptr (Key ChaCha20) -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable (Nounce ChaCha20.ChaCha20) where
fillRandomElements :: Int -> Ptr (Nounce ChaCha20) -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable (Key ChaCha20.XChaCha20) where
fillRandomElements :: Int -> Ptr (Key XChaCha20) -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable (Nounce ChaCha20.XChaCha20) where
fillRandomElements :: Int -> Ptr (Nounce XChaCha20) -> RandomState -> IO ()
fillRandomElements = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements
instance RandomStorable Poly1305.R where
fillRandomElements :: Int -> Ptr R -> RandomState -> IO ()
fillRandomElements Int
n Ptr R
ptr RandomState
state = forall a. Storable a => Int -> Ptr a -> RandomState -> IO ()
unsafeFillRandomElements Int
n Ptr R
ptr RandomState
state forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
clamp
where clamp :: IO ()
clamp = Ptr (Tuple 2 Word64) -> Word64 -> IO ()
verse_poly1305_c_portable_clamp (forall a b. Ptr a -> Ptr b
castPtr Ptr R
ptr) (forall a. Enum a => Int -> a
toEnum Int
n)
instance RandomStorable w => RandomStorable (LE w) where
fillRandomElements :: Int -> Ptr (LE w) -> RandomState -> IO ()
fillRandomElements Int
n = forall a. RandomStorable a => Int -> Ptr a -> RandomState -> IO ()
fillRandomElements Int
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall w. Ptr (LE w) -> Ptr w
lePtrToPtr
where lePtrToPtr :: Ptr (LE w) -> Ptr w
lePtrToPtr :: forall w. Ptr (LE w) -> Ptr w
lePtrToPtr = forall a b. Ptr a -> Ptr b
castPtr
instance RandomStorable w => RandomStorable (BE w) where
fillRandomElements :: Int -> Ptr (BE w) -> RandomState -> IO ()
fillRandomElements Int
n = forall a. RandomStorable a => Int -> Ptr a -> RandomState -> IO ()
fillRandomElements Int
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall w. Ptr (BE w) -> Ptr w
bePtrToPtr
where bePtrToPtr :: Ptr (BE w) -> Ptr w
bePtrToPtr :: forall w. Ptr (BE w) -> Ptr w
bePtrToPtr = forall a b. Ptr a -> Ptr b
castPtr
instance (Dimension d, Unbox w, RandomStorable w) => RandomStorable (Tuple d w) where
fillRandomElements :: Int -> Ptr (Tuple d w) -> RandomState -> IO ()
fillRandomElements Int
n Ptr (Tuple d w)
ptr = forall a. RandomStorable a => Int -> Ptr a -> RandomState -> IO ()
fillRandomElements (Int
n forall a. Num a => a -> a -> a
* forall (d :: Nat) w. Dimension d => Ptr (Tuple d w) -> Int
sz Ptr (Tuple d w)
ptr) forall a b. (a -> b) -> a -> b
$ forall (d :: Nat) w. Ptr (Tuple d w) -> Ptr w
tupPtrToPtr Ptr (Tuple d w)
ptr
where sz :: Dimension d => Ptr (Tuple d w) -> Int
sz :: forall (d :: Nat) w. Dimension d => Ptr (Tuple d w) -> Int
sz = forall (dim :: Nat) a. Dimension dim => Proxy (Tuple dim a) -> Int
dimension' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (d :: Nat) w. Ptr (Tuple d w) -> Proxy (Tuple d w)
getProxy
getProxy :: Ptr (Tuple d w) -> Proxy (Tuple d w)
getProxy :: forall (d :: Nat) w. Ptr (Tuple d w) -> Proxy (Tuple d w)
getProxy = forall a b. a -> b -> a
const forall {k} (t :: k). Proxy t
Proxy
tupPtrToPtr :: Ptr (Tuple d w) -> Ptr w
tupPtrToPtr :: forall (d :: Nat) w. Ptr (Tuple d w) -> Ptr w
tupPtrToPtr = forall a b. Ptr a -> Ptr b
castPtr
class Random a where
random :: RandomState -> IO a
default random :: RandomStorable a => RandomState -> IO a
random RandomState
state = IO a
go
where go :: IO a
go = forall l (ptr :: * -> *) something b.
(LengthUnit l, Pointer ptr) =>
l -> (ptr something -> IO b) -> IO b
allocaBuffer (forall a. Storable a => Proxy a -> BYTES Int
alignedSizeOf forall a b. (a -> b) -> a -> b
$ forall a. IO a -> Proxy a
getProxy IO a
go) forall {b}. RandomStorable b => Ptr b -> IO b
getIt
getIt :: Ptr b -> IO b
getIt Ptr b
ptr = forall a. RandomStorable a => Int -> Ptr a -> RandomState -> IO ()
fillRandomElements Int
1 (forall a. Storable a => Ptr a -> Ptr a
nextLocation Ptr b
ptr) RandomState
state forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Storable a => Ptr a -> IO a
peekAligned Ptr b
ptr
getProxy :: IO a -> Proxy a
getProxy :: forall a. IO a -> Proxy a
getProxy = forall a b. a -> b -> a
const forall {k} (t :: k). Proxy t
Proxy
instance (Random a, Random b) => Random (a,b) where
random :: RandomState -> IO (a, b)
random RandomState
state = (,)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
instance (Random a, Random b, Random c) => Random (a,b,c) where
random :: RandomState -> IO (a, b, c)
random RandomState
state = (,,)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
instance (Random a, Random b, Random c, Random d) => Random (a,b,c,d) where
random :: RandomState -> IO (a, b, c, d)
random RandomState
state = (,,,)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
instance (Random a, Random b, Random c, Random d, Random e) => Random (a,b,c,d,e) where
random :: RandomState -> IO (a, b, c, d, e)
random RandomState
state = (,,,,)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => RandomState -> IO a
random RandomState
state
instance Random Word8
instance Random Word16
instance Random Word32
instance Random Word64
instance Random Int8
instance Random Int16
instance Random Int32
instance Random Int64
instance Random (Key ChaCha20.ChaCha20) where
instance Random (Nounce ChaCha20.ChaCha20) where
instance Random (Key ChaCha20.XChaCha20) where
instance Random (Nounce ChaCha20.XChaCha20) where
instance Storable prim => Random (Key (Keyed prim)) where
random :: RandomState -> IO (Key (Keyed prim))
random RandomState
state = IO (Key (Keyed prim))
randKY
where randKY :: IO (Key (Keyed prim))
randKY = forall a. Encodable a => ByteString -> a
unsafeFromByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall l. LengthUnit l => l -> RandomState -> IO ByteString
randomByteString BYTES Int
sz RandomState
state
sz :: BYTES Int
sz = forall a. Storable a => Proxy a -> BYTES Int
sizeOf forall a b. (a -> b) -> a -> b
$ forall p. IO (Key (Keyed p)) -> Proxy p
getProxy IO (Key (Keyed prim))
randKY
getProxy :: IO (Key (Keyed p)) -> Proxy p
getProxy :: forall p. IO (Key (Keyed p)) -> Proxy p
getProxy IO (Key (Keyed p))
_ = forall {k} (t :: k). Proxy t
Proxy
instance Random Poly1305.R where
instance Random w => Random (LE w) where
random :: RandomState -> IO (LE w)
random RandomState
state = forall w. w -> LE w
littleEndian forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
instance Random w => Random (BE w) where
random :: RandomState -> IO (BE w)
random RandomState
state = forall w. w -> BE w
bigEndian forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => RandomState -> IO a
random RandomState
state
instance (Dimension d, Unbox w, Random w) => Random (Tuple d w) where
random :: RandomState -> IO (Tuple d w)
random RandomState
state = forall (dim :: Nat) a.
(Dimension dim, Unbox a) =>
IO a -> IO (Tuple dim a)
generateIO (forall a. Random a => RandomState -> IO a
random RandomState
state)