Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

About one line in an implementation of MD5

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading