org.randomness
Class Randomness

java.lang.Object
  extended by org.randomness.Randomness
All Implemented Interfaces:
Closeable, Channel, ReadableByteChannel, ScatteringByteChannel
Direct Known Subclasses:
Cryptorandomness, Pseudorandomness, Quasirandomess, Truerandomness

public abstract class Randomness
extends Object
implements Channel, ReadableByteChannel, ScatteringByteChannel

This class specifies basic Random Bit Generator (RBG) life cycle and mechanisms for the generation of random bits.

A randomness represents an open connection to an entity such as a hardware device, or an deterministic algorithm that is capable of producing random output. Life cycle of Random Bit Generator inspired on NIST 800-90 Specification. The RBG mechanisms have four separate functions handle the RBG’s internal state:

  1. The instantiate function determines the initial internal state of RBG using the instantiate algorithm. A RBG shall be instantiated prior to the generation of random bits. Opposite to uninstantiate function.
  2. The generate function generates random bits upon request, using the current internal state, and generates a new internal state for the next request. RBG should be instantiate before generation.
  3. The uninstantiate function zeroizes (i.e., erases) the internal state. A RBG uninstantiate function supports asynchronous closing. Opposite to instantiate function.
  4. The health test function determines that the DRBG mechanism continues to function correctly (optional).

Randomness can be represented in different views:

As specified in the Channel interface RBG are either open or closed, and they are both asynchronously closeable and, in general, should (intended) to be safe for multithreaded access.

Author:
Anton Kabysh - Code, Specefication,
NIST 800-90 autors (Elaine Barker, John Kelsey) - Specification
See Also:
Wikipedia - Random number generation,
NIST Special Publication 800-90: Recommendation for Random Number Generation using Deterministic Random Bit Generators.

Constructor Summary
protected Randomness()
          Default constructor.
 
RBG Functions Summary
abstract  void reset()
          The instantiate function determines the initial internal state of RBG using the instantiate algorithm.
abstract  int read(ByteBuffer dst)
          The generate function generates the requested random bits using the generate algorithm.
abstract  void close()
          The uninstantiate function zeroizes the internal state of RBG interrupting generate function, if proceed.

Additional Operations Summary
abstract  boolean isOpen()
          Tells whether or not this RBG is open to generate random bytes.
abstract  int minlen()
          Minlen is the minimum block of bytes essentially produced per one iteration of generate function (optional operation).
abstract  String toString()
          Returns the name of the algorithm (or process) implemented by this RBG object (optional operation).
 
Read Methods Summary
 int read(byte[] bytes)
          Transfers a sequence generated bytes from this RBG into the given array.
 long read(ByteBuffer[] dsts)
          Reads a sequence of random bytes from this RBG into the given buffers.
 long read(ByteBuffer[] dsts, int offset, int length)
          Reads a sequence of bytes from this RBG into a subsequence of the given buffers.
abstract  int tryRead(ByteBuffer buffer)
          Attempts to read from this RNG into the given buffer, starting at the given file position if generate function is not owned by other thread.
 Future<Integer> readFuture(ByteBuffer dst)
          PROVISIONAL API, WORK IN PROGRESS: Reads asynchronously sequence of bytes in non-blocking mode from this channel into the given buffer, retrieving result in the future when operation is done.
 Pipe.SourceChannel readSink(int bytes)
          PROVISIONAL API, WORK IN PROGRESS: Reads a sequence of bytes in non-blocking mode from this channel into the Pipe.SourceChannel ().
   
Generation Methods Summary
 boolean nextBoolean()
          Return's next generated random 1-bit boolean value (like coin flip).
 byte nextByte()
          Return's next generated random 8-bit byte value.
 char nextChar()
          Return's next generated random unsigned 16-bit char value UNICODE encoded.
 char nextCharASCII()
          Return's next randomly generated 8-bit char value US-ASCII encoded.
 double nextDouble()
          Return's next generated random 64-bit floating-point double value between 0.0 (inclusive) and 1.0 (exclusive).
 float nextFloat()
          Return's next generated random 32-bit floating-point float () value between 0.0 (inclusive) and 1.0 (exclusive).
 String nextHexString(int length)
          Generates a random string of hex characters of specified length.
 int nextInt()
          Return's next generated random 32-bit int value.
 int nextInt(int n)
          Return's next generated random int value drawn uniformly from 0 to n-1.
 long nextLong()
          Return's next generated random 64-bit long value.
 long nextLong(long n)
          Return's next generated random long value drawn uniformly from 0 to n-1.
 boolean nextProbability(float probability)
          Return's next generated boolean with a specified probability of returning true, else returning false.
 short nextShort()
          Return's next generated random 16-bit short () value (typically from nextInt value returned two most significant bytes).
 
