Add an internal-representation no-op function.
[u/mdw/catacomb] / sha512.c
1 /* -*-c-*-
2 *
3 * $Id: sha512.c,v 1.1 2000/10/15 17:48:15 mdw Exp $
4 *
5 * Implementation of the SHA-512 hash function
6 *
7 * (c) 2000 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
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.
18 *
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.
23 *
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,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: sha512.c,v $
33 * Revision 1.1 2000/10/15 17:48:15 mdw
34 * New SHA variants with longer outputs.
35 *
36 */
37
38 /*----- Header files ------------------------------------------------------*/
39
40 #include <mLib/bits.h>
41
42 #include "ghash.h"
43 #include "ghash-def.h"
44 #include "hash.h"
45 #include "sha512.h"
46
47 /*----- Main code ---------------------------------------------------------*/
48
49 /* --- @sha512_compress@, @sha384_compress@ --- *
50 *
51 * Arguments: @sha512_ctx *ctx@ = pointer to context block
52 * @const void *sbuf@ = pointer to buffer of appropriate size
53 *
54 * Returns: ---
55 *
56 * Use: SHA-512 compression function.
57 */
58
59 void sha512_compress(sha512_ctx *ctx, const void *sbuf)
60 {
61 kludge64 a, b, c, d, e, f, g, h;
62 kludge64 buf[80];
63 int i;
64
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)
106 };
107
108 /* --- Fetch the chaining variables --- */
109
110 a = ctx->a;
111 b = ctx->b;
112 c = ctx->c;
113 d = ctx->d;
114 e = ctx->e;
115 f = ctx->f;
116 g = ctx->g;
117 h = ctx->h;
118
119 /* --- Definitions for round functions --- */
120
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); \
124 } while (0)
125
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); \
129 } while (0)
130
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); \
134 } while (0)
135
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);
140
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); \
147 } while (0)
148
149 /* --- Fetch and expand the buffer contents --- */
150
151 {
152 const octet *p;
153
154 for (i = 0, p = sbuf; i < 16; i++, p += 8)
155 LOAD64_(buf[i], p);
156 for (i = 16; i < 80; i++) {
157 kludge64 x;
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]);
161 }
162 }
163
164 /* --- The main compression function --- */
165
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);
175 }
176
177 /* --- Update the chaining variables --- */
178
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);
187 }
188
189 /* --- @sha512_init@, @sha384_init@ --- *
190 *
191 * Arguments: @sha512_ctx *ctx@ = pointer to context block to initialize
192 *
193 * Returns: ---
194 *
195 * Use: Initializes a context block ready for hashing.
196 */
197
198 void sha512_init(sha512_ctx *ctx)
199 {
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);
208 ctx->off = 0;
209 ctx->nh = ctx->nl = 0;
210 }
211
212 void sha384_init(sha512_ctx *ctx)
213 {
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);
222 ctx->off = 0;
223 ctx->nh = ctx->nl = 0;
224 }
225
226 /* --- @sha512_set@, @sha384_set@ --- *
227 *
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
231 *
232 * Returns: ---
233 *
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.
237 */
238
239 void sha512_set(sha512_ctx *ctx, const void *buf, unsigned long count)
240 {
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);
250 ctx->off = 0;
251 ctx->nl = U32(count);
252 ctx->nh = U32(((count & ~MASK32) >> 16) >> 16);
253 }
254
255 /* --- @sha512_hash@, @sha384_hash@ --- *
256 *
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
260 *
261 * Returns: ---
262 *
263 * Use: Hashes a buffer of data. The buffer may be of any size and
264 * alignment.
265 */
266
267 void sha512_hash(sha512_ctx *ctx, const void *buf, size_t sz)
268 {
269 HASH_BUFFER(SHA512, sha512, ctx, buf, sz);
270 }
271
272 /* --- @sha512_done@, @sha384_done@ --- *
273 *
274 * Arguments: @sha512_ctx *ctx@ = pointer to context block
275 * @void *hash@ = pointer to output buffer
276 *
277 * Returns: ---
278 *
279 * Use: Returns the hash of the data read so far.
280 */
281
282 static void final(sha512_ctx *ctx)
283 {
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);
289 }
290
291 void sha512_done(sha512_ctx *ctx, void *hash)
292 {
293 octet *p = hash;
294 final(ctx);
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);
303 }
304
305 void sha384_done(sha384_ctx *ctx, void *hash)
306 {
307 octet *p = hash;
308 final(ctx);
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);
315 }
316
317 /* --- @sha512_state@, @sha384_state@ --- *
318 *
319 * Arguments: @sha512_ctx *ctx@ = pointer to context
320 * @void *state@ = pointer to buffer for current state
321 *
322 * Returns: Number of bytes written to the hash function so far.
323 *
324 * Use: Returns the current state of the hash function such that
325 * it can be passed to @sha512_set@.
326 */
327
328 unsigned long sha512_state(sha512_ctx *ctx, void *state)
329 {
330 octet *p = 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));
340 }
341
342 /* --- Generic interface --- */
343
344 GHASH_DEF(SHA512, sha512)
345
346 /* --- Test code --- */
347
348 HASH_TEST(SHA512, sha512)
349
350 /*----- That's all, folks -------------------------------------------------*/