KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > modules > SHA1


1 /*
2  * SHA1.java - An implementation of the SHA-1 Algorithm
3  *
4  * Modified for Jython by Finn Bock. The original was split
5  * into two files.
6  *
7  * Original author and copyright:
8  *
9  * Copyright (c) 1997 Systemics Ltd
10  * on behalf of the Cryptix Development Team. All rights reserved.
11  * @author David Hopwood
12  *
13  * Cryptix General License
14  * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 The Cryptix Foundation
15  * Limited.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or
19  * without modification, are permitted provided that the
20  * following conditions are met:
21  *
22  * - Redistributions of source code must retain the copyright notice, this
23  * list of conditions and the following disclaimer.
24  * - Redistributions in binary form must reproduce the above
25  * copyright notice, this list of conditions and the following
26  * disclaimer in the documentation and/or other materials
27  * provided with the distribution.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE CRYPTIX FOUNDATION LIMITED
30  * AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
31  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
32  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33  * DISCLAIMED. IN NO EVENT SHALL THE CRYPTIX FOUNDATION LIMITED
34  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  */

43
44 package org.python.modules;
45
46 import java.util.*;
47 import org.python.core.*;
48
49 /**
50  * This class implements the SHA-1 message digest algorithm.
51  * <p>
52  * <b>References:</b>
53  * <ol>
54  * <li> Bruce Schneier,
55  * "Section 18.7 Secure Hash Algorithm (SHA),"
56  * <cite>Applied Cryptography, 2nd edition</cite>,
57  * John Wiley &amp; Sons, 1996
58  * <p>
59  * <li> NIST FIPS PUB 180-1,
60  * "Secure Hash Standard",
61  * U.S. Department of Commerce, May 1993.<br>
62  * <a HREF="http://www.itl.nist.gov/div897/pubs/fip180-1.htm">
63  * http://www.itl.nist.gov/div897/pubs/fip180-1.htm</a>
64  * </ol>
65  * <p>
66  * <b>Copyright</b> &copy; 1995-1997
67  * <a HREF="http://www.systemics.com/">Systemics Ltd</a> on behalf of the
68  * <a HREF="http://www.systemics.com/docs/cryptix/">Cryptix Development
69  * Team</a>.
70  * <br>All rights reserved.
71  * <p>
72  * <b>Revision: 1.7</b>
73  * @author Systemics Ltd
74  * @author David Hopwood
75  * @since Cryptix 2.2.2
76  */

