2
* Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
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.
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.
26
* $Id: sha512.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $
30
* Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
32
* Define SHA512_TEST to test the implementation using the NIST's
33
* sample messages. The output should be:
35
* ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a
36
* 2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f
37
* 8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018
38
* 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909
39
* e718483d0ce76964 4e2e42c7bc15b463 8e1f98b13b204428 5632a803afa973eb
40
* de0ff244877ea60a 4cb0432ce577c31b eb009c5c2c49aa2e 4eadb217ad8cc09b
45
#endif /* HAVE_CONFIG_H */
48
# include <inttypes.h>
60
static const char rcsid[] =
61
"$Id: sha512.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
64
#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
65
#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
66
#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
67
#define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
69
#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
70
#define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
71
#define SIGMA0(x) (ROTR64((x), 28) ^ ROTR64((x), 34) ^ ROTR64((x), 39))
72
#define SIGMA1(x) (ROTR64((x), 14) ^ ROTR64((x), 18) ^ ROTR64((x), 41))
73
#define sigma0(x) (ROTR64((x), 1) ^ ROTR64((x), 8) ^ ((x) >> 7))
74
#define sigma1(x) (ROTR64((x), 19) ^ ROTR64((x), 61) ^ ((x) >> 6))
76
#define DO_ROUND() { \
77
t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
78
t2 = SIGMA0(a) + Maj(a, b, c); \
89
static const uint64_t K[80] = {
90
0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
91
0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
92
0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
93
0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
94
0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
95
0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
96
0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
97
0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
98
0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
99
0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
100
0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
101
0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
102
0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
103
0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
104
0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
105
0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
106
0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
107
0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
108
0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
109
0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
110
0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
111
0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
112
0xd192e819d6ef5218LL, 0xd69906245565a910LL,
113
0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
114
0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
115
0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
116
0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
117
0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
118
0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
119
0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
120
0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
121
0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
122
0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
123
0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
124
0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
125
0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
126
0x28db77f523047d84LL, 0x32caab7b40c72493LL,
127
0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
128
0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
129
0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL
132
#ifndef RUNTIME_ENDIAN
134
#ifdef WORDS_BIGENDIAN
136
#define BYTESWAP(x) (x)
137
#define BYTESWAP64(x) (x)
139
#else /* WORDS_BIGENDIAN */
141
#define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
142
(ROTL((x), 8) & 0x00ff00ffL))
143
#define BYTESWAP64(x) _byteswap64(x)
145
static inline uint64_t _byteswap64(uint64_t x)
147
uint32_t a = x >> 32;
148
uint32_t b = (uint32_t) x;
149
return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
152
#endif /* WORDS_BIGENDIAN */
154
#else /* !RUNTIME_ENDIAN */
156
#define BYTESWAP(x) _byteswap(sc->littleEndian, x)
157
#define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
159
#define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
160
(ROTL((x), 8) & 0x00ff00ffL))
161
#define _BYTESWAP64(x) __byteswap64(x)
163
static inline uint64_t __byteswap64(uint64_t x)
165
uint32_t a = x >> 32;
166
uint32_t b = (uint32_t) x;
167
return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
170
static inline uint32_t _byteswap(int littleEndian, uint32_t x)
178
static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
183
return _BYTESWAP64(x);
186
static inline void setEndian(int *littleEndianp)
194
*littleEndianp = endian.b[0] != 0;
197
#endif /* !RUNTIME_ENDIAN */
199
static const uint8_t padding[128] = {
200
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
219
SHA512Init (SHA512Context *sc)
221
#ifdef RUNTIME_ENDIAN
222
setEndian (&sc->littleEndian);
223
#endif /* RUNTIME_ENDIAN */
225
sc->totalLength[0] = 0LL;
226
sc->totalLength[1] = 0LL;
227
sc->hash[0] = 0x6a09e667f3bcc908LL;
228
sc->hash[1] = 0xbb67ae8584caa73bLL;
229
sc->hash[2] = 0x3c6ef372fe94f82bLL;
230
sc->hash[3] = 0xa54ff53a5f1d36f1LL;
231
sc->hash[4] = 0x510e527fade682d1LL;
232
sc->hash[5] = 0x9b05688c2b3e6c1fLL;
233
sc->hash[6] = 0x1f83d9abfb41bd6bLL;
234
sc->hash[7] = 0x5be0cd19137e2179LL;
235
sc->bufferLength = 0L;
243
memset (buf, 0, sizeof (buf));
244
size -= sizeof (buf);
250
SHA512Guts (SHA512Context *sc, const uint64_t *cbuf)
253
uint64_t *W, *W2, *W7, *W15, *W16;
254
uint64_t a, b, c, d, e, f, g, h;
261
for (i = 15; i >= 0; i--) {
262
*(W++) = BYTESWAP64(*cbuf);
271
for (i = 63; i >= 0; i--) {
272
*(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
289
for (i = 79; i >= 0; i--)
303
SHA512Update (SHA512Context *sc, const void *vdata, uint32_t len)
305
const uint8_t *data = vdata;
306
uint32_t bufferBytesLeft;
307
uint32_t bytesToCopy;
311
#ifdef SHA512_FAST_COPY
312
if (sc->bufferLength) {
313
bufferBytesLeft = 128L - sc->bufferLength;
315
bytesToCopy = bufferBytesLeft;
316
if (bytesToCopy > len)
319
memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
321
carryCheck = sc->totalLength[1];
322
sc->totalLength[1] += bytesToCopy * 8L;
323
if (sc->totalLength[1] < carryCheck)
324
sc->totalLength[0]++;
326
sc->bufferLength += bytesToCopy;
330
if (sc->bufferLength == 128L) {
331
SHA512Guts (sc, sc->buffer.words);
333
sc->bufferLength = 0L;
338
carryCheck = sc->totalLength[1];
339
sc->totalLength[1] += 1024L;
340
if (sc->totalLength[1] < carryCheck)
341
sc->totalLength[0]++;
343
SHA512Guts (sc, data);
351
memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
353
carryCheck = sc->totalLength[1];
354
sc->totalLength[1] += len * 8L;
355
if (sc->totalLength[1] < carryCheck)
356
sc->totalLength[0]++;
358
sc->bufferLength += len;
360
#else /* SHA512_FAST_COPY */
362
bufferBytesLeft = 128L - sc->bufferLength;
364
bytesToCopy = bufferBytesLeft;
365
if (bytesToCopy > len)
368
memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
370
carryCheck = sc->totalLength[1];
371
sc->totalLength[1] += bytesToCopy * 8L;
372
if (sc->totalLength[1] < carryCheck)
373
sc->totalLength[0]++;
375
sc->bufferLength += bytesToCopy;
379
if (sc->bufferLength == 128L) {
380
SHA512Guts (sc, sc->buffer.words);
382
sc->bufferLength = 0L;
385
#endif /* SHA512_FAST_COPY */
388
burnStack (sizeof (uint64_t[90]) + sizeof (uint64_t *[6]) + sizeof (int));
392
SHA512Final (SHA512Context *sc, uint8_t hash[SHA512_HASH_SIZE])
395
uint64_t lengthPad[2];
398
bytesToPad = 240L - sc->bufferLength;
399
if (bytesToPad > 128L)
402
lengthPad[0] = BYTESWAP64(sc->totalLength[0]);
403
lengthPad[1] = BYTESWAP64(sc->totalLength[1]);
405
SHA512Update (sc, padding, bytesToPad);
406
SHA512Update (sc, lengthPad, 16L);
409
for (i = 0; i < SHA512_HASH_WORDS; i++) {
410
#ifdef SHA384_FAST_COPY
411
*((uint64_t *) hash) = BYTESWAP64(sc->hash[i]);
412
#else /* SHA384_FAST_COPY */
413
hash[0] = (uint8_t) (sc->hash[i] >> 56);
414
hash[1] = (uint8_t) (sc->hash[i] >> 48);
415
hash[2] = (uint8_t) (sc->hash[i] >> 40);
416
hash[3] = (uint8_t) (sc->hash[i] >> 32);
417
hash[4] = (uint8_t) (sc->hash[i] >> 24);
418
hash[5] = (uint8_t) (sc->hash[i] >> 16);
419
hash[6] = (uint8_t) (sc->hash[i] >> 8);
420
hash[7] = (uint8_t) sc->hash[i];
421
#endif /* SHA384_FAST_COPY */
434
main (int argc, char *argv[])
437
uint8_t hash[SHA512_HASH_SIZE];
442
SHA512Update (&foo, "abc", 3);
443
SHA512Final (&foo, hash);
445
for (i = 0; i < SHA512_HASH_SIZE;) {
446
printf ("%02x", hash[i++]);
455
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
456
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
458
SHA512Final (&foo, hash);
460
for (i = 0; i < SHA512_HASH_SIZE;) {
461
printf ("%02x", hash[i++]);
469
memset (buf, 'a', sizeof (buf));
470
for (i = 0; i < 1000; i++)
471
SHA512Update (&foo, buf, sizeof (buf));
472
SHA512Final (&foo, hash);
474
for (i = 0; i < SHA512_HASH_SIZE;) {
475
printf ("%02x", hash[i++]);
485
#endif /* SHA512_TEST */