VirtualBox

Changeset 22092 in vbox for trunk


Ignore:
Timestamp:
Aug 7, 2009 9:17:39 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
50841
Message:

iprt/md5.cpp|h: some cleanup and tuning to see how fast it can be (too slow for my purpose).

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/md5.h

    r21918 r22092  
    4646typedef struct RTMD5CONTEXT
    4747{
     48    uint32_t in[16];
    4849    uint32_t buf[4];
    4950    uint32_t bits[2];
    50     uint32_t in[16];
    5151} RTMD5CONTEXT;
    5252
  • trunk/src/VBox/Runtime/common/checksum/md5.cpp

    r21918 r22092  
    11/* $Id$ */
    22/** @file
    3  * MD5 message digest functions
     3 * IPRT - MD5 message digest functions.
    44 */
    55
     
    6262*   Defined Constants And Macros                                               *
    6363*******************************************************************************/
    64 #ifdef sgi
    65 #define HIGHFIRST
     64/* The four core functions - F1 is optimized somewhat */
     65#if 1
     66/* #define F1(x, y, z) (x & y | ~x & z) */
     67# define F1(x, y, z) (z ^ (x & (y ^ z)))
     68# define F2(x, y, z) F1(z, x, y)
     69# define F3(x, y, z) (x ^ y ^ z)
     70# define F4(x, y, z) (y ^ (x | ~z))
     71#else  /* gcc 4.0.1 (x86) benefits from the explicitness of F1() here. */
     72DECL_FORCE_INLINE(uint32_t) F1(uint32_t x, uint32_t y, uint32_t z)
     73{
     74    register uint32_t r = y ^ z;
     75    r &= x;
     76    r ^= z;
     77    return r;
     78}
     79# define F2(x, y, z) F1(z, x, y)
     80DECL_FORCE_INLINE(uint32_t) F3(uint32_t x, uint32_t y, uint32_t z)
     81{
     82    register uint32_t r = x ^ y;
     83    r ^= z;
     84    return r;
     85}
     86DECL_FORCE_INLINE(uint32_t) F4(uint32_t x, uint32_t y, uint32_t z)
     87{
     88    register uint32_t r = ~z;
     89    r |= x;
     90    r ^= y;
     91    return r;
     92}
    6693#endif
    6794
    68 #ifdef sun
    69 #define HIGHFIRST
    70 #endif
    71 
    72 #ifndef HIGHFIRST
    73 #define byteReverse(buf, len)   /* Nothing */
    74 #else
     95/* This is the central step in the MD5 algorithm. */
     96#define MD5STEP(f, w, x, y, z, data, s) \
     97        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
     98
     99
     100/**
     101 * The core of the MD5 algorithm, this alters an existing MD5 hash to reflect
     102 * the addition of 16 longwords of new data.  RTMd5Update blocks the data and
     103 * converts bytes into longwords for this routine.
     104 */
     105static void rtMd5Transform(uint32_t buf[4], uint32_t const in[16])
     106{
     107    uint32_t a, b, c, d;
     108
     109    a = buf[0];
     110    b = buf[1];
     111    c = buf[2];
     112    d = buf[3];
     113
     114    /*      fn, w, x, y, z, data,                 s) */
     115    MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
     116    MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
     117    MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
     118    MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
     119    MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
     120    MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
     121    MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
     122    MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
     123    MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
     124    MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
     125    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
     126    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
     127    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
     128    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
     129    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
     130    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
     131
     132    MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
     133    MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
     134    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
     135    MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
     136    MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
     137    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
     138    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
     139    MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
     140    MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
     141    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
     142    MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
     143    MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
     144    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
     145    MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
     146    MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
     147    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
     148
     149    MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
     150    MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
     151    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
     152    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
     153    MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
     154    MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
     155    MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
     156    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
     157    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
     158    MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
     159    MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
     160    MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
     161    MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
     162    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
     163    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
     164    MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23);
     165
     166    MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
     167    MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10);
     168    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
     169    MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21);
     170    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
     171    MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10);
     172    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
     173    MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21);
     174    MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f,  6);
     175    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
     176    MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15);
     177    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
     178    MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82,  6);
     179    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
     180    MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15);
     181    MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21);
     182
     183    buf[0] += a;
     184    buf[1] += b;
     185    buf[2] += c;
     186    buf[3] += d;
     187}
     188
     189
     190#ifdef RT_BIG_ENDIAN
    75191/*
    76192 * Note: this code is harmless on little-endian machines.
    77193 */
    78 static void byteReverse(uint32_t *buf, unsigned int longs)
     194static void rtMd5ByteReverse(uint32_t *buf, unsigned int longs)
    79195{
    80196    uint32_t t;
    81197    do {
    82         t = (uint32_t) *((uint8_t *)buf + 3) << 24 |
    83             (uint32_t) *((uint8_t *)buf + 2) << 16 |
    84             (uint32_t) *((uint8_t *)buf + 1) << 8 | *(uint8_t *)buf;
     198        t = *buf
     199        t = RT_LE2H_U32(t);
    85200        *buf = t;
    86201        buf++;
    87202    } while (--longs);
    88203}
     204#else   /* little endian - do nothing */
     205# define rtMd5ByteReverse(buf, len) do { /* Nothing */ } while (0)
    89206#endif
    90207
    91 static void MD5Transform(uint32_t buf[4], uint32_t in[16]);
    92208
    93209
     
    115231RTDECL(void) RTMd5Update(PRTMD5CONTEXT ctx, const void *pvBuf, size_t len)
    116232{
    117     const uint8_t *buf = (const uint8_t *)pvBuf;
    118     uint32_t t;
     233    const uint8_t  *buf = (const uint8_t *)pvBuf;
     234    uint32_t        t;
    119235
    120236    /* Update bitcount */
    121 
    122237    t = ctx->bits[0];
    123238    if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
     
    128243
    129244    /* Handle any leading odd-sized chunks */
    130 
    131245    if (t) {
    132246        uint8_t *p = (uint8_t *) ctx->in + t;
     
    138252        }
    139253        memcpy(p, buf, t);
    140         byteReverse(ctx->in, 16);
    141         MD5Transform(ctx->buf, ctx->in);
     254        rtMd5ByteReverse(ctx->in, 16);
     255        rtMd5Transform(ctx->buf, ctx->in);
    142256        buf += t;
    143257        len -= t;
    144258    }
     259
    145260    /* Process data in 64-byte chunks */
    146 
    147     while (len >= 64) {
    148         memcpy(ctx->in, buf, 64);
    149         byteReverse(ctx->in, 16);
    150         MD5Transform(ctx->buf, ctx->in);
    151         buf += 64;
    152         len -= 64;
    153     }
    154 
    155     /* Handle any remaining bytes of data. */
    156 
     261#ifndef RT_BIG_ENDIAN
     262    if (!((uintptr_t)buf & 0x3))
     263    {
     264        while (len >= 64) {
     265            rtMd5Transform(ctx->buf, (uint32_t const *)buf);
     266            buf += 64;
     267            len -= 64;
     268        }
     269    }
     270    else
     271#endif
     272    {
     273        while (len >= 64) {
     274            memcpy(ctx->in, buf, 64);
     275            rtMd5ByteReverse(ctx->in, 16);
     276            rtMd5Transform(ctx->buf, ctx->in);
     277            buf += 64;
     278            len -= 64;
     279        }
     280    }
     281
     282    /* Handle any remaining bytes of data */
    157283    memcpy(ctx->in, buf, len);
    158284}
     
    184310        /* Two lots of padding:  Pad the first block to 64 bytes */
    185311        memset(p, 0, count);
    186         byteReverse(ctx->in, 16);
    187         MD5Transform(ctx->buf, ctx->in);
     312        rtMd5ByteReverse(ctx->in, 16);
     313        rtMd5Transform(ctx->buf, ctx->in);
    188314
    189315        /* Now fill the next block with 56 bytes */
     
    193319        memset(p, 0, count - 8);
    194320    }
    195     byteReverse(ctx->in, 14);
     321    rtMd5ByteReverse(ctx->in, 14);
    196322
    197323    /* Append length in bits and transform */
     
    199325    ctx->in[15] = ctx->bits[1];
    200326
    201     MD5Transform(ctx->buf, ctx->in);
    202     byteReverse(ctx->buf, 4);
     327    rtMd5Transform(ctx->buf, ctx->in);
     328    rtMd5ByteReverse(ctx->buf, 4);
    203329    memcpy(digest, ctx->buf, 16);
    204330    memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */
     
    209335RTDECL(void) RTMd5(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTMD5HASHSIZE])
    210336{
    211     RTMD5CONTEXT Ctx;
    212     RTMd5Init(&Ctx);
    213     RTMd5Update(&Ctx, pvBuf, cbBuf);
    214     RTMd5Final(pabDigest, &Ctx);
     337#if 0
     338    RTMD5CONTEXT        Ctx[2];
     339    PRTMD5CONTEXT const pCtx = RT_ALIGN_PT(&Ctx[0], 64, PRTMD5CONTEXT);
     340#else
     341    RTMD5CONTEXT        Ctx;
     342    PRTMD5CONTEXT const pCtx = &Ctx;
     343#endif
     344
     345    RTMd5Init(pCtx);
     346    for (;;)
     347    {
     348        uint32_t cb = (uint32_t)RT_MIN(cbBuf, _2M);
     349        RTMd5Update(pCtx, pvBuf, cb);
     350        if (cb == cbBuf)
     351            break;
     352        cbBuf -= cb;
     353        pvBuf  = (uint8_t const *)pvBuf + cb;
     354    }
     355    RTMd5Final(pabDigest, pCtx);
    215356}
    216357RT_EXPORT_SYMBOL(RTMd5);
    217358
    218 
    219 /* The four core functions - F1 is optimized somewhat */
    220 
    221 /* #define F1(x, y, z) (x & y | ~x & z) */
    222 #define F1(x, y, z) (z ^ (x & (y ^ z)))
    223 #define F2(x, y, z) F1(z, x, y)
    224 #define F3(x, y, z) (x ^ y ^ z)
    225 #define F4(x, y, z) (y ^ (x | ~z))
    226 
    227 /* This is the central step in the MD5 algorithm. */
    228 #define MD5STEP(f, w, x, y, z, data, s) \
    229         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
    230 
    231 /*
    232  * The core of the MD5 algorithm, this alters an existing MD5 hash to
    233  * reflect the addition of 16 longwords of new data.  MD5Update blocks
    234  * the data and converts bytes into longwords for this routine.
    235  */
    236 static void MD5Transform(uint32_t buf[4], uint32_t in[16])
    237 {
    238     uint32_t a, b, c, d;
    239 
    240     a = buf[0];
    241     b = buf[1];
    242     c = buf[2];
    243     d = buf[3];
    244 
    245     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
    246     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
    247     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
    248     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
    249     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
    250     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
    251     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
    252     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
    253     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
    254     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
    255     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
    256     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
    257     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
    258     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
    259     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
    260     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
    261 
    262     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
    263     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
    264     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
    265     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
    266     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
    267     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
    268     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
    269     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
    270     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
    271     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
    272     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
    273     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
    274     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
    275     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
    276     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
    277     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
    278 
    279     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
    280     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
    281     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
    282     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
    283     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
    284     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
    285     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
    286     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
    287     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
    288     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
    289     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
    290     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
    291     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
    292     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
    293     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
    294     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
    295 
    296     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
    297     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
    298     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
    299     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
    300     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
    301     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
    302     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
    303     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
    304     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
    305     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
    306     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
    307     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
    308     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
    309     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
    310     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
    311     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
    312 
    313     buf[0] += a;
    314     buf[1] += b;
    315     buf[2] += c;
    316     buf[3] += d;
    317 }
    318 
    319 
    320 
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette