Random Numbers
**************

The pseudo-random number generator (PRNG) classes of GNU Crypto are used to generate streams of cryptographically secure pseudo-random bytes.

  * ARCFOUR is an implementation of the ARCFOUR stream cipher's keystream generator. ARCFOUR is the name of a stream cipher that is believed to be compatible with RSA Data Security, Inc.'s RC4 stream cipher, and is a decendent of an algorithm that was posted anonymously to a mailing list in 1994.

  * ICM, or the Integer Counter Mode PRNG, is an algorithm that creates a PRNG around a block cipher. The default cipher used in this implementation is Rijndael, the AES. ICM is described in [McG01].

  * MD, or PRNGs based around a cryptographic hash function.

  * UMAC-KDF is a PRNG based on the UMAC key derivation function.

Figure 16: PRNG class diagram

The IRandom Interface
=====================

 -- Function: void init (java.util.Map ATTRIBUTES)
     Initializes this PRNG, preparing it for use. Throws an IllegalArgumentException if the given attributes are not appropriate for this PRNG algorithm.

 -- Function: byte nextByte () throws LimitReachedException
     Returns the next pseudo-random byte in this generator's sequence. Throws a LimitReachedException if this generator cannot produce any more bytes of any quality.

 -- Function: void nextBytes (byte[] OUT, int OFF, int LEN) throws LimitReachedException
     Fills the buffer OUT with the next LEN bytes in this generator's sequence, storing the bytes beginning at OFF. Throws a LimitReachedException if this generator cannot produce any more bytes of any quality.

 -- Function: java.lang.String name ()
     Returns the canonical name of this PRNG algorithm.

 -- Function: java.lang.Object clone ()
     Returns a copy of this instance. The copy will be in the exact same state as this instance, and will be independent of this instance.

The PRNGFactory Class
=====================

 -- Function: IRandom getInstance (java.lang.String NAME)
     Returns an instance of the named PRNG algorithm, or null if no such named algorithm exists.

 -- Function: java.util.Set names ()
     Returns a java.util.Set of the names (java.lang.String) of all available PRNG algorithms.

ARCFour
=======

The ARCFour keystream is implemented in the class ARCFour, which defines the following additional constant:

 -- Variable: java.lang.String ARCFOUR_KEY_MATERIAL
     A property name in the attributes map used to initialize instances of ARCFour. The value mapped must be a byte array of the secret key, which can be up to 256 bytes long.

Also note that using the ARCFour PRNG as a stream cipher is as simple as:

     IRandom arcfour; // initialized elsewhere.
     byte in, out;

     out = in ^ arcfour.next();

MDGenerator
===========

Generic message digest-based PRNGs are implemented via the MDGenerator class, which defines the following additional constants:

 -- Variable: java.lang.String MD_NAME
     A property name in the attributes map used to initialize instances of MDGenerator. The value mapped must be a String representing the name of the hash function to use, such as ``MD5''. If this attribute is omitted the secure hash algorithm, SHA-1, is used.

 -- Variable: java.lang.String SEEED
     A property name in the attributes map used to initialize instances of MDGenerator. The value mapped must be a byte array carrying the seed, with which to seed the PRNG. This attribute is optional.

ICMGenerator
============

The ICM generator accepts a number of additional parameters, all contained in the following constants of the ICMGenerator class. The appropriate values, including the limits of the integral types, are specific to the ICM generator algorithm.

 -- Variable: java.lang.String BLOCK_INDEX_LENGTH
     A property name in the attributes map used to initialize instances of ICMGenerator. The value mapped must be a java.lang.Integer.

 -- Variable: java.lang.String CIPHER
     A property name in the attributes map used to initialize instances of ICMGenerator. The value mapped must be a gnu.crypto.cipher.IBlockCipher, and is the underlying cipher used in the algorithm.

 -- Variable: java.lang.String OFFSET
     A property name in the attributes map used to initialize instances of ICMGenerator. The value mapped must be a java.math.BigInteger or a byte array of the same length of the underlying cipher's block size.

 -- Variable: java.lang.String SEGMENT_INDEX
     A property name in the attributes map used to initialize instances of ICMGenerator. The value mapped must be a java.math.BigInteger.

 -- Variable: java.lang.String SEGMENT_INDEX_LENGTH
     A property name in the attributes map used to initialize instances of ICMGenerator. The value mapped must be a java.lang.Integer.

UMacGenerator
=============

The UMac KDF generator accepts the following additional parameters, which are contained in the UMacGenerator class.

 -- Variable: java.lang.String CIPHER
     A property name in the attributes map used to initialize instances of UMacGenerator. The value mapped must be of type gnu.crypto.cipher.IBlockCipher.

 -- Variable: java.lang.String INDEX
     A property name in the attributes map used to initialize instances of UMacGenerator. The value mapped must be of type java.lang.Integer.

PRNG Example
============

     Map attrib = ...;
     IRandom rand = PRNGFactory.getInstance("MD");

     attrib.put(MDGenerator.MD_NAME, "MD5");
     attrib.put(MDGenerator.SEEED, seedBytes);

     random.init(attrib);

     for (int i = 0; i < bytes.length; i++)
        {
           in[i] ^= random.nextByte();
        }

     random.nextBytes(bytes, 0, bytes.length);