chiark / gitweb /
New SHA variants with longer outputs.
[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 -------------------------------------------------*/