3 * $Id: sha512.c,v 1.1 2000/10/15 17:48:15 mdw Exp $
5 * Implementation of the SHA-512 hash function
7 * (c) 2000 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.1 2000/10/15 17:48:15 mdw
34 * New SHA variants with longer outputs.
38 /*----- Header files ------------------------------------------------------*/
40 #include <mLib/bits.h>
43 #include "ghash-def.h"
47 /*----- Main code ---------------------------------------------------------*/
49 /* --- @sha512_compress@, @sha384_compress@ --- *
51 * Arguments: @sha512_ctx *ctx@ = pointer to context block
52 * @const void *sbuf@ = pointer to buffer of appropriate size
56 * Use: SHA-512 compression function.
59 void sha512_compress(sha512_ctx *ctx, const void *sbuf)
61 kludge64 a, b, c, d, e, f, g, h;
65 static const kludge64 K[80] = {
66 X64(428a2f98, d728ae22), X64(71374491, 23ef65cd),
67 X64(b5c0fbcf, ec4d3b2f), X64(e9b5dba5, 8189dbbc),
68 X64(3956c25b, f348b538), X64(59f111f1, b605d019),
69 X64(923f82a4, af194f9b), X64(ab1c5ed5, da6d8118),
70 X64(d807aa98, a3030242), X64(12835b01, 45706fbe),
71 X64(243185be, 4ee4b28c), X64(550c7dc3, d5ffb4e2),
72 X64(72be5d74, f27b896f), X64(80deb1fe, 3b1696b1),
73 X64(9bdc06a7, 25c71235), X64(c19bf174, cf692694),
74 X64(e49b69c1, 9ef14ad2), X64(efbe4786, 384f25e3),
75 X64(0fc19dc6, 8b8cd5b5), X64(240ca1cc, 77ac9c65),
76 X64(2de92c6f, 592b0275), X64(4a7484aa, 6ea6e483),
77 X64(5cb0a9dc, bd41fbd4), X64(76f988da, 831153b5),
78 X64(983e5152, ee66dfab), X64(a831c66d, 2db43210),
79 X64(b00327c8, 98fb213f), X64(bf597fc7, beef0ee4),
80 X64(c6e00bf3, 3da88fc2), X64(d5a79147, 930aa725),
81 X64(06ca6351, e003826f), X64(14292967, 0a0e6e70),
82 X64(27b70a85, 46d22ffc), X64(2e1b2138, 5c26c926),
83 X64(4d2c6dfc, 5ac42aed), X64(53380d13, 9d95b3df),
84 X64(650a7354, 8baf63de), X64(766a0abb, 3c77b2a8),
85 X64(81c2c92e, 47edaee6), X64(92722c85, 1482353b),
86 X64(a2bfe8a1, 4cf10364), X64(a81a664b, bc423001),
87 X64(c24b8b70, d0f89791), X64(c76c51a3, 0654be30),
88 X64(d192e819, d6ef5218), X64(d6990624, 5565a910),
89 X64(f40e3585, 5771202a), X64(106aa070, 32bbd1b8),
90 X64(19a4c116, b8d2d0c8), X64(1e376c08, 5141ab53),
91 X64(2748774c, df8eeb99), X64(34b0bcb5, e19b48a8),
92 X64(391c0cb3, c5c95a63), X64(4ed8aa4a, e3418acb),
93 X64(5b9cca4f, 7763e373), X64(682e6ff3, d6b2b8a3),
94 X64(748f82ee, 5defb2fc), X64(78a5636f, 43172f60),
95 X64(84c87814, a1f0ab72), X64(8cc70208, 1a6439ec),
96 X64(90befffa, 23631e28), X64(a4506ceb, de82bde9),
97 X64(bef9a3f7, b2c67915), X64(c67178f2, e372532b),
98 X64(ca273ece, ea26619c), X64(d186b8c7, 21c0c207),
99 X64(eada7dd6, cde0eb1e), X64(f57d4f7f, ee6ed178),
100 X64(06f067aa, 72176fba), X64(0a637dc5, a2c898a6),
101 X64(113f9804, bef90dae), X64(1b710b35, 131c471b),
102 X64(28db77f5, 23047d84), X64(32caab7b, 40c72493),
103 X64(3c9ebe0a, 15c9bebc), X64(431d67c4, 9c100d4c),
104 X64(4cc5d4be, cb3e42b6), X64(597f299c, fc657e2a),
105 X64(5fcb6fab, 3ad6faec), X64(6c44198c, 4a475817)
108 /* --- Fetch the chaining variables --- */
119 /* --- Definitions for round functions --- */
121 #define CH(d, x, y, z) do { \
122 kludge64 _x; AND64((d), (x), (y)); CPL64(_x, (x)); \
123 AND64(_x, _x, (z)); OR64((d), (d), _x); \
126 #define MAJ(d, x, y, z) do { \
127 kludge64 _x; AND64((d), (x), (y)); AND64(_x, (x), (z)); \
128 OR64((d), (d), _x); AND64(_x, (y), (z)); OR64((d), (d), _x); \
131 #define SIGMA(d, x, i, j, k, last, what) do { \
132 kludge64 _x; ROR64_((d), (x), (i)); ROR64_(_x, (x), (j)); \
133 XOR64((d), (d), _x); last##64_(_x, (x), (k)); XOR64((d), (d), _x); \
136 #define S0(d, x) SIGMA(d, x, 28, 34, 39, ROR, S0);
137 #define S1(d, x) SIGMA(d, x, 14, 18, 41, ROR, S1);
138 #define s0(d, x) SIGMA(d, x, 1, 8, 7, LSR, s0);
139 #define s1(d, x) SIGMA(d, x, 19, 61, 6, LSR, s1);
141 #define T(a, b, c, d, e, f, g, h, i) do { \
142 kludge64 t1, t2, x; \
143 ADD64(t1, buf[i], K[i]); ADD64(t1, t1, h); \
144 S1(x, e); ADD64(t1, t1, x); CH(x, e, f, g); ADD64(t1, t1, x); \
145 S0(t2, a); MAJ(x, a, b, c); ADD64(t2, t2, x); \
146 ADD64(d, d, t1); ADD64(h, t1, t2); \
149 /* --- Fetch and expand the buffer contents --- */
154 for (i = 0, p = sbuf; i < 16; i++, p += 8)
156 for (i = 16; i < 80; i++) {
158 buf[i] = buf[i - 7]; s1(x, buf[i - 2]); ADD64(buf[i], buf[i], x);
159 s0(x, buf[i - 15]); ADD64(buf[i], buf[i], x);
160 ADD64(buf[i], buf[i], buf[i - 16]);
164 /* --- The main compression function --- */
166 for (i = 0; i < 80; i += 8) {
167 T(a, b, c, d, e, f, g, h, i + 0);
168 T(h, a, b, c, d, e, f, g, i + 1);
169 T(g, h, a, b, c, d, e, f, i + 2);
170 T(f, g, h, a, b, c, d, e, i + 3);
171 T(e, f, g, h, a, b, c, d, i + 4);
172 T(d, e, f, g, h, a, b, c, i + 5);
173 T(c, d, e, f, g, h, a, b, i + 6);
174 T(b, c, d, e, f, g, h, a, i + 7);
177 /* --- Update the chaining variables --- */
179 ADD64(ctx->a, ctx->a, a);
180 ADD64(ctx->b, ctx->b, b);
181 ADD64(ctx->c, ctx->c, c);
182 ADD64(ctx->d, ctx->d, d);
183 ADD64(ctx->e, ctx->e, e);
184 ADD64(ctx->f, ctx->f, f);
185 ADD64(ctx->g, ctx->g, g);
186 ADD64(ctx->h, ctx->h, h);
189 /* --- @sha512_init@, @sha384_init@ --- *
191 * Arguments: @sha512_ctx *ctx@ = pointer to context block to initialize
195 * Use: Initializes a context block ready for hashing.
198 void sha512_init(sha512_ctx *ctx)
200 SET64(ctx->a, 0x6a09e667, 0xf3bcc908);
201 SET64(ctx->b, 0xbb67ae85, 0x84caa73b);
202 SET64(ctx->c, 0x3c6ef372, 0xfe94f82b);
203 SET64(ctx->d, 0xa54ff53a, 0x5f1d36f1);
204 SET64(ctx->e, 0x510e527f, 0xade682d1);
205 SET64(ctx->f, 0x9b05688c, 0x2b3e6c1f);
206 SET64(ctx->g, 0x1f83d9ab, 0xfb41bd6b);
207 SET64(ctx->h, 0x5be0cd19, 0x137e2179);
209 ctx->nh = ctx->nl = 0;
212 void sha384_init(sha512_ctx *ctx)
214 SET64(ctx->a, 0xcbbb9d5d, 0xc1059ed8);
215 SET64(ctx->b, 0x629a292a, 0x367cd507);
216 SET64(ctx->c, 0x9159015a, 0x3070dd17);
217 SET64(ctx->d, 0x152fecd8, 0xf70e5939);
218 SET64(ctx->e, 0x67332667, 0xffc00b31);
219 SET64(ctx->f, 0x8eb44a87, 0x68581511);
220 SET64(ctx->g, 0xdb0c2e0d, 0x64f98fa7);
221 SET64(ctx->h, 0x47b5481d, 0xbefa4fa4);
223 ctx->nh = ctx->nl = 0;
226 /* --- @sha512_set@, @sha384_set@ --- *
228 * Arguments: @sha512_ctx *ctx@ = pointer to context block
229 * @const void *buf@ = pointer to state buffer
230 * @unsigned long count@ = current count of bytes processed
234 * Use: Initializes a context block from a given state. This is
235 * useful in cases where the initial hash state is meant to be
236 * secret, e.g., for NMAC and HMAC support.
239 void sha512_set(sha512_ctx *ctx, const void *buf, unsigned long count)
241 const octet *p = buf;
242 LOAD64_(ctx->a, p + 0);
243 LOAD64_(ctx->b, p + 8);
244 LOAD64_(ctx->c, p + 16);
245 LOAD64_(ctx->d, p + 24);
246 LOAD64_(ctx->e, p + 32);
247 LOAD64_(ctx->f, p + 40);
248 LOAD64_(ctx->g, p + 48);
249 LOAD64_(ctx->h, p + 56);
251 ctx->nl = U32(count);
252 ctx->nh = U32(((count & ~MASK32) >> 16) >> 16);
255 /* --- @sha512_hash@, @sha384_hash@ --- *
257 * Arguments: @sha512_ctx *ctx@ = pointer to context block
258 * @const void *buf@ = buffer of data to hash
259 * @size_t sz@ = size of buffer to hash
263 * Use: Hashes a buffer of data. The buffer may be of any size and
267 void sha512_hash(sha512_ctx *ctx, const void *buf, size_t sz)
269 HASH_BUFFER(SHA512, sha512, ctx, buf, sz);
272 /* --- @sha512_done@, @sha384_done@ --- *
274 * Arguments: @sha512_ctx *ctx@ = pointer to context block
275 * @void *hash@ = pointer to output buffer
279 * Use: Returns the hash of the data read so far.
282 static void final(sha512_ctx *ctx)
284 HASH_PAD(SHA512, sha512, ctx, 0x80, 0, 16);
285 memset(ctx->buf + SHA512_BUFSZ - 16, 0, 8);
286 STORE32(ctx->buf + SHA512_BUFSZ - 8, (ctx->nl >> 29) | (ctx->nh << 3));
287 STORE32(ctx->buf + SHA512_BUFSZ - 4, ctx->nl << 3);
288 sha512_compress(ctx, ctx->buf);
291 void sha512_done(sha512_ctx *ctx, void *hash)
295 STORE64_(p + 0, ctx->a);
296 STORE64_(p + 8, ctx->b);
297 STORE64_(p + 16, ctx->c);
298 STORE64_(p + 24, ctx->d);
299 STORE64_(p + 32, ctx->e);
300 STORE64_(p + 40, ctx->f);
301 STORE64_(p + 48, ctx->g);
302 STORE64_(p + 56, ctx->h);
305 void sha384_done(sha384_ctx *ctx, void *hash)
309 STORE64_(p + 0, ctx->a);
310 STORE64_(p + 8, ctx->b);
311 STORE64_(p + 16, ctx->c);
312 STORE64_(p + 24, ctx->d);
313 STORE64_(p + 32, ctx->e);
314 STORE64_(p + 40, ctx->f);
317 /* --- @sha512_state@, @sha384_state@ --- *
319 * Arguments: @sha512_ctx *ctx@ = pointer to context
320 * @void *state@ = pointer to buffer for current state
322 * Returns: Number of bytes written to the hash function so far.
324 * Use: Returns the current state of the hash function such that
325 * it can be passed to @sha512_set@.
328 unsigned long sha512_state(sha512_ctx *ctx, void *state)
331 STORE64_(p + 0, ctx->a);
332 STORE64_(p + 8, ctx->b);
333 STORE64_(p + 16, ctx->c);
334 STORE64_(p + 24, ctx->d);
335 STORE64_(p + 32, ctx->e);
336 STORE64_(p + 40, ctx->f);
337 STORE64_(p + 48, ctx->g);
338 STORE64_(p + 56, ctx->h);
339 return (ctx->nl | ((ctx->nh << 16) << 16));
342 /* --- Generic interface --- */
344 GHASH_DEF(SHA512, sha512)
346 /* --- Test code --- */
348 HASH_TEST(SHA512, sha512)
350 /*----- That's all, folks -------------------------------------------------*/