Views Summary
 Random asRandom()
          Represents this RBG as java.util.Random.
 Randomness mixing(Randomness... randomness)
          Returns new RBG represents mixing of this RBG with specified RBG's sequence using default XOR mixing function.
 Randomness reversed(int windowSize)
          Takes bytes generated by an underling Randomness and reverses the order in each small window of configurable size (byte-by-byte).
 Randomness shuffle(Randomness that)
          Shuffle uses one RBG to shuffle the output produced by another RBG to obliterate sequential correlations to produce non-linear output.
 Randomness bind(SocketAddress address)
          PROVISIONAL API, WORK IN PROGRESS: Open a server associated with this RBG on specified port.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

Randomness

protected Randomness()
Default constructor.

Method Detail

map

public static void map(String algorithm,
                       Class<? extends Randomness> provider)
PROVISIONAL API, WORK IN PROGRESS: Associate the specified algorithm with specified provider. To instantiate algorithm from the specified provider it should have default constructor (without parameters).

If a algorithm with the same name exist and it provider was previously added using map(), it is replaced by the new service.

Parameters:
algorithm - the string constrains readable name of algorithm which is producing randomness (possibly with provider prefix or suffix)
provider - the class-provider with default constructor implementing the associated algorithm.
Throws:
IllegalArgumentException - if algorithm or provider is null or if provider does not have default constructor.

isOpen

public abstract boolean isOpen()
Tells whether or not this RBG is open to generate random bytes.

Specified by:
isOpen in interface Channel

reset

public abstract void reset()
The instantiate function determines the initial internal state of RBG using the instantiate algorithm. A RBG shall be instantiated prior to the generation of random bits.

If RBG has already initiated a generate operation, then an invocation of this method will block until the first operation is complete. If RBG already initiated a generate function, then an invocation of instantiate function will block until the generate operation is complete.

Opposite to uninstantiate function.


read

public abstract int read(ByteBuffer dst)
The generate function generates the requested random bits using the generate algorithm.

Transfers a sequence generated bytes from this RBG 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. As many bytes as possible are transferred into each buffer, hence the final position is guaranteed to be equal to that buffer's limit. Also, 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 RBG.

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

Calling uninstantiate function in interrupt this metod normally (without exceptions).

Specified by:
read in interface ReadableByteChannel
Parameters:
dst - The buffer into which random bytes are to be transferred.
Returns:
The number of bytes read from RBG, possibly zero, or -1 if the RBG has reached end-of-stream.
Throws:
NullPointerException - if buffer is null.
NonReadableChannelException - If this RBG was not opened for reading (is closed).

read

public final long read(ByteBuffer[] dsts)
Reads a sequence of random bytes from this RBG into the given buffers.

Scattering reads are often useful when required to produce several fixed-length (or not) segments with randomness bytes. Also, some, especially fixed-length blocks generators can be much more efficient for scattering reads if block size is equal to minlen or multiply of it.

An invocation of this method of the form r.read(dsts) behaves in exactly the same manner as the invocation:

 r.read(dsts, 0, dsts.length);
 

Specified by:
read in interface ScatteringByteChannel
Parameters:
dsts - The buffers into which bytes are to be transferred
Returns:
The number of bytes read, possibly zero, or -1 if the RBG has reached end-of-stream
Throws:
NullPointerException - if one of ByteBuffers in dsts or array itself is null.
NonReadableChannelException - If this RBG was not opened for reading.
See Also:
read(ByteBuffer)

read

public final long read(ByteBuffer[] dsts,
                       int offset,
                       int length)
Reads a sequence of bytes from this RBG into a subsequence of the given buffers.

