comparison rmd128.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children 6362d3854bb4
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11
12 /* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
13 *
14 * This source has been radically overhauled to be portable and work within
15 * the LibTomCrypt API by Tom St Denis
16 */
17 #include "mycrypt.h"
18
19 #ifdef RIPEMD128
20
21 const struct _hash_descriptor rmd128_desc =
22 {
23 "rmd128",
24 8,
25 16,
26 64,
27 &rmd128_init,
28 &rmd128_process,
29 &rmd128_done,
30 &rmd128_test
31 };
32
33 /* the four basic functions F(), G() and H() */
34 #define F(x, y, z) ((x) ^ (y) ^ (z))
35 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
36 #define H(x, y, z) (((x) | ~(y)) ^ (z))
37 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
38
39 /* the eight basic operations FF() through III() */
40 #define FF(a, b, c, d, x, s) \
41 (a) += F((b), (c), (d)) + (x);\
42 (a) = ROL((a), (s));
43
44 #define GG(a, b, c, d, x, s) \
45 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
46 (a) = ROL((a), (s));
47
48 #define HH(a, b, c, d, x, s) \
49 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
50 (a) = ROL((a), (s));
51
52 #define II(a, b, c, d, x, s) \
53 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
54 (a) = ROL((a), (s));
55
56 #define FFF(a, b, c, d, x, s) \
57 (a) += F((b), (c), (d)) + (x);\
58 (a) = ROL((a), (s));
59
60 #define GGG(a, b, c, d, x, s) \
61 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
62 (a) = ROL((a), (s));
63
64 #define HHH(a, b, c, d, x, s) \
65 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
66 (a) = ROL((a), (s));
67
68 #define III(a, b, c, d, x, s) \
69 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
70 (a) = ROL((a), (s));
71
72 #ifdef CLEAN_STACK
73 static void _rmd128_compress(hash_state *md, unsigned char *buf)
74 #else
75 static void rmd128_compress(hash_state *md, unsigned char *buf)
76 #endif
77 {
78 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
79 int i;
80
81 /* load words X */
82 for (i = 0; i < 16; i++){
83 LOAD32L(X[i], buf + (4 * i));
84 }
85
86 /* load state */
87 aa = aaa = md->rmd128.state[0];
88 bb = bbb = md->rmd128.state[1];
89 cc = ccc = md->rmd128.state[2];
90 dd = ddd = md->rmd128.state[3];
91
92 /* round 1 */
93 FF(aa, bb, cc, dd, X[ 0], 11);
94 FF(dd, aa, bb, cc, X[ 1], 14);
95 FF(cc, dd, aa, bb, X[ 2], 15);
96 FF(bb, cc, dd, aa, X[ 3], 12);
97 FF(aa, bb, cc, dd, X[ 4], 5);
98 FF(dd, aa, bb, cc, X[ 5], 8);
99 FF(cc, dd, aa, bb, X[ 6], 7);
100 FF(bb, cc, dd, aa, X[ 7], 9);
101 FF(aa, bb, cc, dd, X[ 8], 11);
102 FF(dd, aa, bb, cc, X[ 9], 13);
103 FF(cc, dd, aa, bb, X[10], 14);
104 FF(bb, cc, dd, aa, X[11], 15);
105 FF(aa, bb, cc, dd, X[12], 6);
106 FF(dd, aa, bb, cc, X[13], 7);
107 FF(cc, dd, aa, bb, X[14], 9);
108 FF(bb, cc, dd, aa, X[15], 8);
109
110 /* round 2 */
111 GG(aa, bb, cc, dd, X[ 7], 7);
112 GG(dd, aa, bb, cc, X[ 4], 6);
113 GG(cc, dd, aa, bb, X[13], 8);
114 GG(bb, cc, dd, aa, X[ 1], 13);
115 GG(aa, bb, cc, dd, X[10], 11);
116 GG(dd, aa, bb, cc, X[ 6], 9);
117 GG(cc, dd, aa, bb, X[15], 7);
118 GG(bb, cc, dd, aa, X[ 3], 15);
119 GG(aa, bb, cc, dd, X[12], 7);
120 GG(dd, aa, bb, cc, X[ 0], 12);
121 GG(cc, dd, aa, bb, X[ 9], 15);
122 GG(bb, cc, dd, aa, X[ 5], 9);
123 GG(aa, bb, cc, dd, X[ 2], 11);
124 GG(dd, aa, bb, cc, X[14], 7);
125 GG(cc, dd, aa, bb, X[11], 13);
126 GG(bb, cc, dd, aa, X[ 8], 12);
127
128 /* round 3 */
129 HH(aa, bb, cc, dd, X[ 3], 11);
130 HH(dd, aa, bb, cc, X[10], 13);
131 HH(cc, dd, aa, bb, X[14], 6);
132 HH(bb, cc, dd, aa, X[ 4], 7);
133 HH(aa, bb, cc, dd, X[ 9], 14);
134 HH(dd, aa, bb, cc, X[15], 9);
135 HH(cc, dd, aa, bb, X[ 8], 13);
136 HH(bb, cc, dd, aa, X[ 1], 15);
137 HH(aa, bb, cc, dd, X[ 2], 14);
138 HH(dd, aa, bb, cc, X[ 7], 8);
139 HH(cc, dd, aa, bb, X[ 0], 13);
140 HH(bb, cc, dd, aa, X[ 6], 6);
141 HH(aa, bb, cc, dd, X[13], 5);
142 HH(dd, aa, bb, cc, X[11], 12);
143 HH(cc, dd, aa, bb, X[ 5], 7);
144 HH(bb, cc, dd, aa, X[12], 5);
145
146 /* round 4 */
147 II(aa, bb, cc, dd, X[ 1], 11);
148 II(dd, aa, bb, cc, X[ 9], 12);
149 II(cc, dd, aa, bb, X[11], 14);
150 II(bb, cc, dd, aa, X[10], 15);
151 II(aa, bb, cc, dd, X[ 0], 14);
152 II(dd, aa, bb, cc, X[ 8], 15);
153 II(cc, dd, aa, bb, X[12], 9);
154 II(bb, cc, dd, aa, X[ 4], 8);
155 II(aa, bb, cc, dd, X[13], 9);
156 II(dd, aa, bb, cc, X[ 3], 14);
157 II(cc, dd, aa, bb, X[ 7], 5);
158 II(bb, cc, dd, aa, X[15], 6);
159 II(aa, bb, cc, dd, X[14], 8);
160 II(dd, aa, bb, cc, X[ 5], 6);
161 II(cc, dd, aa, bb, X[ 6], 5);
162 II(bb, cc, dd, aa, X[ 2], 12);
163
164 /* parallel round 1 */
165 III(aaa, bbb, ccc, ddd, X[ 5], 8);
166 III(ddd, aaa, bbb, ccc, X[14], 9);
167 III(ccc, ddd, aaa, bbb, X[ 7], 9);
168 III(bbb, ccc, ddd, aaa, X[ 0], 11);
169 III(aaa, bbb, ccc, ddd, X[ 9], 13);
170 III(ddd, aaa, bbb, ccc, X[ 2], 15);
171 III(ccc, ddd, aaa, bbb, X[11], 15);
172 III(bbb, ccc, ddd, aaa, X[ 4], 5);
173 III(aaa, bbb, ccc, ddd, X[13], 7);
174 III(ddd, aaa, bbb, ccc, X[ 6], 7);
175 III(ccc, ddd, aaa, bbb, X[15], 8);
176 III(bbb, ccc, ddd, aaa, X[ 8], 11);
177 III(aaa, bbb, ccc, ddd, X[ 1], 14);
178 III(ddd, aaa, bbb, ccc, X[10], 14);
179 III(ccc, ddd, aaa, bbb, X[ 3], 12);
180 III(bbb, ccc, ddd, aaa, X[12], 6);
181
182 /* parallel round 2 */
183 HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
184 HHH(ddd, aaa, bbb, ccc, X[11], 13);
185 HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
186 HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
187 HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
188 HHH(ddd, aaa, bbb, ccc, X[13], 8);
189 HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
190 HHH(bbb, ccc, ddd, aaa, X[10], 11);
191 HHH(aaa, bbb, ccc, ddd, X[14], 7);
192 HHH(ddd, aaa, bbb, ccc, X[15], 7);
193 HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
194 HHH(bbb, ccc, ddd, aaa, X[12], 7);
195 HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
196 HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
197 HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
198 HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
199
200 /* parallel round 3 */
201 GGG(aaa, bbb, ccc, ddd, X[15], 9);
202 GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
203 GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
204 GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
205 GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
206 GGG(ddd, aaa, bbb, ccc, X[14], 6);
207 GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
208 GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
209 GGG(aaa, bbb, ccc, ddd, X[11], 12);
210 GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
211 GGG(ccc, ddd, aaa, bbb, X[12], 5);
212 GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
213 GGG(aaa, bbb, ccc, ddd, X[10], 13);
214 GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
215 GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
216 GGG(bbb, ccc, ddd, aaa, X[13], 5);
217
218 /* parallel round 4 */
219 FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
220 FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
221 FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
222 FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
223 FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
224 FFF(ddd, aaa, bbb, ccc, X[11], 14);
225 FFF(ccc, ddd, aaa, bbb, X[15], 6);
226 FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
227 FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
228 FFF(ddd, aaa, bbb, ccc, X[12], 9);
229 FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
230 FFF(bbb, ccc, ddd, aaa, X[13], 9);
231 FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
232 FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
233 FFF(ccc, ddd, aaa, bbb, X[10], 15);
234 FFF(bbb, ccc, ddd, aaa, X[14], 8);
235
236 /* combine results */
237 ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
238 md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
239 md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
240 md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
241 md->rmd128.state[0] = ddd;
242 }
243
244 #ifdef CLEAN_STACK
245 static void rmd128_compress(hash_state *md, unsigned char *buf)
246 {
247 _rmd128_compress(md, buf);
248 burn_stack(sizeof(ulong32) * 24 + sizeof(int));
249 }
250 #endif
251
252 void rmd128_init(hash_state * md)
253 {
254 _ARGCHK(md != NULL);
255 md->rmd128.state[0] = 0x67452301UL;
256 md->rmd128.state[1] = 0xefcdab89UL;
257 md->rmd128.state[2] = 0x98badcfeUL;
258 md->rmd128.state[3] = 0x10325476UL;
259 md->rmd128.curlen = 0;
260 md->rmd128.length = 0;
261 }
262
263 HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64)
264
265 int rmd128_done(hash_state * md, unsigned char *hash)
266 {
267 int i;
268
269 _ARGCHK(md != NULL);
270 _ARGCHK(hash != NULL);
271
272 if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
273 return CRYPT_INVALID_ARG;
274 }
275
276
277 /* increase the length of the message */
278 md->rmd128.length += md->rmd128.curlen * 8;
279
280 /* append the '1' bit */
281 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
282
283 /* if the length is currently above 56 bytes we append zeros
284 * then compress. Then we can fall back to padding zeros and length
285 * encoding like normal.
286 */
287 if (md->rmd128.curlen > 56) {
288 while (md->rmd128.curlen < 64) {
289 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
290 }
291 rmd128_compress(md, md->rmd128.buf);
292 md->rmd128.curlen = 0;
293 }
294
295 /* pad upto 56 bytes of zeroes */
296 while (md->rmd128.curlen < 56) {
297 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
298 }
299
300 /* store length */
301 STORE64L(md->rmd128.length, md->rmd128.buf+56);
302 rmd128_compress(md, md->rmd128.buf);
303
304 /* copy output */
305 for (i = 0; i < 4; i++) {
306 STORE32L(md->rmd128.state[i], hash+(4*i));
307 }
308 #ifdef CLEAN_STACK
309 zeromem(md, sizeof(hash_state));
310 #endif
311 return CRYPT_OK;
312 }
313
314 int rmd128_test(void)
315 {
316 #ifndef LTC_TEST
317 return CRYPT_NOP;
318 #else
319 static const struct {
320 char *msg;
321 unsigned char md[16];
322 } tests[] = {
323 { "",
324 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
325 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
326 },
327 { "a",
328 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
329 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
330 },
331 { "abc",
332 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
333 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
334 },
335 { "message digest",
336 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
337 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
338 },
339 { "abcdefghijklmnopqrstuvwxyz",
340 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
341 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
342 },
343 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
344 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
345 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
346 }
347 };
348 int x;
349 unsigned char buf[16];
350 hash_state md;
351
352 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
353 rmd128_init(&md);
354 rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
355 rmd128_done(&md, buf);
356 if (memcmp(buf, tests[x].md, 16) != 0) {
357 #if 0
358 printf("Failed test %d\n", x);
359 #endif
360 return CRYPT_FAIL_TESTVECTOR;
361 }
362 }
363 return CRYPT_OK;
364 #endif
365 }
366
367 #endif
368