Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mindbright/security/MD5.java


1   /******************************************************************************
2    *
3    * Copyright (c) 1998-2000 by Mindbright Technology AB, Stockholm, Sweden.
4    *                 www.mindbright.se, info@mindbright.se
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation; either version 2 of the License, or
9    * (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   *****************************************************************************
17   * $Author: nallen $
18   * $Date: 2001/11/12 16:31:15 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.security;
22  
23  public final class MD5 extends MessageDigest implements Cloneable {
24      private int[]  x;
25      private long   count;
26      private int    rest;
27      int[]  hash;
28      byte[] buffer;
29  
30      static byte padding[] = {
31          (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
34      };
35  
36      private static int rotateLeft (int x, int n) {
37    return (x << n) | (x >>> (32 - n));
38      }
39  
40      private static int FF(int a, int b, int c, int d, int x, int s, int ac) {
41    a = a + (((c ^ d) & b) ^ d) + x + ac;
42    return rotateLeft(a, s) + b;
43      }
44  
45      private static int GG(int a, int b, int c, int d, int x, int s, int ac) {
46    a = a + (((b ^ c) & d) ^ c) + x + ac;
47    return rotateLeft(a, s) + b;
48      }
49  
50      private static int HH(int a, int b, int c, int d, int x, int s, int ac) {
51    a = a + (b ^ c ^ d) + x + ac;
52    return rotateLeft(a, s) + b;
53      }
54  
55      private static int II(int a, int b, int c, int d, int x, int s, int ac) {
56    a = a + (c ^ (b | ~d)) + x + ac;
57    return rotateLeft(a, s) + b;
58      }
59  
60      void transform(byte data[], int offset) {
61    int a = hash[0];
62    int b = hash[1];
63    int c = hash[2];
64    int d = hash[3];
65  
66    int i;
67    for (i = 0; i < 16; i++) {
68        x[i] =
69      ((int)  (data[offset++] & 0xff))        |
70      (((int) (data[offset++] & 0xff)) << 8)  |
71      (((int) (data[offset++] & 0xff)) << 16) |
72      (((int) (data[offset++] & 0xff)) << 24);
73    }
74  
75    // Round 1 
76    a = FF (a, b, c, d, x[ 0],   7, 0xd76aa478); // 1
77    d = FF (d, a, b, c, x[ 1],  12, 0xe8c7b756); // 2
78    c = FF (c, d, a, b, x[ 2],  17, 0x242070db); // 3
79    b = FF (b, c, d, a, x[ 3],  22, 0xc1bdceee); // 4
80    a = FF (a, b, c, d, x[ 4],   7, 0xf57c0faf); // 5
81    d = FF (d, a, b, c, x[ 5],  12, 0x4787c62a); // 6
82    c = FF (c, d, a, b, x[ 6],  17, 0xa8304613); // 7
83    b = FF (b, c, d, a, x[ 7],  22, 0xfd469501); // 8
84    a = FF (a, b, c, d, x[ 8],   7, 0x698098d8); // 9
85    d = FF (d, a, b, c, x[ 9],  12, 0x8b44f7af); // 10
86    c = FF (c, d, a, b, x[10],  17, 0xffff5bb1); // 11
87    b = FF (b, c, d, a, x[11],  22, 0x895cd7be); // 12
88    a = FF (a, b, c, d, x[12],   7, 0x6b901122); // 13
89    d = FF (d, a, b, c, x[13],  12, 0xfd987193); // 14
90    c = FF (c, d, a, b, x[14],  17, 0xa679438e); // 15
91    b = FF (b, c, d, a, x[15],  22, 0x49b40821); // 16
92  
93    // Round 2 
94    a = GG (a, b, c, d, x[ 1],   5, 0xf61e2562); // 17
95    d = GG (d, a, b, c, x[ 6],   9, 0xc040b340); // 18
96    c = GG (c, d, a, b, x[11],  14, 0x265e5a51); // 19
97    b = GG (b, c, d, a, x[ 0],  20, 0xe9b6c7aa); // 20
98    a = GG (a, b, c, d, x[ 5],   5, 0xd62f105d); // 21
99    d = GG (d, a, b, c, x[10],   9,  0x2441453); // 22
100   c = GG (c, d, a, b, x[15],  14, 0xd8a1e681); // 23
101   b = GG (b, c, d, a, x[ 4],  20, 0xe7d3fbc8); // 24
102   a = GG (a, b, c, d, x[ 9],   5, 0x21e1cde6); // 25
103   d = GG (d, a, b, c, x[14],   9, 0xc33707d6); // 26
104   c = GG (c, d, a, b, x[ 3],  14, 0xf4d50d87); // 27
105   b = GG (b, c, d, a, x[ 8],  20, 0x455a14ed); // 28
106   a = GG (a, b, c, d, x[13],   5, 0xa9e3e905); // 29
107   d = GG (d, a, b, c, x[ 2],   9, 0xfcefa3f8); // 30
108   c = GG (c, d, a, b, x[ 7],  14, 0x676f02d9); // 31
109   b = GG (b, c, d, a, x[12],  20, 0x8d2a4c8a); // 32
110 
111             // Round 3 
112   a = HH (a, b, c, d, x[ 5],   4, 0xfffa3942); // 33
113   d = HH (d, a, b, c, x[ 8],  11, 0x8771f681); // 34
114   c = HH (c, d, a, b, x[11],  16, 0x6d9d6122); // 35
115   b = HH (b, c, d, a, x[14],  23, 0xfde5380c); // 36
116   a = HH (a, b, c, d, x[ 1],   4, 0xa4beea44); // 37
117   d = HH (d, a, b, c, x[ 4],  11, 0x4bdecfa9); // 38
118   c = HH (c, d, a, b, x[ 7],  16, 0xf6bb4b60); // 39
119   b = HH (b, c, d, a, x[10],  23, 0xbebfbc70); // 40
120   a = HH (a, b, c, d, x[13],   4, 0x289b7ec6); // 41
121   d = HH (d, a, b, c, x[ 0],  11, 0xeaa127fa); // 42
122   c = HH (c, d, a, b, x[ 3],  16, 0xd4ef3085); // 43
123   b = HH (b, c, d, a, x[ 6],  23,  0x4881d05); // 44
124   a = HH (a, b, c, d, x[ 9],   4, 0xd9d4d039); // 45
125   d = HH (d, a, b, c, x[12],  11, 0xe6db99e5); // 46
126   c = HH (c, d, a, b, x[15],  16, 0x1fa27cf8); // 47
127   b = HH (b, c, d, a, x[ 2],  23, 0xc4ac5665); // 48
128 
129             // Round 4 
130   a = II (a, b, c, d, x[ 0],   6, 0xf4292244); // 49
131   d = II (d, a, b, c, x[ 7],  10, 0x432aff97); // 50
132   c = II (c, d, a, b, x[14],  15, 0xab9423a7); // 51
133   b = II (b, c, d, a, x[ 5],  21, 0xfc93a039); // 52
134   a = II (a, b, c, d, x[12],   6, 0x655b59c3); // 53
135   d = II (d, a, b, c, x[ 3],  10, 0x8f0ccc92); // 54
136   c = II (c, d, a, b, x[10],  15, 0xffeff47d); // 55
137   b = II (b, c, d, a, x[ 1],  21, 0x85845dd1); // 56
138   a = II (a, b, c, d, x[ 8],   6, 0x6fa87e4f); // 57
139   d = II (d, a, b, c, x[15],  10, 0xfe2ce6e0); // 58
140   c = II (c, d, a, b, x[ 6],  15, 0xa3014314); // 59
141   b = II (b, c, d, a, x[13],  21, 0x4e0811a1); // 60
142   a = II (a, b, c, d, x[ 4],   6, 0xf7537e82); // 61
143   d = II (d, a, b, c, x[11],  10, 0xbd3af235); // 62
144   c = II (c, d, a, b, x[ 2],  15, 0x2ad7d2bb); // 63
145   b = II (b, c, d, a, x[ 9],  21, 0xeb86d391); // 64
146 
147   hash[0] += a;
148   hash[1] += b;
149   hash[2] += c;
150   hash[3] += d;
151     }
152 
153     public MD5() {
154   buffer = new byte[64];
155   hash   = new int[4];
156   x      = new int[16];
157   reset();
158     }
159 
160     private MD5(MD5 c) {
161   buffer = new byte[64];
162   hash   = new int[4];
163   x      = new int[16];
164   System.arraycopy(c.hash, 0, hash, 0, 4);
165   System.arraycopy(c.buffer, 0, buffer, 0, 64);
166   count = c.count;
167   rest  = c.rest;
168     }
169 
170     public Object clone() {
171   return new MD5(this);
172     }
173 
174     public String getName() {
175         return "MD5";
176     }
177 
178     public void reset() {
179   hash[0] = 0x67452301;
180   hash[1] = 0xefcdab89;
181   hash[2] = 0x98badcfe;
182   hash[3] = 0x10325476;
183   count   = 0;
184         rest    = 0;
185     }
186 
187     public void update(byte[] data, int offset, int length) {
188         int left = 64 - rest;
189 
190         count += length;
191 
192   if(rest > 0 && length >= left) {
193       System.arraycopy(data, offset, buffer, rest, left);
194       transform(buffer, 0);
195       offset += left;
196       length -= left;
197       rest   =  0;
198   }
199 
200   while(length > 63) {
201       transform(data, offset);
202       offset += 64;
203       length -= 64;
204   }
205 
206   if(length > 0) {
207       System.arraycopy(data, offset, buffer, rest, length);
208       rest += length;
209   }
210     }
211 
212     public byte[] digest() {
213   byte[] buf = new byte[16];
214   digestInto(buf, 0);
215         return buf;
216     }
217 
218     public int digestInto(byte[] dest, int destOff) {
219   int padlen = (rest < 56) ? (56 - rest) : (120 - rest);
220 
221   count *= 8;
222   byte[] countBytes = {
223       (byte)(count),
224       (byte)(count >>>  8),
225       (byte)(count >>> 16),
226       (byte)(count >>> 24),
227       (byte)(count >>> 32),
228       (byte)(count >>> 40),
229       (byte)(count >>> 58),
230       (byte)(count >>> 56)
231   };
232 
233   update(padding, 0, padlen);
234   update(countBytes, 0, 8);
235 
236         int i;
237         for (i = 0; i < 4; i++) {
238             dest[destOff++] = (byte) (hash[i] & 0xff);
239             dest[destOff++] = (byte)((hash[i] >>> 8) & 0xff);
240             dest[destOff++] = (byte)((hash[i] >>> 16) & 0xff);
241             dest[destOff++] = (byte)((hash[i] >>> 24) & 0xff);
242         }
243 
244   reset();
245   return 16;
246     }
247 
248     public int blockSize() {
249         return 64;
250     }
251 
252     public int hashSize() {
253         return 16;
254     }
255 }