An invocation of this method attempts to read up to r bytes from this RBG, where r is the total number of bytes remaining the specified subsequence of the given buffer array, that is,

 dsts[offset].remaining()
     + dsts[offset+1].remaining()
     + ... + dsts[offset+length-1].remaining()
 
at the moment that this method is invoked.

Suppose that a byte sequence of length n is read, where 0  <= n <= r. Up to the first dsts[offset].remaining() bytes of this sequence are transferred into buffer dsts[offset], up to the next dsts[offset+1].remaining() bytes are transferred into buffer dsts[offset+1], and so forth, until the entire byte sequence is transferred into the given buffers. As many bytes as possible are transferred into each buffer, hence the final position of each updated buffer, except the last updated buffer, is guaranteed to be equal to that buffer's limit.

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

This method behaves exactly as specified in the generate function.

Specified by:
read in interface ScatteringByteChannel
Parameters:
dsts - The buffers into which bytes are to be transferred
offset - The offset within the buffer array of the first buffer into which bytes are to be transferred; must be non-negative and no larger than dsts.length
length - The maximum number of buffers to be accessed; must be non-negative and no larger than dsts.length  - offset
Returns:
The number of bytes read, possibly zero, or -1 if the RBG has reached end-of-stream
Throws:
IndexOutOfBoundsException - If the preconditions on the offset and length parameters do not hold.
NonReadableChannelException - If this RBG was not opened for reading
NullPointerException - if one of ByteBuffers in dsts or array itself is null.

read

public final int read(byte[] bytes)
Transfers a sequence generated bytes from this RBG into the given array.

This method behaves exactly as specified in the generate function.

Parameters:
bytes - a byte array into which random bytes are to be transferred
Returns:
The number of bytes read, possibly zero.
Throws:
NullPointerException - if array is null.
See Also:
read(ByteBuffer)

readFuture

public final Future<Integer> readFuture(ByteBuffer dst)
PROVISIONAL API, WORK IN PROGRESS: Reads asynchronously sequence of bytes in non-blocking mode from this channel into the given buffer, retrieving result in the future when operation is done.

Parameters:
dst - destination buffer
Returns:
Future result.

tryRead

public abstract int tryRead(ByteBuffer buffer)
Attempts to read from this RBG into the given buffer, if generate function is not owned by other thread.

This method behaves exactly as specified in the generate function except that returns immediately if generate function is owned by other thread.

Parameters:
buffer - The buffer into which random bytes are to be transferred.
Returns:
The number of bytes read from RBG, possibly zero, or -1 if the RBG is owned by other thread.

readSink

public final Pipe.SourceChannel readSink(int bytes)
PROVISIONAL API, WORK IN PROGRESS: Reads a sequence of bytes in non-blocking mode from this channel into the Pipe.SourceChannel ().

Source channel can be managaned by Selector to do a readiness selection of generated bytes.

Parameters:
bytes - number of bytes to read
Returns:
source channel where from random bytes can be aquired.

bind

public final Randomness bind(SocketAddress address)
PROVISIONAL API, WORK IN PROGRESS: Open a server associated with this RBG on specified port.

Parameters:
address -
Returns:
this

close

public abstract void close()
The uninstantiate function zeroizes the internal state of RBG interrupting generate function, if proceed. Opposite to instantiate function.

Asynchronous closability

If RBG blocked on generate function than another thread can invoke RBG close method. This will cause to interrupt generate function without throwing any exceptions and close RBG. This method may be invoked at any time. If some other thread has already invoked it, however, then another invocation will block until the first invocation is complete, after which it will return without effect.

After a RBG is closed, any further attempt to invoke read operations upon it will cause a NonReadableChannelException to be thrown.

The closing status can be tested runtime via isOpen() method.

The closed status of the RBG is cleared by reset function.

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

toString

public abstract String toString()
Returns the name of the algorithm (or process) implemented by this RBG object (optional operation).

In general case, toString description can contain all necessary information about RNG. If type of current RBG is undefined use UNKNOWN as type mark instead.

Overrides:
toString in class Object
Returns:
the name of the algorithm, or UNKNOWN if the algorithm name cannot be determined.

minlen

public abstract int minlen()
Minlen is the minimum block of bytes essentially produced per one iteration of generate function (optional operation).

This method may provide additional information about generator to configure generation process more essential for generator. For example, this method should used as follows:

