1 package org.bouncycastle.crypto.digests;
2
3 import org.bouncycastle.crypto.Digest;
4
5
11 public class SHA1Digest
12 extends GeneralDigest
13 {
14 private static final int DIGEST_LENGTH = 20;
15
16 private intintintintintH1H2H3H4 H5;
17
18 private int[] X = new int[80];
19 private int xOff;
20
21
24 public SHA1Digest()
25 {
26 reset();
27 }
28
29
33 public SHA1Digest(SHA1Digest t)
34 {
35 super(t);
36
37 H1 = t.H1;
38 H2 = t.H2;
39 H3 = t.H3;
40 H4 = t.H4;
41 H5 = t.H5;
42
43 System.arraycopy(t.X, 0, X, 0, t.X.length);
44 xOff = t.xOff;
45 }
46
47 public String getAlgorithmName()
48 {
49 return "SHA-1";
50 }
51
52 public int getDigestSize()
53 {
54 return DIGEST_LENGTH;
55 }
56
57 protected void processWord(
58 byte[] in,
59 int inOff)
60 {
61 X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
62 | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
63
64 if (xOff == 16)
65 {
66 processBlock();
67 }
68 }
69
70 private void unpackWord(
71 int word,
72 byte[] out,
73 int outOff)
74 {
75 out[outOff] = (byte)(word >>> 24);
76 out[outOff + 1] = (byte)(word >>> 16);
77 out[outOff + 2] = (byte)(word >>> 8);
78 out[outOff + 3] = (byte)word;
79 }
80
81 protected void processLength(
82 long bitLength)
83 {
84 if (xOff > 14)
85 {
86 processBlock();
87 }
88
89 X[14] = (int)(bitLength >>> 32);
90 X[15] = (int)(bitLength & 0xffffffff);
91 }
92
93 public int doFinal(
94 byte[] out,
95 int outOff)
96 {
97 finish();
98
99 unpackWord(H1, out, outOff);
100 unpackWord(H2, out, outOff + 4);
101 unpackWord(H3, out, outOff + 8);
102 unpackWord(H4, out, outOff + 12);
103 unpackWord(H5, out, outOff + 16);
104
105 reset();
106
107 return DIGEST_LENGTH;
108 }
109
110
113 public void reset()
114 {
115 super.reset();
116
117 H1 = 0x67452301;
118 H2 = 0xefcdab89;
119 H3 = 0x98badcfe;
120 H4 = 0x10325476;
121 H5 = 0xc3d2e1f0;
122
123 xOff = 0;
124 for (int i = 0; i != X.length; i++)
125 {
126 X[i] = 0;
127 }
128 }
129
130
131
132
133 private static final int Y1 = 0x5a827999;
134 private static final int Y2 = 0x6ed9eba1;
135 private static final int Y3 = 0x8f1bbcdc;
136 private static final int Y4 = 0xca62c1d6;
137
138 private int f(
139 int u,
140 int v,
141 int w)
142 {
143 return ((u & v) | ((~u) & w));
144 }
145
146 private int h(
147 int u,
148 int v,
149 int w)
150 {
151 return (u ^ v ^ w);
152 }
153
154 private int g(
155 int u,
156 int v,
157 int w)
158 {
159 return ((u & v) | (u & w) | (v & w));
160 }
161
162 private int rotateLeft(
163 int x,
164 int n)
165 {
166 return (x << n) | (x >>> (32 - n));
167 }
168
169 protected void processBlock()
170 {
171
172
173
174 for (int i = 16; i <= 79; i++)
175 {
176 X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
177 }
178
179
180
181
182 int A = H1;
183 int B = H2;
184 int C = H3;
185 int D = H4;
186 int E = H5;
187
188
189
190
191 for (int j = 0; j <= 19; j++)
192 {
193 int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
194
195 E = D;
196 D = C;
197 C = rotateLeft(B, 30);
198 B = A;
199 A = t;
200 }
201
202
203
204
205 for (int j = 20; j <= 39; j++)
206 {
207 int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
208
209 E = D;
210 D = C;
211 C = rotateLeft(B, 30);
212 B = A;
213 A = t;
214 }
215
216
217
218
219 for (int j = 40; j <= 59; j++)
220 {
221 int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
222
223 E = D;
224 D = C;
225 C = rotateLeft(B, 30);
226 B = A;
227 A = t;
228 }
229
230
231
232
233 for (int j = 60; j <= 79; j++)
234 {
235 int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
236
237 E = D;
238 D = C;
239 C = rotateLeft(B, 30);
240 B = A;
241 A = t;
242 }
243
244 H1 += A;
245 H2 += B;
246 H3 += C;
247 H4 += D;
248 H5 += E;
249
250
251
252
253 xOff = 0;
254 for (int i = 0; i != X.length; i++)
255 {
256 X[i] = 0;
257 }
258 }
259 }
260