1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.crypto.digests;
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Computer Science and RSA Data Security, Inc.
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>NOTE</b>: This algorithm is only included for backwards compatability
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with legacy applications, it's not secure, don't use it for anything new!
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class MD4Digest
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    extends GeneralDigest
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int    DIGEST_LENGTH = 16;
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int     H1, H2, H3, H4;         // IV's
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int[]   X = new int[16];
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int     xOff;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Standard constructor
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public MD4Digest()
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        reset();
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Copy constructor.  This will copy the state of the provided
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * message digest.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public MD4Digest(MD4Digest t)
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(t);
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H1 = t.H1;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H2 = t.H2;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H3 = t.H3;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H4 = t.H4;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(t.X, 0, X, 0, t.X.length);
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        xOff = t.xOff;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getAlgorithmName()
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return "MD4";
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getDigestSize()
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return DIGEST_LENGTH;
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void processWord(
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]  in,
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int     inOff)
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24);
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (xOff == 16)
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            processBlock();
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void processLength(
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long    bitLength)
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (xOff > 14)
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            processBlock();
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        X[14] = (int)(bitLength & 0xffffffff);
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        X[15] = (int)(bitLength >>> 32);
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void unpackWord(
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int     word,
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]  out,
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int     outOff)
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out[outOff]     = (byte)word;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out[outOff + 1] = (byte)(word >>> 8);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out[outOff + 2] = (byte)(word >>> 16);
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out[outOff + 3] = (byte)(word >>> 24);
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int doFinal(
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]  out,
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int     outOff)
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        finish();
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        unpackWord(H1, out, outOff);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        unpackWord(H2, out, outOff + 4);
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        unpackWord(H3, out, outOff + 8);
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        unpackWord(H4, out, outOff + 12);
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        reset();
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return DIGEST_LENGTH;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * reset the chaining variables to the IV values.
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void reset()
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.reset();
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H1 = 0x67452301;
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H2 = 0xefcdab89;
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H3 = 0x98badcfe;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H4 = 0x10325476;
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        xOff = 0;
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i != X.length; i++)
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            X[i] = 0;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // round 1 left rotates
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S11 = 3;
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S12 = 7;
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S13 = 11;
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S14 = 19;
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // round 2 left rotates
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S21 = 3;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S22 = 5;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S23 = 9;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S24 = 13;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // round 3 left rotates
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S31 = 3;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S32 = 9;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S33 = 11;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int S34 = 15;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * rotate int x left n bits.
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int rotateLeft(
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int x,
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int n)
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (x << n) | (x >>> (32 - n));
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * F, G, H and I are the basic MD4 functions.
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int F(
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int u,
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int v,
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int w)
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (u & v) | (~u & w);
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int G(
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int u,
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int v,
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int w)
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (u & v) | (u & w) | (v & w);
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int H(
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int u,
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int v,
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int w)
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return u ^ v ^ w;
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void processBlock()
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int a = H1;
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int b = H2;
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int c = H3;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int d = H4;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Round 1 - F cycle, 16 times.
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + F(b, c, d) + X[ 0], S11);
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + F(a, b, c) + X[ 1], S12);
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + F(d, a, b) + X[ 2], S13);
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + F(c, d, a) + X[ 3], S14);
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + F(b, c, d) + X[ 4], S11);
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + F(a, b, c) + X[ 5], S12);
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + F(d, a, b) + X[ 6], S13);
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + F(c, d, a) + X[ 7], S14);
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + F(b, c, d) + X[ 8], S11);
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + F(a, b, c) + X[ 9], S12);
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + F(d, a, b) + X[10], S13);
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + F(c, d, a) + X[11], S14);
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + F(b, c, d) + X[12], S11);
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + F(a, b, c) + X[13], S12);
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + F(d, a, b) + X[14], S13);
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + F(c, d, a) + X[15], S14);
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Round 2 - G cycle, 16 times.
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + G(b, c, d) + X[ 0] + 0x5a827999, S21);
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + G(a, b, c) + X[ 4] + 0x5a827999, S22);
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + G(d, a, b) + X[ 8] + 0x5a827999, S23);
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + G(c, d, a) + X[12] + 0x5a827999, S24);
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + G(b, c, d) + X[ 1] + 0x5a827999, S21);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + G(a, b, c) + X[ 5] + 0x5a827999, S22);
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + G(d, a, b) + X[ 9] + 0x5a827999, S23);
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + G(c, d, a) + X[13] + 0x5a827999, S24);
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + G(b, c, d) + X[ 2] + 0x5a827999, S21);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + G(a, b, c) + X[ 6] + 0x5a827999, S22);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + G(d, a, b) + X[10] + 0x5a827999, S23);
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + G(c, d, a) + X[14] + 0x5a827999, S24);
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + G(b, c, d) + X[ 3] + 0x5a827999, S21);
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + G(a, b, c) + X[ 7] + 0x5a827999, S22);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + G(d, a, b) + X[11] + 0x5a827999, S23);
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + G(c, d, a) + X[15] + 0x5a827999, S24);
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Round 3 - H cycle, 16 times.
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + H(b, c, d) + X[ 0] + 0x6ed9eba1, S31);
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x6ed9eba1, S32);
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + H(d, a, b) + X[ 4] + 0x6ed9eba1, S33);
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + H(c, d, a) + X[12] + 0x6ed9eba1, S34);
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + H(b, c, d) + X[ 2] + 0x6ed9eba1, S31);
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + H(a, b, c) + X[10] + 0x6ed9eba1, S32);
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + H(d, a, b) + X[ 6] + 0x6ed9eba1, S33);
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + H(c, d, a) + X[14] + 0x6ed9eba1, S34);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + H(b, c, d) + X[ 1] + 0x6ed9eba1, S31);
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + H(a, b, c) + X[ 9] + 0x6ed9eba1, S32);
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + H(d, a, b) + X[ 5] + 0x6ed9eba1, S33);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + H(c, d, a) + X[13] + 0x6ed9eba1, S34);
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        a = rotateLeft(a + H(b, c, d) + X[ 3] + 0x6ed9eba1, S31);
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        d = rotateLeft(d + H(a, b, c) + X[11] + 0x6ed9eba1, S32);
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        c = rotateLeft(c + H(d, a, b) + X[ 7] + 0x6ed9eba1, S33);
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        b = rotateLeft(b + H(c, d, a) + X[15] + 0x6ed9eba1, S34);
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H1 += a;
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H2 += b;
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H3 += c;
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        H4 += d;
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // reset the offset and clean out the word buffer.
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        xOff = 0;
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i != X.length; i++)
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            X[i] = 0;
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
271