FileDocCategorySizeDatePackage
MD4Digest.javaAPI DocAzureus 3.0.3.47308Tue Jun 08 05:12:58 BST 2004org.bouncycastle.crypto.digests

MD4Digest

public class MD4Digest extends GeneralDigest
implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for Computer Science and RSA Data Security, Inc.

NOTE: This algorithm is only included for backwards compatability with legacy applications, it's not secure, don't use it for anything new!

Fields Summary
private static final int
DIGEST_LENGTH
private int
H1
private int
H2
private int
H3
private int
H4
private int[]
X
private int
xOff
private static final int
S11
private static final int
S12
private static final int
S13
private static final int
S14
private static final int
S21
private static final int
S22
private static final int
S23
private static final int
S24
private static final int
S31
private static final int
S32
private static final int
S33
private static final int
S34
Constructors Summary
public MD4Digest()
Standard constructor


	  	 
     
    
        reset();
    
public MD4Digest(MD4Digest t)
Copy constructor. This will copy the state of the provided message digest.

		super(t);

		H1 = t.H1;
		H2 = t.H2;
		H3 = t.H3;
		H4 = t.H4;

		System.arraycopy(t.X, 0, X, 0, t.X.length);
		xOff = t.xOff;
	
Methods Summary
private intF(int u, int v, int w)

        return (u & v) | (~u & w);
    
private intG(int u, int v, int w)

        return (u & v) | (u & w) | (v & w);
    
private intH(int u, int v, int w)

        return u ^ v ^ w;
    
public intdoFinal(byte[] out, int outOff)

        finish();

        unpackWord(H1, out, outOff);
        unpackWord(H2, out, outOff + 4);
        unpackWord(H3, out, outOff + 8);
        unpackWord(H4, out, outOff + 12);

        reset();

        return DIGEST_LENGTH;
    
public java.lang.StringgetAlgorithmName()

        return "MD4";
    
public intgetDigestSize()

        return DIGEST_LENGTH;
    
