FileDocCategorySizeDatePackage
PRand.javaAPI DocphoneME MR2 API (J2ME)4764Wed May 02 18:00:26 BST 2007com.sun.midp.crypto

PRand

public final class PRand extends SecureRandom
Implements a pseudo random number generator.

Fields Summary
private static MessageDigest
md
Local handle to message digest.
private static byte[]
seed
For an arbitrary choice of the default seed, we use bits from the binary expansion of pi.

This seed is just an example implementation and NOT considered for used in SECURE (unpredicable) protocols, for this class to be considered a secure source of random data the seed MUST be derived from unpredicatable data in a production device at the native level. (see IETF RFC 1750, Randomness Recommendations for Security, http://www.ietf.org/rfc/rfc1750.txt)

private static byte[]
randomBytes
buffer of random bytes
private static int
bytesAvailable
number of random bytes currently available
Constructors Summary
public PRand()
Constructor for random data.

    
         
      
	if (md != null) 
	    return;
	
	try {
	    md = MessageDigest.getInstance("MD5");
	} catch (Exception e) {
	    throw new RuntimeException("MD5 missing");
	}

	randomBytes = new byte[seed.length];
	updateSeed();
    
Methods Summary
public voidnextBytes(byte[] b, int off, int len)
This does a reasonable job of producing unpredictable random data by using a one way hash as a mixing function and the current time in milliseconds as a source of entropy.

param
b buffer of input data
param
off offset into the provided buffer
param
len length of the data to be processed

	synchronized (md) {
	    int i = 0;
	    
	    while (true) {
		// see if we need to buffer more random bytes
		if (bytesAvailable == 0) {
		    md.update(seed, 0, seed.length);
                    try {
                        md.digest(randomBytes, 0, randomBytes.length);
                    } catch (DigestException de) {
                        // nothing to do
                    }

		    updateSeed();
		    bytesAvailable = randomBytes.length;
		}
		
		// hand out some of the random bytes from the buffer
		while (bytesAvailable > 0) {
		    if (i == len)
			return;
		    b[off + i] = randomBytes[--bytesAvailable];
		    i++;
		}
	    }
	}
    
public voidsetSeed(byte[] b, int off, int len)
Set the random number seed.

param
b initial data to use as the seed
param
off offset into the provided buffer
param
len length of the data to be used

	int j = 0;

	if ((len <= 0) || (b.length < (off + len)))
	    return;
	for (int i = 0; i < seed.length; i++, j++) {
	    if (j == len) j = 0;
	    seed[i] = b[off + j];
	}
    
private voidupdateSeed()
This does a reasonable job of producing unpredictable random data by using a one way hash as a mixing function and the current time in milliseconds as a source of entropy for the seed. This method assumes the original seed data is unpredicatble.

	long t = System.currentTimeMillis();
	byte[] tmp = new byte[8];
	
	// Convert the long value into a byte array
	for (int i = 0; i < 8; i++) {
	    tmp[i] = (byte) (t & 0xff);
	    t = (t >>> 8);
	}
	
	md.update(seed, 0, seed.length);
	md.update(tmp, 0, tmp.length);
        try {
            md.digest(seed, 0, seed.length);
        } catch (DigestException de) {
            // nothing to do
        }