From 8c432325c3df2075a77b27eab8a87704cf7b48ee Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 27 Jul 2007 13:16:24 +0200 Subject: [PATCH 1/1] Speed up md5 hash filling/verifying by 20% Get rid of the on-stack hash copies, hash directly into the buffer. We need to 'fix' md5 to just initially clear a/b/c/d in md5_update(). Tested, works, generates same checksums. Signed-off-by: Jens Axboe --- md5.c | 17 +++++++++-------- md5.h | 2 +- verify.c | 19 ++++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/md5.c b/md5.c index cf1f814a..6b61012e 100644 --- a/md5.c +++ b/md5.c @@ -9,10 +9,11 @@ static void md5_transform(uint32_t *hash, uint32_t const *in) { uint32_t a, b, c, d; - a = hash[0]; - b = hash[1]; - c = hash[2]; - d = hash[3]; + /* + * This used to be set from the hash[0..3] input, but we can + * skip a memory clear if we just start from 0 instead. + */ + a = b = c = d = 0; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); @@ -82,10 +83,10 @@ static void md5_transform(uint32_t *hash, uint32_t const *in) MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - hash[0] += a; - hash[1] += b; - hash[2] += c; - hash[3] += d; + hash[0] = a; + hash[1] = b; + hash[2] = c; + hash[3] = d; } void md5_update(struct md5_ctx *mctx, const uint8_t *data, unsigned int len) diff --git a/md5.h b/md5.h index 9d1cf4cf..80fbcec8 100644 --- a/md5.h +++ b/md5.h @@ -17,7 +17,7 @@ (w += f(x, y, z) + in, w = (w<>(32-s)) + x) struct md5_ctx { - uint32_t hash[MD5_HASH_WORDS]; + uint32_t *hash; uint32_t block[MD5_BLOCK_WORDS]; uint64_t byte_count; }; diff --git a/verify.c b/verify.c index 178b6d6a..42a56d71 100644 --- a/verify.c +++ b/verify.c @@ -95,17 +95,18 @@ static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u) static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u) { - unsigned char *p = io_u->buf; - struct md5_ctx md5_ctx; + unsigned char *p = io_u->buf + sizeof(*hdr); + uint32_t hash[MD5_HASH_WORDS]; + struct md5_ctx md5_ctx = { + .hash = hash, + }; - memset(&md5_ctx, 0, sizeof(md5_ctx)); - p += sizeof(*hdr); md5_update(&md5_ctx, p, hdr->len - sizeof(*hdr)); - if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash))) { + if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(hash))) { log_err("md5: verify failed at %llu/%lu\n", io_u->offset, io_u->buflen); hexdump(hdr->md5_digest, sizeof(hdr->md5_digest)); - hexdump(md5_ctx.hash, sizeof(md5_ctx.hash)); + hexdump(md5_ctx.hash, sizeof(hash)); return 1; } @@ -166,11 +167,11 @@ static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len) static void fill_md5(struct verify_header *hdr, void *p, unsigned int len) { - struct md5_ctx md5_ctx; + struct md5_ctx md5_ctx = { + .hash = (uint32_t *) hdr->md5_digest, + }; - memset(&md5_ctx, 0, sizeof(md5_ctx)); md5_update(&md5_ctx, p, len); - memcpy(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash)); } /* -- 2.25.1