org.randomness
Class Cryptorandomness

java.lang.Object
  extended by org.randomness.Randomness
      extended by org.randomness.Cryptorandomness
All Implemented Interfaces:
Closeable, Channel, ReadableByteChannel, ScatteringByteChannel

public abstract class Cryptorandomness
extends Randomness

This class specifies techniques for the compute cryptographically secure bits deterministically using an underlying algorithm that, if an adversary does not know the entropy input, then he can’t tell the difference between the pseudorandom bits and a stream of truly random bits, let alone predict any of the pseudorandom bits. This class of RBGs is known as Cryptographically Secure (Determenistic) Pseudorandom Bit (or Number) Generator (CSPRBG).

The requirements of an ordinary PRNG are also satisfied by a cryptographically secure PRNG, but the reverse is not true. Such properties of CSPRNG's make it suitable for use in cryptography for key, password, nonce, salt generation. The output of CSPRBG's is never repeatable.

PROVISIONAL API, WORK IN PROGRESS

TODO:

  1. Interruptible generation
  2. Support of selectable, nonblocking and asynchronous reading
  3. Full cryptorandomness model (incl full version of NIST 800-90)
  4. Secure Hex Strings
  5. Auto reseeding (limitations, probablistic reseeding, time-pereodic resseeding).
  6. asynchronous escape
  7. Full integration with JCE

General requirements of CSPRNG from NIST 800-90 is:

Term Shall is used to indicate a strong requirement of NIST 800-90 Recommendation.
Term Should is used to indicate a highly desirable feature for a CSPRNG mechanism that is not necessarily required by NIST 800-90 Recommendation.

CSPRNG mechanisms

A CSPRNG mechanism uses an algorithm (a CSPRNG algorithm) that produces a sequence of bits from an initial value that is determined by a seed that is determined from the entropy input. Once the seed is provided and the initial value is determined, the CSPRNG is said to be instantiated. Because of the deterministic nature of the process, a CSPRNG is said to produce pseudorandom bits, rather than random bits. The seed used to instantiate the CSPRNG must contain sufficient entropy to provide an assurance of randomness. If the seed is kept secret, and the algorithm is well designed, the bits output by the CSPRNG will be unpredictable, up to the instantiated security strength of the CSPRNG.

The CSPRNG mechanism functions handle the CSPRNG’s internal state. The CSPRNG mechanisms in this class have five separate functions:

  1. The instantiate function acquires entropy input and may combine it with a nonce and a personalization string to create a seed from which the initial internal state is created.
  2. The generate function generates pseudorandom bits upon request, using the current internal state, and generates a new internal state for the next request.
  3. The reseed function acquires new entropy input and combines it with the current internal state and any additional input that is provided to create a new seed and a new internal state.
  4. The uninstantiate function zeroizes (i.e., erases) the internal state.
  5. The health test function determines that the CSPRNG mechanism continues to function correctly (optional).
This functions is implemented as much as possible close to NIST 800-90 Recommendations. A function need not be implemented using such envelopes, but the function shall have equivalent functionality. The detailed description can be found in documentation to CSPRNG mechanism functions. Specification of this class based on full version of NIST 800-90 special publication.

Author:
Anton Kabysh - Code,
NIST 800-90 autors (Elaine Barker, John Kelsey) - Specification
See Also:
Wikipedia - Cryptographically secure pseudorandom number generator,
Common Problems - CWE-330: Use of Insufficiently Random Values,
Randomness for crypto,
Randomness Extractor,
NIST - Cryptographic Toolkit,
NIST - Special Publications (800 Series),
NIST Special Publication 800-90: Recommendation for Random Number Generation using Deterministic Random Bit Generators.

Field Summary
protected  BigInteger personalizationString
          The intent of a personalization string is to differentiate this instantiation from all other instantiations that might ever be created.
 
Constructor Summary
protected Cryptorandomness(byte[] personalizationString)
          Default constructor define optional personalization string of bits that provides personalization information.
 
Method Summary
 SecureRandom asRandom()
          Represents this CSPRNG as a java.security.SecureRandom.
abstract  void close()
          The uninstantiate function zeroizes (i.e., erases) the internal state.
 boolean equals(Object obj)
          Two different instances of Cryptorandomness are never equal to each other (consistent with hashCode).
 Cryptorandomness escape()
          PROVISIONAL API, WORK IN PROGRESS: Escape from attacker (asynchronous call).
