Home > Enterprise >  About one line in an implementation of MD5
About one line in an implementation of MD5

Time:04-04

I'm confused by one line of code in an implementation of MD5,

void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
    MD5_u32plus saved_lo;
    unsigned long used, available;

    saved_lo = ctx->lo;
    if ((ctx->lo = (saved_lo   size) & 0x1fffffff) < saved_lo)
        ctx->hi  ;
    ctx->hi  = size >> 29;

    used = saved_lo & 0x3f;

    if (used)
    {
        available = 64 - used;

        if (size < available)
        {
            memcpy(&ctx->buffer[used], data, size);
            return;
        }

        memcpy(&ctx->buffer[used], data, available);
        data = (const unsigned char *)data   available;
        size -= available;
        body(ctx, ctx->buffer, 64);
    }

    if (size >= 64)
    {
        data = body(ctx, data, size & ~(unsigned long)0x3f);
        size &= 0x3f;
    }

    memcpy(ctx->buffer, data, size);
}

The question line is if ((ctx->lo = (saved_lo size) & 0x1fffffff) < saved_lo), it seems the 'size' counts bytes, but the 'ctx->lo' and 'saved_lo' count bits. Why add them together? There are also some similar codes in Github, and also some projects use these code. So anyone can give some explanation?

CodePudding user response:

The remarks about "bit counters" are likely misleading - ctx->hi and ctx->lo count bytes, just like size does.

You correctly notice that you're just adding size (bytes) to ctx->lo (and then checking for overflow/propagating overflow into ctx->hi). The overflow check is pretty simple - lo is used as a 29-bit integer, and if the result after adding/masking is less than the original value, then overflow occurred.

The checks around used are also evidence for ctx->lo and ctx->hi being byte counters -- body processes data 64 bytes at a time, and the lo counter is ANDed with 0x3F (i.e. 63).

  •  Tags:  
  • c md5
  • Related