From cb83bd331e5774027bcab965ccf9bcbe798ad167 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Sat, 28 Sep 2013 09:43:12 +0200
Subject: [PATCH] Made hash functions use an uint64_t for the block count.

---
 ChangeLog   |  8 ++++++++
 macros.h    |  5 +----
 md4.c       | 11 ++++++-----
 md4.h       |  2 +-
 md5.c       | 14 ++++++--------
 md5.h       |  2 +-
 ripemd160.c | 12 +++++-------
 ripemd160.h |  2 +-
 sha1.c      | 14 ++++++--------
 sha1.h      |  2 +-
 sha2.h      |  2 +-
 sha256.c    | 14 ++++++--------
 12 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 740ec54a..ca7d0c1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2013-09-28  Niels Möller  <nisse@lysator.liu.se>
 
+	* md4.h (struct md4_ctx): Use single uint64_t variable for block
+	count.
+	* md4.c: Use new block count variable.
+	* md5.c, md5.h (struct md5_ctx): Likewise.
+	* ripemd160.c, ripemd160.h (struct ripemd160_ctx): Likewise.
+	* sha1.c, sha1.h (struct sha1_ctx): Likewise.
+	* sha256.c, sha2.h (struct sha256_ctx): Likewise.
+
 	* testsuite/testutils.c (test_hash_large): Added simple progress
 	indicator.
 
diff --git a/macros.h b/macros.h
index 091b4f04..6bbbb634 100644
--- a/macros.h
+++ b/macros.h
@@ -162,14 +162,11 @@ do {						\
 /* Helper macro for Merkle-Damgård hash functions. Assumes the context
    structs includes the following fields:
 
-     xxx count_low, count_high;		// Two word block count
      uint8_t block[...];		// Buffer holding one block
      unsigned int index;		// Index into block
 */
 
-/* FIXME: Should probably switch to using uint64_t for the count, but
-   due to alignment and byte order that may be an ABI change. */
-
+/* Currently used by sha512 (and sha384) only. */
 #define MD_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low)
 
 /* Takes the compression function f as argument. NOTE: also clobbers
diff --git a/md4.c b/md4.c
index 80d50f6b..05321ee2 100644
--- a/md4.c
+++ b/md4.c
@@ -61,7 +61,7 @@ md4_init(struct md4_ctx *ctx)
     };
   memcpy(ctx->state, iv, sizeof(ctx->state));
   
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   ctx->index = 0;
 }
 
@@ -70,7 +70,7 @@ md4_update(struct md4_ctx *ctx,
 	   size_t length,
 	   const uint8_t *data)
 {
-  MD_UPDATE(ctx, length, data, md4_compress, MD_INCR(ctx));
+  MD_UPDATE(ctx, length, data, md4_compress, ctx->count++);
 }
 
 void
@@ -78,6 +78,7 @@ md4_digest(struct md4_ctx *ctx,
 	   size_t length,
 	   uint8_t *digest)
 {
+  uint64_t bit_count;
   uint32_t data[MD4_DATA_LENGTH];
   unsigned i;
 
@@ -89,9 +90,9 @@ md4_digest(struct md4_ctx *ctx,
 
   /* There are 512 = 2^9 bits in one block 
    * Little-endian order => Least significant word first */
-
-  data[MD4_DATA_LENGTH-1] = (ctx->count_high << 9) | (ctx->count_low >> 23);
-  data[MD4_DATA_LENGTH-2] = (ctx->count_low << 9) | (ctx->index << 3);
+  bit_count = (ctx->count << 9) | (ctx->index << 3);
+  data[MD4_DATA_LENGTH-2] = bit_count;
+  data[MD4_DATA_LENGTH-1] = bit_count >> 32;
   md4_transform(ctx->state, data);
 
   _nettle_write_le32(length, digest, ctx->state);
diff --git a/md4.h b/md4.h
index 5b805c22..a415e021 100644
--- a/md4.h
+++ b/md4.h
@@ -47,7 +47,7 @@ extern "C" {
 struct md4_ctx
 {
   uint32_t state[_MD4_DIGEST_LENGTH];
-  uint32_t count_low, count_high;	/* Block count */
+  uint64_t count;			/* Block count */
   uint8_t block[MD4_DATA_SIZE];		/* Block buffer */
   unsigned index;			/* Into buffer */
 };
diff --git a/md5.c b/md5.c
index 32c3583e..370361b8 100644
--- a/md5.c
+++ b/md5.c
@@ -49,7 +49,7 @@ md5_init(struct md5_ctx *ctx)
       0x10325476,
     };
   memcpy(ctx->state, iv, sizeof(ctx->state));
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   ctx->index = 0;
 }
 
