File: Generate.hs

package info (click to toggle)
haskell-cryptocipher 0.3.5-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 256 kB
  • sloc: haskell: 2,916; ansic: 142; makefile: 3
file content (38 lines) | stat: -rw-r--r-- 1,506 bytes parent folder | download
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
-- |
-- Module      : Number.Generate
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : Good

module Number.Generate
	( generateMax
	, generateBetween
	, generateOfSize
	) where

import Number.Serialize
import Crypto.Random
import qualified Data.ByteString as B
import Data.Bits ((.|.))

-- | generate a positive integer between 0 and m.
-- using as many bytes as necessary to the same size as m, that are converted to integer.
generateMax :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)
generateMax rng m = case genBytes (lengthBytes m) rng of
	Left err         -> Left err
	Right (bs, rng') -> Right (os2ip bs `mod` m, rng')

-- | generate a number between the inclusive bound [low,high].
generateBetween :: CryptoRandomGen g => g -> Integer -> Integer -> Either GenError (Integer, g)
generateBetween rng low high = case generateMax rng (high - low + 1) of
	Left err        -> Left err
	Right (v, rng') -> Right (low + v, rng')

-- | generate a positive integer of a specific size in bits.
-- the number of bits need to be multiple of 8. It will always returns
-- an integer that is close 2^(1+bits/8) by setting the 2 highest bits to 1.
generateOfSize :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)
generateOfSize rng bits = case genBytes (bits `div` 8) rng of
	Left err         -> Left err
	Right (bs, rng') -> Right (os2ip $ snd $ B.mapAccumL (\acc w -> (0, w .|. acc)) 0xc0 bs, rng')