ppad-hmac-drbg-0.1.1: HMAC-based deterministic random bit generator
Copyright(c) 2024 Jared Tobin
LicenseMIT
MaintainerJared Tobin <jared@ppad.tech>
Safe HaskellSafe-Inferred
LanguageHaskell2010

Crypto.DRBG.HMAC

Description

A pure HMAC-DRBG implementation, as specified by NIST SP-800-90A.

Synopsis

DRBG and HMAC function types

data DRBG s Source #

A deterministic random bit generator (DRBG).

Create a DRBG with new, and then use and reuse it to generate bytes as needed.

Instances

Instances details
Show (DRBG s) Source # 
Instance details

Defined in Crypto.DRBG.HMAC

Methods

showsPrec :: Int -> DRBG s -> ShowS #

show :: DRBG s -> String #

showList :: [DRBG s] -> ShowS #

type HMAC = ByteString -> ByteString -> ByteString Source #

A HMAC function, taking a key as the first argument and the input value as the second, producing a MAC digest.

>>> import qualified Crypto.Hash.SHA256 as SHA256
>>> :t SHA256.hmac
SHA256.hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString

DRBG interaction

new Source #

Arguments

:: PrimMonad m 
=> HMAC

HMAC function

-> ByteString

entropy

-> ByteString

nonce

-> ByteString

personalization string

-> m (DRBG (PrimState m)) 

Create a DRBG from the supplied HMAC function, entropy, nonce, and personalization string.

You can instantiate the DRBG using any appropriate HMAC function; it should merely take a key and value as input, as is standard, and return a MAC digest, each being a strict ByteString.

The DRBG is returned in any PrimMonad, e.g. ST or IO.

>>> import qualified Crypto.Hash.SHA256 as SHA256
>>> new SHA256.hmac entropy nonce personalization_string
"<drbg>"

gen Source #

Arguments

:: PrimMonad m 
=> ByteString

additional bytes to inject

-> Word64

number of bytes to generate

-> DRBG (PrimState m) 
-> m ByteString 

Generate bytes from a DRBG, optionally injecting additional bytes per SP 800-90A.

>>> import qualified Data.ByteString.Base16 as B16
>>> drbg <- new SHA256.hmac entropy nonce personalization_string
>>> bytes0 <- gen addl_bytes 16 drbg
>>> bytes1 <- gen addl_bytes 16 drbg
>>> B16.encode bytes0
"938d6ca6d0b797f7b3c653349d6e3135"
>>> B16.encode bytes1
"5f379d16de6f2c6f8a35c56f13f9e5a5"

reseed Source #

Arguments

:: PrimMonad m 
=> ByteString

entropy to inject

-> ByteString

additional bytes to inject

-> DRBG (PrimState m) 
-> m () 

Reseed a DRBG.

Each DRBG has an internal reseed counter that tracks the number of requests made to the generator (note requests made, not bytes generated). SP 800-90A specifies that a HMAC-DRBG should support 2 ^ 48 requests before requiring a reseed, so in practice you're unlikely to ever need to use this to actually reset the counter.

Note however that reseed can be used to implement "explicit" prediction resistance, per SP 800-90A, by injecting entropy generated elsewhere into the DRBG.

>>> import qualified System.Entropy as E
>>> entropy <- E.getEntropy 32
>>> reseed entropy addl_bytes drbg
"<reseeded drbg>"