~ubuntu-branches/ubuntu/utopic/duff/utopic

« back to all changes in this revision

Viewing changes to src/sha512.c

  • Committer: Package Import Robot
  • Author(s): Kamal Mostafa
  • Date: 2012-01-29 08:02:46 UTC
  • Revision ID: package-import@ubuntu.com-20120129080246-jd9w62dkx0v5q7r1
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: sha512.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 SHA512_TEST to test the implementation using the NIST's
 
33
 * sample messages. The output should be:
 
34
 *
 
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
 
41
 */
 
42
 
 
43
#ifdef HAVE_CONFIG_H
 
44
#include <config.h>
 
45
#endif /* HAVE_CONFIG_H */
 
46
 
 
47
#if HAVE_INTTYPES_H
 
48
# include <inttypes.h>
 
49
#else
 
50
# if HAVE_STDINT_H
 
51
#  include <stdint.h>
 
52
# endif
 
53
#endif
 
54
 
 
55
#include <string.h>
 
56
 
 
57
#include "sha512.h"
 
58
 
 
59
#ifndef lint
 
60
static const char rcsid[] =
 
61
        "$Id: sha512.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
 
62
#endif /* !lint */
 
63
 
 
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))))
 
68
 
 
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))
 
75
 
 
76
#define DO_ROUND() { \
 
77
  t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
 
78
  t2 = SIGMA0(a) + Maj(a, b, c); \
 
79
  h = g; \
 
80
  g = f; \
 
81
  f = e; \
 
82
  e = d + t1; \
 
83
  d = c; \
 
84
  c = b; \
 
85
  b = a; \
 
86
  a = t1 + t2; \
 
87
}
 
88
 
 
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
 
130
};
 
131
 
 
132
#ifndef RUNTIME_ENDIAN
 
133
 
 
134
#ifdef WORDS_BIGENDIAN
 
135
 
 
136
#define BYTESWAP(x) (x)
 
137
#define BYTESWAP64(x) (x)
 
138
 
 
139
#else /* WORDS_BIGENDIAN */
 
140
 
 
141
#define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
 
142
                     (ROTL((x), 8) & 0x00ff00ffL))
 
143
#define BYTESWAP64(x) _byteswap64(x)
 
144
 
 
145
static inline uint64_t _byteswap64(uint64_t x)
 
146
{
 
147
  uint32_t a = x >> 32;
 
148
  uint32_t b = (uint32_t) x;
 
149
  return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
 
150
}
 
151
 
 
152
#endif /* WORDS_BIGENDIAN */
 
153
 
 
154
#else /* !RUNTIME_ENDIAN */
 
155
 
 
156
#define BYTESWAP(x) _byteswap(sc->littleEndian, x)
 
157
#define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
 
158
 
 
159
#define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
 
160
                      (ROTL((x), 8) & 0x00ff00ffL))
 
161
#define _BYTESWAP64(x) __byteswap64(x)
 
162
 
 
163
static inline uint64_t __byteswap64(uint64_t x)
 
164
{
 
165
  uint32_t a = x >> 32;
 
166
  uint32_t b = (uint32_t) x;
 
167
  return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
 
168
}
 
169
 
 
170
static inline uint32_t _byteswap(int littleEndian, uint32_t x)
 
171
{
 
172
  if (!littleEndian)
 
173
    return x;
 
174
  else
 
175
    return _BYTESWAP(x);
 
176
}
 
177
 
 
178
static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
 
179
{
 
180
  if (!littleEndian)
 
181
    return x;
 
182
  else
 
183
    return _BYTESWAP64(x);
 
184
}
 
185
 
 
186
static inline void setEndian(int *littleEndianp)
 
187
{
 
188
  union {
 
189
    uint32_t w;
 
190
    uint8_t b[4];
 
191
  } endian;
 
192
 
 
193
  endian.w = 1L;
 
194
  *littleEndianp = endian.b[0] != 0;
 
195
}
 
196
 
 
197
#endif /* !RUNTIME_ENDIAN */
 
198
 
 
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
 
216
};
 
217
 
 
218
void
 
219
SHA512Init (SHA512Context *sc)
 
220
{
 
221
#ifdef RUNTIME_ENDIAN
 
222
  setEndian (&sc->littleEndian);
 
223
#endif /* RUNTIME_ENDIAN */
 
224
 
 
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;
 
236
}
 