Randomness rnd = Cryptorandomness.from(CSPRNG.SHA1);
ByteBuffer buffer = ByteBuffer.allocate(rnd.minlen() * MULTIPLIER);
rnd.read(buffer); // essential for generator. may be optimized.

Returns:
number of bytes generated by RBG per one iteration

nextBoolean

public boolean nextBoolean()
Return's next generated random 1-bit boolean value (like coin flip). Returned values are chosen pseudorandomly with (approximately) uniform distribution from true or false with equal probability.

It is important to remember, that boolean values are hold in platform dependent way (depends from JVM). For large boolean arrays is better to use something like java.util.BitSet.

Returns:
newly generated random boolean value.
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
Wikipedia - Bit, JLS - 4.2.5 The boolean Type and boolean Values

nextProbability

public final boolean nextProbability(float probability)
Return's next generated boolean with a specified probability of returning true, else returning false.

Uses 32-bit precision.

Parameters:
probability - probability must be between 0.0 and 1.0, inclusive.
Returns:
the next generated

nextByte

public byte nextByte()
Return's next generated random 8-bit byte value. Returned values are chosen pseudorandomly with (approximately) uniform distribution from range Byte.MIN_VALUE to Byte.MAX_VALUE.

Returns:
newly generated random byte value in range [ -128..127].
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
Wikipedia - Byte, JLS - 4.2.1 Integral Types and Values

nextShort

public short nextShort()
Return's next generated random 16-bit short () value (typically from nextInt value returned two most significant bytes).

Returns:
newly generated random short value in range [-32768..32767]
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.1 Integral Types and Values

nextChar

public final char nextChar()
Return's next generated random unsigned 16-bit char value UNICODE encoded. Returned values are chosen pseudorandomly with (approximately) uniform distribution from range Character.MIN_VALUE to Character.MAX_VALUE.

Can be used instead of unsigned short.

Returns:
newly generated random char value (2 byte unicode) in range [ ..?] = [0..65535] .
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.1 Integral Types and Values

nextCharASCII

public final char nextCharASCII()
Return's next randomly generated 8-bit char value US-ASCII encoded.

Can be used instead of unsigned byte.

Returns:
newly generated US-ASCII symbol.

nextInt

public int nextInt()
Return's next generated random 32-bit int value. Returned values are chosen randomly with (approximately) uniform distribution from range Integer.MIN_VALUE to Integer.MAX_VALUE.

Returns:
newly generated random int value in range [-2147483648...2147483647].
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.1 Integral Types and Values

nextInt

public final int nextInt(int n)
Return's next generated random int value drawn uniformly from 0 to n-1.

Suffice it to say, n must be > 0, or an IllegalArgumentException is raised.

Returns:
newly generated random int value in range [0...n-1].
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
IllegalArgumentException - if n < 0

nextFloat

public float nextFloat()
Return's next generated random 32-bit floating-point float () value between 0.0 (inclusive) and 1.0 (exclusive). Returned values are chosen randomly with (approximately) uniform distribution greater than or equal to 0.0 and less than 1.0.

Returns:
newly generated random float value in range [0..1).
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.3 Floating-Point Types, Formats, and Values, Wikipedia - IEEE 754

nextLong

public long nextLong()
Return's next generated random 64-bit long value. Returned values are chosen randomly with (approximately) uniform distribution from range Long.MIN_VALUE to Long.MAX_VALUE.

Returns:
newly generated random long value in range [-9223372036854775808...9223372036854775807].
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.1 Integral Types and Values

nextLong

public final long nextLong(long n)
Return's next generated random long value drawn uniformly from 0 to n-1.

Suffice it to say, n must be > 0, or an IllegalArgumentException is raised.

Returns:
newly generated random int value in range [0...n-1].
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
IllegalArgumentException - if n < 0

nextDouble

public double nextDouble()
Return's next generated random 64-bit floating-point double value between 0.0 (inclusive) and 1.0 (exclusive). Returned values are chosen randomly with (approximately) uniform distribution greater than or equal to 0.0 and less than 1.0.

Returns:
newly generated random double value greater than or equal to 0.0 and less than 1.0..
Throws:
NonReadableChannelException - If this RBG was not opened for generation.
See Also:
JLS - 4.2.3 Floating-Point Types, Formats, and Values, Wikipedia - IEEE 754