protected voidprocessBlock()

        int a = H1;
        int b = H2;
        int c = H3;
        int d = H4;

        //
        // Round 1 - F cycle, 16 times.
        //
        a = rotateLeft((a + F(b, c, d) + X[ 0]), S11);
        d = rotateLeft((d + F(a, b, c) + X[ 1]), S12);
        c = rotateLeft((c + F(d, a, b) + X[ 2]), S13);
        b = rotateLeft((b + F(c, d, a) + X[ 3]), S14);
        a = rotateLeft((a + F(b, c, d) + X[ 4]), S11);
        d = rotateLeft((d + F(a, b, c) + X[ 5]), S12);
        c = rotateLeft((c + F(d, a, b) + X[ 6]), S13);
        b = rotateLeft((b + F(c, d, a) + X[ 7]), S14);
        a = rotateLeft((a + F(b, c, d) + X[ 8]), S11);
        d = rotateLeft((d + F(a, b, c) + X[ 9]), S12);
        c = rotateLeft((c + F(d, a, b) + X[10]), S13);
        b = rotateLeft((b + F(c, d, a) + X[11]), S14);
        a = rotateLeft((a + F(b, c, d) + X[12]), S11);
        d = rotateLeft((d + F(a, b, c) + X[13]), S12);
        c = rotateLeft((c + F(d, a, b) + X[14]), S13);
        b = rotateLeft((b + F(c, d, a) + X[15]), S14);

        //
        // Round 2 - G cycle, 16 times.
        //
        a = rotateLeft((a + G(b, c, d) + X[ 0] + 0x5a827999), S21);
        d = rotateLeft((d + G(a, b, c) + X[ 4] + 0x5a827999), S22);
        c = rotateLeft((c + G(d, a, b) + X[ 8] + 0x5a827999), S23);
        b = rotateLeft((b + G(c, d, a) + X[12] + 0x5a827999), S24);
        a = rotateLeft((a + G(b, c, d) + X[ 1] + 0x5a827999), S21);
        d = rotateLeft((d + G(a, b, c) + X[ 5] + 0x5a827999), S22);
        c = rotateLeft((c + G(d, a, b) + X[ 9] + 0x5a827999), S23);
        b = rotateLeft((b + G(c, d, a) + X[13] + 0x5a827999), S24);
        a = rotateLeft((a + G(b, c, d) + X[ 2] + 0x5a827999), S21);
        d = rotateLeft((d + G(a, b, c) + X[ 6] + 0x5a827999), S22);
        c = rotateLeft((c + G(d, a, b) + X[10] + 0x5a827999), S23);
        b = rotateLeft((b + G(c, d, a) + X[14] + 0x5a827999), S24);
        a = rotateLeft((a + G(b, c, d) + X[ 3] + 0x5a827999), S21);
        d = rotateLeft((d + G(a, b, c) + X[ 7] + 0x5a827999), S22);
        c = rotateLeft((c + G(d, a, b) + X[11] + 0x5a827999), S23);
        b = rotateLeft((b + G(c, d, a) + X[15] + 0x5a827999), S24);

        //
        // Round 3 - H cycle, 16 times.
        //
        a = rotateLeft((a + H(b, c, d) + X[ 0] + 0x6ed9eba1), S31);
        d = rotateLeft((d + H(a, b, c) + X[ 8] + 0x6ed9eba1), S32);
        c = rotateLeft((c + H(d, a, b) + X[ 4] + 0x6ed9eba1), S33);
        b = rotateLeft((b + H(c, d, a) + X[12] + 0x6ed9eba1), S34);
        a = rotateLeft((a + H(b, c, d) + X[ 2] + 0x6ed9eba1), S31);
        d = rotateLeft((d + H(a, b, c) + X[10] + 0x6ed9eba1), S32);
        c = rotateLeft((c + H(d, a, b) + X[ 6] + 0x6ed9eba1), S33);
        b = rotateLeft((b + H(c, d, a) + X[14] + 0x6ed9eba1), S34);
        a = rotateLeft((a + H(b, c, d) + X[ 1] + 0x6ed9eba1), S31);
        d = rotateLeft((d + H(a, b, c) + X[ 9] + 0x6ed9eba1), S32);
        c = rotateLeft((c + H(d, a, b) + X[ 5] + 0x6ed9eba1), S33);
        b = rotateLeft((b + H(c, d, a) + X[13] + 0x6ed9eba1), S34);
        a = rotateLeft((a + H(b, c, d) + X[ 3] + 0x6ed9eba1), S31);
        d = rotateLeft((d + H(a, b, c) + X[11] + 0x6ed9eba1), S32);
        c = rotateLeft((c + H(d, a, b) + X[ 7] + 0x6ed9eba1), S33);
        b = rotateLeft((b + H(c, d, a) + X[15] + 0x6ed9eba1), S34);

        H1 += a;
        H2 += b;
        H3 += c;
        H4 += d;

        //
        // reset the offset and clean out the word buffer.
        //
        xOff = 0;
        for (int i = 0; i != X.length; i++)
        {
            X[i] = 0;
        }
    
protected voidprocessLength(long bitLength)

        if (xOff > 14)
        {
            processBlock();
        }

        X[14] = (int)(bitLength & 0xffffffff);
        X[15] = (int)(bitLength >>> 32);
    
protected voidprocessWord(byte[] in, int inOff)

        X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
            | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); 

        if (xOff == 16)
        {
            processBlock();
        }
    
public voidreset()
reset the chaining variables to the IV values.

        super.reset();

        H1 = 0x67452301;
        H2 = 0xefcdab89;
        H3 = 0x98badcfe;
        H4 = 0x10325476;

        xOff = 0;

        for (int i = 0; i != X.length; i++)
        {
            X[i] = 0;
        }
    
private introtateLeft(int x, int n)


    /*
     * rotate int x left n bits.
     */
      
         
         
    
        return (x << n) | (x >>> (32 - n));
    
private voidunpackWord(int word, byte[] out, int outOff)

        out[outOff]     = (byte)word;
        out[outOff + 1] = (byte)(word >>> 8);
        out[outOff + 2] = (byte)(word >>> 16);
        out[outOff + 3] = (byte)(word >>> 24);