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