module Crypto.Number.Generate
( generateMax
, generateBetween
, generateOfSize
) where
import Crypto.Number.Serialize
import Crypto.Random.API
import qualified Data.ByteString as B
import Data.Bits ((.|.))
generateMax :: CPRG g => g -> Integer -> (Integer, g)
generateMax :: g -> Integer -> (Integer, g)
generateMax rng :: g
rng m :: Integer
m = g -> Int -> (ByteString -> Integer) -> (Integer, g)
forall g a. CPRG g => g -> Int -> (ByteString -> a) -> (a, g)
withRandomBytes g
rng (Integer -> Int
lengthBytes Integer
m) ((ByteString -> Integer) -> (Integer, g))
-> (ByteString -> Integer) -> (Integer, g)
forall a b. (a -> b) -> a -> b
$ \bs :: ByteString
bs ->
ByteString -> Integer
os2ip ByteString
bs Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m
generateBetween :: CPRG g => g -> Integer -> Integer -> (Integer, g)
generateBetween :: g -> Integer -> Integer -> (Integer, g)
generateBetween rng :: g
rng low :: Integer
low high :: Integer
high = (Integer
low Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
v, g
rng')
where (v :: Integer
v, rng' :: g
rng') = g -> Integer -> (Integer, g)
forall g. CPRG g => g -> Integer -> (Integer, g)
generateMax g
rng (Integer
high Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
low Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1)
generateOfSize :: CPRG g => g -> Int -> (Integer, g)
generateOfSize :: g -> Int -> (Integer, g)
generateOfSize rng :: g
rng bits :: Int
bits = g -> Int -> (ByteString -> Integer) -> (Integer, g)
forall g a. CPRG g => g -> Int -> (ByteString -> a) -> (a, g)
withRandomBytes g
rng (Int
bits Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` 8) ((ByteString -> Integer) -> (Integer, g))
-> (ByteString -> Integer) -> (Integer, g)
forall a b. (a -> b) -> a -> b
$ \bs :: ByteString
bs ->
ByteString -> Integer
os2ip (ByteString -> Integer) -> ByteString -> Integer
forall a b. (a -> b) -> a -> b
$ (Word8, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((Word8, ByteString) -> ByteString)
-> (Word8, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8 -> (Word8, Word8))
-> Word8 -> ByteString -> (Word8, ByteString)
forall acc.
(acc -> Word8 -> (acc, Word8))
-> acc -> ByteString -> (acc, ByteString)
B.mapAccumL (\acc :: Word8
acc w :: Word8
w -> (0, Word8
w Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
acc)) 0xc0 ByteString
bs