"Fossies" - the Fresh Open Source Software Archive 
Member "duff-0.5.2/src/sha256.c" (10 Apr 2011, 12509 Bytes) of package /linux/privat/old/duff-0.5.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*-
2 * Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $Id: sha256.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $
27 */
28
29 /*
30 * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
31 *
32 * Define SHA256_TEST to test the implementation using the NIST's
33 * sample messages. The output should be:
34 *
35 * ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
36 * 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
37 * cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
38 */
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif /* HAVE_CONFIG_H */
43
44 #if HAVE_INTTYPES_H
45 # include <inttypes.h>
46 #else
47 # if HAVE_STDINT_H
48 # include <stdint.h>
49 # endif
50 #endif
51
52 #include <string.h>
53
54 #include "sha256.h"
55
56 #ifndef lint
57 static const char rcsid[] =
58 "$Id: sha256.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
59 #endif /* !lint */
60
61 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
62 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
63
64 #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
65 #define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
66 #define SIGMA0(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22))
67 #define SIGMA1(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25))
68 #define sigma0(x) (ROTR((x), 7) ^ ROTR((x), 18) ^ ((x) >> 3))
69 #define sigma1(x) (ROTR((x), 17) ^ ROTR((x), 19) ^ ((x) >> 10))
70
71 #define DO_ROUND() { \
72 t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
73 t2 = SIGMA0(a) + Maj(a, b, c); \
74 h = g; \
75 g = f; \
76 f = e; \
77 e = d + t1; \
78 d = c; \
79 c = b; \
80 b = a; \
81 a = t1 + t2; \
82 }
83
84 static const uint32_t K[64] = {
85 0x428a2f98L, 0x71374491L, 0xb5c0fbcfL, 0xe9b5dba5L,
86 0x3956c25bL, 0x59f111f1L, 0x923f82a4L, 0xab1c5ed5L,
87 0xd807aa98L, 0x12835b01L, 0x243185beL, 0x550c7dc3L,
88 0x72be5d74L, 0x80deb1feL, 0x9bdc06a7L, 0xc19bf174L,
89 0xe49b69c1L, 0xefbe4786L, 0x0fc19dc6L, 0x240ca1ccL,
90 0x2de92c6fL, 0x4a7484aaL, 0x5cb0a9dcL, 0x76f988daL,
91 0x983e5152L, 0xa831c66dL, 0xb00327c8L, 0xbf597fc7L,
92 0xc6e00bf3L, 0xd5a79147L, 0x06ca6351L, 0x14292967L,
93 0x27b70a85L, 0x2e1b2138L, 0x4d2c6dfcL, 0x53380d13L,
94 0x650a7354L, 0x766a0abbL, 0x81c2c92eL, 0x92722c85L,
95 0xa2bfe8a1L, 0xa81a664bL, 0xc24b8b70L, 0xc76c51a3L,
96 0xd192e819L, 0xd6990624L, 0xf40e3585L, 0x106aa070L,
97 0x19a4c116L, 0x1e376c08L, 0x2748774cL, 0x34b0bcb5L,
98 0x391c0cb3L, 0x4ed8aa4aL, 0x5b9cca4fL, 0x682e6ff3L,
99 0x748f82eeL, 0x78a5636fL, 0x84c87814L, 0x8cc70208L,
100 0x90befffaL, 0xa4506cebL, 0xbef9a3f7L, 0xc67178f2L
101 };
102
103 #ifndef RUNTIME_ENDIAN
104
105 #ifdef WORDS_BIGENDIAN
106
107 #define BYTESWAP(x) (x)
108 #define BYTESWAP64(x) (x)
109
110 #else /* WORDS_BIGENDIAN */
111
112 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
113 (ROTL((x), 8) & 0x00ff00ffL))
114 #define BYTESWAP64(x) _byteswap64(x)
115
116 static inline uint64_t _byteswap64(uint64_t x)
117 {
118 uint32_t a = x >> 32;
119 uint32_t b = (uint32_t) x;
120 return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
121 }
122
123 #endif /* WORDS_BIGENDIAN */
124
125 #else /* !RUNTIME_ENDIAN */
126
127 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
128 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
129
130 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
131 (ROTL((x), 8) & 0x00ff00ffL))
132 #define _BYTESWAP64(x) __byteswap64(x)
133
134 static inline uint64_t __byteswap64(uint64_t x)
135 {
136 uint32_t a = x >> 32;
137 uint32_t b = (uint32_t) x;
138 return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
139 }
140
141 static inline uint32_t _byteswap(int littleEndian, uint32_t x)
142 {
143 if (!littleEndian)
144 return x;
145 else
146 return _BYTESWAP(x);
147 }
148
149 static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
150 {
151 if (!littleEndian)
152 return x;
153 else
154 return _BYTESWAP64(x);
155 }
156
157 static inline void setEndian(int *littleEndianp)
158 {
159 union {
160 uint32_t w;
161 uint8_t b[4];
162 } endian;
163
164 endian.w = 1L;
165 *littleEndianp = endian.b[0] != 0;
166 }
167
168 #endif /* !RUNTIME_ENDIAN */
169
170 static const uint8_t padding[64] = {
171 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
179 };
180
181 void
182 SHA256Init (SHA256Context *sc)
183 {
184 #ifdef RUNTIME_ENDIAN
185 setEndian (&sc->littleEndian);
186 #endif /* RUNTIME_ENDIAN */
187
188 sc->totalLength = 0LL;
189 sc->hash[0] = 0x6a09e667L;
190 sc->hash[1] = 0xbb67ae85L;
191 sc->hash[2] = 0x3c6ef372L;
192 sc->hash[3] = 0xa54ff53aL;
193 sc->hash[4] = 0x510e527fL;
194 sc->hash[5] = 0x9b05688cL;
195 sc->hash[6] = 0x1f83d9abL;
196 sc->hash[7] = 0x5be0cd19L;
197 sc->bufferLength = 0L;
198 }
199
200 static void
201 burnStack (int size)
202 {
203 char buf[128];
204
205 memset (buf, 0, sizeof (buf));
206 size -= sizeof (buf);
207 if (size > 0)
208 burnStack (size);
209 }
210
211 static void
212 SHA256Guts (SHA256Context *sc, const uint32_t *cbuf)
213 {
214 uint32_t buf[64];
215 uint32_t *W, *W2, *W7, *W15, *W16;
216 uint32_t a, b, c, d, e, f, g, h;
217 uint32_t t1, t2;
218 const uint32_t *Kp;
219 int i;
220
221 W = buf;
222
223 for (i = 15; i >= 0; i--) {
224 *(W++) = BYTESWAP(*cbuf);
225 cbuf++;
226 }
227
228 W16 = &buf[0];
229 W15 = &buf[1];
230 W7 = &buf[9];
231 W2 = &buf[14];
232
233 for (i = 47; i >= 0; i--) {
234 *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
235 W2++;
236 W15++;
237 }
238
239 a = sc->hash[0];
240 b = sc->hash[1];
241 c = sc->hash[2];
242 d = sc->hash[3];
243 e = sc->hash[4];
244 f = sc->hash[5];
245 g = sc->hash[6];
246 h = sc->hash[7];
247
248 Kp = K;
249 W = buf;
250
251 #ifndef SHA256_UNROLL
252 #define SHA256_UNROLL 1
253 #endif /* !SHA256_UNROLL */
254
255 #if SHA256_UNROLL == 1
256 for (i = 63; i >= 0; i--)
257 DO_ROUND();
258 #elif SHA256_UNROLL == 2
259 for (i = 31; i >= 0; i--) {
260 DO_ROUND(); DO_ROUND();
261 }
262 #elif SHA256_UNROLL == 4
263 for (i = 15; i >= 0; i--) {
264 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
265 }
266 #elif SHA256_UNROLL == 8
267 for (i = 7; i >= 0; i--) {
268 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
269 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
270 }
271 #elif SHA256_UNROLL == 16
272 for (i = 3; i >= 0; i--) {
273 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
274 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
275 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
276 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
277 }
278 #elif SHA256_UNROLL == 32
279 for (i = 1; i >= 0; i--) {
280 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
281 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
282 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
283 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
284 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
285 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
286 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
287 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
288 }
289 #elif SHA256_UNROLL == 64
290 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
291 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
292 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
293 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
294 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
295 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
296 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
297 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
298 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
299 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
300 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
301 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
302 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
303 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
304 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
305 DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
306 #else
307 #error "SHA256_UNROLL must be 1, 2, 4, 8, 16, 32, or 64!"
308 #endif
309
310 sc->hash[0] += a;
311 sc->hash[1] += b;
312 sc->hash[2] += c;
313 sc->hash[3] += d;
314 sc->hash[4] += e;
315 sc->hash[5] += f;
316 sc->hash[6] += g;
317 sc->hash[7] += h;
318 }
319
320 void
321 SHA256Update (SHA256Context *sc, const void *vdata, uint32_t len)
322 {
323 const uint8_t *data = vdata;
324 uint32_t bufferBytesLeft;
325 uint32_t bytesToCopy;
326 int needBurn = 0;
327
328 #ifdef SHA256_FAST_COPY
329 if (sc->bufferLength) {
330 bufferBytesLeft = 64L - sc->bufferLength;
331
332 bytesToCopy = bufferBytesLeft;
333 if (bytesToCopy > len)
334 bytesToCopy = len;
335
336 memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
337
338 sc->totalLength += bytesToCopy * 8L;
339
340 sc->bufferLength += bytesToCopy;
341 data += bytesToCopy;
342 len -= bytesToCopy;
343
344 if (sc->bufferLength == 64L) {
345 SHA256Guts (sc, sc->buffer.words);
346 needBurn = 1;
347 sc->bufferLength = 0L;
348 }
349 }
350
351 while (len > 63L) {
352 sc->totalLength += 512L;
353
354 SHA256Guts (sc, data);
355 needBurn = 1;
356
357 data += 64L;
358 len -= 64L;
359 }
360
361 if (len) {
362 memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
363
364 sc->totalLength += len * 8L;
365
366 sc->bufferLength += len;
367 }
368 #else /* SHA256_FAST_COPY */
369 while (len) {
370 bufferBytesLeft = 64L - sc->bufferLength;
371
372 bytesToCopy = bufferBytesLeft;
373 if (bytesToCopy > len)
374 bytesToCopy = len;
375
376 memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
377
378 sc->totalLength += bytesToCopy * 8L;
379
380 sc->bufferLength += bytesToCopy;
381 data += bytesToCopy;
382 len -= bytesToCopy;
383
384 if (sc->bufferLength == 64L) {
385 SHA256Guts (sc, sc->buffer.words);
386 needBurn = 1;
387 sc->bufferLength = 0L;
388 }
389 }
390 #endif /* SHA256_FAST_COPY */
391
392 if (needBurn)
393 burnStack (sizeof (uint32_t[74]) + sizeof (uint32_t *[6]) + sizeof (int));
394 }
395
396 void
397 SHA256Final (SHA256Context *sc, uint8_t hash[SHA256_HASH_SIZE])
398 {
399 uint32_t bytesToPad;
400 uint64_t lengthPad;
401 int i;
402
403 bytesToPad = 120L - sc->bufferLength;
404 if (bytesToPad > 64L)
405 bytesToPad -= 64L;
406
407 lengthPad = BYTESWAP64(sc->totalLength);
408
409 SHA256Update (sc, padding, bytesToPad);
410 SHA256Update (sc, &lengthPad, 8L);
411
412 if (hash) {
413 for (i = 0; i < SHA256_HASH_WORDS; i++) {
414 #ifdef SHA256_FAST_COPY
415 *((uint32_t *) hash) = BYTESWAP(sc->hash[i]);
416 #else /* SHA256_FAST_COPY */
417 hash[0] = (uint8_t) (sc->hash[i] >> 24);
418 hash[1] = (uint8_t) (sc->hash[i] >> 16);
419 hash[2] = (uint8_t) (sc->hash[i] >> 8);
420 hash[3] = (uint8_t) sc->hash[i];
421 #endif /* SHA256_FAST_COPY */
422 hash += 4;
423 }
424 }
425 }
426
427 #ifdef SHA256_TEST
428
429 #include <stdio.h>
430 #include <stdlib.h>
431 #include <string.h>
432
433 int
434 main (int argc, char *argv[])
435 {
436 SHA256Context foo;
437 uint8_t hash[SHA256_HASH_SIZE];
438 char buf[1000];
439 int i;
440
441 SHA256Init (&foo);
442 SHA256Update (&foo, "abc", 3);
443 SHA256Final (&foo, hash);
444
445 for (i = 0; i < SHA256_HASH_SIZE;) {
446 printf ("%02x", hash[i++]);
447 if (!(i % 4))
448 printf (" ");
449 }
450 printf ("\n");
451
452 SHA256Init (&foo);
453 SHA256Update (&foo,
454 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
455 56);
456 SHA256Final (&foo, hash);
457
458 for (i = 0; i < SHA256_HASH_SIZE;) {
459 printf ("%02x", hash[i++]);
460 if (!(i % 4))
461 printf (" ");
462 }
463 printf ("\n");
464
465 SHA256Init (&foo);
466 memset (buf, 'a', sizeof (buf));
467 for (i = 0; i < 1000; i++)
468 SHA256Update (&foo, buf, sizeof (buf));
469 SHA256Final (&foo, hash);
470
471 for (i = 0; i < SHA256_HASH_SIZE;) {
472 printf ("%02x", hash[i++]);
473 if (!(i % 4))
474 printf (" ");
475 }
476 printf ("\n");
477
478 exit (0);
479 }
480
481 #endif /* SHA256_TEST */