77 public final class SHA1 {
78     /**
79      * The buffer used to store the last incomplete block.
80      */

81     private byte[] buffer;
82
83     /**
84      * The number of bytes currently stored in <code>buffer</code>.
85      */

86     private int buffered;
87
88     /**
89      * The number of bytes that have been input to the digest.
90      */

91     private long count;
92
93
94
95
96     /**
97      * <b>SPI</b>: Updates the message digest with a byte of new data.
98      *
99      * @param b the byte to be added.
100      */

101     protected void engineUpdate(byte b)
102     {
103         byte[] data = { b };
104         engineUpdate(data, 0, 1);
105     }
106
107     /**
108      * <b>SPI</b>: Updates the message digest with new data.
109      *
110      * @param data the data to be added.
111      * @param offset the start of the data in the array.
112      * @param length the number of bytes of data to add.
113      */

114     protected void engineUpdate(byte[] data, int offset, int length)
115     {
116         count += length;
117
118         int datalen = DATA_LENGTH;
119         int remainder;
120
121         while (length >= (remainder = datalen - buffered)) {
122             System.arraycopy(data, offset, buffer, buffered, remainder);
123             engineTransform(buffer);
124             length -= remainder;
125             offset += remainder;
126             buffered = 0;
127         }
128
129         if (length > 0) {
130             System.arraycopy(data, offset, buffer, buffered, length);
131             buffered += length;
132         }
133     }
134
135     /**
136      * <b>SPI</b>: Calculates the final digest. BlockMessageDigest
137      * subclasses should not usually override this method.
138      *
139      * @return the digest as a byte array.
140      */

141     protected byte[] engineDigest()
142     {
143         return engineDigest(buffer, buffered);
144     }
145
146
147
148 // SHA-1 constants and variables
149
//...........................................................................
150

151     /**
152      * Length of the final hash (in bytes).
153      */

154     private static final int HASH_LENGTH = 20;
155
156     /**
157      * Length of a block (i.e. the number of bytes hashed in every transform).
158      */

159     private static final int DATA_LENGTH = 64;
160
161     private int[] data;
162     private int[] digest;
163     private byte[] tmp;
164     private int[] w;
165
166     private byte[] digestBits;
167
168
169     /**
170      * Constructs a SHA-1 message digest.
171      */

172     public SHA1()
173     {
174         buffer = new byte[DATA_LENGTH];
175         java_init();
176         engineReset();
177     }
178
179     private void java_init()
180     {
181         digest = new int[HASH_LENGTH/4];
182         data = new int[DATA_LENGTH/4];
183         tmp = new byte[DATA_LENGTH];
184         w = new int[80];
185     }
186
187     /**
188      * This constructor is here to implement cloneability of this class.
189      */

190     private SHA1 (SHA1 md) {
191         this();
192         data = (int[])md.data.clone();
193         digest = (int[])md.digest.clone();
194         tmp = (byte[])md.tmp.clone();
195         w = (int[])md.w.clone();
196         buffer = (byte[])md.buffer.clone();
197         buffered = md.buffered;
198         count = md.count;
199     }
200
201     /**
202      * Initializes (resets) the message digest.
203      */

204     protected void engineReset()
205     {
206         buffered = 0;
207         count = 0;
208         java_reset();
209     }
210
211     private void java_reset()
212     {
213         digest[0] = 0x67452301;
214         digest[1] = 0xefcdab89;
215         digest[2] = 0x98badcfe;
216         digest[3] = 0x10325476;
217         digest[4] = 0xc3d2e1f0;
218     }
219
220     /**
221      * Adds data to the message digest.
222      *
223      * @param data The data to be added.
224      * @param offset The start of the data in the array.
225      * @param length The amount of data to add.
226      */

227     protected void engineTransform(byte[] in)
228     {
229         java_transform(in);
230     }
231
232     private void java_transform(byte[] in)
233     {
234         byte2int(in, 0, data, 0, DATA_LENGTH/4);
235         transform(data);
236     }
237
238     /**
239      * Returns the digest of the data added and resets the digest.
240      * @return the digest of all the data added to the message digest
241      * as a byte array.
242      */

243     protected byte[] engineDigest(byte[] in, int length)
244     {
245         byte b[] = java_digest(in, length);
246         engineReset();
247         return b;
248     }
249
250     private byte[] java_digest(byte[] in, int pos)
251     {
252         if (pos != 0) System.arraycopy(in, 0, tmp, 0, pos);
253
254         tmp[pos++] = (byte)0x80;
255
256         if (pos > DATA_LENGTH - 8)
257         {
258             while (pos < DATA_LENGTH)
259                 tmp[pos++] = 0;
260
261             byte2int(tmp, 0, data, 0, DATA_LENGTH/4);
262             transform(data);
263             pos = 0;
264         }
265
266         while (pos < DATA_LENGTH - 8)
267             tmp[pos++] = 0;
268
269         byte2int(tmp, 0, data, 0, (DATA_LENGTH/4)-2);
270
271         // Big endian
272
// WARNING: int>>>32 != 0 !!!
273
// bitcount() used to return a long, now it's an int.
274
long bc = count * 8;
275         data[14] = (int) (bc>>>32);
276         data[15] = (int) bc;
277
278         transform(data);
279
280         byte buf[] = new byte[HASH_LENGTH];
281
282         // Big endian
283
int off = 0;
284         for (int i = 0; i < HASH_LENGTH/4; ++i) {
285             int d = digest[i];
286             buf[off++] = (byte) (d>>>24);
287             buf[off++] = (byte) (d>>>16);
288             buf[off++] = (byte) (d>>>8);
289             buf[off++] = (byte) d;
290         }
291         return buf;
292     }
293
294
295 // SHA-1 transform routines
296
//...........................................................................
297

298     private static int f1(int a, int b, int c) {
299         return (c^(a&(b^c))) + 0x5A827999;
300     }
301     private static int f2(int a, int b, int c) {
302         return (a^b^c) + 0x6ED9EBA1;
303     }
304     private static int f3(int a, int b, int c) {
305         return ((a&b)|(c&(a|b))) + 0x8F1BBCDC;
306     }
307     private static int f4(int a, int b, int c) {
308         return (a^b^c) + 0xCA62C1D6;
309     }
310
311     private void transform (int[] X)
312     {
313         int A = digest[0];
314         int B = digest[1];
315         int C = digest[2];
316         int D = digest[3];
317         int E = digest[4];
318
319         int W[] = w;
320         for (int i=0; i<16; i++)
321         {
322             W[i] = X[i];
323         }
324         for (int i=16; i<80; i++)
325         {
326             int j = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3];
327             W[i] = j;
328             W[i] = (j << 1) | (j >>> -1);
329         }
330
331         E += ((A<<5)|(A >>> -5)) + f1(B,C,D) + W[0]; B =((B<<30)|(B>>>-30));
332         D += ((E<<5)|(E >>> -5)) + f1(A,B,C) + W[1]; A =((A<<30)|(A>>>-30));
333         C += ((D<<5)|(D >>> -5)) + f1(E,A,B) + W[2]; E =((E<<30)|(E>>>-30));
334         B += ((C<<5)|(C >>> -5)) + f1(D,E,A) + W[3]; D =((D<<30)|(D>>>-30));
335         A += ((B<<5)|(B >>> -5)) + f1(C,D,E) + W[4]; C =((C<<30)|(C>>>-30));
336         E += ((A<<5)|(A >>> -5)) + f1(B,C,D) + W[5]; B =((B<<30)|(B>>>-30));
337         D += ((E<<5)|(E >>> -5)) + f1(A,B,C) + W[6]; A =((A<<30)|(A>>>-30));
338         C += ((D<<5)|(D >>> -5)) + f1(E,A,B) + W[7]; E =((E<<30)|(E>>>-30));
339         B += ((C<<5)|(C >>> -5)) + f1(D,E,A) + W[8]; D =((D<<30)|(D>>>-30));
340         A += ((B<<5)|(B >>> -5)) + f1(C,D,E) + W[9]; C =((C<<30)|(C>>>-30));
341         E += ((A<<5)|(A >>> -5)) + f1(B,C,D) + W[10]; B =((B<<30)|(B>>>-30));
342         D += ((E<<5)|(E >>> -5)) + f1(A,B,C) + W[11]; A =((A<<30)|(A>>>-30));
343         C += ((D<<5)|(D >>> -5)) + f1(E,A,B) + W[12]; E =((E<<30)|(E>>>-30));
344         B += ((C<<5)|(C >>> -5)) + f1(D,E,A) + W[13]; D =((D<<30)|(D>>>-30));
345         A += ((B<<5)|(B >>> -5)) + f1(C,D,E) + W[14]; C =((C<<30)|(C>>>-30));
346         E += ((A<<5)|(A >>> -5)) + f1(B,C,D) + W[15]; B =((B<<30)|(B>>>-30));
347         D += ((E<<5)|(E >>> -5)) + f1(A,B,C) + W[16]; A =((A<<30)|(A>>>-30));
348         C += ((D<<5)|(D >>> -5)) + f1(E,A,B) + W[17]; E =((E<<30)|(E>>>-30));
349         B += ((C<<5)|(C >>> -5)) + f1(D,E,A) + W[18]; D =((D<<30)|(D>>>-30));
350         A += ((B<<5)|(B >>> -5)) + f1(C,D,E) + W[19]; C =((C<<30)|(C>>>-30));
351         E += ((A<<5)|(A >>> -5)) + f2(B,C,D) + W[20]; B =((B<<30)|(B>>>-30));
352         D += ((E<<5)|(E >>> -5)) + f2(A,B,C) + W[21]; A =((A<<30)|(A>>>-30));
353         C += ((D<<5)|(D >>> -5)) + f2(E,A,B) + W[22]; E =((E<<30)|(E>>>-30));
354         B += ((C<<5)|(C >>> -5)) + f2(D,E,A) + W[23]; D =((D<<30)|(D>>>-30));
355         A += ((B<<5)|(B >>> -5)) + f2(C,D,E) + W[24]; C =((C<<30)|(C>>>-30));
356         E += ((A<<5)|(A >>> -5)) + f2(B,C,D) + W[25]; B =((B<<30)|(B>>>-30));
357         D += ((E<<5)|(E >>> -5)) + f2(A,B,C) + W[26]; A =((A<<30)|(A>>>-30));
358         C += ((D<<5)|(D >>> -5)) + f2(E,A,B) + W[27]; E =((E<<30)|(E>>>-30));
359         B += ((C<<5)|(C >>> -5)) + f2(D,E,A) + W[28]; D =((D<<30)|(D>>>-30));
360         A += ((B<<5)|(B >>> -5)) + f2(C,D,E) + W[29]; C =((C<<30)|(C>>>-30));
361         E += ((A<<5)|(A >>> -5)) + f2(B,C,D) + W[30]; B =((B<<30)|(B>>>-30));
362         D += ((E<<5)|(E >>> -5)) + f2(A,B,C) + W[31]; A =((A<<30)|(A>>>-30));
363         C += ((D<<5)|(D >>> -5)) + f2(E,A,B) + W[32]; E =((E<<30)|(E>>>-30));
364         B += ((C<<5)|(C >>> -5)) + f2(D,E,A) + W[33]; D =((D<<30)|(D>>>-30));
365         A += ((B<<5)|(B >>> -5)) + f2(C,D,E) + W[34]; C =((C<<30)|(C>>>-30));
366         E += ((A<<5)|(A >>> -5)) + f2(B,C,D) + W[35]; B =((B<<30)|(B>>>-30));
367         D += ((E<<5)|(E >>> -5)) + f2(A,B,C) + W[36]; A =((A<<30)|(A>>>-30));
368         C += ((D<<5)|(D >>> -5)) + f2(E,A,B) + W[37]; E =((E<<30)|(E>>>-30));
369         B += ((C<<5)|(C >>> -5)) + f2(D,E,A) + W[38]; D =((D<<30)|(D>>>-30));
370         A += ((B<<5)|(B >>> -5)) + f2(C,D,E) + W[39]; C =((C<<30)|(C>>>-30));
371         E += ((A<<5)|(A >>> -5)) + f3(B,C,D) + W[40]; B =((B<<30)|(B>>>-30));
372         D += ((E<<5)|(E >>> -5)) + f3(A,B,C) + W[41]; A =((A<<30)|(A>>>-30));
373         C += ((D<<5)|(D >>> -5)) + f3(E,A,B) + W[42]; E =((E<<30)|(E>>>-30));
374         B += ((C<<5)|(C >>> -5)) + f3(D,E,A) + W[43]; D =((D<<30)|(D>>>-30));
375         A += ((B<<5)|(B >>> -5)) + f3(C,D,E) + W[44]; C =((C<<30)|(C>>>-30));
376         E += ((A<<5)|(A >>> -5)) + f3(B,C,D) + W[45]; B =((B<<30)|(B>>>-30));
377         D += ((E<<5)|(E >>> -5)) + f3(A,B,C) + W[46]; A =((A<<30)|(A>>>-30));
378         C += ((D<<5)|(D >>> -5)) + f3(E,A,B) + W[47]; E =((E<<30)|(E>>>-30));
379         B += ((C<<5)|(C >>> -5)) + f3(D,E,A) + W[48]; D =((D<<30)|(D>>>-30));
380         A += ((B<<5)|(B >>> -5)) + f3(C,D,E) + W[49]; C =((C<<30)|(C>>>-30));
381         E += ((A<<5)|(A >>> -5)) + f3(B,C,D) + W[50]; B =((B<<30)|(B>>>-30));
382         D += ((E<<5)|(E >>> -5)) + f3(A,B,C) + W[51]; A =((A<<30)|(A>>>-30));
383         C += ((D<<5)|(D >>> -5)) + f3(E,A,B) + W[52]; E =((E<<30)|(E>>>-30));
384         B += ((C<<5)|(C >>> -5)) + f3(D,E,A) + W[53]; D =((D<<30)|(D>>>-30));
385         A += ((B<<5)|(B >>> -5)) + f3(C,D,E) + W[54]; C =((C<<30)|(C>>>-30));
386         E += ((A<<5)|(A >>> -5)) + f3(B,C,D) + W[55]; B =((B<<30)|(B>>>-30));
387         D += ((E<<5)|(E >>> -5)) + f3(A,B,C) + W[56]; A =((A<<30)|(A>>>-30));
388         C += ((D<<5)|(D >>> -5)) + f3(E,A,B) + W[57]; E =((E<<30)|(E>>>-30));
389         B += ((C<<5)|(C >>> -5)) + f3(D,E,A) + W[58]; D =((D<<30)|(D>>>-30));
390         A += ((B<<5)|(B >>> -5)) + f3(C,D,E) + W[59]; C =((C<<30)|(C>>>-30));
391         E += ((A<<5)|(A >>> -5)) + f4(B,C,D) + W[60]; B =((B<<30)|(B>>>-30));
392         D += ((E<<5)|(E >>> -5)) + f4(A,B,C) + W[61]; A =((A<<30)|(A>>>-30));
393         C += ((D<<5)|(D >>> -5)) + f4(E,A,B) + W[62]; E =((E<<30)|(E>>>-30));
394         B += ((C<<5)|(C >>> -5)) + f4(D,E,A) + W[63]; D =((D<<30)|(D>>>-30));
395         A += ((B<<5)|(B >>> -5)) + f4(C,D,E) + W[64]; C =((C<<30)|(C>>>-30));
396         E += ((A<<5)|(A >>> -5)) + f4(B,C,D) + W[65]; B =((B<<30)|(B>>>-30));
397         D += ((E<<5)|(E >>> -5)) + f4(A,B,C) + W[66]; A =((A<<30)|(A>>>-30));
398         C += ((D<<5)|(D >>> -5)) + f4(E,A,B) + W[67]; E =((E<<30)|(E>>>-30));
399         B += ((C<<5)|(C >>> -5)) + f4(D,E,A) + W[68]; D =((D<<30)|(D>>>-30));
400         A += ((B<<5)|(B >>> -5)) + f4(C,D,E) + W[69]; C =((C<<30)|(C>>>-30));
401         E += ((A<<5)|(A >>> -5)) + f4(B,C,D) + W[70]; B =((B<<30)|(B>>>-30));
402         D += ((E<<5)|(E >>> -5)) + f4(A,B,C) + W[71]; A =((A<<30)|(A>>>-30));
403         C += ((D<<5)|(D >>> -5)) + f4(E,A,B) + W[72]; E =((E<<30)|(E>>>-30));
404         B += ((C<<5)|(C >>> -5)) + f4(D,E,A) + W[73]; D =((D<<30)|(D>>>-30));
405         A += ((B<<5)|(B >>> -5)) + f4(C,D,E) + W[74]; C =((C<<30)|(C>>>-30));
406         E += ((A<<5)|(A >>> -5)) + f4(B,C,D) + W[75]; B =((B<<30)|(B>>>-30));
407         D += ((E<<5)|(E >>> -5)) + f4(A,B,C) + W[76]; A =((A<<30)|(A>>>-30));
408         C += ((D<<5)|(D >>> -5)) + f4(E,A,B) + W[77]; E =((E<<30)|(E>>>-30));
409         B += ((C<<5)|(C >>> -5)) + f4(D,E,A) + W[78]; D =((D<<30)|(D>>>-30));
410         A += ((B<<5)|(B >>> -5)) + f4(C,D,E) + W[79]; C =((C<<30)|(C>>>-30));
411
412         digest[0] += A;
413         digest[1] += B;
414         digest[2] += C;
415         digest[3] += D;
416         digest[4] += E;
417     }
418
419     // why was this public?
420
// Note: parameter order changed to be consistent with System.arraycopy.
421
private static void byte2int(byte[] src, int srcOffset,
422                                  int[] dst, int dstOffset, int length)
423     {
424         while (length-- > 0)
425         {
426             // Big endian
427
dst[dstOffset++] = (src[srcOffset++] << 24) |
428                                ((src[srcOffset++] & 0xFF) << 16) |
429                                ((src[srcOffset++] & 0xFF) << 8) |
430                                 (src[srcOffset++] & 0xFF);
431         }
432     }
433
434
435
436
437
438
439
440     public static PyString __doc__update = new PyString(
441         "Update this hashing object's state with the provided string."
442     );
443
444     /**
445      * Add an array of bytes to the digest.
446      */

