5776623 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$ cat -n MD5.java
  1 /* MD5.java -- Class implementing the MD5 algorithm as specified in RFC1321.
  2    Copyright (C) 1999, 2002 Free Software Foundation, Inc.
  3    The file was changed by Radek Polak to work as midlet in MIDP 1.0
  4 
  5 This file is part of GNU Classpath.
  6 
  7 GNU Classpath is free software; you can redistribute it and/or modify
  8 it under the terms of the GNU General Public License as published by
  9 the Free Software Foundation; either version 2, or (at your option)
 10 any later version.
 11 
 12 GNU Classpath is distributed in the hope that it will be useful, but
 13 WITHOUT ANY WARRANTY; without even the implied warranty of
 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15 General Public License for more details.
 16 
 17 You should have received a copy of the GNU General Public License
 18 along with GNU Classpath; see the file COPYING.  If not, write to the
 19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 20 02111-1307 USA.
 21 
 22 Linking this library statically or dynamically with other modules is
 23 making a combined work based on this library.  Thus, the terms and
 24 conditions of the GNU General Public License cover the whole
 25 combination.
 26 
 27 As a special exception, the copyright holders of this library give you
 28 permission to link this library with independent modules to produce an
 29 executable, regardless of the license terms of these independent
 30 modules, and to copy and distribute the resulting executable under
 31 terms of your choice, provided that you also meet, for each linked
 32 independent module, the terms and conditions of the license of that
 33 module.  An independent module is a module which is not derived from
 34 or based on this library.  If you modify this library, you may extend
 35 this exception to your version of the library, but you are not
 36 obligated to do so.  If you do not wish to do so, delete this
 37 exception statement from your version. */
 38 
 39 
 40 package ssh;
 41 
 42 /**
 43    This class implements the MD5 algorithm as described in RFC1321.
 44 
 45    @see java.security.MessageDigest
 46 */
 47 public class MD5
 48 {
 49   private final int W[] = new int[16];
 50   private long bytecount;
 51   private int A;
 52   private int B;
 53   private int C;
 54   private int D;
 55 
 56   public MD5()
 57   {
 58     super();
 59     engineReset ();
 60   }
 61 
 62   // Intialize the A,B,C,D needed for the hash
 63   public void engineReset()
 64   {
 65     bytecount = 0;
 66     A = 0x67452301;
 67     B = 0xefcdab89;
 68     C = 0x98badcfe;
 69     D = 0x10325476;
 70     for(int i = 0; i < 16; i++)
 71       W[i] = 0;
 72   }
 73 
 74   public void update (byte b)
 75   {
 76     int i = (int)bytecount % 64;
 77     int shift = (3 - i % 4) * 8;
 78     int idx = i / 4;
 79 
 80     // if you could index ints, this would be: W[idx][shift/8] = b
 81     W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift);
 82 
 83     // if we've filled up a block, then process it
 84     if ((++ bytecount) % 64 == 0)
 85       munch ();
 86   }
 87 
 88   public void update(byte[] input)
 89   {
 90     update(input, 0, input.length);
 91   }
 92 
 93   public void update (byte bytes[], int off, int len)
 94   {
 95     if (len < 0)
 96       throw new ArrayIndexOutOfBoundsException ();
 97 
 98     int end = off + len;
 99     while (off < end)
100       update (bytes[off++]);
101   }
102 
103   public byte[] digest(byte[] input)
104   {
105     update(input);
106     return digest();
107   }
108 
109   public byte[] digest()
110   {
111     long bitcount = bytecount * 8;
112     update ((byte)0x80); // 10000000 in binary; the start of the padding
113 
114     // add the rest of the padding to fill this block out, but leave 8
115     // bytes to put in the original bytecount
116     while ((int)bytecount % 64 != 56)
117       update ((byte)0);
118 
119     // add the length of the original, unpadded block to the end of
120     // the padding
121     W[14] = SWAP((int)(0xffffffff & bitcount));
122     W[15] = SWAP((int)(0xffffffff & (bitcount >>> 32)));
123     bytecount += 8;
124 
125     // digest the fully padded block
126     munch ();
127 
128     A = SWAP(A);
129     B = SWAP(B);
130     C = SWAP(C);
131     D = SWAP(D);
132     byte[] result = new byte[] {(byte)(A >>> 24), (byte)(A >>> 16),
133                 (byte)(A >>> 8), (byte)A,
134                 (byte)(B >>> 24), (byte)(B >>> 16),
135                 (byte)(B >>> 8), (byte)B,
136                 (byte)(C >>> 24), (byte)(C >>> 16),
137                 (byte)(C >>> 8), (byte)C,
138                 (byte)(D >>> 24), (byte)(D >>> 16),
139                 (byte)(D >>> 8), (byte)D};
140 
141     engineReset ();
142     return result;
143   }
144 
145   private int F( int X, int Y, int Z)
146   {
147     return ((X & Y) | (~X & Z));
148   }
149 
150   private int G( int X, int Y, int Z)
151   {
152     return ((X & Z) | (Y & ~Z));
153   }
154 
155   private int H( int X, int Y, int Z)
156   {
157     return (X ^ Y ^ Z);
158   }
159 
160   private int I( int X, int Y, int Z)
161   {
162     return (Y ^ (X | ~Z));
163   }
164 
165   private int rotateLeft( int i, int count)
166   {
167     //Taken from FIPS 180-1
168     return ( (i << count) | (i >>> (32 - count)) ) ;
169   }
170 
171   /* Round 1. */
172   private int FF( int a, int b, int c, int d, int k, int s, int i)
173   {
174     /* Let [abcd k s i] denote the operation */
175     a += F(b,c,d) + k + i;
176     return b + rotateLeft(a, s);
177   }
178   /* Round 2. */
179   private int GG( int a, int b, int c, int d, int k, int s, int i)
180   {
181     /* Let [abcd k s i] denote the operation */
182     a += G(b,c,d) + k + i;
183     return b + rotateLeft(a, s);
184   }
185   /* Round 3. */
186   private int HH( int a, int b, int c, int d, int k, int s, int i)
187   {
188     /* Let [abcd k s t] denote the operation */
189     a += H(b,c,d) + k + i;
190     return b + rotateLeft(a, s);
191   }
192 
193   /* Round 4. */
194   private int II( int a, int b, int c, int d, int k, int s, int i)
195   {
196     /* Let [abcd k s t] denote the operation */
197     a += I(b,c,d) + k + i;
198     return b + rotateLeft(a, s);
199   }
200 
201   private int SWAP(int n)
202   {
203     //Copied from md5.c in FSF Gnu Privacy Guard 0.9.2
204     return (( (0xff & n) << 24) | ((n & 0xff00) << 8) | ((n >>> 8) & 0xff00) | (n >>> 24));
205   }
206 
207   private void munch()
208   {
209     int AA,BB,CC,DD, j;
210     int X[] = new int[16];
211 
212     /* Copy block i into X. */
213     for(j = 0; j < 16; j++)
214       X[j] = SWAP(W[j]);
215 
216     /* Save A as AA, B as BB, C as CC, and D as DD. */
217     AA = A;
218     BB = B;
219     CC = C;
220     DD = D;
221 
222     /* The hex constants are from md5.c
223        in FSF Gnu Privacy Guard 0.9.2 */
224     /* Round 1. */
225     /* Let [abcd k s i] denote the operation
226        a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
227     /* Do the following 16 operations. */
228     A = FF(A,B,C,D,  X[0],  7,  0xd76aa478);
229     D = FF(D,A,B,C,  X[1], 12,  0xe8c7b756);
230     C = FF(C,D,A,B,  X[2], 17,  0x242070db);
231     B = FF(B,C,D,A,  X[3], 22,  0xc1bdceee);
232 
233     A = FF(A,B,C,D,  X[4],  7,  0xf57c0faf);
234     D = FF(D,A,B,C,  X[5], 12,  0x4787c62a);
235     C = FF(C,D,A,B,  X[6], 17,  0xa8304613);
236     B = FF(B,C,D,A,  X[7], 22,  0xfd469501);
237 
238     A = FF(A,B,C,D,  X[8],  7,  0x698098d8);
239     D = FF(D,A,B,C,  X[9], 12,  0x8b44f7af);
240     C = FF(C,D,A,B, X[10], 17,  0xffff5bb1);
241     B = FF(B,C,D,A, X[11], 22,  0x895cd7be);
242 
243     A = FF(A,B,C,D, X[12],  7,  0x6b901122);
244     D = FF(D,A,B,C, X[13], 12,  0xfd987193);
245     C = FF(C,D,A,B, X[14], 17,  0xa679438e);
246     B = FF(B,C,D,A, X[15], 22,  0x49b40821);
247 
248     /* Round 2. */
249     /* Let [abcd k s i] denote the operation
250        a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
251     /* Do the following 16 operations. */
252     A = GG(A,B,C,D,  X[1],  5, 0xf61e2562);
253     D = GG(D,A,B,C,  X[6],  9, 0xc040b340);
254     C = GG(C,D,A,B, X[11], 14, 0x265e5a51);
255     B = GG(B,C,D,A,  X[0], 20, 0xe9b6c7aa);
256 
257     A = GG(A,B,C,D,  X[5],  5, 0xd62f105d);
258     D = GG(D,A,B,C, X[10],  9, 0x02441453);
259     C = GG(C,D,A,B, X[15], 14, 0xd8a1e681);
260     B = GG(B,C,D,A,  X[4], 20, 0xe7d3fbc8);
261 
262     A = GG(A,B,C,D,  X[9],  5, 0x21e1cde6);
263     D = GG(D,A,B,C, X[14],  9, 0xc33707d6);
264     C = GG(C,D,A,B,  X[3], 14, 0xf4d50d87);
265     B = GG(B,C,D,A,  X[8], 20, 0x455a14ed);
266 
267     A = GG(A,B,C,D, X[13],  5, 0xa9e3e905);
268     D = GG(D,A,B,C,  X[2],  9, 0xfcefa3f8);
269     C = GG(C,D,A,B,  X[7], 14, 0x676f02d9);
270     B = GG(B,C,D,A, X[12], 20, 0x8d2a4c8a);
271 
272     /* Round 3. */
273     /* Let [abcd k s t] denote the operation
274        a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
275     /* Do the following 16 operations. */
276     A = HH(A,B,C,D,  X[5],  4, 0xfffa3942);
277     D = HH(D,A,B,C,  X[8], 11, 0x8771f681);
278     C = HH(C,D,A,B, X[11], 16, 0x6d9d6122);
279     B = HH(B,C,D,A, X[14], 23, 0xfde5380c);
280 
281     A = HH(A,B,C,D,  X[1],  4, 0xa4beea44);
282     D = HH(D,A,B,C,  X[4], 11, 0x4bdecfa9);
283     C = HH(C,D,A,B,  X[7], 16, 0xf6bb4b60);
284     B = HH(B,C,D,A, X[10], 23, 0xbebfbc70);
285 
286     A = HH(A,B,C,D, X[13],  4, 0x289b7ec6);
287     D = HH(D,A,B,C,  X[0], 11, 0xeaa127fa);
288     C = HH(C,D,A,B,  X[3], 16, 0xd4ef3085);
289     B = HH(B,C,D,A,  X[6], 23, 0x04881d05);
290 
291     A = HH(A,B,C,D,  X[9],  4, 0xd9d4d039);
292     D = HH(D,A,B,C, X[12], 11, 0xe6db99e5);
293     C = HH(C,D,A,B, X[15], 16, 0x1fa27cf8);
294     B = HH(B,C,D,A,  X[2], 23, 0xc4ac5665);
295 
296     /* Round 4. */
297     /* Let [abcd k s t] denote the operation
298        a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
299     /* Do the following 16 operations. */
300     A = II(A,B,C,D,  X[0],  6, 0xf4292244);
301     D = II(D,A,B,C,  X[7], 10, 0x432aff97);
302     C = II(C,D,A,B, X[14], 15, 0xab9423a7);
303     B = II(B,C,D,A,  X[5], 21, 0xfc93a039);
304 
305     A = II(A,B,C,D, X[12],  6, 0x655b59c3);
306     D = II(D,A,B,C,  X[3], 10, 0x8f0ccc92);
307     C = II(C,D,A,B, X[10], 15, 0xffeff47d);
308     B = II(B,C,D,A,  X[1], 21, 0x85845dd1);
309 
310     A = II(A,B,C,D,  X[8],  6, 0x6fa87e4f);
311     D = II(D,A,B,C, X[15], 10, 0xfe2ce6e0);
312     C = II(C,D,A,B,  X[6], 15, 0xa3014314);
313     B = II(B,C,D,A, X[13], 21, 0x4e0811a1);
314 
315     A = II(A,B,C,D,  X[4],  6, 0xf7537e82);
316     D = II(D,A,B,C, X[11], 10, 0xbd3af235);
317     C = II(C,D,A,B,  X[2], 15, 0x2ad7d2bb);
318     B = II(B,C,D,A,  X[9], 21, 0xeb86d391);
319 
320     /* Then perform the following additions. (That is increment each
321        of the four registers by the value it had before this block
322        was started.) */
323     A = A + AA;
324     B = B + BB;
325     C = C + CC;
326     D = D + DD;
327   }
328 }
5776624 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 22:44:06