static Cryptorandomness from(CSPRNG algorithm)
          Returns a new Cryptorandomness object that implements the specified Cryptosecure Random Number Generator algorithm ( CSPRNG).
static Cryptorandomness from(SecureRandomSpi spi)
          PROVISIONAL API, WORK IN PROGRESS: Create Cryptorandomness from the specified SPI.
protected  byte[] getEntropyInput(int min_entropy)
          A limited entropy function is used to obtain entropy input.
protected  byte[] getEntropyInput(int min_entropy, int min_length, int max_length)
          A entropy function is used to obtain entropy input.
 int hashCode()
          Returns the unique hash code value of this Cryptorandomness (consistent with equals).
 long limit()
          PROVISIONAL API, WORK IN PROGRESS: Returns limit of bytes generated between two autoreseedings.
 Cryptorandomness limit(long newLimit)
          PROVISIONAL API, WORK IN PROGRESS: Set's new limit of bytes
 String nextHexString(int length)
          TODO PROVISIONAL API, WORK IN PROGRESS: Returns a random string of hex characters from a secure random sequence.
protected  byte[] nonce()
          Nonce - is a time-varying value that has at most a negligible chance of repeating, e.g., a random value that is generated anew for each use, a timestamp, a sequence number, or some combination of these.
abstract  int read(ByteBuffer buffer)
          The generate function is used to generate the requested pseudorandom bits after instantiation or reseeding using the generate algorithm.
abstract  void reseed(ByteBuffer additionalInput)
          The reseed function acquires new entropy input and combines it with the current internal state and any additional input that is provided to create a new seed and a new internal state.
 Cryptorandomness reseed(float probability)
          PROVISIONAL API, WORK IN PROGRESS:Try to reseed on every call with specified probability.
abstract  void reset()
          The instantiate function acquires entropy input and may combine it with a nonce and a personalization string to create a seed from which the initial internal state is created.
protected  int securityStrength()
          Returns the security strength of this CSPRNG in bytes.
protected abstract  int seedlen()
          Returns the seed length used by underlying CSPRNG algorithm in bytes.
 
Methods inherited from class org.randomness.Randomness
bind, isOpen, map, minlen, mixing, newBuffer, nextBoolean, nextByte, nextChar, nextCharASCII, nextDouble, nextFloat, nextInt, nextInt, nextLong, nextLong, nextProbability, nextShort, read, read, read, readFuture, readSink, reversed, shuffle, toString, tryRead
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

personalizationString

protected final transient BigInteger personalizationString
The intent of a personalization string is to differentiate this instantiation from all other instantiations that might ever be created. During instantiation, a personalization string should be used to derive the seed.

Constructor Detail

Cryptorandomness

protected Cryptorandomness(byte[] personalizationString)
Default constructor define optional personalization string of bits that provides personalization information. Personalization string is combined with a secret input and a nonce to produce a seed. The personalization string should be set to some unmodifiable bitstring that is as unique as possible, may include secret information. Secret information should not be used in the personalization string if it requires a level of protection that is greater than the intended security strength of the CSPRNG instantiation. Following NIST recommendations, good choices for the personalization string contents include:
  1. Device serial numbers,
  2. Public keys,
  3. Special secret key values for this specific instantiation,
  4. Secret per-module or per-device values,
  5. User identification,
  6. Timestamps,
  7. Network addresses,
  8. Application identifiers,
  9. Protocol version identifiers,
  10. Random numbers,
  11. Seedfiles,
  12. Nonce.
Or some combination of this.

If personalization string is null or represented by empty array, then used underlying default algorithm to determine personalization string in according to security strength as combination of NIST recommendation techniques.

See also at NIST SP 800-90:

Parameters:
personalizationString - - an optional input that provides personalization information. Maximum personalization string length if configured by CSPRNG.MAX_PERSONALIZATION_STRING_LENGTH with default value 1024 bytes.
Throws:
IllegalArgumentException - if personalizationString length is greater than max_personalization_string_length value.
Method Detail

from

public static final Cryptorandomness from(CSPRNG algorithm)
Returns a new Cryptorandomness object that implements the specified Cryptosecure Random Number Generator algorithm ( CSPRNG).

Parameters:
algorithm - a specified algorithm.
Returns:
a new Cryptorandomness generator

from