447     public synchronized void update(byte input[]) {
448         engineUpdate(input, 0, input.length);
449     }
450
451
452
453     public static PyString __doc__copy = new PyString(
454         "Return a copy of the hashing object."
455     );
456
457     /**
458      * Add an array of bytes to the digest.
459      */

460     public SHA1 copy() {
461         return new SHA1(this);
462     }
463
464
465
466     public static PyString __doc__hexdigest = new PyString(
467         "Return the digest value as a string of hexadecimal digits."
468     );
469
470     /**
471      * Print out the digest in a form that can be easily compared
472      * to the test vectors.
473      */

474     public String JavaDoc hexdigest() {
475         if (digestBits == null)
476             digestBits = engineDigest();
477
478         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
479         for (int i = 0; i < 20; i++) {
480             char c1, c2;
481
482             c1 = (char) ((digestBits[i] >>> 4) & 0xf);
483             c2 = (char) (digestBits[i] & 0xf);
484             c1 = (char) ((c1 > 9) ? 'a' + (c1 - 10) : '0' + c1);
485             c2 = (char) ((c2 > 9) ? 'a' + (c2 - 10) : '0' + c2);
486             sb.append(c1);
487             sb.append(c2);
488         }
489         return sb.toString();
490     }
491
492
493     public static PyString __doc__digest = new PyString(
494         "Return the digest value as a string of binary data."
495     );
496
497     public String JavaDoc digest() {
498         if (digestBits == null)
499             digestBits = engineDigest();
500         return new String JavaDoc(digestBits, 0, 0, digestBits.length);
501     }
502
503     // XXX should become PyObject and use Py.idstr?
504
public String JavaDoc toString() {
505         return "<SHA object at" + System.identityHashCode(this) + ">";
506     }
507 }
508
Popular Tags