KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > softabar > sha4j > Sha4J


1 /*
2  * Sha4J implements SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 algorithms.
3  *
4  * Copyright (C) 2006 Softabar
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * 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, but
12  * 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  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the
18  * Free Software Foundation, * Inc., * 59 Temple Place, * Suite 330,
19  * Boston, MA 02111-1307 USA
20 */

21 package com.softabar.sha4j;
22
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 /**
26  * Sha4J implements SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 algorithms.<br/>
27  *
28  * <pre>
29  * Copyright (C) 2006 Softabar
30  *
31  * This program is free software; you can redistribute it and/or modify it
32  * under the terms of the GNU General Public License as published by the
33  * Free Software Foundation; either version 2 of the License, or
34  * (at your option) any later version.
35  *
36  * This program is distributed in the hope that it will be useful, but
37  * WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39  * GNU General Public License for more details.
40  *
41  * You should have received a copy of the GNU General Public License
42  * along with this program; if not, write to the
43  * Free Software Foundation, * Inc., * 59 Temple Place, * Suite 330,
44  * Boston, MA 02111-1307 USA
45  * </pre>
46  *
47  * @version 1.0
48  */

49 public class Sha4J
50 {
51   private boolean closeInputStream=true;
52   
53   public Sha4J()
54   {
55     this(true);
56   }
57   
58   public Sha4J(boolean closeInputStream)
59   {
60     this.closeInputStream=closeInputStream;
61   }
62   
63   //Start SHA-1 implementation
64
// variables and functions also used in other SHA
65
// algorithms
66
private long messageLength = 0;
67
68   public byte[] sha1Digest(InputStream JavaDoc inputStream) throws IOException JavaDoc
69   {
70     // read bytes
71
byte[] Mb = new byte[64];// 512-bit block
72
int[] M = new int[16];
73     int[] W = new int[80];
74
75     // SHA-1 constants, digest initial value
76
// Hash values
77
int H0 = 0x67452301;
78     int H1 = 0xefcdab89;
79     int H2 = 0x98badcfe;
80     int H3 = 0x10325476;
81     int H4 = 0xc3d2e1f0;
82
83     int[] H =
84     { H0, H1, H2, H3, H4 };
85
86     // read bytes from inputstream
87
// and pad if necessary
88
boolean padBlock = false;
89     boolean padded = false;
90     int bytesRead = inputStream.read(Mb, 0, 64);
91     for (;;)
92     {
93       if (bytesRead == -1)
94       {
95         if (!padded)
96         {
97           doPadBlock(H, M, W, true);
98         }
99
100         byte[] digest = new byte[20];
101         int i = 0;
102         int j = 0;
103
104         for (; j < 5; i += 4, j++)
105         {
106           digest[i] = (byte) (H[j] >>> 24);
107           digest[i + 1] = (byte) (H[j] >>> 16);
108           digest[i + 2] = (byte) (H[j] >>> 8);
109           digest[i + 3] = (byte) (H[j]);
110         }
111         if(closeInputStream)
112         {
113           inputStream.close();
114         }
115         
116         return digest;
117       }
118
119       messageLength += (bytesRead << 3);// messageLength in bits,
120

121       if (bytesRead < 55)
122       {
123         padded = true;
124         // do padding if read bytes is smaller than 55 ==> total message length
125
// can be added in this block as 64-bit value
126

127         // add 1 after message
128
Mb[bytesRead] = (byte) 0x80;
129         for (int i = bytesRead + 1; i < 56; i++)
130         {
131           Mb[i] = 0;
132         }
133         // add length as 64 bit value at the end of Mb
134
addLength128(Mb);
135
136       }
137
138       if (bytesRead == 55)
139       {
140         padded = true;
141
142         // need to add totally new 512 bit block with all zeros except
143
// last 64 bits which is message length
144
Mb[55] = (byte) (0x80);
145         addLength128(Mb);
146
147       }
148
149       if (bytesRead > 55 && bytesRead < 64)
150       {
151         padded = true;
152
153         // need to add totally new 512 bit block with all zeros except
154
// last 64 bits which is message length
155
Mb[bytesRead] = (byte) 0x80;
156         for (int i = bytesRead + 1; i < 64; i++)
157         {
158           Mb[i] = 0;
159         }
160         padBlock = true;// padBlock is 448-bits of zero + 64 bit length
161
}
162
163       // convert to int array. Java int is 32-bits
164
// int is a 32-bit word in FIPS 180-2 specification
165
int i = 0;
166       int j = 0;
167       for (; i < 16; j += 4, i++)
168       {
169         M[i] = (Mb[j] << 24) | (((Mb[j + 1]) & 0xff) << 16)
170             | (((Mb[j + 2]) & 0xff) << 8) | ((Mb[j + 3]) & 0xff);
171       }
172
173       // prepare message schedule
174
prepareMessageSchedule(M, W);
175
176       // init working variables
177
int a = H[0];// 1732584193;
178
int b = H[1];// 4023233417;
179
int c = H[2];// 2562383102;
180
int d = H[3];// 271733878;
181
int e = H[4];// 3285377520;
182

183       int t = 0;
184       for (; t < 80; t++)
185       {
186         int T = modulo32Add(modulo32Add(modulo32Add(ROTL(5, a), f(t, b, c, d)),
187             modulo32Add(e, K(t))), W[t]);
188         e = d;
189         d = c;
190         c = ROTL(30, b);
191         b = a;
192         a = T;
193
194       }
195
196       // interMediateHash128(H,a,b,c,d,e);
197
H[0] = modulo32Add(H[0], a);
198       H[1] = modulo32Add(H[1], b);
199       H[2] = modulo32Add(H[2], c);
200       H[3] = modulo32Add(H[3], d);
201       H[4] = modulo32Add(H[4], e);
202
203       // do last pad
204
if (padBlock)
205       {
206         doPadBlock(H, M, W, false);
207       }
208
209       bytesRead = inputStream.read(Mb, 0, 64);
210     }
211
212   }
213
214   private void addLength128(byte[] Mb)
215   {
216     Mb[56] = (byte) (messageLength >>> 56);
217     Mb[57] = (byte) (messageLength >>> 48);
218     Mb[58] = (byte) (messageLength >>> 40);
219     Mb[59] = (byte) (messageLength >>> 32);
220     Mb[60] = (byte) (messageLength >>> 24);
221     Mb[61] = (byte) (messageLength >>> 16);
222     Mb[62] = (byte) (messageLength >>> 8);
223     Mb[63] = (byte) messageLength;
224   }
225
226   private void doPadBlock(int[] H, int[] M, int[] W, boolean addOne)
227   {
228
229     // addOne is the required 1 before
230
M[0] = addOne ? 0x80000000 : 0;
231     for (int i = 1; i < 14; i++)
232     {
233       M[i] = 0;
234     }
235
236     M[14] = (int) (messageLength >>> 32);
237     M[15] = (int) messageLength;
238
239     // prepare message schedule
240
prepareMessageSchedule(M, W);
241
242     // init working variables
243
int a = H[0];// 1732584193;
244
int b = H[1];// 4023233417;
245
int c = H[2];// 2562383102;
246
int d = H[3];// 271733878;
247
int e = H[4];// 3285377520;
248

249     int t = 0;
250     for (; t < 80; t++)
251     {
252       int T = modulo32Add(modulo32Add(modulo32Add(ROTL(5, a), f(t, b, c, d)),
253           modulo32Add(e, K(t))), W[t]);
254       e = d;
255       d = c;
256       c = ROTL(30, b);
257       b = a;
258       a = T;
259
260     }
261     H[0] = modulo32Add(H[0], a);
262     H[1] = modulo32Add(H[1], b);
263     H[2] = modulo32Add(H[2], c);
264     H[3] = modulo32Add(H[3], d);
265     H[4] = modulo32Add(H[4], e);
266
267   }
268
269   private void prepareMessageSchedule(int[] M, int[] W)
270   {
271     for (int t = 0; t < 80; t++)
272     {
273       if (t < 16)
274       {
275         W[t] = M[t];
276       }
277       else
278       {
279         W[t] = ROTL(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
280       }
281
282     }
283   }
284
285   private int modulo32Add(int x, int y)
286   {
287     return (x ^ 0x80000000) + (y ^ 0x80000000);
288   }
289
290   private int f(int t, int x, int y, int z)
291   {
292     if (t < 20)
293     {
294       return (x & y) ^ (~x & z);//Ch(x, y, z);
295
}
296     if (t < 40)
297     {
298       return x ^ y ^ z;//Parity(x, y, z);
299
}
300     if (t < 60)
301     {
302       return (x & y) ^ (x & z) ^ (y & z);//Maj(x, y, z);
303
}
304
305     return x ^ y ^ z;//Parity(x, y, z);
306

307   }
308
309   private int Ch(int x, int y, int z)
310   {
311     return (x & y) ^ (~x & z);
312   }
313  
314   private int Maj(int x, int y, int z)
315   {
316     return (x & y) ^ (x & z) ^ (y & z);
317   }
318
319   private int ROTL(int n, int x)
320   {
321     return (x << n) | (x >>> (32 - n));
322   }
323
324   private int K(int t)
325   {
326
327     if (t < 20)
328     {
329       return 0x5a827999;
330     }
331     if (t < 40)
332     {
333       return 0x6ed9eba1;
334     }
335     if (t < 60)
336     {
337       return 0x8f1bbcdc;
338     }
339
340     return 0xca62c1d6;
341   }
342
343   // End SHA-1 implementation
344

345   // Start SHA-224/SHA-256 implementation
346

347   public byte[] sha224Digest(InputStream JavaDoc inputStream) throws IOException JavaDoc
348   {
349     return sha256Digest(inputStream,true);
350   }
351
352   public byte[] sha256Digest(InputStream JavaDoc inputStream) throws IOException JavaDoc
353   {
354     return sha256Digest(inputStream,false);
355   }
356   
357   private byte[] sha256Digest(InputStream JavaDoc inputStream,boolean sha224) throws IOException JavaDoc
358   {
359     // read bytes
360
byte[] Mb = new byte[64];// 512-bit block
361
int[] M = new int[16];
362     int[] W = new int[64];
363
364     // SHA-256 constants, digest initial value
365

366     int H0 = 0x6a09e667;
367     int H1 = 0xbb67ae85;
368     int H2 = 0x3c6ef372;
369     int H3 = 0xa54ff53a;
370     int H4 = 0x510e527f;
371     int H5 = 0x9b05688c;
372     int H6 = 0x1f83d9ab;
373     int H7 = 0x5be0cd19;
374
375     if(sha224)
376     {
377       H0=0xc1059ed8;
378       H1=0x367cd507;
379       H2=0x3070dd17;
380       H3=0xf70e5939;
381       H4=0xffc00b31;
382       H5=0x68581511;
383       H6=0x64f98fa7;
384       H7=0xbefa4fa4;
385     }
386     
387     
388     int[] H =
389     { H0, H1, H2, H3, H4, H5, H6, H7 };
390
391     // read bytes from inputstream
392
// and pad if necessary
393
boolean padBlock = false;
394     boolean padded = false;
395     int bytesRead = inputStream.read(Mb, 0, 64);
396     for (;;)
397     {
398       if (bytesRead == -1)
399       {
400         if (!padded)
401         {
402           doPadBlock256(H, M, W, true);
403         }
404
405         byte[] digest = new byte[32];
406         int i = 0;
407         int j = 0;
408         for (; j < 8; i += 4, j++)
409         {
410           digest[i] = (byte) (H[j] >>> 24);
411           digest[i + 1] = (byte) (H[j] >>> 16);
412           digest[i + 2] = (byte) (H[j] >>> 8);
413           digest[i + 3] = (byte) (H[j]);
414         }
415         if(closeInputStream)
416         {
417           inputStream.close();
418         }
419
420         if(sha224)
421         {
422           byte[] digest2 = new byte[28];
423           for (int k = 0; k < digest2.length; k++)
424           {
425             digest2[k] = digest[k];
426           }
427           return digest2;
428         }
429         return digest;
430       }
431
432       messageLength += (bytesRead << 3);// messageLength in bits,
433

434       if (bytesRead < 55)
435       {
436         padded = true;
437         // do padding if read bytes is smaller than 55 ==> total message length
438
// can be added in this block as 64-bit value
439

440         // add 1 after message
441
Mb[bytesRead] = (byte) 0x80;
442         for (int i = bytesRead + 1; i < 56; i++)
443         {
444           Mb[i] = 0;
445         }
446         // add length as 64 bit value at the end of Mb
447
addLength128(Mb);
448
449       }
450
451       if (bytesRead == 55)
452       {
453         padded = true;
454
455         // need to add totally new 512 bit block with all zeros except
456
// last 64 bits which is message length
457
Mb[55] = (byte) (0x80);
458         addLength128(Mb);
459
460       }
461
462       if (bytesRead > 55 && bytesRead < 64)
463       {
464         padded = true;
465
466         // need to add totally new 512 bit block with all zeros except
467
// last 64 bits which is message length
468
Mb[bytesRead] = (byte) 0x80;
469         for (int i = bytesRead + 1; i < 64; i++)
470         {
471           Mb[i] = 0;
472         }
473         padBlock = true;// padBlock is 448-bits of zero + 64 bit length
474
}
475
476       // convert to int array. Java int is 32-bits
477
// int is a 32-bit word in FIPS 180-2 specification
478
int i = 0;
479       int j = 0;
480       for (; i < 16; j += 4, i++)
481       {
482         M[i] = (Mb[j] << 24) | (((Mb[j + 1]) & 0xff) << 16)
483             | (((Mb[j + 2]) & 0xff) << 8) | ((Mb[j + 3]) & 0xff);
484
485       }
486
487       // prepare message schedule
488
prepareMessageSchedule256(M, W);
489
490       // init working variables
491
int a = H[0];// 1732584193;
492
int b = H[1];// 4023233417;
493
int c = H[2];// 2562383102;
494
int d = H[3];// 271733878;
495
int e = H[4];// 3285377520;
496
int f = H[5];// 3285377520;
497
int g = H[6];// 3285377520;
498
int h = H[7];// 3285377520;
499

500       int t = 0;
501       for (; t < 64; t++)
502       {
503         int T1 = modulo32Add(modulo32Add(modulo32Add(h, SIGMA256_1(e)),
504             modulo32Add(Ch(e, f, g), K256[t])), W[t]);
505         int T2 = modulo32Add(SIGMA256_0(a), Maj(a, b, c));
506         h = g;
507         g = f;
508         f = e;
509         e = modulo32Add(d, T1);
510         d = c;
511         c = b;
512         b = a;
513         a = modulo32Add(T1, T2);
514       }
515
516       H[0] = modulo32Add(H[0], a);
517       H[1] = modulo32Add(H[1], b);
518       H[2] = modulo32Add(H[2], c);
519       H[3] = modulo32Add(H[3], d);
520       H[4] = modulo32Add(H[4], e);
521       H[5] = modulo32Add(H[5], f);
522       H[6] = modulo32Add(H[6], g);
523       H[7] = modulo32Add(H[7], h);
524
525       // do last pad
526
if (padBlock)
527       {
528         doPadBlock256(H, M, W, false);
529       }
530
531       bytesRead = inputStream.read(Mb, 0, 64);
532     }
533
534   }
535
536   private void doPadBlock256(int[] H, int[] M, int[] W, boolean addOne)
537   {
538     // addOne is the required 1 before
539
M[0] = addOne ? 0x80000000 : 0;
540     for (int i = 1; i < 14; i++)
541     {
542       M[i] = 0;
543     }
544
545     M[14] = (int) (messageLength >>> 32);
546     M[15] = (int) messageLength;
547
548     // prepare message schedule
549
prepareMessageSchedule256(M, W);
550
551     // init working variables
552
int a = H[0];// 1732584193;
553
int b = H[1];// 4023233417;
554
int c = H[2];// 2562383102;
555
int d = H[3];// 271733878;
556
int e = H[4];// 3285377520;
557
int f = H[5];// 3285377520;
558
int g = H[6];// 3285377520;
559
int h = H[7];// 3285377520;
560

561     int t = 0;
562     int T1 = 0;
563     int T2 = 0;
564     for (; t < 64; t++)
565     {
566       T1 = modulo32Add(modulo32Add(modulo32Add(h, SIGMA256_1(e)), modulo32Add(
567           Ch(e, f, g), K256[t])), W[t]);
568       T2 = modulo32Add(SIGMA256_0(a), Maj(a, b, c));
569       h = g;
570       g = f;
571       f = e;
572       e = modulo32Add(d, T1);
573       d = c;
574       c = b;
575       b = a;
576       a = modulo32Add(T1, T2);
577     }
578
579     H[0] = modulo32Add(H[0], a);
580     H[1] = modulo32Add(H[1], b);
581     H[2] = modulo32Add(H[2], c);
582     H[3] = modulo32Add(H[3], d);
583     H[4] = modulo32Add(H[4], e);
584     H[5] = modulo32Add(H[5], f);
585     H[6] = modulo32Add(H[6], g);
586     H[7] = modulo32Add(H[7], h);
587
588   }
589
590   private static final int[] K256 =
591   { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
592       0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
593       0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
594       0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
595       0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
596       0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
597       0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
598       0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
599       0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
600       0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
601       0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
602
603   private void prepareMessageSchedule256(int[] M, int[] W)
604   {
605     for (int t = 0; t < 64; t++)
606     {
607
608       if (t < 16)
609       {
610         W[t] = M[t];
611       }
612       else
613       {
614         W[t] = modulo32Add(modulo32Add(sigma256_1(W[t - 2]), W[t - 7]),
615             modulo32Add(sigma256_0(W[t - 15]), W[t - 16]));
616       }
617
618     }
619
620   }
621
622   private int SIGMA256_0(int x)
623   {
624     return ROTR(2,x) ^ ROTR(13,x) ^ ROTR(22,x);
625
626   }
627
628
629   private int SIGMA256_1(int x)
630   {
631     return ROTR(6,x) ^ ROTR(11,x) ^ ROTR(25,x);
632
633   }
634
635
636   private int sigma256_0(int x)
637   {
638     return ROTR(7,x) ^ ROTR(18,x) ^ SHR(3,x);
639
640   }
641
642   private int sigma256_1(int x)
643   {
644     return ROTR(17,x) ^ ROTR(19,x) ^ SHR(10,x);
645
646   }
647
648   private int ROTR(int n, int x)
649   {
650     return (x >>> n) | (x << (32 - n));
651
652   }
653
654
655   private int SHR(int n, int x)
656   {
657     return x >>> n;
658
659   }
660
661
662   // End SHA-224/256 implementation
663

664   // Start SHA-512/384 implementation
665

666   // SHA512 max length is 128bits
667
private long messageLengthUpper = 0L;
668
669   private long messageLengthLower = 0L;
670
671   public byte[] sha384Digest(InputStream JavaDoc inputStream) throws IOException JavaDoc
672   {
673     return sha512Digest(inputStream, true);
674
675   }
676
677   public byte[] sha512Digest(InputStream JavaDoc inputStream) throws IOException JavaDoc
678   {
679     return sha512Digest(inputStream, false);
680   }
681
682   private byte[] sha512Digest(InputStream JavaDoc inputStream, boolean sha384)
683       throws IOException JavaDoc
684   {
685
686     // read bytes
687
byte[] Mb = new byte[128];// 1024-bit block
688
long[] M = new long[16];
689     long[] W = new long[80];
690
691     // SHA-512 constants, digest initial value
692
long H0 = 0x6a09e667f3bcc908L;
693     long H1 = 0xbb67ae8584caa73bL;
694     long H2 = 0x3c6ef372fe94f82bL;
695     long H3 = 0xa54ff53a5f1d36f1L;
696     long H4 = 0x510e527fade682d1L;
697     long H5 = 0x9b05688c2b3e6c1fL;
698     long H6 = 0x1f83d9abfb41bd6bL;
699     long H7 = 0x5be0cd19137e2179L;
700     if (sha384)
701     {
702       H0 = 0xcbbb9d5dc1059ed8L;
703       H1 = 0x629a292a367cd507L;
704       H2 = 0x9159015a3070dd17L;
705       H3 = 0x152fecd8f70e5939L;
706       H4 = 0x67332667ffc00b31L;
707       H5 = 0x8eb44a8768581511L;
708       H6 = 0xdb0c2e0d64f98fa7L;
709       H7 = 0x47b5481dbefa4fa4L;
710     }
711
712     long[] H =
713     { H0, H1, H2, H3, H4, H5, H6, H7 };
714
715     // read bytes from inputstream
716
// and pad if necessary
717
boolean padBlock = false;
718     boolean padded = false;
719     int bytesRead = inputStream.read(Mb, 0, 128);
720     for (;;)
721     {
722       if (bytesRead == -1)
723       {
724         if (!padded)
725         {
726           doPadBlock512(H, M, W, true);
727         }
728
729         byte[] digest = new byte[64];
730         int i = 0;
731         int j = 0;
732         for (; j < 8; i += 8, j++)
733         {
734           digest[i] = (byte) (H[j] >>> 56);
735           digest[i + 1] = (byte) (H[j] >>> 48);
736           digest[i + 2] = (byte) (H[j] >>> 40);
737           digest[i + 3] = (byte) (H[j] >>> 32);
738           digest[i + 4] = (byte) (H[j] >>> 24);
739           digest[i + 5] = (byte) (H[j] >>> 16);
740           digest[i + 6] = (byte) (H[j] >>> 8);
741           digest[i + 7] = (byte) (H[j]);
742
743         }
744         if(closeInputStream)
745         {
746           inputStream.close();
747         }
748
749         if (sha384)
750         {
751           byte[] digest2 = new byte[48];
752           for (int k = 0; k < digest2.length; k++)
753           {
754             digest2[k] = digest[k];
755           }
756           return digest2;
757         }
758
759         return digest;
760       }
761
762       messageLengthLower += (bytesRead << 3);// messageLength in bits,
763

764       if (bytesRead < 110)
765       {
766         padded = true;
767         // do padding if read bytes is smaller than 55 ==> total message length
768
// can be added in this block as 64-bit value
769
// add 1 after message
770
Mb[bytesRead] = (byte) 0x80;
771         for (int i = bytesRead + 1; i < 112; i++)
772         {
773           Mb[i] = 0;
774         }
775         // add length as 128 bit value at the end of Mb
776
addLength512(Mb);
777       }
778
779       if (bytesRead == 110)
780       {
781         padded = true;
782
783         // need to add totally new 512 bit block with all zeros except
784
// last 64 bits which is message length
785
Mb[110] = (byte) (0x80);
786         addLength512(Mb);
787       }
788
789       if (bytesRead > 110 && bytesRead < 128)
790       {
791         padded = true;
792
793         // need to add totally new 512 bit block with all zeros except
794
// last 64 bits which is message length
795
Mb[bytesRead] = (byte) 0x80;
796         for (int i = bytesRead + 1; i < 128; i++)
797         {
798           Mb[i] = 0;
799         }
800         padBlock = true;// padBlock is 896-bits of zero + 128 bit length
801
}
802
803       // convert to long array. Java long is 64-bits
804
int i = 0;
805       int j = 0;
806       for (; i < 16; j += 8, i++)
807       {
808
809         M[i] = (((long) Mb[j]) << 56) | ((long) ((Mb[j + 1]) & 0xff) << 48)
810             | ((long) ((Mb[j + 2]) & 0xff) << 40)
811             | ((long) ((Mb[j + 3]) & 0xff) << 32)
812             | ((long) ((Mb[j + 4]) & 0xff) << 24)
813             | ((long) ((Mb[j + 5]) & 0xff) << 16)
814             | ((long) ((Mb[j + 6]) & 0xff) << 8) | ((long) (Mb[j + 7]) & 0xff);
815       }
816
817       // prepare message schedule
818
prepareMessageSchedule512(M, W);
819       // init working variables
820
long a = H[0];// 1732584193;
821
long b = H[1];// 4023233417;
822
long c = H[2];// 2562383102;
823
long d = H[3];// 271733878;
824
long e = H[4];// 3285377520;
825
long f = H[5];// 3285377520;
826
long g = H[6];// 3285377520;
827
long h = H[7];// 3285377520;
828

829       int t = 0;
830       for (; t < 80; t++)
831       {
832         long T1 = modulo64Add(
833                     modulo64Add(h, SIGMA512_1(e)), modulo64Add(modulo64Add(Ch(e, f, g),
834                         K512[t]), W[t]));
835
836         long T2 = modulo64Add(SIGMA512_0(a), Maj(a, b, c));
837
838         h = g;
839         g = f;
840         f = e;
841         e = modulo64Add(d, T1);
842         d = c;
843         c = b;
844         b = a;
845         a = modulo64Add(T1, T2);
846
847       }
848
849       H[0] = modulo64Add(H[0], a);
850       H[1] = modulo64Add(H[1], b);
851       H[2] = modulo64Add(H[2], c);
852       H[3] = modulo64Add(H[3], d);
853       H[4] = modulo64Add(H[4], e);
854       H[5] = modulo64Add(H[5], f);
855       H[6] = modulo64Add(H[6], g);
856       H[7] = modulo64Add(H[7], h);
857
858       // do last pad
859
if (padBlock)
860       {
861         doPadBlock512(H, M, W, false);
862       }
863
864       bytesRead = inputStream.read(Mb, 0, 128);
865     }
866
867   }
868
869   private void doPadBlock512(long[] H, long[] M, long[] W, boolean addOne)
870   {
871     // addOne is the required 1 before
872
M[0] = addOne ? 0x8000000000000000L : 0;
873     for (int i = 1; i < 14; i++)
874     {
875       M[i] = 0;
876     }
877
878     M[14] = messageLengthUpper;
879     M[15] = messageLengthLower;
880
881     // prepare message schedule
882
prepareMessageSchedule512(M, W);
883
884     // init working variables
885
long a = H[0];// 1732584193;
886
long b = H[1];// 4023233417;
887
long c = H[2];// 2562383102;
888
long d = H[3];// 271733878;
889
long e = H[4];// 3285377520;
890
long f = H[5];// 3285377520;
891
long g = H[6];// 3285377520;
892
long h = H[7];// 3285377520;
893

894     int t = 0;
895     long T1 = 0;
896     long T2 = 0;
897     for (; t < 80; t++)
898     {
899       T1 = modulo64Add(modulo64Add(modulo64Add(modulo64Add(h, SIGMA512_1(e)),
900           Ch(e, f, g)), K512[t]), W[t]);
901       T2 = modulo64Add(SIGMA512_0(a), Maj(a, b, c));
902       h = g;
903       g = f;
904       f = e;
905       e = modulo64Add(d, T1);
906       d = c;
907       c = b;
908       b = a;
909       a = modulo64Add(T1, T2);
910
911     }
912
913     H[0] = modulo64Add(H[0], a);
914     H[1] = modulo64Add(H[1], b);
915     H[2] = modulo64Add(H[2], c);
916     H[3] = modulo64Add(H[3], d);
917     H[4] = modulo64Add(H[4], e);
918     H[5] = modulo64Add(H[5], f);
919     H[6] = modulo64Add(H[6], g);
920     H[7] = modulo64Add(H[7], h);
921
922   }
923
924   private static final long[] K512 =
925   { 0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL,
926       0xe9b5dba58189dbbcL, 0x3956c25bf348b538L, 0x59f111f1b605d019L,
927       0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, 0xd807aa98a3030242L,
928       0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
929       0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L,
930       0xc19bf174cf692694L, 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L,
931       0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, 0x2de92c6f592b0275L,
932       0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
933       0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL,
934       0xbf597fc7beef0ee4L, 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L,
935       0x06ca6351e003826fL, 0x142929670a0e6e70L, 0x27b70a8546d22ffcL,
936       0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
937       0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L,
938       0x92722c851482353bL, 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L,
939       0xc24b8b70d0f89791L, 0xc76c51a30654be30L, 0xd192e819d6ef5218L,
940       0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L,
941       0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L,
942       0x34b0bcb5e19b48a8L, 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL,
943       0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, 0x748f82ee5defb2fcL,
944       0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
945       0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L,
946       0xc67178f2e372532bL, 0xca273eceea26619cL, 0xd186b8c721c0c207L,
947       0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, 0x06f067aa72176fbaL,
948       0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL,
949       0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL,
950       0x431d67c49c100d4cL, 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL,
951       0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L };
952
953   private long Ch(long x, long y, long z)
954   {
955     return (x & y) ^ (~x & z);
956
957   }
958
959   private long Maj(long x, long y, long z)
960   {
961     return (x & y) ^ (x & z) ^ (y & z);
962   }
963
964   private long SIGMA512_0(long x)
965   {
966     return ROTR(28, x) ^ ROTR(34, x) ^ ROTR(39, x);
967
968   }
969
970   private long SIGMA512_1(long x)
971   {
972     return ROTR(14, x) ^ ROTR(18, x) ^ ROTR(41, x);
973
974   }
975
976   private void prepareMessageSchedule512(long[] M, long[] W)
977   {
978     for (int t = 0; t < 80; t++)
979     {
980       if (t < 16)
981       {
982         W[t] = M[t];
983       }
984       else
985       {
986
987         W[t] = modulo64Add(modulo64Add(sigma512_1(W[t - 2]), W[t - 7]),
988             modulo64Add(sigma512_0(W[t - 15]), W[t - 16]));
989
990       }
991     }
992   }
993
994   private long sigma512_0(long x)
995   {
996     return ROTR(1, x) ^ ROTR(8, x) ^ SHR(7, x);
997   }
998
999   private long sigma512_1(long x)
1000  {
1001    return ROTR(19, x) ^ ROTR(61, x) ^ SHR(6, x);
1002  }
1003
1004  private long ROTR(int n, long x)
1005  {
1006    return (x >>> n) | (x << (64 - n));
1007
1008  }
1009
1010  private long SHR(int n, long x)
1011  {
1012    return x >>> n;
1013
1014  }
1015
1016  private long modulo64Add(long x, long y)
1017  {
1018    return (x ^ 0x8000000000000000L) + (y ^ 0x8000000000000000L);
1019
1020  }
1021
1022  private void addLength512(byte[] Mb)
1023  {
1024    Mb[112] = (byte) (messageLengthUpper >>> 56);
1025    Mb[113] = (byte) (messageLengthUpper >>> 48);
1026    Mb[114] = (byte) (messageLengthUpper >>> 40);
1027    Mb[115] = (byte) (messageLengthUpper >>> 32);
1028    Mb[116] = (byte) (messageLengthUpper >>> 24);
1029    Mb[117] = (byte) (messageLengthUpper >>> 16);
1030    Mb[118] = (byte) (messageLengthUpper >>> 8);
1031    Mb[119] = (byte) messageLengthUpper;
1032
1033    Mb[120] = (byte) (messageLengthLower >>> 56);
1034    Mb[121] = (byte) (messageLengthLower >>> 48);
1035    Mb[122] = (byte) (messageLengthLower >>> 40);
1036    Mb[123] = (byte) (messageLengthLower >>> 32);
1037    Mb[124] = (byte) (messageLengthLower >>> 24);
1038    Mb[125] = (byte) (messageLengthLower >>> 16);
1039    Mb[126] = (byte) (messageLengthLower >>> 8);
1040    Mb[127] = (byte) messageLengthLower;
1041
1042  }
1043
1044  // ENd SHA-512 implementation
1045

1046  /**
1047   * Resets instance for use in other operation. This must be
1048   * called before each consequent operation. If not called
1049   * results are not correct.
1050   */

1051  public void reset()
1052  {
1053    // sha-1 variables
1054
this.messageLength = 0;
1055
1056    // sha-512 variables
1057
this.messageLengthUpper = 0L;
1058    this.messageLengthLower = 0L;
1059
1060  }
1061}
1062
Popular Tags