public static final Cryptorandomness from(SecureRandomSpi spi)
PROVISIONAL API, WORK IN PROGRESS: Create Cryptorandomness from the specified SPI.

Parameters:
spi -
Returns:
the SPRNG from specified SPI

reset

public abstract void reset()
The instantiate function acquires entropy input and may combine it with a nonce and a personalization string to create a seed from which the initial internal state is created.

A CSPRNG shall be instantiated prior to the generation of pseudorandom bits. The instantiate function:

  1. Checks the validity of the input parameters,
  2. Determines the security strength for the CSPRNG instantiation,
  3. Determines any CSPRNG mechanism specific parameters (e.g., elliptic curve domain parameters),
  4. Obtains entropy input with entropy sufficient to support the security strength,
  5. Obtains the nonce (if required),
  6. Determines the initial internal state using the instantiate algorithm,
  7. Open instantiation to generate random bits.

The seed material used to determine a seed for instantiation consists of entropy input, a nonce and an optional personalization string. Depending on the CSPRNG mechanism and the source of the entropy input, a derivation function may be required to derive a seed from the seed material. However, in certain circumstances, the CSPRNG mechanism based on block cipher algorithms may be implemented without a derivation function.

Seed Construction for instantiation generated and handled as specified in NIST 800-90 recommendations. The hash-based derivation function used in default implementation to create cryptographic seed from specified entropy input, nonce, and personalization string. It hashes an input string and returns the requested number of bits.

See also at NIST SP 800-90:

Specified by:
reset in class Randomness

read

public abstract int read(ByteBuffer buffer)
The generate function is used to generate the requested pseudorandom bits after instantiation or reseeding using the generate algorithm.

The generate function:

  1. Checks the validity of the input parameters ( is open, is instantiated).
  2. Calls the reseed function to obtain sufficient entropy if the instantiation needs additional entropy because the end of the seedlife has been reached or prediction resistance is required.
  3. Generates the requested pseudorandom bits using the generate algorithm.
  4. Updates the working state.
  5. Returns the requested pseudorandom bits to the consuming application.

In other words, transfers a sequence generated bytes from this CSPRNG into the given buffer. An attempt is made to read up to r bytes from RBG, where r is the number of bytes remaining in the buffer, that is, buffer.remaining(), at the moment this method is invoked.

Suppose that a byte sequence of length n is read, where 0  <= n <= r. This byte sequence will be transferred into the buffer so that the first byte in the sequence is at index p and the last byte is at index p + n - 1, where p is the buffer's position at the moment this method is invoked. Upon return the buffer's position will be equal to p + n; its limit will not have changed. A read operation might not fill the buffer, and in fact it might not read any bytes at all. Whether or not it does so depends upon the nature and state of the channel.

This method may be invoked at any time. If another thread has already initiated a read operation upon this channel, however, then an invocation of this method will block until the first operation is complete (no interruption).

See also at NIST SP 800-90:

Specified by:
read in interface ReadableByteChannel
Specified by:
read in class Randomness
Parameters:
buffer - The buffer into which random bytes are to be transferred
Returns:
The number of bytes read, possibly zero.
Throws:
NullPointerException - if buffer is null.
NonReadableChannelException - If this CSPRNG was not opened for reading (is closed).

reseed

public abstract void reseed(ByteBuffer additionalInput)
The reseed function acquires new entropy input and combines it with the current internal state and any additional input that is provided to create a new seed and a new internal state. The reseeding of an instantiation is not required, but is recommended whenever a comsuming application and implementation are able to perform this process. Reseeding will insert additional entropy into the generation of pseudorandom bits.

Reseeding may be:

The reseed function:

  1. Checks the validity of the input parameters,
  2. Obtains entropy input with sufficient entropy to support the security strength, and
  3. Using the reseed algorithm, combines the current working state with the new entropy input and any additional input to determine the new working state.
  4. Open instantiation to generate random bits.

The seed material for reseeding consists of a value that is carried in the internal state, new entropy input and, optionally, additional input. The internal state value and the entropy input are required. The entropy input shall have entropy that is equal to or greater than the security strength of the instantiation. Additional entropy may be provided in the nonce or the optional personalization string during instantiation, or in the additional input during reseeding and generation, but this is not required. A derivation function may be required for reseeding.

See also at NIST SP 800-90:

