12bbfc5762b21dd7b065eab9358889078a88f429
[u/mdw/catacomb] / mars-mktab.c
1 /* -*-c-*-
2 *
3 * $Id: mars-mktab.c,v 1.1 2001/04/29 18:11:19 mdw Exp $
4 *
5 * Generate the MARS S-box table
6 *
7 * (c) 2001 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: mars-mktab.c,v $
33 * Revision 1.1 2001/04/29 18:11:19 mdw
34 * New block cipher MARS.
35 *
36 */
37
38 /*----- Header files ------------------------------------------------------*/
39
40 #include <assert.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include <mLib/bits.h>
46
47 #include "sha.h"
48
49 /*----- SHA-1 (quick version) ---------------------------------------------*/
50
51 /* --- @sha_compress@ --- *
52 *
53 * Arguments: @sha_ctx *ctx@ = pointer to context block
54 * @const void *sbuf@ = pointer to buffer of appropriate size
55 *
56 * Returns: ---
57 *
58 * Use: SHA-1 compression function.
59 */
60
61 void sha_compress(sha_ctx *ctx, const void *sbuf)
62 {
63 uint32 a, b, c, d, e;
64 uint32 buf[80];
65
66 /* --- Fetch the chaining variables --- */
67
68 a = ctx->a;
69 b = ctx->b;
70 c = ctx->c;
71 d = ctx->d;
72 e = ctx->e;
73
74 /* --- Fetch and expand the buffer contents --- */
75
76 {
77 int i;
78 const octet *p;
79
80 for (i = 0, p = sbuf; i < 16; i++, p += 4)
81 buf[i] = LOAD32(p);
82 for (i = 16; i < 80; i++) {
83 uint32 x = buf[i - 3] ^ buf[i - 8] ^ buf[i - 14] ^ buf[i - 16];
84 buf[i] = ROL32(x, 1);
85 }
86 }
87
88 /* --- Definitions for round functions --- */
89
90 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
91 #define G(x, y, z) ((x) ^ (y) ^ (z))
92 #define H(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
93
94 #define T(v, w, x, y, z, i, f, k) do { \
95 uint32 _x; \
96 z = ROL32(v, 5) + f(w, x, y) + z + buf[i] + k; \
97 w = ROR32(w, 2); \
98 _x = v; v = z; z = y; y = x; x = w; w = _x; \
99 } while (0)
100
101 #define FF(v, w, x, y, z, i) T(v, w, x, y, z, i, F, 0x5a827999)
102 #define GG(v, w, x, y, z, i) T(v, w, x, y, z, i, G, 0x6ed9eba1)
103 #define HH(v, w, x, y, z, i) T(v, w, x, y, z, i, H, 0x8f1bbcdc)
104 #define II(v, w, x, y, z, i) T(v, w, x, y, z, i, G, 0xca62c1d6)
105
106 /* --- The main compression function --- */
107
108 {
109 unsigned i;
110 for (i = 0; i < 20; i++)
111 FF(a, b, c, d, e, i);
112 for (i = 20; i < 40; i++)
113 GG(a, b, c, d, e, i);
114 for (i = 40; i < 60; i++)
115 HH(a, b, c, d, e, i);
116 for (i = 60; i < 80; i++)
117 II(a, b, c, d, e, i);
118 }
119
120 ctx->a += a;
121 ctx->b += b;
122 ctx->c += c;
123 ctx->d += d;
124 ctx->e += e;
125 }
126
127 /* --- @sha_init@ --- *
128 *
129 * Arguments: @sha_ctx *ctx@ = pointer to context block to initialize
130 *
131 * Returns: ---
132 *
133 * Use: Initializes a context block ready for hashing.
134 */
135
136 void sha_init(sha_ctx *ctx)
137 {
138 ctx->a = 0x67452301;
139 ctx->b = 0xefcdab89;
140 ctx->c = 0x98badcfe;
141 ctx->d = 0x10325476;
142 ctx->e = 0xc3d2e1f0;
143 ctx->off = 0;
144 ctx->nl = ctx->nh = 0;
145 }
146
147 /* --- @sha_hash@ --- *
148 *
149 * Arguments: @sha_ctx *ctx@ = pointer to context block
150 * @const void *buf@ = buffer of data to hash
151 * @size_t sz@ = size of buffer to hash
152 *
153 * Returns: ---
154 *
155 * Use: Hashes a buffer of data. The buffer may be of any size and
156 * alignment.
157 */
158
159 void sha_hash(sha_ctx *ctx, const void *buf, size_t sz)
160 {
161 sha_ctx *_bctx = (ctx);
162 size_t _bsz = (sz);
163 const octet *_bbuf = (octet *) (buf);
164
165 {
166 uint32 _l = ((uint32) ((_bsz) & MASK32));
167 uint32 _h = ((_bsz & ~MASK32) >> 16) >> 16;
168 _bctx->nh += _h;
169 _bctx->nl += _l;
170 if (_bctx->nl < _l || _bctx->nl & ~MASK32)
171 _bctx->nh++;
172 }
173 if (_bctx->off + _bsz < SHA_BUFSZ) {
174 memcpy(_bctx->buf + _bctx->off, _bbuf, _bsz);
175 _bctx->off += _bsz;
176 } else {
177 if (_bctx->off) {
178 size_t s = SHA_BUFSZ - _bctx->off;
179 memcpy(_bctx->buf + _bctx->off, _bbuf, s);
180 sha_compress(_bctx, _bctx->buf);
181 _bsz -= s;
182 _bbuf += s;
183 }
184 while (_bsz >= SHA_BUFSZ) {
185 sha_compress(_bctx, _bbuf);
186 _bsz -= SHA_BUFSZ;
187 _bbuf += SHA_BUFSZ;
188 }
189 if (_bsz)
190 memcpy(_bctx->buf, _bbuf, _bsz);
191 _bctx->off = _bsz;
192 }
193 }
194
195 /* --- @sha_done@ --- *
196 *
197 * Arguments: @sha_ctx *ctx@ = pointer to context block
198 * @void *hash@ = pointer to output buffer
199 *
200 * Returns: ---
201 *
202 * Use: Returns the hash of the data read so far.
203 */
204
205 void sha_done(sha_ctx *ctx, void *hash)
206 {
207 octet *p = hash;
208 {
209 sha_ctx *_pctx = (ctx);
210 _pctx->buf[_pctx->off] = 0x80;
211 _pctx->off++;
212 if (_pctx->off > SHA_BUFSZ - 8) {
213 if (_pctx->off < SHA_BUFSZ)
214 memset(_pctx->buf + _pctx->off, 0, SHA_BUFSZ - _pctx->off);
215 sha_compress(_pctx, _pctx->buf);
216 memset(_pctx->buf, 0, SHA_BUFSZ - 8);
217 } else
218 memset(_pctx->buf + _pctx->off, 0, SHA_BUFSZ - _pctx->off - 8);
219 }
220 STORE32(ctx->buf + SHA_BUFSZ - 8, (ctx->nl >> 29) | (ctx->nh << 3));
221 STORE32(ctx->buf + SHA_BUFSZ - 4, ctx->nl << 3);
222 sha_compress(ctx, ctx->buf);
223 STORE32(p + 0, ctx->a);
224 STORE32(p + 4, ctx->b);
225 STORE32(p + 8, ctx->c);
226 STORE32(p + 12, ctx->d);
227 STORE32(p + 16, ctx->e);
228 }
229
230 /*----- Main code ---------------------------------------------------------*/
231
232 static void mks(uint32 c3, uint32 *s)
233 {
234 octet ibuf[16], obuf[20];
235 sha_ctx h;
236 unsigned i, j;
237
238 STORE32_L(ibuf + 4, 0xb7e15162);
239 STORE32_L(ibuf + 8, 0x243f6a88);
240 STORE32_L(ibuf + 12, c3);
241
242 for (i = 0; i < 510; i += 5) {
243 STORE32_L(ibuf, i);
244 sha_init(&h);
245 sha_hash(&h, ibuf, sizeof(ibuf));
246 sha_done(&h, obuf);
247 for (j = 0; j < 5; j++)
248 *s++ = LOAD32_L(obuf + (4 * j));
249 }
250 STORE32_L(ibuf, i);
251 sha_init(&h);
252 sha_hash(&h, ibuf, sizeof(ibuf));
253 sha_done(&h, obuf);
254 for (j = 0; i < 512; j++, i++)
255 *s++ = LOAD32_L(obuf + (4 * j));
256 }
257
258 static void fix(uint32 *s)
259 {
260 unsigned i, j, n;
261 uint32 d;
262
263 for (i = 0; i < 512; i++) {
264 for (j = i & ~255u; j < ((i + 255) & ~255u); j++) {
265 if (i == j)
266 continue;
267 d = s[i] ^ s[j];
268 n = 0;
269 if (!(d & 0xff000000)) n++;
270 if (!(d & 0x00ff0000)) n++;
271 if (!(d & 0x0000ff00)) n++;
272 if (!(d & 0x000000ff)) n++;
273 if (n >= 2) {
274 s[i] = U32(s[i] * 3);
275 goto fixed;
276 }
277 }
278 fixed:;
279 }
280 }
281
282 int main(void)
283 {
284 uint32 s[512];
285 unsigned i;
286
287 mks(0x02917d59, s);
288 fix(s);
289
290 puts("\
291 /* -*-c-*-\n\
292 *\n\
293 * MARS tables [generated]\n\
294 */\n\
295 \n\
296 #ifndef CATACOMB_MARS_TAB_H\n\
297 #define CATACOMB_MARS_TAB_H\n\
298 ");
299
300 fputs("\
301 /* --- The S-box --- */\n\
302 \n\
303 #define MARS_S { \\\n\
304 ", stdout);
305 for (i = 0; i < 512; i++) {
306 printf("0x%08lx", (unsigned long)s[i]);
307 if (i == 511)
308 fputs(" \\\n}\n\n", stdout);
309 else if (i % 4 == 3)
310 fputs(", \\\n ", stdout);
311 else
312 fputs(", ", stdout);
313 }
314
315 puts("#endif");
316
317 if (fclose(stdout)) {
318 fprintf(stderr, "error writing data\n");
319 exit(EXIT_FAILURE);
320 }
321
322 return (0);
323 }
324
325 /*----- That's all, folks -------------------------------------------------*/