nextHexString

public String nextHexString(int length)
Generates a random string of hex characters of specified length.

The generated string will be random, but not cryptographically secure. To generate cryptographically secure strings, use nextSecureHexString

Preconditions:

Parameters:
length - the length of the string to be generated
Returns:
random string of hex characters of length len
Throws:
IllegalArgumentException - if len < 0

newBuffer

protected ByteBuffer newBuffer(int bufferSize)
Returns new instance of ByteBuffer with specified capacity.

Called by buffered and reversed RBG to instantiate their internal buffers. Users can override this method to provide custom buffer creation.

The default implementations look's:

return bufferSize > BUFFER_LIMIT ? ByteBuffer.allocateDirect(bufferSize) : ByteBuffer.allocate(bufferSize);

where BUFFER_LIMIT is equal to 10 000 000 bytes.

Parameters:
bufferSize - size of new buffer
Returns:
the newly allocated buffer (not null).

asRandom

public Random asRandom()
Represents this RBG as java.util.Random. The java legacy code use java.util.Random as a main type for randomness. This method convert this RBG into java.util.Random instance, to be used instead it. For example:

BigInteger big = new BigInteger(128, Randomness.from(TRNG.NATIVE).asRandom());

Note: Calling of sedSeed(long) method has no effect.

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

Returns:
view as java.util.Random over RBG.
See Also:
Pseudorandomness.asRandom(), Cryptorandomness.asRandom()

mixing

public final Randomness mixing(Randomness... randomness)
Returns new RBG represents mixing of this RBG with specified RBG's sequence using default XOR mixing function.

The best overall strategy for obtaining unguessable random numbers is to obtain input from a number of uncorrelated sources and to mix them with a strong mixing function. Such a function will preserve the entropy present in any of the sources, even if other quantities being combined happen to be fixed or easily guessable (low entropy). This approach may be advisable even with a good hardware source, as hardware can also fail. However, this should be weighed against a possible increase in the chance of overall failure due to added software complexity.

When combining generators, it is important to understand what we do and we should be careful to examine the structure of the combination, not only of the quality of the components. By blindly combining two good components, it is indeed possible (and not too difficult) to obtain a bad (worst) RNG.

The mixing view is not a part of the RBG itself. The two mixing views of the same RBG is independent from each other, and the RBG become a shared resource among them.

This method may overridden to implements the strongest mixing functions.

Parameters:
randomness - a RBG sequence to be mixed
Returns:
mixing of RBG with XOR mixing function.
Throws:
IllegalArgumentException - if method calls without passing any randomness to mix.
See Also:
RFC 4086: Randomness Requirements for Security. Sections 5. Mixing, 5.1. A Trivial Mixing Function, p. 16-17

reversed

public final Randomness reversed(int windowSize)
Takes bytes generated by an underling Randomness and reverses the order in each small window of configurable size (byte-by-byte). The following example illustrate how reverse function is works:
 Randomness r = Pseudorandomness.from(PRNG.XOR_SHIFT);
 r = r.reversed(4); 
 r.read(ByteBuffer.allocate(8)); 

The window size is 4. Read operation twice fill window, and reverse it content while writing into buffer. So the following code will work in next manner:

 First window: [-66, -110, -46, -115]
 Second window: [50, 13, -46, 100]
 Final buffer content: [-115, -46, -110, -66, 100, -46, 13, 50]
 
The reversed view is not a part of the RBG itself. The two reversed views of the same RBG is independent from each other, and the RBG become a shared resource among them.

Parameters:
windowSize - - a window size in bytes
Returns:
Reversed Randomness.
Throws:
IllegalArgumentException - if windowSize < 0

shuffle

public final Randomness shuffle(Randomness that)
Shuffle uses one RBG to shuffle the output produced by another RBG to obliterate sequential correlations to produce non-linear output.

To initialize Shuffle, pass it two RBG's. The first RBG is used to generate a table of random output and the second is used to choose one from the table. The table size is determined by minlen value of shuffled RBG's.

The shuffle view is not a part of the RBG itself. The two shuffle views of the same RBG is independent from each other, and the RBG become a shared resource among them.

Parameters:
that - the RBG to shuffle with
Returns:
this