@@ -60,7 +60,7 @@ md5_update(struct md5_ctx *ctx,
 	   size_t length,
 	   const uint8_t *data)
 {
-  MD_UPDATE(ctx, length, data, COMPRESS, MD_INCR(ctx));
+  MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++);
 }
 
 void
@@ -68,18 +68,16 @@ md5_digest(struct md5_ctx *ctx,
 	   size_t length,
 	   uint8_t *digest)
 {
-  uint32_t high, low;
+  uint64_t bit_count;
   
   assert(length <= MD5_DIGEST_SIZE);
 
   MD_PAD(ctx, 8, COMPRESS);
 
-  /* There are 512 = 2^9 bits in one block */  
-  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
-  low = (ctx->count_low << 9) | (ctx->index << 3);
+  /* There are 512 = 2^9 bits in one block */
+  bit_count = (ctx->count << 9) | (ctx->index << 3);
 
-  LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 8), low);
-  LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 4), high);
+  LE_WRITE_UINT64(ctx->block + (MD5_DATA_SIZE - 8), bit_count);
   _nettle_md5_compress(ctx->state, ctx->block);
 
   _nettle_write_le32(length, digest, ctx->state);
diff --git a/md5.h b/md5.h
index 2899cdfc..40932900 100644
--- a/md5.h
+++ b/md5.h
@@ -46,7 +46,7 @@ extern "C" {
 struct md5_ctx
 {
   uint32_t state[_MD5_DIGEST_LENGTH];
-  uint32_t count_low, count_high; /* Block count */
+  uint64_t count;               /* Block count */
   uint8_t block[MD5_DATA_SIZE]; /* Block buffer */
   unsigned index;               /* Into buffer */
 };
diff --git a/ripemd160.c b/ripemd160.c
index 92a6414f..2f9735ca 100644
--- a/ripemd160.c
+++ b/ripemd160.c
@@ -155,7 +155,7 @@ ripemd160_init(struct ripemd160_ctx *ctx)
       0xC3D2E1F0,
     };
   memcpy(ctx->state, iv, sizeof(ctx->state));
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   ctx->index = 0;
 }
 
@@ -167,25 +167,23 @@ ripemd160_init(struct ripemd160_ctx *ctx)
 void
 ripemd160_update(struct ripemd160_ctx *ctx, size_t length, const uint8_t *data)
 {
-  MD_UPDATE(ctx, length, data, COMPRESS, MD_INCR(ctx));
+  MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++);
 }
 
 void
 ripemd160_digest(struct ripemd160_ctx *ctx, size_t length, uint8_t *digest)
 {
-  uint32_t high, low;
+  uint64_t bit_count;
 
   assert(length <= RIPEMD160_DIGEST_SIZE);
 
   MD_PAD(ctx, 8, COMPRESS);
 
   /* There are 2^9 bits in one block */
-  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
-  low = (ctx->count_low << 9) | (ctx->index << 3);
+  bit_count = (ctx->count << 9) | (ctx->index << 3);
 									\
   /* append the 64 bit count */
-  LE_WRITE_UINT32(ctx->block + 56, low);
-  LE_WRITE_UINT32(ctx->block + 60, high);
+  LE_WRITE_UINT64(ctx->block + 56, bit_count);
   _nettle_ripemd160_compress(ctx->state, ctx->block);
 
   _nettle_write_le32(length, digest, ctx->state);
diff --git a/ripemd160.h b/ripemd160.h
index eca98736..9ef86d31 100644
--- a/ripemd160.h
+++ b/ripemd160.h
@@ -48,7 +48,7 @@ extern "C" {
 struct ripemd160_ctx
 {
   uint32_t state[_RIPEMD160_DIGEST_LENGTH];
-  uint32_t count_low, count_high;         /* 64-bit block count */
+  uint64_t count;         /* 64-bit block count */
   uint8_t block[RIPEMD160_DATA_SIZE];
   unsigned int index;
 };
diff --git a/sha1.c b/sha1.c
index b7ab9412..e53913c9 100644
--- a/sha1.c
+++ b/sha1.c
@@ -66,7 +66,7 @@ sha1_init(struct sha1_ctx *ctx)
     };
 
   memcpy(ctx->state, iv, sizeof(ctx->state));
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   
   /* Initialize buffer */
   ctx->index = 0;
@@ -78,7 +78,7 @@ void
 sha1_update(struct sha1_ctx *ctx,
 	    size_t length, const uint8_t *data)
 {
-  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
+  MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++);
 }
 	  
 void
