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