Parameters:
additionalInput - an additional Input (Optional). An optional input. The maximum length of the additional_input ( max_additional_input_length) is implementation dependent, but shall be less than or equal to the maximum value specified for the given CSPRNG mechanism. Suppose that max_additional_input_length shall not be greater than max_entropy_input_length. If the input by a consuming application of additional_input is not supported, then additional entropy may be provided in the nonce or the optional personalization string during instantiation, but this is not required.
Throws:
IllegalArgumentException - if additionalInput length is greater than max_additional_input_length value.

close

public abstract void close()
The uninstantiate function zeroizes (i.e., erases) the internal state. The internal state for an instantiation may need to be “released” by erasing (i.e., zeroizing) the contents of the internal state.

The uninstantiate function:

  1. Closes this instantiation to ever produce random bytes.
  2. Erases the internal state to null value.

The instantiation may be instantiated again calling one of reset() or reseed() methods.

See also at NIST SP 800-90:

Specified by:
close in interface Closeable
Specified by:
close in interface Channel
Specified by:
close in class Randomness

seedlen

protected abstract int seedlen()
Returns the seed length used by underlying CSPRNG algorithm in bytes. The minimum seed length depends on the CSPRNG mechanism and the security strength required by the consuming application.

Returns:
the seed length of this CSPRNG in bytes

limit

public long limit()
PROVISIONAL API, WORK IN PROGRESS: Returns limit of bytes generated between two autoreseedings.

Returns:
current limit

limit

public Cryptorandomness limit(long newLimit)
PROVISIONAL API, WORK IN PROGRESS: Set's new limit of bytes

Parameters:
newLimit -
Returns:
this

reseed

public Cryptorandomness reseed(float probability)
PROVISIONAL API, WORK IN PROGRESS:Try to reseed on every call with specified probability.

Returns:
this

escape

public Cryptorandomness escape()
PROVISIONAL API, WORK IN PROGRESS: Escape from attacker (asynchronous call).

Returns:
this

securityStrength

protected int securityStrength()
Returns the security strength of this CSPRNG in bytes. Security strength - is a number associated with the amount of work (that is, the number of operations) that is required to break a cryptographic algorithm or system. The amount of work needed is 2security_strength. From this value depends size of nonce string and used derivation function.

A security strength for the instantiation is requested by a consuming application during instantiation, and the instantiate function obtains the appropriate amount of entropy for the requested security strength. The actual security strength supported by a given instantiation depends on the CSPRNG implementation and on the amount of entropy provided to the instantiate function. Note that the security strength actually supported by a particular instantiation could be less than the maximum security strength possible for that CSPRNG implementation . For example, a CSPRNG that is designed to support a maximum security strength of 256 bits could, instead, be instantiated to support only a 128-bit security strength if the additional security provided by the 256-bit security strength is not required (i.e., by requesting only 128 bits of entropy during instantiation, rather than 256 bits of entropy).

It is hard to determine security strength for all kind of CSPRNG so, we use lower bound of security strength defined as seedlen/2 Recommendation taken from SP 800 57, Table 3, p. 64 Hash function security strengths for cryptographic applications:

The default CSPRNG using following rules:

If security strength <= 128 than used SHA-1 hash function as derivation function.
Else if security strength <= 256 than used SHA-256 hash function as derivation function.
If security strength > 256 used SHA-512 hash function as derivation function.
If SHA hash functions family is not supported, used bundled MD5 hash function as as derivation function.

See also at NIST SP 800-57:

See also at NIST SP 800-90:

Returns:
the security strength of this CSPRNG in bytes

getEntropyInput

protected byte[] getEntropyInput(int min_entropy,
                                 int min_length,
                                 int max_length)
A entropy function is used to obtain entropy input. The function call is requests a string of bits (entropy_input) with at least min_entropy bytes of entropy from source of entropy to provide desired security strength. The length for the string shall be equal to or greater than min_length bits, and less than or equal to max_length bits. The security_strength <= min_entropy <= min_length <= seedlen <= max_length shall be required.

The source of the entropy input shall be either:

  1. An Approved non-deterministic random bit generators ( True Random Number Generators).
  2. An Approved CSPRNG, thus forming a chain of at least two CSPRNGs; the highestlevel CSPRNG in the chain shall be seeded by an Approved NRBG or an entropy source.
  3. An appropriate entropy source.

The entropy input shall not be provided by a consuming application as an input parameter in an instantiate or reseed request.

