1 /*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18 /*!\file ripemd320.c
19 * \brief RIPEMD-320 hash function.
20 * \author Jeff Johnson <jbj@rpm5.org>
21 * \author Bob Deblier <bob.deblier@telenet.be>
22 * \ingroup HASH_m HASH_ripemd320_m
23 */
24
25 #define BEECRYPT_DLL_EXPORT
26
27 #if HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include "beecrypt/ripemd320.h"
32 #include "beecrypt/endianness.h"
33
34 /*!\addtogroup HASH_ripemd320_m
35 * \{
36 */
37
38 /*@unchecked@*/ /*@observer@*/
39 static uint32_t ripemd320hinit[10] = {
40 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U,
41 0x76543210U, 0xfedcba98U, 0x89abcdefU, 0x01234567U, 0x3c2d1e0fU
42 };
43
44 /*@-sizeoftype@*/
45 /*@unchecked@*/ /*@observer@*/
46 const hashFunction ripemd320 = {
47 .name = "RIPEMD-320",
48 .paramsize = sizeof(ripemd320Param),
49 .blocksize = 64,
50 .digestsize = 40,
51 .reset = (hashFunctionReset) ripemd320Reset,
52 .update = (hashFunctionUpdate) ripemd320Update,
53 .digest = (hashFunctionDigest) ripemd320Digest
54 };
55 /*@=sizeoftype@*/
56
ripemd320Reset(register ripemd320Param * mp)57 int ripemd320Reset(register ripemd320Param* mp)
58 {
59 /*@-sizeoftype@*/
60 memcpy(mp->h, ripemd320hinit, 10 * sizeof(uint32_t));
61 memset(mp->data, 0, 16 * sizeof(uint32_t));
62 /*@=sizeoftype@*/
63 #if (MP_WBITS == 64)
64 mpzero(1, mp->length);
65 #elif (MP_WBITS == 32)
66 mpzero(2, mp->length);
67 #else
68 # error
69 #endif
70 mp->offset = 0;
71 return 0;
72 }
73
74 #define LSR1(a, b, c, d, e, x, s) \
75 a = ROTL32((b^c^d) + a + x, s) + e;\
76 c = ROTL32(c, 10);
77 #define LSR2(a, b, c, d, e, x, s) \
78 a = ROTL32(((b&c)|(~b&d)) + a + x + 0x5a827999U, s) + e;\
79 c = ROTL32(c, 10);
80 #define LSR3(a, b, c, d, e, x, s) \
81 a = ROTL32(((b|~c)^d) + a + x + 0x6ed9eba1U, s) + e; \
82 c = ROTL32(c, 10);
83 #define LSR4(a, b, c, d, e, x, s) \
84 a = ROTL32(((b&d)|(c&~d)) + a + x + 0x8f1bbcdcU, s) + e; \
85 c = ROTL32(c, 10);
86 #define LSR5(a, b, c, d, e, x, s) \
87 a = ROTL32((b^(c|~d)) + a + x + 0xa953fd4eU, s) + e; \
88 c = ROTL32(c, 10);
89
90 #define RSR5(a, b, c, d, e, x, s) \
91 a = ROTL32((b^c^d) + a + x, s) + e;\
92 c = ROTL32(c, 10);
93 #define RSR4(a, b, c, d, e, x, s) \
94 a = ROTL32(((b&c)|(~b&d)) + a + x + 0x7a6d76e9U, s) + e;\
95 c = ROTL32(c, 10);
96 #define RSR3(a, b, c, d, e, x, s) \
97 a = ROTL32(((b|~c)^d) + a + x + 0x6d703ef3U, s) + e; \
98 c = ROTL32(c, 10);
99 #define RSR2(a, b, c, d, e, x, s) \
100 a = ROTL32(((b&d)|(c&~d)) + a + x + 0x5c4dd124U, s) + e; \
101 c = ROTL32(c, 10);
102 #define RSR1(a, b, c, d, e, x, s) \
103 a = ROTL32((b^(c|~d)) + a + x + 0x50a28be6U, s) + e; \
104 c = ROTL32(c, 10);
105
106 #ifndef ASM_RIPEMD320PROCESS
ripemd320Process(ripemd320Param * mp)107 void ripemd320Process(ripemd320Param* mp)
108 {
109 register uint32_t la, lb, lc, ld, le;
110 register uint32_t ra, rb, rc, rd, re;
111 register uint32_t temp;
112 register uint32_t* x;
113 #ifdef WORDS_BIGENDIAN
114 register byte t;
115 #endif
116
117 x = mp->data;
118 #ifdef WORDS_BIGENDIAN
119 t = 16;
120 while (t--)
121 {
122 temp = swapu32(*x);
123 *(x++) = temp;
124 }
125 x = mp->data;
126 #endif
127
128 la = mp->h[0]; lb = mp->h[1]; lc = mp->h[2]; ld = mp->h[3]; le = mp->h[4];
129 ra = mp->h[5]; rb = mp->h[6]; rc = mp->h[7]; rd = mp->h[8]; re = mp->h[9];
130
131 /* In theory OpenMP would allows us to do the 'left' and 'right' sections in parallel,
132 * but in practice the overhead make the code much slower
133 */
134
135 /* left round 1 */
136 LSR1(la, lb, lc, ld, le, x[ 0], 11);
137 LSR1(le, la, lb, lc, ld, x[ 1], 14);
138 LSR1(ld, le, la, lb, lc, x[ 2], 15);
139 LSR1(lc, ld, le, la, lb, x[ 3], 12);
140 LSR1(lb, lc, ld, le, la, x[ 4], 5);
141 LSR1(la, lb, lc, ld, le, x[ 5], 8);
142 LSR1(le, la, lb, lc, ld, x[ 6], 7);
143 LSR1(ld, le, la, lb, lc, x[ 7], 9);
144 LSR1(lc, ld, le, la, lb, x[ 8], 11);
145 LSR1(lb, lc, ld, le, la, x[ 9], 13);
146 LSR1(la, lb, lc, ld, le, x[10], 14);
147 LSR1(le, la, lb, lc, ld, x[11], 15);
148 LSR1(ld, le, la, lb, lc, x[12], 6);
149 LSR1(lc, ld, le, la, lb, x[13], 7);
150 LSR1(lb, lc, ld, le, la, x[14], 9);
151 LSR1(la, lb, lc, ld, le, x[15], 8);
152
153 /* right round 1 */
154 RSR1(ra, rb, rc, rd, re, x[ 5], 8);
155 RSR1(re, ra, rb, rc, rd, x[14], 9);
156 RSR1(rd, re, ra, rb, rc, x[ 7], 9);
157 RSR1(rc, rd, re, ra, rb, x[ 0], 11);
158 RSR1(rb, rc, rd, re, ra, x[ 9], 13);
159 RSR1(ra, rb, rc, rd, re, x[ 2], 15);
160 RSR1(re, ra, rb, rc, rd, x[11], 15);
161 RSR1(rd, re, ra, rb, rc, x[ 4], 5);
162 RSR1(rc, rd, re, ra, rb, x[13], 7);
163 RSR1(rb, rc, rd, re, ra, x[ 6], 7);
164 RSR1(ra, rb, rc, rd, re, x[15], 8);
165 RSR1(re, ra, rb, rc, rd, x[ 8], 11);
166 RSR1(rd, re, ra, rb, rc, x[ 1], 14);
167 RSR1(rc, rd, re, ra, rb, x[10], 14);
168 RSR1(rb, rc, rd, re, ra, x[ 3], 12);
169 RSR1(ra, rb, rc, rd, re, x[12], 6);
170
171 temp = la; la = ra; ra = temp;
172
173 /* left round 2 */
174 LSR2(le, la, lb, lc, ld, x[ 7], 7);
175 LSR2(ld, le, la, lb, lc, x[ 4], 6);
176 LSR2(lc, ld, le, la, lb, x[13], 8);
177 LSR2(lb, lc, ld, le, la, x[ 1], 13);
178 LSR2(la, lb, lc, ld, le, x[10], 11);
179 LSR2(le, la, lb, lc, ld, x[ 6], 9);
180 LSR2(ld, le, la, lb, lc, x[15], 7);
181 LSR2(lc, ld, le, la, lb, x[ 3], 15);
182 LSR2(lb, lc, ld, le, la, x[12], 7);
183 LSR2(la, lb, lc, ld, le, x[ 0], 12);
184 LSR2(le, la, lb, lc, ld, x[ 9], 15);
185 LSR2(ld, le, la, lb, lc, x[ 5], 9);
186 LSR2(lc, ld, le, la, lb, x[ 2], 11);
187 LSR2(lb, lc, ld, le, la, x[14], 7);
188 LSR2(la, lb, lc, ld, le, x[11], 13);
189 LSR2(le, la, lb, lc, ld, x[ 8], 12);
190
191 /* right round 2 */
192 RSR2(re, ra, rb, rc, rd, x[ 6], 9);
193 RSR2(rd, re, ra, rb, rc, x[11], 13);
194 RSR2(rc, rd, re, ra, rb, x[ 3], 15);
195 RSR2(rb, rc, rd, re, ra, x[ 7], 7);
196 RSR2(ra, rb, rc, rd, re, x[ 0], 12);
197 RSR2(re, ra, rb, rc, rd, x[13], 8);
198 RSR2(rd, re, ra, rb, rc, x[ 5], 9);
199 RSR2(rc, rd, re, ra, rb, x[10], 11);
200 RSR2(rb, rc, rd, re, ra, x[14], 7);
201 RSR2(ra, rb, rc, rd, re, x[15], 7);
202 RSR2(re, ra, rb, rc, rd, x[ 8], 12);
203 RSR2(rd, re, ra, rb, rc, x[12], 7);
204 RSR2(rc, rd, re, ra, rb, x[ 4], 6);
205 RSR2(rb, rc, rd, re, ra, x[ 9], 15);
206 RSR2(ra, rb, rc, rd, re, x[ 1], 13);
207 RSR2(re, ra, rb, rc, rd, x[ 2], 11);
208
209 temp = lb; lb = rb; rb = temp;
210
211 /* left round 3 */
212 LSR3(ld, le, la, lb, lc, x[ 3], 11);
213 LSR3(lc, ld, le, la, lb, x[10], 13);
214 LSR3(lb, lc, ld, le, la, x[14], 6);
215 LSR3(la, lb, lc, ld, le, x[ 4], 7);
216 LSR3(le, la, lb, lc, ld, x[ 9], 14);
217 LSR3(ld, le, la, lb, lc, x[15], 9);
218 LSR3(lc, ld, le, la, lb, x[ 8], 13);
219 LSR3(lb, lc, ld, le, la, x[ 1], 15);
220 LSR3(la, lb, lc, ld, le, x[ 2], 14);
221 LSR3(le, la, lb, lc, ld, x[ 7], 8);
222 LSR3(ld, le, la, lb, lc, x[ 0], 13);
223 LSR3(lc, ld, le, la, lb, x[ 6], 6);
224 LSR3(lb, lc, ld, le, la, x[13], 5);
225 LSR3(la, lb, lc, ld, le, x[11], 12);
226 LSR3(le, la, lb, lc, ld, x[ 5], 7);
227 LSR3(ld, le, la, lb, lc, x[12], 5);
228
229 /* right round 3 */
230 RSR3(rd, re, ra, rb, rc, x[15], 9);
231 RSR3(rc, rd, re, ra, rb, x[ 5], 7);
232 RSR3(rb, rc, rd, re, ra, x[ 1], 15);
233 RSR3(ra, rb, rc, rd, re, x[ 3], 11);
234 RSR3(re, ra, rb, rc, rd, x[ 7], 8);
235 RSR3(rd, re, ra, rb, rc, x[14], 6);
236 RSR3(rc, rd, re, ra, rb, x[ 6], 6);
237 RSR3(rb, rc, rd, re, ra, x[ 9], 14);
238 RSR3(ra, rb, rc, rd, re, x[11], 12);
239 RSR3(re, ra, rb, rc, rd, x[ 8], 13);
240 RSR3(rd, re, ra, rb, rc, x[12], 5);
241 RSR3(rc, rd, re, ra, rb, x[ 2], 14);
242 RSR3(rb, rc, rd, re, ra, x[10], 13);
243 RSR3(ra, rb, rc, rd, re, x[ 0], 13);
244 RSR3(re, ra, rb, rc, rd, x[ 4], 7);
245 RSR3(rd, re, ra, rb, rc, x[13], 5);
246
247 temp = lc; lc = rc; rc = temp;
248
249 /* left round 4 */
250 LSR4(lc, ld, le, la, lb, x[ 1], 11);
251 LSR4(lb, lc, ld, le, la, x[ 9], 12);
252 LSR4(la, lb, lc, ld, le, x[11], 14);
253 LSR4(le, la, lb, lc, ld, x[10], 15);
254 LSR4(ld, le, la, lb, lc, x[ 0], 14);
255 LSR4(lc, ld, le, la, lb, x[ 8], 15);
256 LSR4(lb, lc, ld, le, la, x[12], 9);
257 LSR4(la, lb, lc, ld, le, x[ 4], 8);
258 LSR4(le, la, lb, lc, ld, x[13], 9);
259 LSR4(ld, le, la, lb, lc, x[ 3], 14);
260 LSR4(lc, ld, le, la, lb, x[ 7], 5);
261 LSR4(lb, lc, ld, le, la, x[15], 6);
262 LSR4(la, lb, lc, ld, le, x[14], 8);
263 LSR4(le, la, lb, lc, ld, x[ 5], 6);
264 LSR4(ld, le, la, lb, lc, x[ 6], 5);
265 LSR4(lc, ld, le, la, lb, x[ 2], 12);
266
267 /* right round 4 */
268 RSR4(rc, rd, re, ra, rb, x[ 8], 15);
269 RSR4(rb, rc, rd, re, ra, x[ 6], 5);
270 RSR4(ra, rb, rc, rd, re, x[ 4], 8);
271 RSR4(re, ra, rb, rc, rd, x[ 1], 11);
272 RSR4(rd, re, ra, rb, rc, x[ 3], 14);
273 RSR4(rc, rd, re, ra, rb, x[11], 14);
274 RSR4(rb, rc, rd, re, ra, x[15], 6);
275 RSR4(ra, rb, rc, rd, re, x[ 0], 14);
276 RSR4(re, ra, rb, rc, rd, x[ 5], 6);
277 RSR4(rd, re, ra, rb, rc, x[12], 9);
278 RSR4(rc, rd, re, ra, rb, x[ 2], 12);
279 RSR4(rb, rc, rd, re, ra, x[13], 9);
280 RSR4(ra, rb, rc, rd, re, x[ 9], 12);
281 RSR4(re, ra, rb, rc, rd, x[ 7], 5);
282 RSR4(rd, re, ra, rb, rc, x[10], 15);
283 RSR4(rc, rd, re, ra, rb, x[14], 8);
284
285 temp = ld; ld = rd; rd = temp;
286
287 /* left round 5 */
288 LSR5(lb, lc, ld, le, la, x[ 4], 9);
289 LSR5(la, lb, lc, ld, le, x[ 0], 15);
290 LSR5(le, la, lb, lc, ld, x[ 5], 5);
291 LSR5(ld, le, la, lb, lc, x[ 9], 11);
292 LSR5(lc, ld, le, la, lb, x[ 7], 6);
293 LSR5(lb, lc, ld, le, la, x[12], 8);
294 LSR5(la, lb, lc, ld, le, x[ 2], 13);
295 LSR5(le, la, lb, lc, ld, x[10], 12);
296 LSR5(ld, le, la, lb, lc, x[14], 5);
297 LSR5(lc, ld, le, la, lb, x[ 1], 12);
298 LSR5(lb, lc, ld, le, la, x[ 3], 13);
299 LSR5(la, lb, lc, ld, le, x[ 8], 14);
300 LSR5(le, la, lb, lc, ld, x[11], 11);
301 LSR5(ld, le, la, lb, lc, x[ 6], 8);
302 LSR5(lc, ld, le, la, lb, x[15], 5);
303 LSR5(lb, lc, ld, le, la, x[13], 6);
304
305 /* right round 5 */
306 RSR5(rb, rc, rd, re, ra, x[12] , 8);
307 RSR5(ra, rb, rc, rd, re, x[15] , 5);
308 RSR5(re, ra, rb, rc, rd, x[10] , 12);
309 RSR5(rd, re, ra, rb, rc, x[ 4] , 9);
310 RSR5(rc, rd, re, ra, rb, x[ 1] , 12);
311 RSR5(rb, rc, rd, re, ra, x[ 5] , 5);
312 RSR5(ra, rb, rc, rd, re, x[ 8] , 14);
313 RSR5(re, ra, rb, rc, rd, x[ 7] , 6);
314 RSR5(rd, re, ra, rb, rc, x[ 6] , 8);
315 RSR5(rc, rd, re, ra, rb, x[ 2] , 13);
316 RSR5(rb, rc, rd, re, ra, x[13] , 6);
317 RSR5(ra, rb, rc, rd, re, x[14] , 5);
318 RSR5(re, ra, rb, rc, rd, x[ 0] , 15);
319 RSR5(rd, re, ra, rb, rc, x[ 3] , 13);
320 RSR5(rc, rd, re, ra, rb, x[ 9] , 11);
321 RSR5(rb, rc, rd, re, ra, x[11] , 11);
322
323 temp = le; le = re; re = temp;
324
325 /* combine results */
326 mp->h[0] += la;
327 mp->h[1] += lb;
328 mp->h[2] += lc;
329 mp->h[3] += ld;
330 mp->h[4] += le;
331 mp->h[5] += ra;
332 mp->h[6] += rb;
333 mp->h[7] += rc;
334 mp->h[8] += rd;
335 mp->h[9] += re;
336 }
337 #endif
338
ripemd320Update(ripemd320Param * mp,const byte * data,size_t size)339 int ripemd320Update(ripemd320Param* mp, const byte* data, size_t size)
340 {
341 register uint32_t proclength;
342
343 #if (MP_WBITS == 64)
344 mpw add[1];
345 mpsetw(1, add, size);
346 mplshift(1, add, 3);
347 mpadd(1, mp->length, add);
348 #elif (MP_WBITS == 32)
349 mpw add[2];
350 mpsetw(2, add, size);
351 mplshift(2, add, 3);
352 (void) mpadd(2, mp->length, add);
353 #else
354 # error
355 #endif
356
357 while (size > 0)
358 {
359 proclength = ((mp->offset + size) > 64U) ? (64U - mp->offset) : size;
360 /*@-mayaliasunique@*/
361 memcpy(((byte *) mp->data) + mp->offset, data, proclength);
362 /*@=mayaliasunique@*/
363 size -= proclength;
364 data += proclength;
365 mp->offset += proclength;
366
367 if (mp->offset == 64U)
368 {
369 ripemd320Process(mp);
370 mp->offset = 0;
371 }
372 }
373 return 0;
374 }
375
ripemd320Finish(ripemd320Param * mp)376 static void ripemd320Finish(ripemd320Param* mp)
377 /*@modifies mp @*/
378 {
379 register byte *ptr = ((byte *) mp->data) + mp->offset++;
380
381 *(ptr++) = 0x80;
382
383 if (mp->offset > 56)
384 {
385 while (mp->offset++ < 64)
386 *(ptr++) = 0;
387
388 ripemd320Process(mp);
389 mp->offset = 0;
390 }
391
392 ptr = ((byte *) mp->data) + mp->offset;
393 while (mp->offset++ < 56)
394 *(ptr++) = 0;
395
396 #if (MP_WBITS == 64)
397 ptr[0] = (byte)(mp->length[0] );
398 ptr[1] = (byte)(mp->length[0] >> 8);
399 ptr[2] = (byte)(mp->length[0] >> 16);
400 ptr[3] = (byte)(mp->length[0] >> 24);
401 ptr[4] = (byte)(mp->length[0] >> 32);
402 ptr[5] = (byte)(mp->length[0] >> 40);
403 ptr[6] = (byte)(mp->length[0] >> 48);
404 ptr[7] = (byte)(mp->length[0] >> 56);
405 #elif (MP_WBITS == 32)
406 ptr[0] = (byte)(mp->length[1] );
407 ptr[1] = (byte)(mp->length[1] >> 8);
408 ptr[2] = (byte)(mp->length[1] >> 16);
409 ptr[3] = (byte)(mp->length[1] >> 24);
410 ptr[4] = (byte)(mp->length[0] );
411 ptr[5] = (byte)(mp->length[0] >> 8);
412 ptr[6] = (byte)(mp->length[0] >> 16);
413 ptr[7] = (byte)(mp->length[0] >> 24);
414 #else
415 # error
416 #endif
417
418 ripemd320Process(mp);
419
420 mp->offset = 0;
421 }
422
423 /*@-protoparammatch@*/
ripemd320Digest(ripemd320Param * mp,byte * data)424 int ripemd320Digest(ripemd320Param* mp, byte* data)
425 {
426 ripemd320Finish(mp);
427
428 /* encode 5 integers little-endian style */
429 data[ 0] = (byte)(mp->h[0] );
430 data[ 1] = (byte)(mp->h[0] >> 8);
431 data[ 2] = (byte)(mp->h[0] >> 16);
432 data[ 3] = (byte)(mp->h[0] >> 24);
433 data[ 4] = (byte)(mp->h[1] );
434 data[ 5] = (byte)(mp->h[1] >> 8);
435 data[ 6] = (byte)(mp->h[1] >> 16);
436 data[ 7] = (byte)(mp->h[1] >> 24);
437 data[ 8] = (byte)(mp->h[2] );
438 data[ 9] = (byte)(mp->h[2] >> 8);
439 data[10] = (byte)(mp->h[2] >> 16);
440 data[11] = (byte)(mp->h[2] >> 24);
441 data[12] = (byte)(mp->h[3] );
442 data[13] = (byte)(mp->h[3] >> 8);
443 data[14] = (byte)(mp->h[3] >> 16);
444 data[15] = (byte)(mp->h[3] >> 24);
445 data[16] = (byte)(mp->h[4] );
446 data[17] = (byte)(mp->h[4] >> 8);
447 data[18] = (byte)(mp->h[4] >> 16);
448 data[19] = (byte)(mp->h[4] >> 24);
449
450 data[20] = (byte)(mp->h[5] );
451 data[21] = (byte)(mp->h[5] >> 8);
452 data[22] = (byte)(mp->h[5] >> 16);
453 data[23] = (byte)(mp->h[5] >> 24);
454 data[24] = (byte)(mp->h[6] );
455 data[25] = (byte)(mp->h[6] >> 8);
456 data[26] = (byte)(mp->h[6] >> 16);
457 data[27] = (byte)(mp->h[6] >> 24);
458 data[28] = (byte)(mp->h[7] );
459 data[29] = (byte)(mp->h[7] >> 8);
460 data[30] = (byte)(mp->h[7] >> 16);
461 data[31] = (byte)(mp->h[7] >> 24);
462 data[32] = (byte)(mp->h[8] );
463 data[33] = (byte)(mp->h[8] >> 8);
464 data[34] = (byte)(mp->h[8] >> 16);
465 data[35] = (byte)(mp->h[8] >> 24);
466 data[36] = (byte)(mp->h[9] );
467 data[37] = (byte)(mp->h[9] >> 8);
468 data[38] = (byte)(mp->h[9] >> 16);
469 data[39] = (byte)(mp->h[9] >> 24);
470
471 (void) ripemd320Reset(mp);
472
473 return 0;
474 }
475 /*@=protoparammatch@*/
476
477 /*!\}
478 */
479
480