More changes. Still embryonic.
[u/mdw/catacomb] / md4.c
1 /* -*-c-*-
2 *
3 * $Id: md4.c,v 1.2 1999/12/10 23:20:03 mdw Exp $
4 *
5 * The MD4 message digest function
6 *
7 * (c) 1999 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: md4.c,v $
33 * Revision 1.2 1999/12/10 23:20:03 mdw
34 * New hash interface requirements.
35 *
36 * Revision 1.1 1999/09/03 08:41:12 mdw
37 * Initial import.
38 *
39 */
40
41 /*----- Header files ------------------------------------------------------*/
42
43 #include <mLib/bits.h>
44
45 #include "ghash.h"
46 #include "ghash-def.h"
47 #include "hash.h"
48 #include "md4.h"
49
50 /*----- Main code ---------------------------------------------------------*/
51
52 /* --- @md4_compress@ --- *
53 *
54 * Arguments: @md4_ctx *ctx@ = pointer to context block
55 * @const void *sbuf@ = pointer to buffer of appropriate size
56 *
57 * Returns: ---
58 *
59 * Use: RIPEMD-160 compression function.
60 */
61
62 void md4_compress(md4_ctx *ctx, const void *sbuf)
63 {
64 uint32 a, b, c, d;
65 uint32 buf[16];
66
67 /* --- Fetch the chaining variables --- */
68
69 a = ctx->a;
70 b = ctx->b;
71 c = ctx->c;
72 d = ctx->d;
73
74 /* --- Fetch 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_L(p);
82 }
83
84 /* --- Definitions for round functions --- */
85
86 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
87 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
88 #define H(x, y, z) ((x) ^ (y) ^ (z))
89
90 #define T(w, x, y, z, i, r, k, f) do { \
91 uint32 _t = w + f(x, y, z) + buf[i] + k; \
92 w = ROL32(_t, r); \
93 } while (0)
94
95 #define FF(w, x, y, z, i, r) T(w, x, y, z, i, r, 0x00000000, F)
96 #define GG(w, x, y, z, i, r) T(w, x, y, z, i, r, 0x5a827999, G)
97 #define HH(w, x, y, z, i, r) T(w, x, y, z, i, r, 0x6ed9eba1, H)
98
99 /* --- The main compression function --- */
100
101 FF(a, b, c, d, 0, 3);
102 FF(d, a, b, c, 1, 7);
103 FF(c, d, a, b, 2, 11);
104 FF(b, c, d, a, 3, 19);
105 FF(a, b, c, d, 4, 3);
106 FF(d, a, b, c, 5, 7);
107 FF(c, d, a, b, 6, 11);
108 FF(b, c, d, a, 7, 19);
109 FF(a, b, c, d, 8, 3);
110 FF(d, a, b, c, 9, 7);
111 FF(c, d, a, b, 10, 11);
112 FF(b, c, d, a, 11, 19);
113 FF(a, b, c, d, 12, 3);
114 FF(d, a, b, c, 13, 7);
115 FF(c, d, a, b, 14, 11);
116 FF(b, c, d, a, 15, 19);
117
118 GG(a, b, c, d, 0, 3);
119 GG(d, a, b, c, 4, 5);
120 GG(c, d, a, b, 8, 9);
121 GG(b, c, d, a, 12, 13);
122 GG(a, b, c, d, 1, 3);
123 GG(d, a, b, c, 5, 5);
124 GG(c, d, a, b, 9, 9);
125 GG(b, c, d, a, 13, 13);
126 GG(a, b, c, d, 2, 3);
127 GG(d, a, b, c, 6, 5);
128 GG(c, d, a, b, 10, 9);
129 GG(b, c, d, a, 14, 13);
130 GG(a, b, c, d, 3, 3);
131 GG(d, a, b, c, 7, 5);
132 GG(c, d, a, b, 11, 9);
133 GG(b, c, d, a, 15, 13);
134
135 HH(a, b, c, d, 0, 3);
136 HH(d, a, b, c, 8, 9);
137 HH(c, d, a, b, 4, 11);
138 HH(b, c, d, a, 12, 15);
139 HH(a, b, c, d, 2, 3);
140 HH(d, a, b, c, 10, 9);
141 HH(c, d, a, b, 6, 11);
142 HH(b, c, d, a, 14, 15);
143 HH(a, b, c, d, 1, 3);
144 HH(d, a, b, c, 9, 9);
145 HH(c, d, a, b, 5, 11);
146 HH(b, c, d, a, 13, 15);
147 HH(a, b, c, d, 3, 3);
148 HH(d, a, b, c, 11, 9);
149 HH(c, d, a, b, 7, 11);
150 HH(b, c, d, a, 15, 15);
151
152 /* --- Update the chaining variables --- */
153
154 ctx->a += a;
155 ctx->b += b;
156 ctx->c += c;
157 ctx->d += d;
158 }
159
160 /* --- @md4_init@ --- *
161 *
162 * Arguments: @md4_ctx *ctx@ = pointer to context block to initialize
163 *
164 * Returns: ---
165 *
166 * Use: Initializes a context block ready for hashing.
167 */
168
169 void md4_init(md4_ctx *ctx)
170 {
171 ctx->a = 0x67452301;
172 ctx->b = 0xefcdab89;
173 ctx->c = 0x98badcfe;
174 ctx->d = 0x10325476;
175 ctx->off = 0;
176 ctx->nl = ctx->nh = 0;
177 }
178
179 /* --- @md4_set@ --- *
180 *
181 * Arguments: @md4_ctx *ctx@ = pointer to context block
182 * @const void *buf@ = pointer to state buffer
183 * @unsigned long count@ = current count of bytes processed
184 *
185 * Returns: ---
186 *
187 * Use: Initializes a context block from a given state. This is
188 * useful in cases where the initial hash state is meant to be
189 * secret, e.g., for NMAC and HMAC support.
190 */
191
192 void md4_set(md4_ctx *ctx, const void *buf, unsigned long count)
193 {
194 const octet *p = buf;
195 ctx->a = LOAD32_L(p + 0);
196 ctx->b = LOAD32_L(p + 4);
197 ctx->c = LOAD32_L(p + 8);
198 ctx->d = LOAD32_L(p + 12);
199 ctx->off = 0;
200 ctx->nl = U32(count);
201 ctx->nh = U32((count >> 16) >> 16);
202 }
203
204 /* --- @md4_hash@ --- *
205 *
206 * Arguments: @md4_ctx *ctx@ = pointer to context block
207 * @const void *buf@ = buffer of data to hash
208 * @size_t sz@ = size of buffer to hash
209 *
210 * Returns: ---
211 *
212 * Use: Hashes a buffer of data. The buffer may be of any size and
213 * alignment.
214 */
215
216 void md4_hash(md4_ctx *ctx, const void *buf, size_t sz)
217 {
218 HASH_BUFFER(MD4, md4, ctx, buf, sz);
219 }
220
221 /* --- @md4_done@ --- *
222 *
223 * Arguments: @md4_ctx *ctx@ = pointer to context block
224 * @void *hash@ = pointer to output buffer
225 *
226 * Returns: ---
227 *
228 * Use: Returns the hash of the data read so far.
229 */
230
231 void md4_done(md4_ctx *ctx, void *hash)
232 {
233 octet *p = hash;
234 HASH_MD5STRENGTH(MD4, md4, ctx);
235 STORE32_L(p + 0, ctx->a);
236 STORE32_L(p + 4, ctx->b);
237 STORE32_L(p + 8, ctx->c);
238 STORE32_L(p + 12, ctx->d);
239 }
240
241 /* --- @md4_state@ --- *
242 *
243 * Arguments: @md4_ctx *ctx@ = pointer to context
244 * @void *state@ = pointer to buffer for current state
245 *
246 * Returns: Number of bytes written to the hash function so far.
247 *
248 * Use: Returns the current state of the hash function such that
249 * it can be passed to @md4_set@.
250 */
251
252 unsigned long md4_state(md4_ctx *ctx, void *state)
253 {
254 octet *p = state;
255 STORE32_L(p + 0, ctx->a);
256 STORE32_L(p + 4, ctx->b);
257 STORE32_L(p + 8, ctx->c);
258 STORE32_L(p + 12, ctx->d);
259 return (ctx->nl | ((ctx->nh >> 16) >> 16));
260 }
261
262 /* --- Generic interface --- */
263
264 GHASH_DEF(MD4, md4)
265
266 /* --- Test rig --- */
267
268 HASH_TEST(MD4, md4)
269
270 /*----- That's all, folks -------------------------------------------------*/