Bug 798634 - Style patrol on mfbt/SHA1.*. r=espindola
authorJeff Walden <jwalden@mit.edu>
Tue, 28 Aug 2012 17:27:05 -0700
changeset 109883 2a8a8a60451193e8b6e737860899cf5da1f06510
parent 109882 b1a02ad79a22a63d030df127394c4f782f4ff9f7
child 109884 4e3e7e1496afe9c27fd503f14f33b9cb461d98ec
push idunknown
push userunknown
push dateunknown
reviewersespindola
bugs798634
milestone19.0a1
Bug 798634 - Style patrol on mfbt/SHA1.*. r=espindola
mfbt/SHA1.cpp
mfbt/SHA1.h
mfbt/tests/TestSHA1.cpp
--- a/mfbt/SHA1.cpp
+++ b/mfbt/SHA1.cpp
@@ -1,65 +1,72 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <string.h>
+#include "mozilla/Assertions.h"
 #include "mozilla/SHA1.h"
-#include "mozilla/Assertions.h"
+
+#include <string.h>
 
 // FIXME: We should probably create a more complete mfbt/Endian.h. This assumes
 // that any compiler that doesn't define these macros is little endian.
 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define MOZ_IS_LITTLE_ENDIAN
-#endif
+#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#    define MOZ_IS_LITTLE_ENDIAN
+#  endif
 #else
-#define MOZ_IS_LITTLE_ENDIAN
+#  define MOZ_IS_LITTLE_ENDIAN
 #endif
 
-using namespace mozilla;
+using mozilla::SHA1Sum;
 
-static inline uint32_t SHA_ROTL(uint32_t t, uint32_t n)
+static inline uint32_t
+SHA_ROTL(uint32_t t, uint32_t n)
 {
-    return ((t << n) | (t >> (32 - n)));
+  MOZ_ASSERT(n < 32);
+  return (t << n) | (t >> (32 - n));
 }
 
