1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6    @file rmd320.c
7    RMD320 hash function
8 */
9 
10 #ifdef LTC_RIPEMD320
11 
12 const struct ltc_hash_descriptor rmd320_desc =
13 {
14     "rmd320",
15     14,
16     40,
17     64,
18 
19     /* OID ... does not exist
20      * http://oid-info.com/get/1.3.36.3.2 */
21    { 0 },
22    0,
23 
24     &rmd320_init,
25     &rmd320_process,
26     &rmd320_done,
27     &rmd320_test,
28     NULL
29 };
30 
31 /* the five basic functions F(), G() and H() */
32 #define F(x, y, z)        ((x) ^ (y) ^ (z))
33 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
34 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
35 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
36 #define J(x, y, z)        ((x) ^ ((y) | ~(z)))
37 
38 /* the ten basic operations FF() through III() */
39 #define FF(a, b, c, d, e, x, s)        \
40       (a) += F((b), (c), (d)) + (x);\
41       (a) = ROLc((a), (s)) + (e);\
42       (c) = ROLc((c), 10);
43 
44 #define GG(a, b, c, d, e, x, s)        \
45       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
46       (a) = ROLc((a), (s)) + (e);\
47       (c) = ROLc((c), 10);
48 
49 #define HH(a, b, c, d, e, x, s)        \
50       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
51       (a) = ROLc((a), (s)) + (e);\
52       (c) = ROLc((c), 10);
53 
54 #define II(a, b, c, d, e, x, s)        \
55       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
56       (a) = ROLc((a), (s)) + (e);\
57       (c) = ROLc((c), 10);
58 
59 #define JJ(a, b, c, d, e, x, s)        \
60       (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
61       (a) = ROLc((a), (s)) + (e);\
62       (c) = ROLc((c), 10);
63 
64 #define FFF(a, b, c, d, e, x, s)        \
65       (a) += F((b), (c), (d)) + (x);\
66       (a) = ROLc((a), (s)) + (e);\
67       (c) = ROLc((c), 10);
68 
69 #define GGG(a, b, c, d, e, x, s)        \
70       (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
71       (a) = ROLc((a), (s)) + (e);\
72       (c) = ROLc((c), 10);
73 
74 #define HHH(a, b, c, d, e, x, s)        \
75       (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
76       (a) = ROLc((a), (s)) + (e);\
77       (c) = ROLc((c), 10);
78 
79 #define III(a, b, c, d, e, x, s)        \
80       (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
81       (a) = ROLc((a), (s)) + (e);\
82       (c) = ROLc((c), 10);
83 
84 #define JJJ(a, b, c, d, e, x, s)        \
85       (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
86       (a) = ROLc((a), (s)) + (e);\
87       (c) = ROLc((c), 10);
88 
89 
90 #ifdef LTC_CLEAN_STACK
ss_rmd320_compress(hash_state * md,const unsigned char * buf)91 static int ss_rmd320_compress(hash_state *md, const unsigned char *buf)
92 #else
93 static int  s_rmd320_compress(hash_state *md, const unsigned char *buf)
94 #endif
95 {
96    ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
97    int i;
98 
99    /* load words X */
100    for (i = 0; i < 16; i++){
101       LOAD32L(X[i], buf + (4 * i));
102    }
103 
104    /* load state */
105    aa = md->rmd320.state[0];
106    bb = md->rmd320.state[1];
107    cc = md->rmd320.state[2];
108    dd = md->rmd320.state[3];
109    ee = md->rmd320.state[4];
110    aaa = md->rmd320.state[5];
111    bbb = md->rmd320.state[6];
112    ccc = md->rmd320.state[7];
113    ddd = md->rmd320.state[8];
114    eee = md->rmd320.state[9];
115 
116    /* round 1 */
117    FF(aa, bb, cc, dd, ee, X[ 0], 11);
118    FF(ee, aa, bb, cc, dd, X[ 1], 14);
119    FF(dd, ee, aa, bb, cc, X[ 2], 15);
120    FF(cc, dd, ee, aa, bb, X[ 3], 12);
121    FF(bb, cc, dd, ee, aa, X[ 4],  5);
122    FF(aa, bb, cc, dd, ee, X[ 5],  8);
123    FF(ee, aa, bb, cc, dd, X[ 6],  7);
124    FF(dd, ee, aa, bb, cc, X[ 7],  9);
125    FF(cc, dd, ee, aa, bb, X[ 8], 11);
126    FF(bb, cc, dd, ee, aa, X[ 9], 13);
127    FF(aa, bb, cc, dd, ee, X[10], 14);
128    FF(ee, aa, bb, cc, dd, X[11], 15);
129    FF(dd, ee, aa, bb, cc, X[12],  6);
130    FF(cc, dd, ee, aa, bb, X[13],  7);
131    FF(bb, cc, dd, ee, aa, X[14],  9);
132    FF(aa, bb, cc, dd, ee, X[15],  8);
133 
134    /* parallel round 1 */
135    JJJ(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
136    JJJ(eee, aaa, bbb, ccc, ddd, X[14],  9);
137    JJJ(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
138    JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
139    JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
140    JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
141    JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
142    JJJ(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
143    JJJ(ccc, ddd, eee, aaa, bbb, X[13],  7);
144    JJJ(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
145    JJJ(aaa, bbb, ccc, ddd, eee, X[15],  8);
146    JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
147    JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
148    JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
149    JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
150    JJJ(aaa, bbb, ccc, ddd, eee, X[12],  6);
151 
152    tmp = aa; aa = aaa; aaa = tmp;
153 
154    /* round 2 */
155    GG(ee, aa, bb, cc, dd, X[ 7],  7);
156    GG(dd, ee, aa, bb, cc, X[ 4],  6);
157    GG(cc, dd, ee, aa, bb, X[13],  8);
158    GG(bb, cc, dd, ee, aa, X[ 1], 13);
159    GG(aa, bb, cc, dd, ee, X[10], 11);
160    GG(ee, aa, bb, cc, dd, X[ 6],  9);
161    GG(dd, ee, aa, bb, cc, X[15],  7);
162    GG(cc, dd, ee, aa, bb, X[ 3], 15);
163    GG(bb, cc, dd, ee, aa, X[12],  7);
164    GG(aa, bb, cc, dd, ee, X[ 0], 12);
165    GG(ee, aa, bb, cc, dd, X[ 9], 15);
166    GG(dd, ee, aa, bb, cc, X[ 5],  9);
167    GG(cc, dd, ee, aa, bb, X[ 2], 11);
168    GG(bb, cc, dd, ee, aa, X[14],  7);
169    GG(aa, bb, cc, dd, ee, X[11], 13);
170    GG(ee, aa, bb, cc, dd, X[ 8], 12);
171 
172    /* parallel round 2 */
173    III(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
174    III(ddd, eee, aaa, bbb, ccc, X[11], 13);
175    III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
176    III(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
177    III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
178    III(eee, aaa, bbb, ccc, ddd, X[13],  8);
179    III(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
180    III(ccc, ddd, eee, aaa, bbb, X[10], 11);
181    III(bbb, ccc, ddd, eee, aaa, X[14],  7);
182    III(aaa, bbb, ccc, ddd, eee, X[15],  7);
183    III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
184    III(ddd, eee, aaa, bbb, ccc, X[12],  7);
185    III(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
186    III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
187    III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
188    III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
189 
190    tmp = bb; bb = bbb; bbb = tmp;
191 
192    /* round 3 */
193    HH(dd, ee, aa, bb, cc, X[ 3], 11);
194    HH(cc, dd, ee, aa, bb, X[10], 13);
195    HH(bb, cc, dd, ee, aa, X[14],  6);
196    HH(aa, bb, cc, dd, ee, X[ 4],  7);
197    HH(ee, aa, bb, cc, dd, X[ 9], 14);
198    HH(dd, ee, aa, bb, cc, X[15],  9);
199    HH(cc, dd, ee, aa, bb, X[ 8], 13);
200    HH(bb, cc, dd, ee, aa, X[ 1], 15);
201    HH(aa, bb, cc, dd, ee, X[ 2], 14);
202    HH(ee, aa, bb, cc, dd, X[ 7],  8);
203    HH(dd, ee, aa, bb, cc, X[ 0], 13);
204    HH(cc, dd, ee, aa, bb, X[ 6],  6);
205    HH(bb, cc, dd, ee, aa, X[13],  5);
206    HH(aa, bb, cc, dd, ee, X[11], 12);
207    HH(ee, aa, bb, cc, dd, X[ 5],  7);
208    HH(dd, ee, aa, bb, cc, X[12],  5);
209 
210    /* parallel round 3 */
211    HHH(ddd, eee, aaa, bbb, ccc, X[15],  9);
212    HHH(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
213    HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
214    HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
215    HHH(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
216    HHH(ddd, eee, aaa, bbb, ccc, X[14],  6);
217    HHH(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
218    HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
219    HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
220    HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
221    HHH(ddd, eee, aaa, bbb, ccc, X[12],  5);
222    HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
223    HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
224    HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
225    HHH(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
226    HHH(ddd, eee, aaa, bbb, ccc, X[13],  5);
227 
228    tmp = cc; cc = ccc; ccc = tmp;
229 
230    /* round 4 */
231    II(cc, dd, ee, aa, bb, X[ 1], 11);
232    II(bb, cc, dd, ee, aa, X[ 9], 12);
233    II(aa, bb, cc, dd, ee, X[11], 14);
234    II(ee, aa, bb, cc, dd, X[10], 15);
235    II(dd, ee, aa, bb, cc, X[ 0], 14);
236    II(cc, dd, ee, aa, bb, X[ 8], 15);
237    II(bb, cc, dd, ee, aa, X[12],  9);
238    II(aa, bb, cc, dd, ee, X[ 4],  8);
239    II(ee, aa, bb, cc, dd, X[13],  9);
240    II(dd, ee, aa, bb, cc, X[ 3], 14);
241    II(cc, dd, ee, aa, bb, X[ 7],  5);
242    II(bb, cc, dd, ee, aa, X[15],  6);
243    II(aa, bb, cc, dd, ee, X[14],  8);
244    II(ee, aa, bb, cc, dd, X[ 5],  6);
245    II(dd, ee, aa, bb, cc, X[ 6],  5);
246    II(cc, dd, ee, aa, bb, X[ 2], 12);
247 
248    /* parallel round 4 */
249    GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
250    GGG(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
251    GGG(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
252    GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
253    GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
254    GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
255    GGG(bbb, ccc, ddd, eee, aaa, X[15],  6);
256    GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
257    GGG(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
258    GGG(ddd, eee, aaa, bbb, ccc, X[12],  9);
259    GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
260    GGG(bbb, ccc, ddd, eee, aaa, X[13],  9);
261    GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
262    GGG(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
263    GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
264    GGG(ccc, ddd, eee, aaa, bbb, X[14],  8);
265 
266    tmp = dd; dd = ddd; ddd = tmp;
267 
268    /* round 5 */
269    JJ(bb, cc, dd, ee, aa, X[ 4],  9);
270    JJ(aa, bb, cc, dd, ee, X[ 0], 15);
271    JJ(ee, aa, bb, cc, dd, X[ 5],  5);
272    JJ(dd, ee, aa, bb, cc, X[ 9], 11);
273    JJ(cc, dd, ee, aa, bb, X[ 7],  6);
274    JJ(bb, cc, dd, ee, aa, X[12],  8);
275    JJ(aa, bb, cc, dd, ee, X[ 2], 13);
276    JJ(ee, aa, bb, cc, dd, X[10], 12);
277    JJ(dd, ee, aa, bb, cc, X[14],  5);
278    JJ(cc, dd, ee, aa, bb, X[ 1], 12);
279    JJ(bb, cc, dd, ee, aa, X[ 3], 13);
280    JJ(aa, bb, cc, dd, ee, X[ 8], 14);
281    JJ(ee, aa, bb, cc, dd, X[11], 11);
282    JJ(dd, ee, aa, bb, cc, X[ 6],  8);
283    JJ(cc, dd, ee, aa, bb, X[15],  5);
284    JJ(bb, cc, dd, ee, aa, X[13],  6);
285 
286    /* parallel round 5 */
287    FFF(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
288    FFF(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
289    FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
290    FFF(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
291    FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
292    FFF(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
293    FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
294    FFF(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
295    FFF(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
296    FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
297    FFF(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
298    FFF(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
299    FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
300    FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
301    FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
302    FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
303 
304    tmp = ee; ee = eee; eee = tmp;
305 
306    /* combine results */
307    md->rmd320.state[0] += aa;
308    md->rmd320.state[1] += bb;
309    md->rmd320.state[2] += cc;
310    md->rmd320.state[3] += dd;
311    md->rmd320.state[4] += ee;
312    md->rmd320.state[5] += aaa;
313    md->rmd320.state[6] += bbb;
314    md->rmd320.state[7] += ccc;
315    md->rmd320.state[8] += ddd;
316    md->rmd320.state[9] += eee;
317 
318    return CRYPT_OK;
319 }
320 
321 #ifdef LTC_CLEAN_STACK
s_rmd320_compress(hash_state * md,const unsigned char * buf)322 static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
323 {
324    int err;
325    err = ss_rmd320_compress(md, buf);
326    burn_stack(sizeof(ulong32) * 27 + sizeof(int));
327    return err;
328 }
329 #endif
330 
331 /**
332    Initialize the hash state
333    @param md   The hash state you wish to initialize
334    @return CRYPT_OK if successful
335 */
rmd320_init(hash_state * md)336 int rmd320_init(hash_state * md)
337 {
338    LTC_ARGCHK(md != NULL);
339    md->rmd320.state[0] = 0x67452301UL;
340    md->rmd320.state[1] = 0xefcdab89UL;
341    md->rmd320.state[2] = 0x98badcfeUL;
342    md->rmd320.state[3] = 0x10325476UL;
343    md->rmd320.state[4] = 0xc3d2e1f0UL;
344    md->rmd320.state[5] = 0x76543210UL;
345    md->rmd320.state[6] = 0xfedcba98UL;
346    md->rmd320.state[7] = 0x89abcdefUL;
347    md->rmd320.state[8] = 0x01234567UL;
348    md->rmd320.state[9] = 0x3c2d1e0fUL;
349    md->rmd320.curlen   = 0;
350    md->rmd320.length   = 0;
351    return CRYPT_OK;
352 }
353 
354 /**
355    Process a block of memory though the hash
356    @param md     The hash state
357    @param in     The data to hash
358    @param inlen  The length of the data (octets)
359    @return CRYPT_OK if successful
360 */
361 HASH_PROCESS(rmd320_process, s_rmd320_compress, rmd320, 64)
362 
363 /**
364    Terminate the hash to get the digest
365    @param md  The hash state
366    @param out [out] The destination of the hash (20 bytes)
367    @return CRYPT_OK if successful
368 */
rmd320_done(hash_state * md,unsigned char * out)369 int rmd320_done(hash_state * md, unsigned char *out)
370 {
371     int i;
372 
373     LTC_ARGCHK(md  != NULL);
374     LTC_ARGCHK(out != NULL);
375 
376     if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
377        return CRYPT_INVALID_ARG;
378     }
379 
380 
381     /* increase the length of the message */
382     md->rmd320.length += md->rmd320.curlen * 8;
383 
384     /* append the '1' bit */
385     md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
386 
387     /* if the length is currently above 56 bytes we append zeros
388      * then compress.  Then we can fall back to padding zeros and length
389      * encoding like normal.
390      */
391     if (md->rmd320.curlen > 56) {
392         while (md->rmd320.curlen < 64) {
393             md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
394         }
395         s_rmd320_compress(md, md->rmd320.buf);
396         md->rmd320.curlen = 0;
397     }
398 
399     /* pad upto 56 bytes of zeroes */
400     while (md->rmd320.curlen < 56) {
401         md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
402     }
403 
404     /* store length */
405     STORE64L(md->rmd320.length, md->rmd320.buf+56);
406     s_rmd320_compress(md, md->rmd320.buf);
407 
408     /* copy output */
409     for (i = 0; i < 10; i++) {
410         STORE32L(md->rmd320.state[i], out+(4*i));
411     }
412 #ifdef LTC_CLEAN_STACK
413     zeromem(md, sizeof(hash_state));
414 #endif
415     return CRYPT_OK;
416 }
417 
418 /**
419   Self-test the hash
420   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
421 */
rmd320_test(void)422 int rmd320_test(void)
423 {
424 #ifndef LTC_TEST
425    return CRYPT_NOP;
426 #else
427    static const struct {
428         const char *msg;
429         unsigned char hash[40];
430    } tests[] = {
431    { "",
432      { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
433        0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
434        0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
435        0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
436    },
437    { "a",
438      { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
439        0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
440        0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
441        0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
442    },
443    { "abc",
444      { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
445        0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
446        0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
447        0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
448    },
449    { "message digest",
450      { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
451        0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
452        0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
453        0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
454    },
455    { "abcdefghijklmnopqrstuvwxyz",
456      { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
457        0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
458        0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
459        0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
460    },
461    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
462      { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
463        0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
464        0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
465        0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
466    }
467    };
468 
469    int i;
470    unsigned char tmp[40];
471    hash_state md;
472 
473    for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
474        rmd320_init(&md);
475        rmd320_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
476        rmd320_done(&md, tmp);
477        if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD320", i)) {
478           return CRYPT_FAIL_TESTVECTOR;
479        }
480    }
481    return CRYPT_OK;
482 #endif
483 }
484 
485 #endif
486