finished last of the compile errors
[org.ibex.crypto.git] / src / org / ibex / crypto / MD5.java
1 /* Copyright (c) 2000 The Legion Of The Bouncy Castle 
2  * (http://www.bouncycastle.org)
3  * 
4  * Permission is hereby granted, free of charge, to any person obtaining a 
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation 
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
8  * and/or sell copies of the Software, and to permit persons to whom the 
9  * Software is furnished to do so, subject to the following conditions:
10  * 
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  * 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
20  * DEALINGS IN THE SOFTWARE.
21  */
22
23 package org.ibex.crypto;
24
25 /**
26  * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
27  */
28 public class MD5
29     extends Digest
30 {
31     private static final int    DIGEST_LENGTH = 16;
32
33     private int     H1, H2, H3, H4;         // IV's
34
35     private int[]   X = new int[16];
36     private int     xOff;
37
38     /**
39      * Standard constructor
40      */
41     public MD5()
42     {
43         reset();
44     }
45
46     public int getDigestSize()
47     {
48         return DIGEST_LENGTH;
49     }
50
51     protected void processWord(
52         byte[]  in,
53         int     inOff)
54     {
55         X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
56             | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); 
57
58         if (xOff == 16)
59         {
60             processBlock();
61         }
62     }
63
64     protected void processLength(
65         long    bitLength)
66     {
67         if (xOff > 14)
68         {
69             processBlock();
70         }
71
72         X[14] = (int)(bitLength & 0xffffffff);
73         X[15] = (int)(bitLength >>> 32);
74     }
75
76     private void unpackWord(
77         int     word,
78         byte[]  out,
79         int     outOff)
80     {
81         out[outOff]     = (byte)word;
82         out[outOff + 1] = (byte)(word >>> 8);
83         out[outOff + 2] = (byte)(word >>> 16);
84         out[outOff + 3] = (byte)(word >>> 24);
85     }
86
87     public void doFinal(
88         byte[]  out,
89         int     outOff)
90     {
91         finish();
92
93         unpackWord(H1, out, outOff);
94         unpackWord(H2, out, outOff + 4);
95         unpackWord(H3, out, outOff + 8);
96         unpackWord(H4, out, outOff + 12);
97
98         reset();
99     }
100
101     /**
102      * reset the chaining variables to the IV values.
103      */
104     public void reset()
105     {
106         super.reset();
107
108         H1 = 0x67452301;
109         H2 = 0xefcdab89;
110         H3 = 0x98badcfe;
111         H4 = 0x10325476;
112
113         xOff = 0;
114
115         for (int i = 0; i != X.length; i++)
116         {
117             X[i] = 0;
118         }
119     }
120
121     /*
122      * rotate int x left n bits.
123      */
124     private int rotateLeft(
125         int x,
126         int n)
127     {
128         return (x << n) | (x >>> (32 - n));
129     }
130
131     /*
132      * F, G, H and I are the basic MD5 functions.
133      */
134     private int F(
135         int u,
136         int v,
137         int w)
138     {
139         return (u & v) | (~u & w);
140     }
141
142     private int G(
143         int u,
144         int v,
145         int w)
146     {
147         return (u & w) | (v & ~w);
148     }
149
150     private int H(
151         int u,
152         int v,
153         int w)
154     {
155         return u ^ v ^ w;
156     }
157
158     private int K(
159         int u,
160         int v,
161         int w)
162     {
163         return v ^ (u | ~w);
164     }
165
166     protected void processBlock()
167     {
168         int a = H1;
169         int b = H2;
170         int c = H3;
171         int d = H4;
172
173         //
174         // Round 1 - F cycle, 16 times.
175         //
176         a = rotateLeft((a + F(b, c, d) + X[ 0] + 0xd76aa478), 7) + b;
177         d = rotateLeft((d + F(a, b, c) + X[ 1] + 0xe8c7b756), 12) + a;
178         c = rotateLeft((c + F(d, a, b) + X[ 2] + 0x242070db), 17) + d;
179         b = rotateLeft((b + F(c, d, a) + X[ 3] + 0xc1bdceee), 22) + c;
180         a = rotateLeft((a + F(b, c, d) + X[ 4] + 0xf57c0faf), 7) + b;
181         d = rotateLeft((d + F(a, b, c) + X[ 5] + 0x4787c62a), 12) + a;
182         c = rotateLeft((c + F(d, a, b) + X[ 6] + 0xa8304613), 17) + d;
183         b = rotateLeft((b + F(c, d, a) + X[ 7] + 0xfd469501), 22) + c;
184         a = rotateLeft((a + F(b, c, d) + X[ 8] + 0x698098d8), 7) + b;
185         d = rotateLeft((d + F(a, b, c) + X[ 9] + 0x8b44f7af), 12) + a;
186         c = rotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), 17) + d;
187         b = rotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), 22) + c;
188         a = rotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), 7) + b;
189         d = rotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), 12) + a;
190         c = rotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), 17) + d;
191         b = rotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), 22) + c;
192
193         //
194         // Round 2 - G cycle, 16 times.
195         //
196         a = rotateLeft((a + G(b, c, d) + X[ 1] + 0xf61e2562), 5) + b;
197         d = rotateLeft((d + G(a, b, c) + X[ 6] + 0xc040b340), 9) + a;
198         c = rotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), 14) + d;
199         b = rotateLeft((b + G(c, d, a) + X[ 0] + 0xe9b6c7aa), 20) + c;
200         a = rotateLeft((a + G(b, c, d) + X[ 5] + 0xd62f105d), 5) + b;
201         d = rotateLeft((d + G(a, b, c) + X[10] + 0x02441453), 9) + a;
202         c = rotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), 14) + d;
203         b = rotateLeft((b + G(c, d, a) + X[ 4] + 0xe7d3fbc8), 20) + c;
204         a = rotateLeft((a + G(b, c, d) + X[ 9] + 0x21e1cde6), 5) + b;
205         d = rotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), 9) + a;
206         c = rotateLeft((c + G(d, a, b) + X[ 3] + 0xf4d50d87), 14) + d;
207         b = rotateLeft((b + G(c, d, a) + X[ 8] + 0x455a14ed), 20) + c;
208         a = rotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), 5) + b;
209         d = rotateLeft((d + G(a, b, c) + X[ 2] + 0xfcefa3f8), 9) + a;
210         c = rotateLeft((c + G(d, a, b) + X[ 7] + 0x676f02d9), 14) + d;
211         b = rotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20) + c;
212
213         //
214         // Round 3 - H cycle, 16 times.
215         //
216         a = rotateLeft((a + H(b, c, d) + X[ 5] + 0xfffa3942), 4) + b;
217         d = rotateLeft((d + H(a, b, c) + X[ 8] + 0x8771f681), 11) + a;
218         c = rotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), 16) + d;
219         b = rotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), 23) + c;
220         a = rotateLeft((a + H(b, c, d) + X[ 1] + 0xa4beea44), 4) + b;
221         d = rotateLeft((d + H(a, b, c) + X[ 4] + 0x4bdecfa9), 11) + a;
222         c = rotateLeft((c + H(d, a, b) + X[ 7] + 0xf6bb4b60), 16) + d;
223         b = rotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), 23) + c;
224         a = rotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), 4) + b;
225         d = rotateLeft((d + H(a, b, c) + X[ 0] + 0xeaa127fa), 11) + a;
226         c = rotateLeft((c + H(d, a, b) + X[ 3] + 0xd4ef3085), 16) + d;
227         b = rotateLeft((b + H(c, d, a) + X[ 6] + 0x04881d05), 23) + c;
228         a = rotateLeft((a + H(b, c, d) + X[ 9] + 0xd9d4d039), 4) + b;
229         d = rotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), 11) + a;
230         c = rotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16) + d;
231         b = rotateLeft((b + H(c, d, a) + X[ 2] + 0xc4ac5665), 23) + c;
232
233         //
234         // Round 4 - K cycle, 16 times.
235         //
236         a = rotateLeft((a + K(b, c, d) + X[ 0] + 0xf4292244), 6) + b;
237         d = rotateLeft((d + K(a, b, c) + X[ 7] + 0x432aff97), 10) + a;
238         c = rotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), 15) + d;
239         b = rotateLeft((b + K(c, d, a) + X[ 5] + 0xfc93a039), 21) + c;
240         a = rotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), 6) + b;
241         d = rotateLeft((d + K(a, b, c) + X[ 3] + 0x8f0ccc92), 10) + a;
242         c = rotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), 15) + d;
243         b = rotateLeft((b + K(c, d, a) + X[ 1] + 0x85845dd1), 21) + c;
244         a = rotateLeft((a + K(b, c, d) + X[ 8] + 0x6fa87e4f), 6) + b;
245         d = rotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), 10) + a;
246         c = rotateLeft((c + K(d, a, b) + X[ 6] + 0xa3014314), 15) + d;
247         b = rotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), 21) + c;
248         a = rotateLeft((a + K(b, c, d) + X[ 4] + 0xf7537e82), 6) + b;
249         d = rotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), 10) + a;
250         c = rotateLeft((c + K(d, a, b) + X[ 2] + 0x2ad7d2bb), 15) + d;
251         b = rotateLeft((b + K(c, d, a) + X[ 9] + 0xeb86d391), 21) + c;
252
253         H1 += a;
254         H2 += b;
255         H3 += c;
256         H4 += d;
257
258         //
259         // reset the offset and clean out the word buffer.
260         //
261         xOff = 0;
262         for (int i = 0; i != X.length; i++)
263         {
264             X[i] = 0;
265         }
266     }
267 }