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 ripemd256.c
19 * \brief RIPEMD-256 hash function.
20 * \author Jeff Johnson <jbj@rpm5.org>
21 * \author Bob Deblier <bob.deblier@telenet.be>
22 * \ingroup HASH_m HASH_ripemd256_m
23 */
24
25 #define BEECRYPT_DLL_EXPORT
26
27 #if HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include "beecrypt/ripemd256.h"
32 #include "beecrypt/endianness.h"
33
34 /*!\addtogroup HASH_ripemd256_m
35 * \{
36 */
37
38 /*@unchecked@*/ /*@observer@*/
39 static uint32_t ripemd256hinit[8] = {
40 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U,
41 0x76543210U, 0xfedcba98U, 0x89abcdefU, 0x01234567U
42 };
43
44 /*@-sizeoftype@*/
45 /*@unchecked@*/ /*@observer@*/
46 const hashFunction ripemd256 = {
47 .name = "RIPEMD-256",
48 .paramsize = sizeof(ripemd256Param),
49 .blocksize = 64,
50 .digestsize = 32,
51 .reset = (hashFunctionReset) ripemd256Reset,
52 .update = (hashFunctionUpdate) ripemd256Update,
53 .digest = (hashFunctionDigest) ripemd256Digest
54 };
55 /*@=sizeoftype@*/
56
ripemd256Reset(register ripemd256Param * mp)57 int ripemd256Reset(register ripemd256Param* mp)
58 {
59 /*@-sizeoftype@*/
60 memcpy(mp->h, ripemd256hinit, 8 * 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, x, s) \
75 a = ROTL32((b^c^d) + a + x, s);
76 #define LSR2(a, b, c, d, x, s) \
77 a = ROTL32(((b&c)|(~b&d)) + a + x + 0x5a827999U, s);
78 #define LSR3(a, b, c, d, x, s) \
79 a = ROTL32(((b|~c)^d) + a + x + 0x6ed9eba1U, s);
80 #define LSR4(a, b, c, d, x, s) \
81 a = ROTL32(((b&d)|(c&~d)) + a + x + 0x8f1bbcdcU, s);
82
83 #define RSR4(a, b, c, d, x, s) \
84 a = ROTL32((b^c^d) + a + x, s);
85 #define RSR3(a, b, c, d, x, s) \
86 a = ROTL32(((b&c)|(~b&d)) + a + x + 0x6d703ef3U, s);
87 #define RSR2(a, b, c, d, x, s) \
88 a = ROTL32(((b|~c)^d) + a + x + 0x5c4dd124U, s);
89 #define RSR1(a, b, c, d, x, s) \
90 a = ROTL32(((b&d)|(c&~d)) + a + x + 0x50a28be6U, s);
91
92 #ifndef ASM_RIPEMD256PROCESS
ripemd256Process(ripemd256Param * mp)93 void ripemd256Process(ripemd256Param* mp)
94 {
95 register uint32_t la, lb, lc, ld;
96 register uint32_t ra, rb, rc, rd;
97 register uint32_t temp;
98 register uint32_t* x;
99 #ifdef WORDS_BIGENDIAN
100 register byte t;
101 #endif
102
103 x = mp->data;
104 #ifdef WORDS_BIGENDIAN
105 t = 16;
106 while (t--)
107 {
108 temp = swapu32(*x);
109 *(x++) = temp;
110 }
111 x = mp->data;
112 #endif
113
114 la = mp->h[0]; lb = mp->h[1]; lc = mp->h[2]; ld = mp->h[3];
115 ra = mp->h[4]; rb = mp->h[5]; rc = mp->h[6]; rd = mp->h[7];
116
117 /* In theory OpenMP would allows us to do the 'left' and 'right' sections in parallel,
118 * but in practice the overhead make the code much slower
119 */
120
121 /* left round 1 */
122 LSR1(la, lb, lc, ld, x[ 0], 11);
123 LSR1(ld, la, lb, lc, x[ 1], 14);
124 LSR1(lc, ld, la, lb, x[ 2], 15);
125 LSR1(lb, lc, ld, la, x[ 3], 12);
126 LSR1(la, lb, lc, ld, x[ 4], 5);
127 LSR1(ld, la, lb, lc, x[ 5], 8);
128 LSR1(lc, ld, la, lb, x[ 6], 7);
129 LSR1(lb, lc, ld, la, x[ 7], 9);
130 LSR1(la, lb, lc, ld, x[ 8], 11);
131 LSR1(ld, la, lb, lc, x[ 9], 13);
132 LSR1(lc, ld, la, lb, x[10], 14);
133 LSR1(lb, lc, ld, la, x[11], 15);
134 LSR1(la, lb, lc, ld, x[12], 6);
135 LSR1(ld, la, lb, lc, x[13], 7);
136 LSR1(lc, ld, la, lb, x[14], 9);
137 LSR1(lb, lc, ld, la, x[15], 8);
138
139 /* right round 1 */
140 RSR1(ra, rb, rc, rd, x[ 5], 8);
141 RSR1(rd, ra, rb, rc, x[14], 9);
142 RSR1(rc, rd, ra, rb, x[ 7], 9);
143 RSR1(rb, rc, rd, ra, x[ 0], 11);
144 RSR1(ra, rb, rc, rd, x[ 9], 13);
145 RSR1(rd, ra, rb, rc, x[ 2], 15);
146 RSR1(rc, rd, ra, rb, x[11], 15);
147 RSR1(rb, rc, rd, ra, x[ 4], 5);
148 RSR1(ra, rb, rc, rd, x[13], 7);
149 RSR1(rd, ra, rb, rc, x[ 6], 7);
150 RSR1(rc, rd, ra, rb, x[15], 8);
151 RSR1(rb, rc, rd, ra, x[ 8], 11);
152 RSR1(ra, rb, rc, rd, x[ 1], 14);
153 RSR1(rd, ra, rb, rc, x[10], 14);
154 RSR1(rc, rd, ra, rb, x[ 3], 12);
155 RSR1(rb, rc, rd, ra, x[12], 6);
156
157 temp = la; la = ra; ra = temp;
158
159 /* left round 2 */
160 LSR2(la, lb, lc, ld, x[ 7], 7);
161 LSR2(ld, la, lb, lc, x[ 4], 6);
162 LSR2(lc, ld, la, lb, x[13], 8);
163 LSR2(lb, lc, ld, la, x[ 1], 13);
164 LSR2(la, lb, lc, ld, x[10], 11);
165 LSR2(ld, la, lb, lc, x[ 6], 9);
166 LSR2(lc, ld, la, lb, x[15], 7);
167 LSR2(lb, lc, ld, la, x[ 3], 15);
168 LSR2(la, lb, lc, ld, x[12], 7);
169 LSR2(ld, la, lb, lc, x[ 0], 12);
170 LSR2(lc, ld, la, lb, x[ 9], 15);
171 LSR2(lb, lc, ld, la, x[ 5], 9);
172 LSR2(la, lb, lc, ld, x[ 2], 11);
173 LSR2(ld, la, lb, lc, x[14], 7);
174 LSR2(lc, ld, la, lb, x[11], 13);
175 LSR2(lb, lc, ld, la, x[ 8], 12);
176
177 /* right round 2 */
178 RSR2(ra, rb, rc, rd, x[ 6], 9);
179 RSR2(rd, ra, rb, rc, x[11], 13);
180 RSR2(rc, rd, ra, rb, x[ 3], 15);
181 RSR2(rb, rc, rd, ra, x[ 7], 7);
182 RSR2(ra, rb, rc, rd, x[ 0], 12);
183 RSR2(rd, ra, rb, rc, x[13], 8);
184 RSR2(rc, rd, ra, rb, x[ 5], 9);
185 RSR2(rb, rc, rd, ra, x[10], 11);
186 RSR2(ra, rb, rc, rd, x[14], 7);
187 RSR2(rd, ra, rb, rc, x[15], 7);
188 RSR2(rc, rd, ra, rb, x[ 8], 12);
189 RSR2(rb, rc, rd, ra, x[12], 7);
190 RSR2(ra, rb, rc, rd, x[ 4], 6);
191 RSR2(rd, ra, rb, rc, x[ 9], 15);
192 RSR2(rc, rd, ra, rb, x[ 1], 13);
193 RSR2(rb, rc, rd, ra, x[ 2], 11);
194
195 temp = lb; lb = rb; rb = temp;
196
197 /* left round 3 */
198 LSR3(la, lb, lc, ld, x[ 3], 11);
199 LSR3(ld, la, lb, lc, x[10], 13);
200 LSR3(lc, ld, la, lb, x[14], 6);
201 LSR3(lb, lc, ld, la, x[ 4], 7);
202 LSR3(la, lb, lc, ld, x[ 9], 14);
203 LSR3(ld, la, lb, lc, x[15], 9);
204 LSR3(lc, ld, la, lb, x[ 8], 13);
205 LSR3(lb, lc, ld, la, x[ 1], 15);
206 LSR3(la, lb, lc, ld, x[ 2], 14);
207 LSR3(ld, la, lb, lc, x[ 7], 8);
208 LSR3(lc, ld, la, lb, x[ 0], 13);
209 LSR3(lb, lc, ld, la, x[ 6], 6);
210 LSR3(la, lb, lc, ld, x[13], 5);
211 LSR3(ld, la, lb, lc, x[11], 12);
212 LSR3(lc, ld, la, lb, x[ 5], 7);
213 LSR3(lb, lc, ld, la, x[12], 5);
214
215 /* right round 3 */
216 RSR3(ra, rb, rc, rd, x[15], 9);
217 RSR3(rd, ra, rb, rc, x[ 5], 7);
218 RSR3(rc, rd, ra, rb, x[ 1], 15);
219 RSR3(rb, rc, rd, ra, x[ 3], 11);
220 RSR3(ra, rb, rc, rd, x[ 7], 8);
221 RSR3(rd, ra, rb, rc, x[14], 6);
222 RSR3(rc, rd, ra, rb, x[ 6], 6);
223 RSR3(rb, rc, rd, ra, x[ 9], 14);
224 RSR3(ra, rb, rc, rd, x[11], 12);
225 RSR3(rd, ra, rb, rc, x[ 8], 13);
226 RSR3(rc, rd, ra, rb, x[12], 5);
227 RSR3(rb, rc, rd, ra, x[ 2], 14);
228 RSR3(ra, rb, rc, rd, x[10], 13);
229 RSR3(rd, ra, rb, rc, x[ 0], 13);
230 RSR3(rc, rd, ra, rb, x[ 4], 7);
231 RSR3(rb, rc, rd, ra, x[13], 5);
232
233 temp = lc; lc = rc; rc = temp;
234
235 /* left round 4 */
236 LSR4(la, lb, lc, ld, x[ 1], 11);
237 LSR4(ld, la, lb, lc, x[ 9], 12);
238 LSR4(lc, ld, la, lb, x[11], 14);
239 LSR4(lb, lc, ld, la, x[10], 15);
240 LSR4(la, lb, lc, ld, x[ 0], 14);
241 LSR4(ld, la, lb, lc, x[ 8], 15);
242 LSR4(lc, ld, la, lb, x[12], 9);
243 LSR4(lb, lc, ld, la, x[ 4], 8);
244 LSR4(la, lb, lc, ld, x[13], 9);
245 LSR4(ld, la, lb, lc, x[ 3], 14);
246 LSR4(lc, ld, la, lb, x[ 7], 5);
247 LSR4(lb, lc, ld, la, x[15], 6);
248 LSR4(la, lb, lc, ld, x[14], 8);
249 LSR4(ld, la, lb, lc, x[ 5], 6);
250 LSR4(lc, ld, la, lb, x[ 6], 5);
251 LSR4(lb, lc, ld, la, x[ 2], 12);
252
253 /* right round 4 */
254 RSR4(ra, rb, rc, rd, x[ 8], 15);
255 RSR4(rd, ra, rb, rc, x[ 6], 5);
256 RSR4(rc, rd, ra, rb, x[ 4], 8);
257 RSR4(rb, rc, rd, ra, x[ 1], 11);
258 RSR4(ra, rb, rc, rd, x[ 3], 14);
259 RSR4(rd, ra, rb, rc, x[11], 14);
260 RSR4(rc, rd, ra, rb, x[15], 6);
261 RSR4(rb, rc, rd, ra, x[ 0], 14);
262 RSR4(ra, rb, rc, rd, x[ 5], 6);
263 RSR4(rd, ra, rb, rc, x[12], 9);
264 RSR4(rc, rd, ra, rb, x[ 2], 12);
265 RSR4(rb, rc, rd, ra, x[13], 9);
266 RSR4(ra, rb, rc, rd, x[ 9], 12);
267 RSR4(rd, ra, rb, rc, x[ 7], 5);
268 RSR4(rc, rd, ra, rb, x[10], 15);
269 RSR4(rb, rc, rd, ra, x[14], 8);
270
271 temp = ld; ld = rd; rd = temp;
272
273 /* combine results */
274 mp->h[0] += la;
275 mp->h[1] += lb;
276 mp->h[2] += lc;
277 mp->h[3] += ld;
278 mp->h[4] += ra;
279 mp->h[5] += rb;
280 mp->h[6] += rc;
281 mp->h[7] += rd;
282 }
283 #endif
284
ripemd256Update(ripemd256Param * mp,const byte * data,size_t size)285 int ripemd256Update(ripemd256Param* mp, const byte* data, size_t size)
286 {
287 register uint32_t proclength;
288
289 #if (MP_WBITS == 64)
290 mpw add[1];
291 mpsetw(1, add, size);
292 mplshift(1, add, 3);
293 mpadd(1, mp->length, add);
294 #elif (MP_WBITS == 32)
295 mpw add[2];
296 mpsetw(2, add, size);
297 mplshift(2, add, 3);
298 (void) mpadd(2, mp->length, add);
299 #else
300 # error
301 #endif
302
303 while (size > 0)
304 {
305 proclength = ((mp->offset + size) > 64U) ? (64U - mp->offset) : size;
306 /*@-mayaliasunique@*/
307 memcpy(((byte *) mp->data) + mp->offset, data, proclength);
308 /*@=mayaliasunique@*/
309 size -= proclength;
310 data += proclength;
311 mp->offset += proclength;
312
313 if (mp->offset == 64U)
314 {
315 ripemd256Process(mp);
316 mp->offset = 0;
317 }
318 }
319 return 0;
320 }
321
ripemd256Finish(ripemd256Param * mp)322 static void ripemd256Finish(ripemd256Param* mp)
323 /*@modifies mp @*/
324 {
325 register byte *ptr = ((byte *) mp->data) + mp->offset++;
326
327 *(ptr++) = 0x80;
328
329 if (mp->offset > 56)
330 {
331 while (mp->offset++ < 64)
332 *(ptr++) = 0;
333
334 ripemd256Process(mp);
335 mp->offset = 0;
336 }
337
338 ptr = ((byte *) mp->data) + mp->offset;
339 while (mp->offset++ < 56)
340 *(ptr++) = 0;
341
342 #if (MP_WBITS == 64)
343 ptr[0] = (byte)(mp->length[0] );
344 ptr[1] = (byte)(mp->length[0] >> 8);
345 ptr[2] = (byte)(mp->length[0] >> 16);
346 ptr[3] = (byte)(mp->length[0] >> 24);
347 ptr[4] = (byte)(mp->length[0] >> 32);
348 ptr[5] = (byte)(mp->length[0] >> 40);
349 ptr[6] = (byte)(mp->length[0] >> 48);
350 ptr[7] = (byte)(mp->length[0] >> 56);
351 #elif (MP_WBITS == 32)
352 ptr[0] = (byte)(mp->length[1] );
353 ptr[1] = (byte)(mp->length[1] >> 8);
354 ptr[2] = (byte)(mp->length[1] >> 16);
355 ptr[3] = (byte)(mp->length[1] >> 24);
356 ptr[4] = (byte)(mp->length[0] );
357 ptr[5] = (byte)(mp->length[0] >> 8);
358 ptr[6] = (byte)(mp->length[0] >> 16);
359 ptr[7] = (byte)(mp->length[0] >> 24);
360 #else
361 # error
362 #endif
363
364 ripemd256Process(mp);
365
366 mp->offset = 0;
367 }
368
369 /*@-protoparammatch@*/
ripemd256Digest(ripemd256Param * mp,byte * data)370 int ripemd256Digest(ripemd256Param* mp, byte* data)
371 {
372 ripemd256Finish(mp);
373
374 /* encode 8 integers little-endian style */
375 data[ 0] = (byte)(mp->h[0] );
376 data[ 1] = (byte)(mp->h[0] >> 8);
377 data[ 2] = (byte)(mp->h[0] >> 16);
378 data[ 3] = (byte)(mp->h[0] >> 24);
379 data[ 4] = (byte)(mp->h[1] );
380 data[ 5] = (byte)(mp->h[1] >> 8);
381 data[ 6] = (byte)(mp->h[1] >> 16);
382 data[ 7] = (byte)(mp->h[1] >> 24);
383 data[ 8] = (byte)(mp->h[2] );
384 data[ 9] = (byte)(mp->h[2] >> 8);
385 data[10] = (byte)(mp->h[2] >> 16);
386 data[11] = (byte)(mp->h[2] >> 24);
387 data[12] = (byte)(mp->h[3] );
388 data[13] = (byte)(mp->h[3] >> 8);
389 data[14] = (byte)(mp->h[3] >> 16);
390 data[15] = (byte)(mp->h[3] >> 24);
391
392 data[16] = (byte)(mp->h[4] );
393 data[17] = (byte)(mp->h[4] >> 8);
394 data[18] = (byte)(mp->h[4] >> 16);
395 data[19] = (byte)(mp->h[4] >> 24);
396 data[20] = (byte)(mp->h[5] );
397 data[21] = (byte)(mp->h[5] >> 8);
398 data[22] = (byte)(mp->h[5] >> 16);
399 data[23] = (byte)(mp->h[5] >> 24);
400 data[24] = (byte)(mp->h[6] );
401 data[25] = (byte)(mp->h[6] >> 8);
402 data[26] = (byte)(mp->h[6] >> 16);
403 data[27] = (byte)(mp->h[6] >> 24);
404 data[28] = (byte)(mp->h[7] );
405 data[29] = (byte)(mp->h[7] >> 8);
406 data[30] = (byte)(mp->h[7] >> 16);
407 data[31] = (byte)(mp->h[7] >> 24);
408
409 (void) ripemd256Reset(mp);
410
411 return 0;
412 }
413 /*@=protoparammatch@*/
414
415 /*!\}
416 */
417
418