237
 
 
238
static void
 
239
burnStack (int size)
 
240
{
 
241
  char buf[128];
 
242
 
 
243
  memset (buf, 0, sizeof (buf));
 
244
  size -= sizeof (buf);
 
245
  if (size > 0)
 
246
    burnStack (size);
 
247
}
 
248
 
 
249
static void
 
250
SHA512Guts (SHA512Context *sc, const uint64_t *cbuf)
 
251
{
 
252
  uint64_t buf[80];
 
253
  uint64_t *W, *W2, *W7, *W15, *W16;
 
254
  uint64_t a, b, c, d, e, f, g, h;
 
255
  uint64_t t1, t2;
 
256
  const uint64_t *Kp;
 
257
  int i;
 
258
 
 
259
  W = buf;
 
260
 
 
261
  for (i = 15; i >= 0; i--) {
 
262
    *(W++) = BYTESWAP64(*cbuf);
 
263
    cbuf++;
 
264
  }
 
265
 
 
266
  W16 = &buf[0];
 
267
  W15 = &buf[1];
 
268
  W7 = &buf[9];
 
269
  W2 = &buf[14];
 
270
 
 
271
  for (i = 63; i >= 0; i--) {
 
272
    *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
 
273
    W2++;
 
274
    W15++;
 
275
  }
 
276
 
 
277
  a = sc->hash[0];
 
278
  b = sc->hash[1];
 
279
  c = sc->hash[2];
 
280
  d = sc->hash[3];
 
281
  e = sc->hash[4];
 
282
  f = sc->hash[5];
 
283
  g = sc->hash[6];
 
284
  h = sc->hash[7];
 
285
 
 
286
  Kp = K;
 
287
  W = buf;
 
288
 
 
289
  for (i = 79; i >= 0; i--)
 
290
    DO_ROUND();
 
291
 
 
292
  sc->hash[0] += a;
 
293
  sc->hash[1] += b;
 
294
  sc->hash[2] += c;
 
295
  sc->hash[3] += d;
 
296
  sc->hash[4] += e;
 
297
  sc->hash[5] += f;
 
298
  sc->hash[6] += g;
 
299
  sc->hash[7] += h;
 
300
}
 
301
 
 
302
void
 
303
SHA512Update (SHA512Context *sc, const void *vdata, uint32_t len)
 
304
{
 
305
  const uint8_t *data = vdata;
 
306
  uint32_t bufferBytesLeft;
 
307
  uint32_t bytesToCopy;
 
308
  uint64_t carryCheck;
 
309
  int needBurn = 0;
 
310
 
 
311
#ifdef SHA512_FAST_COPY
 
312
  if (sc->bufferLength) {
 
313
    bufferBytesLeft = 128L - sc->bufferLength;
 
314
 
 
315
    bytesToCopy = bufferBytesLeft;
 
316
    if (bytesToCopy > len)
 
317
      bytesToCopy = len;
 
318
 
 
319
    memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
 
320
 
 
321
    carryCheck = sc->totalLength[1];
 
322
    sc->totalLength[1] += bytesToCopy * 8L;
 
323
    if (sc->totalLength[1] < carryCheck)
 
324
      sc->totalLength[0]++;
 
325
 
 
326
    sc->bufferLength += bytesToCopy;
 
327
    data += bytesToCopy;
 
328
    len -= bytesToCopy;
 
329
 
 
330
    if (sc->bufferLength == 128L) {
 
331
      SHA512Guts (sc, sc->buffer.words);
 
332
      needBurn = 1;
 
333
      sc->bufferLength = 0L;
 
334
    }
 
335
  }
 
336
 
 
337
  while (len > 127) {
 
338
    carryCheck = sc->totalLength[1];
 
339
    sc->totalLength[1] += 1024L;
 
340
    if (sc->totalLength[1] < carryCheck)
 
341
      sc->totalLength[0]++;
 
342
 
 
343
    SHA512Guts (sc, data);
 
344
    needBurn = 1;
 
345
 
 
346
    data += 128L;
 
347
    len -= 128L;
 
348
  }
 
349
 
 
350
  if (len) {
 
351
    memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
 
352
 
 
353
    carryCheck = sc->totalLength[1];
 
354
    sc->totalLength[1] += len * 8L;
 
355
    if (sc->totalLength[1] < carryCheck)
 
356
      sc->totalLength[0]++;
 
357
 
 
358
    sc->bufferLength += len;
 
359
  }
 
360
#else /* SHA512_FAST_COPY */
 
361
  while (len) {
 
362
    bufferBytesLeft = 128L - sc->bufferLength;
 
363
 
 
364
    bytesToCopy = bufferBytesLeft;
 
365
    if (bytesToCopy > len)
 
366
      bytesToCopy = len;
 
367
 
 
368
    memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
 
369
 
 
370
    carryCheck = sc->totalLength[1];
 
371
    sc->totalLength[1] += bytesToCopy * 8L;
 
372
    if (sc->totalLength[1] < carryCheck)
 
373
      sc->totalLength[0]++;
 
374
 
 
375
    sc->bufferLength += bytesToCopy;
 
376
    data += bytesToCopy;
 
377
    len -= bytesToCopy;
 
378
 
 
379
    if (sc->bufferLength == 128L) {
 
380
      SHA512Guts (sc, sc->buffer.words);
 
381
      needBurn = 1;
 
382
      sc->bufferLength = 0L;
 
383
    }
 
384
  }
 
385
#endif /* SHA512_FAST_COPY */
 
386
 
 
387
  if (needBurn)
 
388
    burnStack (sizeof (uint64_t[90]) + sizeof (uint64_t *[6]) + sizeof (int));
 
389
}
 
