File: Random.hs

package info (click to toggle)
haskell-crypto-random 0.0.9-10
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 96 kB
  • sloc: haskell: 401; ansic: 52; makefile: 2
file content (60 lines) | stat: -rw-r--r-- 2,021 bytes parent folder | download | duplicates (4)
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
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : Good
--
-- Provide a safe abstraction for cryptographic pseudo
-- random generator.
--
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.Random
    (
    -- * Entropy
      EntropyPool
    , createEntropyPool
    , grabEntropy
    , grabEntropyIO
    -- * Random generation
    , CPRG(..)
    , withRandomBytes
    -- * System generator
    , SystemRNG
    -- * Testing and mocking
    , createTestEntropyPool
    ) where

import Crypto.Random.Entropy
import Crypto.Random.Generator
import Data.ByteString (ByteString)
import Data.Typeable (Typeable)
import qualified Data.ByteString.Internal as B (unsafeCreate)

-- | System entropy generator.
--
-- This generator doesn't use the entropy reseed level, as the only bytes
-- generated are comping from the entropy pool already.
--
-- This generator doesn't create reproducible output, and might be difficult to
-- use for testing and debugging purpose, but otherwise for real world use case
-- should be fine.
data SystemRNG = SystemRNG EntropyPool
  deriving Typeable

instance CPRG SystemRNG where
    cprgCreate entPool                   = SystemRNG entPool
    cprgSetReseedThreshold _ r           = r
    cprgFork r@(SystemRNG entPool)       = (r, cprgCreate entPool)
    cprgGenerate n g@(SystemRNG entPool) = (B.unsafeCreate n (grabEntropyPtr n entPool), g)
    -- we don't need to do anything different when generating withEntropy, as the generated
    -- bytes are already stricly entropy bytes.
    cprgGenerateWithEntropy n g          = cprgGenerate n g

-- | generate @len random bytes and mapped the bytes to the function @f.
--
-- This is equivalent to use Control.Arrow 'first' with 'cprgGenerate'
withRandomBytes :: CPRG g => g -> Int -> (ByteString -> a) -> (a, g)
withRandomBytes rng len f = (f bs, rng')
  where (bs, rng') = cprgGenerate len rng