KickJava   Java API By Example, From Geeks To Geeks.

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


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 SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
24  *
25  * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
26  * is the "endienness" of the word processing!
27  */

28 public class SHA1Digest
29     extends GeneralDigest {
30   private static final int DIGEST_LENGTH = 20;
31
32   private int H1, H2, H3, H4, H5;
33
34   private int[] X = new int[80];
35   private int xOff;
36
37   /**
38    * Standard constructor
39    */

40   public SHA1Digest() {
41     reset();
42   }
43
44   /**
45    * Copy constructor. This will copy the state of the provided
46    * message digest.
47    */

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

119   public void reset() {
120     super.reset();
121
122     H1 = 0x67452301;
123     H2 = 0xefcdab89;
124     H3 = 0x98badcfe;
125     H4 = 0x10325476;
126     H5 = 0xc3d2e1f0;
127
128     xOff = 0;
129     for (int i = 0; i != X.length; i++) {
130       X[i] = 0;
131     }
132   }
133
134   //
135
// Additive constants
136
//
137
private static final int Y1 = 0x5a827999;
138   private static final int Y2 = 0x6ed9eba1;
139   private static final int Y3 = 0x8f1bbcdc;
140   private static final int Y4 = 0xca62c1d6;
141
142   private int f(
143       int u,
144       int v,
145       int w) {
146     return ( (u & v) | ( (~u) & w));
147   }
148
149   private int h(
150       int u,
151       int v,
152       int w) {
153     return (u ^ v ^ w);
154   }
155
156   private int g(
157       int u,
158       int v,
159       int w) {
160     return ( (u & v) | (u & w) | (v & w));
161   }
162
163   private int rotateLeft(
164       int x,
165       int n) {
166     return (x << n) | (x >>> (32 - n));
167   }
168
169   protected void processBlock() {
170     //
171
// expand 16 word block into 80 word block.
172
//
173
for (int i = 16; i <= 79; i++) {
174       X[i] = rotateLeft( (X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
175     }
176
177     //
178
// set up working variables.
179
//
180
int A = H1;
181     int B = H2;
182     int C = H3;
183     int D = H4;
184     int E = H5;
185
186     //
187
// round 1
188
//
189
for (int j = 0; j <= 19; j++) {
190       int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
191
192       E = D;
193       D = C;
194       C = rotateLeft(B, 30);
195       B = A;
196       A = t;
197     }
198
199     //
200
// round 2
201
//
202
for (int j = 20; j <= 39; j++) {
203       int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
204
205       E = D;
206       D = C;
207       C = rotateLeft(B, 30);
208       B = A;
209       A = t;
210     }
211
212     //
213
// round 3
214
//
215
for (int j = 40; j <= 59; j++) {
216       int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
217
218       E = D;
219       D = C;
220       C = rotateLeft(B, 30);
221       B = A;
222       A = t;
223     }
224
225     //
226
// round 4
227
//
228
for (int j = 60; j <= 79; j++) {
229       int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
230
231       E = D;
232       D = C;
233       C = rotateLeft(B, 30);
234       B = A;
235       A = t;
236     }
237
238     H1 += A;
239     H2 += B;
240     H3 += C;
241     H4 += D;
242     H5 += E;
243
244     //
245
// reset the offset and clean out the word buffer.
246
//
247
xOff = 0;
248     for (int i = 0; i != X.length; i++) {
249       X[i] = 0;
250     }
251   }
252 }
253
Popular Tags