KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > digests > MD5Digest


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.digests;
21
22 /**
23  * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
24  */

25 public class MD5Digest
26     extends GeneralDigest {
27   private static final int DIGEST_LENGTH = 16;
28
29   private int H1, H2, H3, H4; // IV's
30

31   private int[] X = new int[16];
32   private int xOff;
33
34   /**
35    * Standard constructor
36    */

37   public MD5Digest() {
38     reset();
39   }
40
41   /**
42    * Copy constructor. This will copy the state of the provided
43    * message digest.
44    */

45   public MD5Digest(MD5Digest t) {
46     super(t);
47
48     H1 = t.H1;
49     H2 = t.H2;
50     H3 = t.H3;
51     H4 = t.H4;
52
53     System.arraycopy(t.X, 0, X, 0, t.X.length);
54     xOff = t.xOff;
55   }
56
57   public String JavaDoc getAlgorithmName() {
58     return "MD5";
59   }
60
61   public int getDigestSize() {
62     return DIGEST_LENGTH;
63   }
64
65   protected void processWord(
66       byte[] in,
67       int inOff) {
68     X[xOff++] = (in[inOff] & 0xff) | ( (in[inOff + 1] & 0xff) << 8)
69         | ( (in[inOff + 2] & 0xff) << 16) | ( (in[inOff + 3] & 0xff) << 24);
70
71     if (xOff == 16) {
72       processBlock();
73     }
74   }
75
76   protected void processLength(
77       long bitLength) {
78     if (xOff > 14) {
79       processBlock();
80     }
81
82     X[14] = (int) (bitLength & 0xffffffff);
83     X[15] = (int) (bitLength >>> 32);
84   }
85
86   private void unpackWord(
87       int word,
88       byte[] out,
89       int outOff) {
90     out[outOff] = (byte) word;
91     out[outOff + 1] = (byte) (word >>> 8);
92     out[outOff + 2] = (byte) (word >>> 16);
93     out[outOff + 3] = (byte) (word >>> 24);
94   }
95
96   public int doFinal(
97       byte[] out,
98       int outOff) {
99     finish();
100
101     unpackWord(H1, out, outOff);
102     unpackWord(H2, out, outOff + 4);
103     unpackWord(H3, out, outOff + 8);
104     unpackWord(H4, out, outOff + 12);
105
106     reset();
107
108     return DIGEST_LENGTH;
109   }
110
111   /**
112    * reset the chaining variables to the IV values.
113    */

114   public void reset() {
115     super.reset();
116
117     H1 = 0x67452301;
118     H2 = 0xefcdab89;
119     H3 = 0x98badcfe;
120     H4 = 0x10325476;
121
122     xOff = 0;
123
124     for (int i = 0; i != X.length; i++) {
125       X[i] = 0;
126     }
127   }
128
129   //
130
// round 1 left rotates
131
//
132
private static final int S11 = 7;
133   private static final int S12 = 12;
134   private static final int S13 = 17;
135   private static final int S14 = 22;
136
137   //
138
// round 2 left rotates
139
//
140
private static final int S21 = 5;
141   private static final int S22 = 9;
142   private static final int S23 = 14;
143   private static final int S24 = 20;
144
145   //
146
// round 3 left rotates
147
//
148
private static final int S31 = 4;
149   private static final int S32 = 11;
150   private static final int S33 = 16;
151   private static final int S34 = 23;
152
153   //
154
// round 4 left rotates
155
//
156
private static final int S41 = 6;
157   private static final int S42 = 10;
158   private static final int S43 = 15;
159   private static final int S44 = 21;
160
161   /*
162    * rotate int x left n bits.
163    */

164   private int rotateLeft(
165       int x,
166       int n) {
167     return (x << n) | (x >>> (32 - n));
168   }
169
170   /*
171    * F, G, H and I are the basic MD5 functions.
172    */

173   private int F(
174       int u,
175       int v,
176       int w) {
177     return (u & v) | (~u & w);
178   }
179
180   private int G(
181       int u,
182       int v,
183       int w) {
184     return (u & w) | (v & ~w);
185   }
186
187   private int H(
188       int u,
189       int v,
190       int w) {
191     return u ^ v ^ w;
192   }
193
194   private int K(
195       int u,
196       int v,
197       int w) {
198     return v ^ (u | ~w);
199   }
200
201   protected void processBlock() {
202     int a = H1;
203     int b = H2;
204     int c = H3;
205     int d = H4;
206
207     //
208
// Round 1 - F cycle, 16 times.
209
//
210
a = rotateLeft( (a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b;
211     d = rotateLeft( (d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a;
212     c = rotateLeft( (c + F(d, a, b) + X[2] + 0x242070db), S13) + d;
213     b = rotateLeft( (b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c;
214     a = rotateLeft( (a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b;
215     d = rotateLeft( (d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a;
216     c = rotateLeft( (c + F(d, a, b) + X[6] + 0xa8304613), S13) + d;
217     b = rotateLeft( (b + F(c, d, a) + X[7] + 0xfd469501), S14) + c;
218     a = rotateLeft( (a + F(b, c, d) + X[8] + 0x698098d8), S11) + b;
219     d = rotateLeft( (d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a;
220     c = rotateLeft( (c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d;
221     b = rotateLeft( (b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c;
222     a = rotateLeft( (a + F(b, c, d) + X[12] + 0x6b901122), S11) + b;
223     d = rotateLeft( (d + F(a, b, c) + X[13] + 0xfd987193), S12) + a;
224     c = rotateLeft( (c + F(d, a, b) + X[14] + 0xa679438e), S13) + d;
225     b = rotateLeft( (b + F(c, d, a) + X[15] + 0x49b40821), S14) + c;
226
227     //
228
// Round 2 - G cycle, 16 times.
229
//
230
a = rotateLeft( (a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b;
231     d = rotateLeft( (d + G(a, b, c) + X[6] + 0xc040b340), S22) + a;
232     c = rotateLeft( (c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d;
233     b = rotateLeft( (b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c;
234     a = rotateLeft( (a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b;
235     d = rotateLeft( (d + G(a, b, c) + X[10] + 0x02441453), S22) + a;
236     c = rotateLeft( (c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d;
237     b = rotateLeft( (b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c;
238     a = rotateLeft( (a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b;
239     d = rotateLeft( (d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a;
240     c = rotateLeft( (c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d;
241     b = rotateLeft( (b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c;
242     a = rotateLeft( (a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b;
243     d = rotateLeft( (d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a;
244     c = rotateLeft( (c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d;
245     b = rotateLeft( (b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c;
246
247     //
248
// Round 3 - H cycle, 16 times.
249
//
250
a = rotateLeft( (a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b;
251     d = rotateLeft( (d + H(a, b, c) + X[8] + 0x8771f681), S32) + a;
252     c = rotateLeft( (c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d;
253     b = rotateLeft( (b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c;
254     a = rotateLeft( (a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b;
255     d = rotateLeft( (d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a;
256     c = rotateLeft( (c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d;
257     b = rotateLeft( (b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c;
258     a = rotateLeft( (a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b;
259     d = rotateLeft( (d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a;
260     c = rotateLeft( (c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d;
261     b = rotateLeft( (b + H(c, d, a) + X[6] + 0x04881d05), S34) + c;
262     a = rotateLeft( (a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b;
263     d = rotateLeft( (d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a;
264     c = rotateLeft( (c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d;
265     b = rotateLeft( (b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c;
266
267     //
268
// Round 4 - K cycle, 16 times.
269
//
270
a = rotateLeft( (a + K(b, c, d) + X[0] + 0xf4292244), S41) + b;
271     d = rotateLeft( (d + K(a, b, c) + X[7] + 0x432aff97), S42) + a;
272     c = rotateLeft( (c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d;
273     b = rotateLeft( (b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c;
274     a = rotateLeft( (a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b;
275     d = rotateLeft( (d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a;
276     c = rotateLeft( (c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d;
277     b = rotateLeft( (b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c;
278     a = rotateLeft( (a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b;
279     d = rotateLeft( (d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a;
280     c = rotateLeft( (c + K(d, a, b) + X[6] + 0xa3014314), S43) + d;
281     b = rotateLeft( (b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c;
282     a = rotateLeft( (a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b;
283     d = rotateLeft( (d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a;
284     c = rotateLeft( (c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d;
285     b = rotateLeft( (b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c;
286
287     H1 += a;
288     H2 += b;
289     H3 += c;
290     H4 += d;
291
292     //
293
// reset the offset and clean out the word buffer.
294
//
295
xOff = 0;
296     for (int i = 0; i != X.length; i++) {
297       X[i] = 0;
298     }
299   }
300 }
301
Popular Tags