Hash DRBG#

Deterministic Random Bit Generator (DRBG) is the class of random bit generators (RBGs) for computing bits deterministically using an algorithm. A DRBG is based on a DRBG mechanism and includes a source of randomness. A DRBG mechanism uses an algorithm (i.e., a DRBG algorithm) that produces a sequence of bits from an initial value that is determined by a seed that is determined from the output of the randomness source. Once the seed is provided and the initial value is determined, the DRBG is said to be instantiated and may be used to produce output. The seed used to instantiate the DRBG must contain sufficient entropy to provide an assurance of randomness.

The implementation is based on the NIST SP 800-90A Rev. 1

The DRBG mechanism requires five functions: instantiate, generate, reseed, uninstantiate and health testing.

A Hash DRBG mechanism is based on a hash function that is one-way and may be used by consuming applications requiring various security strengths, providing that the appropriate hash function is used and sufficient entropy is obtained for the seed. The Hash DRBG requires the use of a hash function during the instantiate, reseed and generate functions.

Security Strength#

The security strength is determined by the user-specified hashing method and can take one of the values from the set {128, 192, 256}. The hashing methods and their corresponding maximum security strengths are shown in Table 1.

Table 1: Maximum security strengths for hash functions in bits

Security strength

Hashing method

128

SHA-1

192

SHA-224, SHA-512/224

256

SHA-256, SHA-512/256, SHA-384, SHA-512

Since the current implementation supports only SHA-256, SHA-512/256, SHA-384, and SHA-512 hashing methods, the security strength is initially set to 256 bits. However, it can be changed when a different security strength is requested during instantiation (see The Instantiate function description).

Refer to the NIST SP 800-57 Part 1 Rev. 5 for more details.

Minimum and maximum values for the Hash DRBG#

Lowest supported security strength

128 bits

Minimum entropy input length

sec.strength + ½ sec.strength

Maximum entropy input length

231 - 1 bits

Maximum personalization string length

231 - 1 bits

Maximum additional_input length

231 - 1 bits

Maximum number of bits per request

216 bits

Maximum number of requests between reseeds (reseed interval)

224

Entropy Input#

Within the current implementation of the Hash DRBG, a separate entity IppsHashDRBG_EntropyInputCtx is used to store entropy input buffer. The entropy input context contains a pointer to the entropy input buffer and the maximum length of this buffer in bits.

Prediction Resistance#

The implementation of the Hash DRBG supports prediction resistance and provides it upon request.

The supported hashing methods#

  • SHA-256

  • SHA-512/256

  • SHA-384

  • SHA-512

Example. Random Numbers Generation#

#include "ippcp.h"

...

/* Must provide the entropy input during instantiation, reseeding,
   and, if prediction resistance is requested, generation */
static IppStatus getEntropyInputCallback(Ipp8u* entropyInput,
                                         int* pEntropyBitsLen,
                                         const int minEntropyInBits,
                                         const int maxEntropyInBits,
                                         const int predResistanceRequest)
{
    /* Implementation of obtaining entropy input from an entropy source,
       an NRBG or another DRBG */

    ...

    return status;
}

  ...

{
    const IppsHashMethod* pHashMethod = ippsHashMethod_SHA256_TT();

    int entrInputCtxSize;
    /* As an example, set the entropy input buffer size to the minimum value,
       since requestedSecurityStrength is set to 128 below */
    int entrInputBitsLen = 192;
    /* Get the size (in bytes) for the Entropy input context */
    status = ippsHashDRBG_EntropyInputCtxGetSize(&entrInputCtxSize, entrInputBitsLen, pHashMethod);

    /* Allocate memory for the Entropy input context */
    std::vector<Ipp8u> entrInputCtxBuff(entrInputCtxSize);
    IppsHashDRBG_EntropyInputCtx* pEntrInputCtx = (IppsHashDRBG_EntropyInputCtx*)(entrInputCtxBuff.data());

    /* Initialize the context */
    status = ippsHashDRBG_EntropyInputCtxInit(pEntrInputCtx, entrInputBitsLen, getEntropyInputCallback);

    int requestedSecurityStrength = 128;
    /* Indicates whether or not prediction resistance may be required */
    int predictionResistanceFlag = 1;

    int size;
    /* Get the size (in bytes) for the Hash DRBG state */
    status = ippsHashDRBG_GetSize(&size, pHashMethod);

    /* Allocate memory for the Hash DRBG context */
    std::vector<Ipp8u> ctxBuff(size);
    IppsHashDRBGState* pDrbgCtx = (IppsHashDRBGState*)(ctxBuff.data());

    /* Initialize the state and set hashing method and some initial values */
    status = ippsHashDRBG_Init(pHashMethod, pDrbgCtx);

    /* Instantiate the Hash DRBG */
    status = ippsHashDRBG_Instantiate(requestedSecurityStrength,
                                      predictionResistanceFlag,
                                      persStr.data(),
                                      persStrBitsLen,
                                      pEntrInputCtx,
                                      pDrbgCtx);

    /* Indicates whether or not prediction resistance is to be provided during the request */
    int predResistRequested = 1;
    std::vector<Ipp8u> returnedRndData(returnedBitsLen / 8, 0);

    /* Generate pseudorandom 32-bit numbers.
       If prediction resistance is requested, calls reseed inside and
       requires fresh entropy input */
    status = ippsHashDRBG_Gen((Ipp32u*)returnedRndData.data(),
                              returnedBitsLen,
                              requestedSecurityStrength,
                              predResistRequested,
                              addtlInputGenerate.data(),
                              addtlInputGenLen,
                              pEntrInputCtx,
                              pDrbgCtx);

    /* Remove the Hash DRBG instantiation */
    status = ippsHashDRBG_Uninstantiate(pDrbgCtx);

    ...