+static inline unsigned
+SHA_HTONL(unsigned x)
+{
 #ifdef MOZ_IS_LITTLE_ENDIAN
-static inline unsigned SHA_HTONL(unsigned x) {
   const unsigned int mask = 0x00FF00FF;
   x = (x << 16) | (x >> 16);
   return ((x & mask) << 8) | ((x >> 8) & mask);
-}
 #else
-static inline unsigned SHA_HTONL(unsigned x) {
   return x;
+#endif
 }
-#endif
 
-static void shaCompress(volatile unsigned *X, const uint32_t * datain);
+static void
+shaCompress(volatile unsigned* X, const uint32_t* datain);
 
-#define SHA_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
-#define SHA_F2(X,Y,Z) ((X)^(Y)^(Z))
-#define SHA_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
-#define SHA_F4(X,Y,Z) ((X)^(Y)^(Z))
+#define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
+#define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
+#define SHA_F3(X, Y, Z) (((X) & (Y)) | ((Z) & ((X) | (Y))))
+#define SHA_F4(X, Y, Z) ((X) ^ (Y) ^ (Z))
 
-#define SHA_MIX(n,a,b,c)    XW(n) = SHA_ROTL(XW(a)^XW(b)^XW(c)^XW(n), 1)
+#define SHA_MIX(n, a, b, c)    XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^XW(n), 1)
 
-SHA1Sum::SHA1Sum() : size(0), mDone(false)
+SHA1Sum::SHA1Sum()
+  : size(0), mDone(false)
 {
   // Initialize H with constants from FIPS180-1.
   H[0] = 0x67452301L;
   H[1] = 0xefcdab89L;
   H[2] = 0x98badcfeL;
   H[3] = 0x10325476L;
   H[4] = 0xc3d2e1f0L;
 }
 
-/* Explanation of H array and index values:
+/*
+ * Explanation of H array and index values:
+ *
  * The context's H array is actually the concatenation of two arrays
  * defined by SHA1, the H array of state variables (5 elements),
  * and the W array of intermediate values, of which there are 16 elements.
  * The W array starts at H[5], that is W[0] is H[5].
  * Although these values are defined as 32-bit values, we use 64-bit
  * variables to hold them because the AMD64 stores 64 bit values in
  * memory MUCH faster than it stores any smaller values.
  *
@@ -86,90 +93,87 @@ SHA1Sum::SHA1Sum() : size(0), mDone(fals
  * higher.  This results in much bigger and slower code.
  */
 #define H2X 11 /* X[0] is H[11], and H[0] is X[-11] */
 #define W2X  6 /* X[0] is W[6],  and W[0] is X[-6]  */
 
 /*
  *  SHA: Add data to context.
  */
-void SHA1Sum::update(const uint8_t *dataIn, uint32_t len)
+void
+SHA1Sum::update(const uint8_t* dataIn, uint32_t len)
 {
-  MOZ_ASSERT(!mDone);
-  register unsigned int lenB;
-  register unsigned int togo;
+  MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
 
-  if (!len)
+  if (len == 0)
     return;
 
-  /* accumulate the byte count. */
-  lenB = (unsigned int)(size) & 63U;
+  /* Accumulate the byte count. */
+  unsigned int lenB = static_cast<unsigned int>(size) & 63U;
 
   size += len;
 
-  /*
-   *  Read the data into W and process blocks as they get full
-   */
+  /* Read the data into W and process blocks as they get full. */
+  unsigned int togo;
   if (lenB > 0) {
     togo = 64U - lenB;
     if (len < togo)
       togo = len;
     memcpy(u.b + lenB, dataIn, togo);
-    len    -= togo;
+    len -= togo;
     dataIn += togo;
-    lenB    = (lenB + togo) & 63U;
-    if (!lenB) {
+    lenB = (lenB + togo) & 63U;
+    if (!lenB)
       shaCompress(&H[H2X], u.w);
-    }
   }
+
   while (len >= 64U) {
-    len    -= 64U;
-    shaCompress(&H[H2X], (uint32_t *)dataIn);
+    len -= 64U;
+    shaCompress(&H[H2X], reinterpret_cast<const uint32_t*>(dataIn));
     dataIn += 64U;
   }
-  if (len) {
+
+  if (len > 0)
     memcpy(u.b, dataIn, len);
-  }
 }
 
 
 /*
  *  SHA: Generate hash value
  */
-void SHA1Sum::finish(uint8_t hashout[20])
+void
+SHA1Sum::finish(SHA1Sum::Hash& hashOut)
 {
-  MOZ_ASSERT(!mDone);
-  register uint64_t size2 = size;
-  register uint32_t lenB = (uint32_t)size2 & 63;
+  MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
+
+  uint64_t size2 = size;
+  uint32_t lenB = uint32_t(size2) & 63;
 
-  static const uint8_t bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0,
-          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  };
+  static const uint8_t bulk_pad[64] =
+    { 0x80,0,0,0,0,0,0,0,0,0,
+      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
-  /*
-   *  Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits
-   */
+  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits. */
+  update(bulk_pad, (((55 + 64) - lenB) & 63) + 1);
+  MOZ_ASSERT((uint32_t(size) & 63) == 56);
 
-  update(bulk_pad, (((55+64) - lenB) & 63) + 1);
-  MOZ_ASSERT(((uint32_t)size & 63) == 56);
   /* Convert size from bytes to bits. */
   size2 <<= 3;
-  u.w[14] = SHA_HTONL((uint32_t)(size2 >> 32));
-  u.w[15] = SHA_HTONL((uint32_t)size2);
+  u.w[14] = SHA_HTONL(uint32_t(size2 >> 32));
+  u.w[15] = SHA_HTONL(uint32_t(size2));
   shaCompress(&H[H2X], u.w);
 
-  /*
-   *  Output hash
-   */
+  /* Output hash. */
   u.w[0] = SHA_HTONL(H[0]);
   u.w[1] = SHA_HTONL(H[1]);
   u.w[2] = SHA_HTONL(H[2]);
   u.w[3] = SHA_HTONL(H[3]);
   u.w[4] = SHA_HTONL(H[4]);
-  memcpy(hashout, u.w, 20);
+  memcpy(hashOut, u.w, 20);
   mDone = true;
 }
 
 /*
  *  SHA: Compression function, unrolled.
  *
  * Some operations in shaCompress are done as 5 groups of 16 operations.
  * Others are done as 4 groups of 20 operations.
@@ -213,35 +217,34 @@ void SHA1Sum::finish(uint8_t hashout[20]
  *
  * The combination of this code and the -O3 optimizer flag on GCC 3.4.3
  * results in code that is 3 times faster than the previous NSS sha_fast
  * code on AMD64.
  */
 static void
 shaCompress(volatile unsigned *X, const uint32_t *inbuf)
 {
-  register unsigned A, B, C, D, E;
-
+  unsigned A, B, C, D, E;
 
-#define XH(n) X[n-H2X]
-#define XW(n) X[n-W2X]
+#define XH(n) X[n - H2X]
+#define XW(n) X[n - W2X]
 
 #define K0 0x5a827999L
 #define K1 0x6ed9eba1L
 #define K2 0x8f1bbcdcL
 #define K3 0xca62c1d6L
 
-#define SHA_RND1(a,b,c,d,e,n) \
-  a = SHA_ROTL(b,5)+SHA_F1(c,d,e)+a+XW(n)+K0; c=SHA_ROTL(c,30) 
-#define SHA_RND2(a,b,c,d,e,n) \
-  a = SHA_ROTL(b,5)+SHA_F2(c,d,e)+a+XW(n)+K1; c=SHA_ROTL(c,30) 
-#define SHA_RND3(a,b,c,d,e,n) \
-  a = SHA_ROTL(b,5)+SHA_F3(c,d,e)+a+XW(n)+K2; c=SHA_ROTL(c,30) 
-#define SHA_RND4(a,b,c,d,e,n) \
-  a = SHA_ROTL(b,5)+SHA_F4(c,d,e)+a+XW(n)+K3; c=SHA_ROTL(c,30) 
+#define SHA_RND1(a, b, c, d, e, n) \
+  a = SHA_ROTL(b, 5) + SHA_F1(c, d, e) + a + XW(n) + K0; c = SHA_ROTL(c, 30)
+#define SHA_RND2(a, b, c, d, e, n) \
+  a = SHA_ROTL(b, 5) + SHA_F2(c, d, e) + a + XW(n) + K1; c = SHA_ROTL(c, 30)
+#define SHA_RND3(a, b, c, d, e, n) \
+  a = SHA_ROTL(b, 5) + SHA_F3(c, d, e) + a + XW(n) + K2; c = SHA_ROTL(c, 30)
+#define SHA_RND4(a, b, c, d, e, n) \
+  a = SHA_ROTL(b ,5) + SHA_F4(c, d, e) + a + XW(n) + K3; c = SHA_ROTL(c, 30)
 
 #define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
 
   A = XH(0);
   B = XH(1);
   C = XH(2);
   D = XH(3);
   E = XH(4);
--- a/mfbt/SHA1.h
+++ b/mfbt/SHA1.h
@@ -1,46 +1,60 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Simple class for computing SHA1. */
 
-/*
- * To compute the SHA1 of a buffer using this class you should write something
- * like:
- * void SHA1(const uint8_t* buf, unsigned size, uint8_t hash[20])
- * {
- *   SHA1Sum S;
- *   S.update(buf, size);
- *   S.finish(hash);
- * }
- * If there are multiple buffers or chunks, the update method can be called
- * multiple times and the SHA1 is computed on the concatenation of all the
- * buffers passed to it.
- * The finish method may only be called once and cannot be followed by calls
- * to update.
- */
-
 #ifndef mozilla_SHA1_h_
 #define mozilla_SHA1_h_
 
 #include "mozilla/StandardInteger.h"
+
+#include <stddef.h>
+
 namespace mozilla {
-class SHA1Sum {
-  union {
-    uint32_t w[16];         /* input buffer */
-    uint8_t  b[64];
-  } u;
-  uint64_t size;            /* count of hashed bytes. */
-  unsigned H[22];           /* 5 state variables, 16 tmp values, 1 extra */
-  bool mDone;
 
-public:
-  static const unsigned int HashSize = 20;
-  SHA1Sum();
-  void update(const uint8_t *dataIn, uint32_t len);
-  void finish(uint8_t hashout[20]);
+/**
+ * This class computes the SHA1 hash of a byte sequence, or of the concatenation
+ * of multiple sequences.  For example, computing the SHA1 of two sequences of
+ * bytes could be done as follows:
+ *
+ *   void SHA1(const uint8_t* buf1, uint32_t size1,
+ *             const uint8_t* buf2, uint32_t size2,
+ *             SHA1Sum::Hash& hash)
+ *   {
+ *     SHA1Sum s;
+ *     s.update(buf1, size1);
+ *     s.update(buf2, size2);
+ *     s.finish(hash);
+ *   }
+ *
+ * The finish method may only be called once and cannot be followed by calls
+ * to update.
+ */
+class SHA1Sum
+{
+    union {
+        uint32_t w[16]; /* input buffer */
+        uint8_t b[64];
+    } u;
+    uint64_t size; /* count of hashed bytes. */
+    unsigned H[22]; /* 5 state variables, 16 tmp values, 1 extra */
+    bool mDone;
+
+  public:
+    SHA1Sum();
+
+    static const size_t HashSize = 20;
+    typedef uint8_t Hash[HashSize];
+
+    /* Add len bytes of dataIn to the data sequence being hashed. */
+    void update(const uint8_t* dataIn, uint32_t len);
+
+    /* Compute the final hash of all data into hashOut. */
+    void finish(SHA1Sum::Hash& hashOut);
 };
-}
+
+} /* namespace mozilla */
 
 #endif /* mozilla_SHA1_h_ */
--- a/mfbt/tests/TestSHA1.cpp
+++ b/mfbt/tests/TestSHA1.cpp
@@ -1,17 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/Assertions.h"
 #include "mozilla/SHA1.h"
 
-using namespace mozilla;
+using mozilla::SHA1Sum;
 
-static unsigned int TestV[1024] = {
+static unsigned int testV[1024] = {
   0x048edc1a, 0x4345588c, 0x0ef03cbf, 0x1d6438f5, 0x094e0a1e, 0x68535f60,
   0x14e8c927, 0x60190043, 0x5d640ab7, 0x73dc7c62, 0x364223f9, 0x47320292,
   0x3924cae0, 0x5f6b26d3, 0x5efa04ef, 0x7aab361e, 0x2773b1aa, 0x1631b07d,
   0x385b5dd1, 0x26c809b0, 0x28ad3a9f, 0x0315292a, 0x1a544e67, 0x1e79dcb9,
   0x787683e8, 0x3a591c75, 0x1dd338c7, 0x01c539e5, 0x1c15b23e, 0x0697c25c,
   0x4df5fd45, 0x672aa324, 0x39f74e6e, 0x269cdd5f, 0x087b6fce, 0x293509db,
   0x0aef54a9, 0x210c4cc5, 0x29d6dc4a, 0x16320825, 0x3ab7b181, 0x56d6fd25,
   0x6837fda2, 0x3e7994c2, 0x37f77529, 0x48c85472, 0x424fd84d, 0x00aba7fa,
@@ -175,25 +176,29 @@ static unsigned int TestV[1024] = {
   0x1bb788cb, 0x791ad5c7, 0x5129330e, 0x016c4436, 0x430f05bf, 0x1f06b5cd,
   0x62df1378, 0x0423b9b4, 0x0341acaf, 0x3189543c, 0x7b96b2ea, 0x6c4865c3,
   0x4cc7adc3, 0x78a2bff6, 0x642db7c7, 0x70d02300, 0x7cd43ac0, 0x4f5fe414,
   0x333b52c2, 0x500d3c74, 0x65782c01, 0x3f72a2c5, 0x278f59d8, 0x493bf7f8,
   0x16bf51a0, 0x6cc70ced, 0x6ed15979, 0x1a77abae, 0x08cadbb7, 0x2f2e0bc0,
   0x236f5e8d, 0x1a4b4495, 0x360bd008, 0x32227d40
 };
 
-int main()
+int
+main()
 {
-  SHA1Sum S;
-  unsigned char hash[20];
-  S.update((const unsigned char*) TestV, sizeof(TestV));
-  S.finish(hash);
-  const unsigned char expected[20] = {
-    0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
-    0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81};
+  SHA1Sum sum;
+  SHA1Sum::Hash hash;
+  sum.update(reinterpret_cast<const uint8_t*>(testV), sizeof(testV));
+  sum.finish(hash);
 
-  for (unsigned int i = 0; i < 20; ++i) {
-    if (hash[i] != expected[i]) {
-      return 1;
-    }
-  }
+  static const uint8_t expected[20] =
+    { 0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
+      0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81 };
+
+  MOZ_STATIC_ASSERT(sizeof(expected) == sizeof(SHA1Sum::Hash),
+                    "expected-data size should be the same as the actual hash "
+                    "size");
+
+  for (size_t i = 0; i < SHA1Sum::HashSize; i++)
+    MOZ_ASSERT(hash[i] == expected[i]);
+
   return 0;
 }