@@ -86,19 +86,17 @@ sha1_digest(struct sha1_ctx *ctx,
 	    size_t length,
 	    uint8_t *digest)
 {
-  uint32_t high, low;
+  uint64_t bit_count;
 
   assert(length <= SHA1_DIGEST_SIZE);
 
   MD_PAD(ctx, 8, COMPRESS);
 
-  /* There are 512 = 2^9 bits in one block */  
-  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
-  low = (ctx->count_low << 9) | (ctx->index << 3);
+  /* There are 512 = 2^9 bits in one block */
+  bit_count = (ctx->count << 9) | (ctx->index << 3);
 
   /* append the 64 bit count */
-  WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 8), high);
-  WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 4), low);
+  WRITE_UINT64(ctx->block + (SHA1_DATA_SIZE - 8), bit_count);
   _nettle_sha1_compress(ctx->state, ctx->block);
 
   _nettle_write_be32(length, digest, ctx->state);
diff --git a/sha1.h b/sha1.h
index 9452f0aa..da6bfbd0 100644
--- a/sha1.h
+++ b/sha1.h
@@ -48,7 +48,7 @@ extern "C" {
 struct sha1_ctx
 {
   uint32_t state[_SHA1_DIGEST_LENGTH];    /* State variables */
-  uint32_t count_low, count_high;         /* 64-bit block count */
+  uint64_t count;                         /* 64-bit block count */
   uint8_t block[SHA1_DATA_SIZE];          /* SHA1 data buffer */
   unsigned int index;                     /* index into buffer */
 };
diff --git a/sha2.h b/sha2.h
index 3a0b449a..f095dad1 100644
--- a/sha2.h
+++ b/sha2.h
@@ -55,7 +55,7 @@ extern "C" {
 struct sha256_ctx
 {
   uint32_t state[_SHA256_DIGEST_LENGTH];    /* State variables */
-  uint32_t count_low, count_high;           /* 64-bit block count */
+  uint64_t count;                           /* 64-bit block count */
   uint8_t block[SHA256_DATA_SIZE];          /* SHA256 data buffer */
   unsigned int index;                       /* index into buffer */
 };
diff --git a/sha256.c b/sha256.c
index 276f1351..46cccffe 100644
--- a/sha256.c
+++ b/sha256.c
@@ -79,7 +79,7 @@ sha256_init(struct sha256_ctx *ctx)
   memcpy(ctx->state, H0, sizeof(H0));
 
   /* Initialize bit count */
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   
   /* Initialize buffer */
   ctx->index = 0;
@@ -89,7 +89,7 @@ void
 sha256_update(struct sha256_ctx *ctx,
 	      size_t length, const uint8_t *data)
 {
-  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
+  MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++);
 }
 
 static void
@@ -97,21 +97,19 @@ sha256_write_digest(struct sha256_ctx *ctx,
 		    size_t length,
 		    uint8_t *digest)
 {
-  uint32_t high, low;
+  uint64_t bit_count;
 
   assert(length <= SHA256_DIGEST_SIZE);
 
   MD_PAD(ctx, 8, COMPRESS);
 
   /* There are 512 = 2^9 bits in one block */  
-  high = (ctx->count_high << 9) | (ctx->count_low >> 23);
-  low = (ctx->count_low << 9) | (ctx->index << 3);
+  bit_count = (ctx->count << 9) | (ctx->index << 3);
 
   /* This is slightly inefficient, as the numbers are converted to
      big-endian format, and will be converted back by the compression
      function. It's probably not worth the effort to fix this. */
-  WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 8), high);
-  WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 4), low);
+  WRITE_UINT64(ctx->block + (SHA256_DATA_SIZE - 8), bit_count);
   COMPRESS(ctx, ctx->block);
 
   _nettle_write_be32(length, digest, ctx->state);
@@ -141,7 +139,7 @@ sha224_init(struct sha256_ctx *ctx)
   memcpy(ctx->state, H0, sizeof(H0));
 
   /* Initialize bit count */
-  ctx->count_low = ctx->count_high = 0;
+  ctx->count = 0;
   
   /* Initialize buffer */
   ctx->index = 0;
-- 
GitLab