Initial commit.
[BoarSSL] / Crypto / SHA1.cs
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 using System;
26
27 namespace Crypto {
28
29 /*
30 * SHA-1 implementation. SHA-1 is described in FIPS 180-4. Note that
31 * SHA-1 collisions can be computed more efficiently than what would be
32 * expected from an ideal hash function with the same output size; and
33 * this was actually done at least once. Use with care.
34 */
35
36 public sealed class SHA1 : DigestCore {
37
38 const int BLOCK_LEN = 64;
39
40 uint A, B, C, D, E;
41 byte[] block, saveBlock;
42 int ptr;
43 ulong byteCount;
44
45 /*
46 * Create a new instance. It is ready to process data bytes.
47 */
48 public SHA1()
49 {
50 block = new byte[BLOCK_LEN];
51 saveBlock = new byte[BLOCK_LEN];
52 Reset();
53 }
54
55 /* see IDigest */
56 public override string Name {
57 get {
58 return "SHA-1";
59 }
60 }
61
62 /* see IDigest */
63 public override int DigestSize {
64 get {
65 return 20;
66 }
67 }
68
69 /* see IDigest */
70 public override int BlockSize {
71 get {
72 return 64;
73 }
74 }
75
76 /* see IDigest */
77 public override void Reset()
78 {
79 A = 0x67452301;
80 B = 0xEFCDAB89;
81 C = 0x98BADCFE;
82 D = 0x10325476;
83 E = 0xC3D2E1F0;
84 byteCount = 0;
85 ptr = 0;
86 }
87
88 /* see IDigest */
89 public override void Update(byte b)
90 {
91 block[ptr ++] = b;
92 byteCount ++;
93 if (ptr == BLOCK_LEN) {
94 ProcessBlock();
95 }
96 }
97
98 /* see IDigest */
99 public override void Update(byte[] buf, int off, int len)
100 {
101 if (len < 0) {
102 throw new ArgumentException("negative chunk length");
103 }
104 byteCount += (ulong)len;
105 while (len > 0) {
106 int clen = Math.Min(len, BLOCK_LEN - ptr);
107 Array.Copy(buf, off, block, ptr, clen);
108 off += clen;
109 len -= clen;
110 ptr += clen;
111 if (ptr == BLOCK_LEN) {
112 ProcessBlock();
113 }
114 }
115 }
116
117 /* see IDigest */
118 public override void DoPartial(byte[] outBuf, int off)
119 {
120 /*
121 * Save current state.
122 */
123 uint saveA = A;
124 uint saveB = B;
125 uint saveC = C;
126 uint saveD = D;
127 uint saveE = E;
128 int savePtr = ptr;
129 Array.Copy(block, 0, saveBlock, 0, savePtr);
130
131 /*
132 * Add padding. This may involve processing an extra block.
133 */
134 block[ptr ++] = 0x80;
135 if (ptr > BLOCK_LEN - 8) {
136 for (int j = ptr; j < BLOCK_LEN; j ++) {
137 block[j] = 0;
138 }
139 ProcessBlock();
140 }
141 for (int j = ptr; j < (BLOCK_LEN - 8); j ++) {
142 block[j] = 0;
143 }
144 ulong x = byteCount << 3;
145 Enc32be((uint)(x >> 32), block, BLOCK_LEN - 8);
146 Enc32be((uint)x, block, BLOCK_LEN - 4);
147
148 /*
149 * Process final block and encode result.
150 */
151 ProcessBlock();
152 Enc32be(A, outBuf, off);
153 Enc32be(B, outBuf, off + 4);
154 Enc32be(C, outBuf, off + 8);
155 Enc32be(D, outBuf, off + 12);
156 Enc32be(E, outBuf, off + 16);
157
158 /*
159 * Restore current state.
160 */
161 Array.Copy(saveBlock, 0, block, 0, savePtr);
162 A = saveA;
163 B = saveB;
164 C = saveC;
165 D = saveD;
166 E = saveE;
167 ptr = savePtr;
168 }
169
170 /* see IDigest */
171 public override IDigest Dup()
172 {
173 SHA1 h = new SHA1();
174 h.A = A;
175 h.B = B;
176 h.C = C;
177 h.D = D;
178 h.E = E;
179 h.ptr = ptr;
180 h.byteCount = byteCount;
181 Array.Copy(block, 0, h.block, 0, ptr);
182 return h;
183 }
184
185 /* see IDigest */
186 public override void CurrentState(byte[] outBuf, int off)
187 {
188 Enc32be(A, outBuf, off);
189 Enc32be(B, outBuf, off + 4);
190 Enc32be(C, outBuf, off + 8);
191 Enc32be(D, outBuf, off + 12);
192 Enc32be(E, outBuf, off + 16);
193 }
194
195 const uint K1 = 0x5A827999;
196 const uint K2 = 0x6ED9EBA1;
197 const uint K3 = 0x8F1BBCDC;
198 const uint K4 = 0xCA62C1D6;
199
200 void ProcessBlock()
201 {
202 /*
203 * Read state words.
204 */
205 uint wa = A;
206 uint wb = B;
207 uint wc = C;
208 uint wd = D;
209 uint we = E;
210
211 /*
212 * Rounds 0 to 19.
213 */
214 uint x0 = Dec32be(block, 0);
215 we += ((wa << 5) | (wa >> 27)) + (wd ^ (wb & (wc ^ wd))) + x0 + K1;
216 wb = (wb << 30) | (wb >> 2);
217 uint x1 = Dec32be(block, 4);
218 wd += ((we << 5) | (we >> 27)) + (wc ^ (wa & (wb ^ wc))) + x1 + K1;
219 wa = (wa << 30) | (wa >> 2);
220 uint x2 = Dec32be(block, 8);
221 wc += ((wd << 5) | (wd >> 27)) + (wb ^ (we & (wa ^ wb))) + x2 + K1;
222 we = (we << 30) | (we >> 2);
223 uint x3 = Dec32be(block, 12);
224 wb += ((wc << 5) | (wc >> 27)) + (wa ^ (wd & (we ^ wa))) + x3 + K1;
225 wd = (wd << 30) | (wd >> 2);
226 uint x4 = Dec32be(block, 16);
227 wa += ((wb << 5) | (wb >> 27)) + (we ^ (wc & (wd ^ we))) + x4 + K1;
228 wc = (wc << 30) | (wc >> 2);
229 uint x5 = Dec32be(block, 20);
230 we += ((wa << 5) | (wa >> 27)) + (wd ^ (wb & (wc ^ wd))) + x5 + K1;
231 wb = (wb << 30) | (wb >> 2);
232 uint x6 = Dec32be(block, 24);
233 wd += ((we << 5) | (we >> 27)) + (wc ^ (wa & (wb ^ wc))) + x6 + K1;
234 wa = (wa << 30) | (wa >> 2);
235 uint x7 = Dec32be(block, 28);
236 wc += ((wd << 5) | (wd >> 27)) + (wb ^ (we & (wa ^ wb))) + x7 + K1;
237 we = (we << 30) | (we >> 2);
238 uint x8 = Dec32be(block, 32);
239 wb += ((wc << 5) | (wc >> 27)) + (wa ^ (wd & (we ^ wa))) + x8 + K1;
240 wd = (wd << 30) | (wd >> 2);
241 uint x9 = Dec32be(block, 36);
242 wa += ((wb << 5) | (wb >> 27)) + (we ^ (wc & (wd ^ we))) + x9 + K1;
243 wc = (wc << 30) | (wc >> 2);
244 uint xA = Dec32be(block, 40);
245 we += ((wa << 5) | (wa >> 27)) + (wd ^ (wb & (wc ^ wd))) + xA + K1;
246 wb = (wb << 30) | (wb >> 2);
247 uint xB = Dec32be(block, 44);
248 wd += ((we << 5) | (we >> 27)) + (wc ^ (wa & (wb ^ wc))) + xB + K1;
249 wa = (wa << 30) | (wa >> 2);
250 uint xC = Dec32be(block, 48);
251 wc += ((wd << 5) | (wd >> 27)) + (wb ^ (we & (wa ^ wb))) + xC + K1;
252 we = (we << 30) | (we >> 2);
253 uint xD = Dec32be(block, 52);
254 wb += ((wc << 5) | (wc >> 27)) + (wa ^ (wd & (we ^ wa))) + xD + K1;
255 wd = (wd << 30) | (wd >> 2);
256 uint xE = Dec32be(block, 56);
257 wa += ((wb << 5) | (wb >> 27)) + (we ^ (wc & (wd ^ we))) + xE + K1;
258 wc = (wc << 30) | (wc >> 2);
259 uint xF = Dec32be(block, 60);
260 we += ((wa << 5) | (wa >> 27)) + (wd ^ (wb & (wc ^ wd))) + xF + K1;
261 wb = (wb << 30) | (wb >> 2);
262 x0 ^= xD ^ x8 ^ x2;
263 x0 = (x0 << 1) | (x0 >> 31);
264 wd += ((we << 5) | (we >> 27)) + (wc ^ (wa & (wb ^ wc))) + x0 + K1;
265 wa = (wa << 30) | (wa >> 2);
266 x1 ^= xE ^ x9 ^ x3;
267 x1 = (x1 << 1) | (x1 >> 31);
268 wc += ((wd << 5) | (wd >> 27)) + (wb ^ (we & (wa ^ wb))) + x1 + K1;
269 we = (we << 30) | (we >> 2);
270 x2 ^= xF ^ xA ^ x4;
271 x2 = (x2 << 1) | (x2 >> 31);
272 wb += ((wc << 5) | (wc >> 27)) + (wa ^ (wd & (we ^ wa))) + x2 + K1;
273 wd = (wd << 30) | (wd >> 2);
274 x3 ^= x0 ^ xB ^ x5;
275 x3 = (x3 << 1) | (x3 >> 31);
276 wa += ((wb << 5) | (wb >> 27)) + (we ^ (wc & (wd ^ we))) + x3 + K1;
277 wc = (wc << 30) | (wc >> 2);
278
279 /*
280 * Rounds 20 to 39.
281 */
282 x4 ^= x1 ^ xC ^ x6;
283 x4 = (x4 << 1) | (x4 >> 31);
284 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + x4 + K2;
285 wb = (wb << 30) | (wb >> 2);
286 x5 ^= x2 ^ xD ^ x7;
287 x5 = (x5 << 1) | (x5 >> 31);
288 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + x5 + K2;
289 wa = (wa << 30) | (wa >> 2);
290 x6 ^= x3 ^ xE ^ x8;
291 x6 = (x6 << 1) | (x6 >> 31);
292 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + x6 + K2;
293 we = (we << 30) | (we >> 2);
294 x7 ^= x4 ^ xF ^ x9;
295 x7 = (x7 << 1) | (x7 >> 31);
296 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + x7 + K2;
297 wd = (wd << 30) | (wd >> 2);
298 x8 ^= x5 ^ x0 ^ xA;
299 x8 = (x8 << 1) | (x8 >> 31);
300 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + x8 + K2;
301 wc = (wc << 30) | (wc >> 2);
302 x9 ^= x6 ^ x1 ^ xB;
303 x9 = (x9 << 1) | (x9 >> 31);
304 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + x9 + K2;
305 wb = (wb << 30) | (wb >> 2);
306 xA ^= x7 ^ x2 ^ xC;
307 xA = (xA << 1) | (xA >> 31);
308 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + xA + K2;
309 wa = (wa << 30) | (wa >> 2);
310 xB ^= x8 ^ x3 ^ xD;
311 xB = (xB << 1) | (xB >> 31);
312 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + xB + K2;
313 we = (we << 30) | (we >> 2);
314 xC ^= x9 ^ x4 ^ xE;
315 xC = (xC << 1) | (xC >> 31);
316 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + xC + K2;
317 wd = (wd << 30) | (wd >> 2);
318 xD ^= xA ^ x5 ^ xF;
319 xD = (xD << 1) | (xD >> 31);
320 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + xD + K2;
321 wc = (wc << 30) | (wc >> 2);
322 xE ^= xB ^ x6 ^ x0;
323 xE = (xE << 1) | (xE >> 31);
324 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + xE + K2;
325 wb = (wb << 30) | (wb >> 2);
326 xF ^= xC ^ x7 ^ x1;
327 xF = (xF << 1) | (xF >> 31);
328 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + xF + K2;
329 wa = (wa << 30) | (wa >> 2);
330 x0 ^= xD ^ x8 ^ x2;
331 x0 = (x0 << 1) | (x0 >> 31);
332 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + x0 + K2;
333 we = (we << 30) | (we >> 2);
334 x1 ^= xE ^ x9 ^ x3;
335 x1 = (x1 << 1) | (x1 >> 31);
336 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + x1 + K2;
337 wd = (wd << 30) | (wd >> 2);
338 x2 ^= xF ^ xA ^ x4;
339 x2 = (x2 << 1) | (x2 >> 31);
340 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + x2 + K2;
341 wc = (wc << 30) | (wc >> 2);
342 x3 ^= x0 ^ xB ^ x5;
343 x3 = (x3 << 1) | (x3 >> 31);
344 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + x3 + K2;
345 wb = (wb << 30) | (wb >> 2);
346 x4 ^= x1 ^ xC ^ x6;
347 x4 = (x4 << 1) | (x4 >> 31);
348 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + x4 + K2;
349 wa = (wa << 30) | (wa >> 2);
350 x5 ^= x2 ^ xD ^ x7;
351 x5 = (x5 << 1) | (x5 >> 31);
352 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + x5 + K2;
353 we = (we << 30) | (we >> 2);
354 x6 ^= x3 ^ xE ^ x8;
355 x6 = (x6 << 1) | (x6 >> 31);
356 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + x6 + K2;
357 wd = (wd << 30) | (wd >> 2);
358 x7 ^= x4 ^ xF ^ x9;
359 x7 = (x7 << 1) | (x7 >> 31);
360 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + x7 + K2;
361 wc = (wc << 30) | (wc >> 2);
362
363 /*
364 * Rounds 40 to 59.
365 */
366 x8 ^= x5 ^ x0 ^ xA;
367 x8 = (x8 << 1) | (x8 >> 31);
368 we += ((wa << 5) | (wa >> 27)) + ((wc & wd) ^ (wb & (wc ^ wd))) + x8 + K3;
369 wb = (wb << 30) | (wb >> 2);
370 x9 ^= x6 ^ x1 ^ xB;
371 x9 = (x9 << 1) | (x9 >> 31);
372 wd += ((we << 5) | (we >> 27)) + ((wb & wc) ^ (wa & (wb ^ wc))) + x9 + K3;
373 wa = (wa << 30) | (wa >> 2);
374 xA ^= x7 ^ x2 ^ xC;
375 xA = (xA << 1) | (xA >> 31);
376 wc += ((wd << 5) | (wd >> 27)) + ((wa & wb) ^ (we & (wa ^ wb))) + xA + K3;
377 we = (we << 30) | (we >> 2);
378 xB ^= x8 ^ x3 ^ xD;
379 xB = (xB << 1) | (xB >> 31);
380 wb += ((wc << 5) | (wc >> 27)) + ((we & wa) ^ (wd & (we ^ wa))) + xB + K3;
381 wd = (wd << 30) | (wd >> 2);
382 xC ^= x9 ^ x4 ^ xE;
383 xC = (xC << 1) | (xC >> 31);
384 wa += ((wb << 5) | (wb >> 27)) + ((wd & we) ^ (wc & (wd ^ we))) + xC + K3;
385 wc = (wc << 30) | (wc >> 2);
386 xD ^= xA ^ x5 ^ xF;
387 xD = (xD << 1) | (xD >> 31);
388 we += ((wa << 5) | (wa >> 27)) + ((wc & wd) ^ (wb & (wc ^ wd))) + xD + K3;
389 wb = (wb << 30) | (wb >> 2);
390 xE ^= xB ^ x6 ^ x0;
391 xE = (xE << 1) | (xE >> 31);
392 wd += ((we << 5) | (we >> 27)) + ((wb & wc) ^ (wa & (wb ^ wc))) + xE + K3;
393 wa = (wa << 30) | (wa >> 2);
394 xF ^= xC ^ x7 ^ x1;
395 xF = (xF << 1) | (xF >> 31);
396 wc += ((wd << 5) | (wd >> 27)) + ((wa & wb) ^ (we & (wa ^ wb))) + xF + K3;
397 we = (we << 30) | (we >> 2);
398 x0 ^= xD ^ x8 ^ x2;
399 x0 = (x0 << 1) | (x0 >> 31);
400 wb += ((wc << 5) | (wc >> 27)) + ((we & wa) ^ (wd & (we ^ wa))) + x0 + K3;
401 wd = (wd << 30) | (wd >> 2);
402 x1 ^= xE ^ x9 ^ x3;
403 x1 = (x1 << 1) | (x1 >> 31);
404 wa += ((wb << 5) | (wb >> 27)) + ((wd & we) ^ (wc & (wd ^ we))) + x1 + K3;
405 wc = (wc << 30) | (wc >> 2);
406 x2 ^= xF ^ xA ^ x4;
407 x2 = (x2 << 1) | (x2 >> 31);
408 we += ((wa << 5) | (wa >> 27)) + ((wc & wd) ^ (wb & (wc ^ wd))) + x2 + K3;
409 wb = (wb << 30) | (wb >> 2);
410 x3 ^= x0 ^ xB ^ x5;
411 x3 = (x3 << 1) | (x3 >> 31);
412 wd += ((we << 5) | (we >> 27)) + ((wb & wc) ^ (wa & (wb ^ wc))) + x3 + K3;
413 wa = (wa << 30) | (wa >> 2);
414 x4 ^= x1 ^ xC ^ x6;
415 x4 = (x4 << 1) | (x4 >> 31);
416 wc += ((wd << 5) | (wd >> 27)) + ((wa & wb) ^ (we & (wa ^ wb))) + x4 + K3;
417 we = (we << 30) | (we >> 2);
418 x5 ^= x2 ^ xD ^ x7;
419 x5 = (x5 << 1) | (x5 >> 31);
420 wb += ((wc << 5) | (wc >> 27)) + ((we & wa) ^ (wd & (we ^ wa))) + x5 + K3;
421 wd = (wd << 30) | (wd >> 2);
422 x6 ^= x3 ^ xE ^ x8;
423 x6 = (x6 << 1) | (x6 >> 31);
424 wa += ((wb << 5) | (wb >> 27)) + ((wd & we) ^ (wc & (wd ^ we))) + x6 + K3;
425 wc = (wc << 30) | (wc >> 2);
426 x7 ^= x4 ^ xF ^ x9;
427 x7 = (x7 << 1) | (x7 >> 31);
428 we += ((wa << 5) | (wa >> 27)) + ((wc & wd) ^ (wb & (wc ^ wd))) + x7 + K3;
429 wb = (wb << 30) | (wb >> 2);
430 x8 ^= x5 ^ x0 ^ xA;
431 x8 = (x8 << 1) | (x8 >> 31);
432 wd += ((we << 5) | (we >> 27)) + ((wb & wc) ^ (wa & (wb ^ wc))) + x8 + K3;
433 wa = (wa << 30) | (wa >> 2);
434 x9 ^= x6 ^ x1 ^ xB;
435 x9 = (x9 << 1) | (x9 >> 31);
436 wc += ((wd << 5) | (wd >> 27)) + ((wa & wb) ^ (we & (wa ^ wb))) + x9 + K3;
437 we = (we << 30) | (we >> 2);
438 xA ^= x7 ^ x2 ^ xC;
439 xA = (xA << 1) | (xA >> 31);
440 wb += ((wc << 5) | (wc >> 27)) + ((we & wa) ^ (wd & (we ^ wa))) + xA + K3;
441 wd = (wd << 30) | (wd >> 2);
442 xB ^= x8 ^ x3 ^ xD;
443 xB = (xB << 1) | (xB >> 31);
444 wa += ((wb << 5) | (wb >> 27)) + ((wd & we) ^ (wc & (wd ^ we))) + xB + K3;
445 wc = (wc << 30) | (wc >> 2);
446
447 /*
448 * Rounds 60 to 79.
449 */
450 xC ^= x9 ^ x4 ^ xE;
451 xC = (xC << 1) | (xC >> 31);
452 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + xC + K4;
453 wb = (wb << 30) | (wb >> 2);
454 xD ^= xA ^ x5 ^ xF;
455 xD = (xD << 1) | (xD >> 31);
456 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + xD + K4;
457 wa = (wa << 30) | (wa >> 2);
458 xE ^= xB ^ x6 ^ x0;
459 xE = (xE << 1) | (xE >> 31);
460 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + xE + K4;
461 we = (we << 30) | (we >> 2);
462 xF ^= xC ^ x7 ^ x1;
463 xF = (xF << 1) | (xF >> 31);
464 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + xF + K4;
465 wd = (wd << 30) | (wd >> 2);
466 x0 ^= xD ^ x8 ^ x2;
467 x0 = (x0 << 1) | (x0 >> 31);
468 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + x0 + K4;
469 wc = (wc << 30) | (wc >> 2);
470 x1 ^= xE ^ x9 ^ x3;
471 x1 = (x1 << 1) | (x1 >> 31);
472 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + x1 + K4;
473 wb = (wb << 30) | (wb >> 2);
474 x2 ^= xF ^ xA ^ x4;
475 x2 = (x2 << 1) | (x2 >> 31);
476 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + x2 + K4;
477 wa = (wa << 30) | (wa >> 2);
478 x3 ^= x0 ^ xB ^ x5;
479 x3 = (x3 << 1) | (x3 >> 31);
480 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + x3 + K4;
481 we = (we << 30) | (we >> 2);
482 x4 ^= x1 ^ xC ^ x6;
483 x4 = (x4 << 1) | (x4 >> 31);
484 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + x4 + K4;
485 wd = (wd << 30) | (wd >> 2);
486 x5 ^= x2 ^ xD ^ x7;
487 x5 = (x5 << 1) | (x5 >> 31);
488 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + x5 + K4;
489 wc = (wc << 30) | (wc >> 2);
490 x6 ^= x3 ^ xE ^ x8;
491 x6 = (x6 << 1) | (x6 >> 31);
492 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + x6 + K4;
493 wb = (wb << 30) | (wb >> 2);
494 x7 ^= x4 ^ xF ^ x9;
495 x7 = (x7 << 1) | (x7 >> 31);
496 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + x7 + K4;
497 wa = (wa << 30) | (wa >> 2);
498 x8 ^= x5 ^ x0 ^ xA;
499 x8 = (x8 << 1) | (x8 >> 31);
500 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + x8 + K4;
501 we = (we << 30) | (we >> 2);
502 x9 ^= x6 ^ x1 ^ xB;
503 x9 = (x9 << 1) | (x9 >> 31);
504 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + x9 + K4;
505 wd = (wd << 30) | (wd >> 2);
506 xA ^= x7 ^ x2 ^ xC;
507 xA = (xA << 1) | (xA >> 31);
508 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + xA + K4;
509 wc = (wc << 30) | (wc >> 2);
510 xB ^= x8 ^ x3 ^ xD;
511 xB = (xB << 1) | (xB >> 31);
512 we += ((wa << 5) | (wa >> 27)) + (wb ^ wc ^ wd) + xB + K4;
513 wb = (wb << 30) | (wb >> 2);
514 xC ^= x9 ^ x4 ^ xE;
515 xC = (xC << 1) | (xC >> 31);
516 wd += ((we << 5) | (we >> 27)) + (wa ^ wb ^ wc) + xC + K4;
517 wa = (wa << 30) | (wa >> 2);
518 xD ^= xA ^ x5 ^ xF;
519 xD = (xD << 1) | (xD >> 31);
520 wc += ((wd << 5) | (wd >> 27)) + (we ^ wa ^ wb) + xD + K4;
521 we = (we << 30) | (we >> 2);
522 xE ^= xB ^ x6 ^ x0;
523 xE = (xE << 1) | (xE >> 31);
524 wb += ((wc << 5) | (wc >> 27)) + (wd ^ we ^ wa) + xE + K4;
525 wd = (wd << 30) | (wd >> 2);
526 xF ^= xC ^ x7 ^ x1;
527 xF = (xF << 1) | (xF >> 31);
528 wa += ((wb << 5) | (wb >> 27)) + (wc ^ wd ^ we) + xF + K4;
529 wc = (wc << 30) | (wc >> 2);
530
531 /*
532 * Update state words and reset block pointer.
533 */
534 A += wa;
535 B += wb;
536 C += wc;
537 D += wd;
538 E += we;
539 ptr = 0;
540 }
541
542 static uint Dec32be(byte[] buf, int off)
543 {
544 return ((uint)buf[off] << 24)
545 | ((uint)buf[off + 1] << 16)
546 | ((uint)buf[off + 2] << 8)
547 | (uint)buf[off + 3];
548 }
549
550 static void Enc32be(uint x, byte[] buf, int off)
551 {
552 buf[off] = (byte)(x >> 24);
553 buf[off + 1] = (byte)(x >> 16);
554 buf[off + 2] = (byte)(x >> 8);
555 buf[off + 3] = (byte)x;
556 }
557 }
558
559 }