1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.digests;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.util.Pack;
4a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstromimport org.bouncycastle.util.Memoable;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
10a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom * is the "endianness" of the word processing!
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class SHA1Digest
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    extends GeneralDigest
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final int    DIGEST_LENGTH = 20;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int     H1, H2, H3, H4, H5;
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int[]   X = new int[80];
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int     xOff;
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Standard constructor
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public SHA1Digest()
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        reset();
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Copy constructor.  This will copy the state of the provided
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * message digest.
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public SHA1Digest(SHA1Digest t)
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        super(t);
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
38a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        copyIn(t);
39a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    }
40a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
41a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    private void copyIn(SHA1Digest t)
42a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    {
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H1 = t.H1;
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H2 = t.H2;
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H3 = t.H3;
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H4 = t.H4;
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H5 = t.H5;
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        System.arraycopy(t.X, 0, X, 0, t.X.length);
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        xOff = t.xOff;
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getAlgorithmName()
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "SHA-1";
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getDigestSize()
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return DIGEST_LENGTH;
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected void processWord(
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  in,
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     inOff)
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // Note: Inlined for performance
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//        X[xOff] = Pack.bigEndianToInt(in, inOff);
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int n = in[  inOff] << 24;
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        n |= (in[++inOff] & 0xff) << 16;
71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        n |= (in[++inOff] & 0xff) << 8;
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        n |= (in[++inOff] & 0xff);
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        X[xOff] = n;
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (++xOff == 16)
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            processBlock();
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected void processLength(
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        long    bitLength)
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (xOff > 14)
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            processBlock();
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X[14] = (int)(bitLength >>> 32);
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X[15] = (int)(bitLength & 0xffffffff);
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int doFinal(
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  out,
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     outOff)
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        finish();
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Pack.intToBigEndian(H1, out, outOff);
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Pack.intToBigEndian(H2, out, outOff + 4);
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Pack.intToBigEndian(H3, out, outOff + 8);
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Pack.intToBigEndian(H4, out, outOff + 12);
103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Pack.intToBigEndian(H5, out, outOff + 16);
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        reset();
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return DIGEST_LENGTH;
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * reset the chaining variables
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void reset()
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        super.reset();
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H1 = 0x67452301;
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H2 = 0xefcdab89;
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H3 = 0x98badcfe;
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H4 = 0x10325476;
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H5 = 0xc3d2e1f0;
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        xOff = 0;
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != X.length; i++)
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            X[i] = 0;
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    //
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    // Additive constants
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    //
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final int    Y1 = 0x5a827999;
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final int    Y2 = 0x6ed9eba1;
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final int    Y3 = 0x8f1bbcdc;
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final int    Y4 = 0xca62c1d6;
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int f(
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    u,
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    v,
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    w)
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return ((u & v) | ((~u) & w));
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int h(
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    u,
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    v,
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    w)
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return (u ^ v ^ w);
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int g(
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    u,
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    v,
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int    w)
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return ((u & v) | (u & w) | (v & w));
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected void processBlock()
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // expand 16 word block into 80 word block.
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 16; i < 80; i++)
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            int t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            X[i] = t << 1 | t >>> 31;
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // set up working variables.
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     A = H1;
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     B = H2;
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     C = H3;
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     D = H4;
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     E = H5;
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // round 1
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int idx = 0;
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int j = 0; j < 4; j++)
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // E = rotateLeft(A, 5) + f(B, C, D) + E + X[idx++] + Y1
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // B = rotateLeft(B, 30)
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E += (A << 5 | A >>> 27) + f(B, C, D) + X[idx++] + Y1;
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B = B << 30 | B >>> 2;
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D += (E << 5 | E >>> 27) + f(A, B, C) + X[idx++] + Y1;
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A = A << 30 | A >>> 2;
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C += (D << 5 | D >>> 27) + f(E, A, B) + X[idx++] + Y1;
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E = E << 30 | E >>> 2;
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B += (C << 5 | C >>> 27) + f(D, E, A) + X[idx++] + Y1;
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D = D << 30 | D >>> 2;
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A += (B << 5 | B >>> 27) + f(C, D, E) + X[idx++] + Y1;
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C = C << 30 | C >>> 2;
205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // round 2
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int j = 0; j < 4; j++)
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y2
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // B = rotateLeft(B, 30)
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y2;
215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B = B << 30 | B >>> 2;
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y2;
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A = A << 30 | A >>> 2;
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y2;
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E = E << 30 | E >>> 2;
222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y2;
224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D = D << 30 | D >>> 2;
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y2;
227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C = C << 30 | C >>> 2;
228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // round 3
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int j = 0; j < 4; j++)
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // E = rotateLeft(A, 5) + g(B, C, D) + E + X[idx++] + Y3
236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // B = rotateLeft(B, 30)
237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E += (A << 5 | A >>> 27) + g(B, C, D) + X[idx++] + Y3;
238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B = B << 30 | B >>> 2;
239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D += (E << 5 | E >>> 27) + g(A, B, C) + X[idx++] + Y3;
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A = A << 30 | A >>> 2;
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C += (D << 5 | D >>> 27) + g(E, A, B) + X[idx++] + Y3;
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E = E << 30 | E >>> 2;
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B += (C << 5 | C >>> 27) + g(D, E, A) + X[idx++] + Y3;
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D = D << 30 | D >>> 2;
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A += (B << 5 | B >>> 27) + g(C, D, E) + X[idx++] + Y3;
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C = C << 30 | C >>> 2;
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // round 4
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int j = 0; j <= 3; j++)
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y4
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // B = rotateLeft(B, 30)
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y4;
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B = B << 30 | B >>> 2;
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y4;
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A = A << 30 | A >>> 2;
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y4;
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            E = E << 30 | E >>> 2;
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y4;
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D = D << 30 | D >>> 2;
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y4;
273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            C = C << 30 | C >>> 2;
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H1 += A;
278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H2 += B;
279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H3 += C;
280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H4 += D;
281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        H5 += E;
282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // reset start of the buffer.
285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        xOff = 0;
287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i < 16; i++)
288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            X[i] = 0;
290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
292a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
293a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    public Memoable copy()
294a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    {
295a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        return new SHA1Digest(this);
296a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    }
297a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
298a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    public void reset(Memoable other)
299a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    {
300a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        SHA1Digest d = (SHA1Digest)other;
301a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom
302a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        super.copyIn(d);
303a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        copyIn(d);
304a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom    }
305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
310