390
 
 
391
void
 
392
SHA512Final (SHA512Context *sc, uint8_t hash[SHA512_HASH_SIZE])
 
393
{
 
394
  uint32_t bytesToPad;
 
395
  uint64_t lengthPad[2];
 
396
  int i;
 
397
 
 
398
  bytesToPad = 240L - sc->bufferLength;
 
399
  if (bytesToPad > 128L)
 
400
    bytesToPad -= 128L;
 
401
 
 
402
  lengthPad[0] = BYTESWAP64(sc->totalLength[0]);
 
403
  lengthPad[1] = BYTESWAP64(sc->totalLength[1]);
 
404
 
 
405
  SHA512Update (sc, padding, bytesToPad);
 
406
  SHA512Update (sc, lengthPad, 16L);
 
407
 
 
408
  if (hash) {
 
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 */
 
422
      hash += 8;
 
423
    }
 
424
  }
 
425
}
 
426
 
 
427
#ifdef SHA512_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
  SHA512Context foo;
 
437
  uint8_t hash[SHA512_HASH_SIZE];
 
438
  char buf[1000];
 
439
  int i;
 
440
 
 
441
  SHA512Init (&foo);
 
442
  SHA512Update (&foo, "abc", 3);
 
443
  SHA512Final (&foo, hash);
 
444
 
 
445
  for (i = 0; i < SHA512_HASH_SIZE;) {
 
446
    printf ("%02x", hash[i++]);
 
447
    if (!(i % 8))
 
448
      printf (" ");
 
449
    if (!(i % 32))
 
450
      printf ("\n");
 
451
  }
 
452
 
 
453
  SHA512Init (&foo);
 
454
  SHA512Update (&foo,
 
455
                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
 
456
                "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
 
457
                112);
 
458
  SHA512Final (&foo, hash);
 
459
 
 
460
  for (i = 0; i < SHA512_HASH_SIZE;) {
 
461
    printf ("%02x", hash[i++]);
 
462
    if (!(i % 8))
 
463
      printf (" ");
 
464
    if (!(i % 32))
 
465
      printf ("\n");
 
466
  }
 
467
 
 
468
  SHA512Init (&foo);
 
469
  memset (buf, 'a', sizeof (buf));
 
470
  for (i = 0; i < 1000; i++)
 
471
    SHA512Update (&foo, buf, sizeof (buf));
 
472
  SHA512Final (&foo, hash);
 
473
 
 
474
  for (i = 0; i < SHA512_HASH_SIZE;) {
 
475
    printf ("%02x", hash[i++]);
 
476
    if (!(i % 8))
 
477
      printf (" ");
 
478
    if (!(i % 32))
 
479
      printf ("\n");
 
480
  }
 
481
 
 
482
  exit (0);
 
483
}
 
484
 
 
485
#endif /* SHA512_TEST */