The most important feature of the interaction between the entropy input and the CSPRNG mechanism is that if an adversary does not know the entropy input, then he can’t tell the difference between the pseudorandom bits and a stream of truly random bits, let alone predict any of the pseudorandom bits. On the other hand, if he knows (or can guess) the entropy input, then he will be able to predict or reproduce the pseudorandom bits. Thus, the security of the CSPRNG output is directly related to the adversary’s inability to guess the entropy input and the seed. The entropy source is the critical component of an RBG that provides un-guessable values for the deterministic algorithm to use as entropy input for the random bit generation process.

Note that an implementation may choose to define this functionality differently. The developer using a own source shall document the adversary’s ability to predict or observe the output of the noise source and shall provide a model that justifies his claims for the amount of entropy produced by the noise source (i.e., how unguessable the values are for the observer).

See also at NIST SP 800-90:

Parameters:
min_entropy - number bits of entropy (required minimum entropy for instantiate and reseed - security strength).
min_length - minimum length of returned bitstring.
max_length - maximum length of returned bitstring. The max_length shall not be greater than value configured by Maximum entropy input length (default 1024 bytes).
Returns:
string of bits with at least min_entropy bits of entropy.
Throws:
IllegalArgumentException -
  1. if min_entropy is negative,
  2. if min_entropy is lower than security strength (Optional),
  3. if min_length is lower than min_entropy,
  4. if min_length is lower than seedlen (Optional),
  5. if min_length is greater than max_length,
  6. if max_length is greater than Maximum entropy input length value.
InternalError - if no such entropy in the system.

getEntropyInput

protected final byte[] getEntropyInput(int min_entropy)
A limited entropy function is used to obtain entropy input. Equal to full entropy function function from NIST 800-90 recomendations, where min_length is equal to min_entropy, and max_length is equal to Maximum entropy input length (default 1024 byte).

Common Problems

Reccomendation:

Parameters:
min_entropy - number bytes of entropy.
Returns:
a byte array containing min_entropy bytes of entropy.

nonce

protected byte[] nonce()
Nonce - is a time-varying value that has at most a negligible chance of repeating, e.g., a random value that is generated anew for each use, a timestamp, a sequence number, or some combination of these. A nonce required in the construction of a seed during instantation in order to provide a security cushion to block certain attacks.

The nonce shall be either:

For case a, the nonce may be acquired from the same source and at the same time as the entropy input . In this case, the seed could be considered to be constructed from an “extra strong” entropy input and the optional personalization string, where the entropy for the entropy input is equal to or greater than (3/2 security_strength) bytes.

This implementation reads 1/2 security_strength)-bytes of entropy from entropy function.

The default Cryptorandomness implementation use a combined non-linear approach: a (1/2 security_strength)-byte random value initialized by system entropy, entropy function and internal cryptosecure RNG. In resutl, Nonce is a non-linear function of nonce bitstring, counter and cryptosecure RNG.

Returns:
nonce bytes
See Also:
Wikipedia - Cryptographic nonce

equals

public final boolean equals(Object obj)
Two different instances of Cryptorandomness are never equal to each other (consistent with hashCode). CSPRNG must hide their internal states to prevent possible attacks.

Overrides:
equals in class Object
Parameters:
obj - the reference object with which to compare.
Returns:
true if this == obj; false otherwise.

hashCode

public final int hashCode()
Returns the unique hash code value of this Cryptorandomness (consistent with equals).

Unique hash code value used to hide internal state of Cryptorandomness and prevent some possible attacks, where internal state of object can be restored using hash code value.

Overrides:
hashCode in class Object
Returns:
a unique hash code value for this object.

nextHexString

public String nextHexString(int length)
TODO PROVISIONAL API, WORK IN PROGRESS: Returns a random string of hex characters from a secure random sequence.

Overrides:
nextHexString in class Randomness
Parameters:
length - the length of the generated string
Returns:
the random string
Throws:
IllegalArgumentException - if len <= 0

asRandom

public SecureRandom asRandom()
Represents this CSPRNG as a java.security.SecureRandom.

This method convert this PRNG into java.security.SecureRandom instance, to be used instead it in java legacy code.

The view is typically part of the CSPRNG itself (created only once) and every call return this instance.

Overrides:
asRandom in class Randomness
Returns:
view as java.security.SecureRandom over this Cryptorandomness.
See Also:
Pseudorandomness.asRandom(), asRandom()