[pacman-dev] [PATCH 1/4] Use 32-bit wide integer type in PolarSSL code

Dan McGee dan at archlinux.org
Sat Jan 7 12:28:56 EST 2012


A look at what this does on 64 bit systems since we were using the
unnecessarily large 'unsigned long' type before even though it was 64
bits wide:

$ ~/bin/bloat-o-meter libalpm.so.old lib/libalpm/.libs/libalpm.so
add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-10412 (-10412)
function                                     old     new   delta
md5_finish                                   370     356     -14
sha2_finish                                  547     531     -16
md5_process                                 3762    2643   -1119
sha2_process                               20356   11093   -9263

The code size is nearly halved in the sha2 case (44% smaller code size),
and md5 gets a nice size reduction (27% smaller) as well.

We also move base64 code to <stdint.h> types as well; we can use
'uint32_t' rather than 'unsigned long' for at least two variables in the
decode function. This doesn't net the same size benefit as the hash code
case, but it is more proper.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/base64.c |    6 ++-
 lib/libalpm/md5.c    |   81 +++++++++++++++++++++++-----------------------
 lib/libalpm/sha2.c   |   87 +++++++++++++++++++++++++------------------------
 3 files changed, 89 insertions(+), 85 deletions(-)

diff --git a/lib/libalpm/base64.c b/lib/libalpm/base64.c
index 0d29f65..32c4445 100644
--- a/lib/libalpm/base64.c
+++ b/lib/libalpm/base64.c
@@ -32,6 +32,8 @@
  *  * removal of SELF_TEST code
  */
 
+#include <stdint.h>
+
 #include "base64.h"
 
 static const unsigned char base64_enc_map[64] =
@@ -133,8 +135,8 @@ int base64_encode( unsigned char *dst, size_t *dlen,
 int base64_decode( unsigned char *dst, size_t *dlen,
                    const unsigned char *src, size_t slen )
 {
-    size_t i, j, n;
-    unsigned long x;
+    size_t i, n;
+    uint32_t j, x;
     unsigned char *p;
 
     for( i = j = n = 0; i < slen; i++ )
diff --git a/lib/libalpm/md5.c b/lib/libalpm/md5.c
index b4391a6..0d5ed9e 100644
--- a/lib/libalpm/md5.c
+++ b/lib/libalpm/md5.c
@@ -33,33 +33,34 @@
  *  GPL. This is from version 1.0.0 of the library, and has been modified
  *  as following, which may be helpful for future updates:
  *  * remove "polarssl/config.h" include
- *  * change include from "polarssl/sha2.h" to "sha2.h"
+ *  * change include from "polarssl/md5.h" to "md5.h"
  *  * removal of HMAC code
  *  * removal of SELF_TEST code
- *  * removal of ipad and opad from the md5_context struct in sha2.h
+ *  * removal of ipad and opad from the md5_context struct in md5.h
  *  * increase the size of buffer for performance reasons
- *  * various static changes
+ *  * change 'unsigned long' to uint32_t
  */
 
 #include <stdio.h>
+#include <stdint.h>
 
 #include "md5.h"
 
 /*
  * 32-bit integer manipulation macros (little endian)
  */
-#ifndef GET_ULONG_LE
-#define GET_ULONG_LE(n,b,i)                             \
+#ifndef GET_U32_LE
+#define GET_U32_LE(n,b,i)                               \
 {                                                       \
-    (n) = ( (unsigned long) (b)[(i)    ]       )        \
-        | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
-        | ( (unsigned long) (b)[(i) + 2] << 16 )        \
-        | ( (unsigned long) (b)[(i) + 3] << 24 );       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
 }
 #endif
 
-#ifndef PUT_ULONG_LE
-#define PUT_ULONG_LE(n,b,i)                             \
+#ifndef PUT_U32_LE
+#define PUT_U32_LE(n,b,i)                               \
 {                                                       \
     (b)[(i)    ] = (unsigned char) ( (n)       );       \
     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
@@ -84,24 +85,24 @@ static void md5_starts( md5_context *ctx )
 
 static void md5_process( md5_context *ctx, const unsigned char data[64] )
 {
-    unsigned long X[16], A, B, C, D;
-
-    GET_ULONG_LE( X[ 0], data,  0 );
-    GET_ULONG_LE( X[ 1], data,  4 );
-    GET_ULONG_LE( X[ 2], data,  8 );
-    GET_ULONG_LE( X[ 3], data, 12 );
-    GET_ULONG_LE( X[ 4], data, 16 );
-    GET_ULONG_LE( X[ 5], data, 20 );
-    GET_ULONG_LE( X[ 6], data, 24 );
-    GET_ULONG_LE( X[ 7], data, 28 );
-    GET_ULONG_LE( X[ 8], data, 32 );
-    GET_ULONG_LE( X[ 9], data, 36 );
-    GET_ULONG_LE( X[10], data, 40 );
-    GET_ULONG_LE( X[11], data, 44 );
-    GET_ULONG_LE( X[12], data, 48 );
-    GET_ULONG_LE( X[13], data, 52 );
-    GET_ULONG_LE( X[14], data, 56 );
-    GET_ULONG_LE( X[15], data, 60 );
+    uint32_t X[16], A, B, C, D;
+
+    GET_U32_LE( X[ 0], data,  0 );
+    GET_U32_LE( X[ 1], data,  4 );
+    GET_U32_LE( X[ 2], data,  8 );
+    GET_U32_LE( X[ 3], data, 12 );
+    GET_U32_LE( X[ 4], data, 16 );
+    GET_U32_LE( X[ 5], data, 20 );
+    GET_U32_LE( X[ 6], data, 24 );
+    GET_U32_LE( X[ 7], data, 28 );
+    GET_U32_LE( X[ 8], data, 32 );
+    GET_U32_LE( X[ 9], data, 36 );
+    GET_U32_LE( X[10], data, 40 );
+    GET_U32_LE( X[11], data, 44 );
+    GET_U32_LE( X[12], data, 48 );
+    GET_U32_LE( X[13], data, 52 );
+    GET_U32_LE( X[14], data, 56 );
+    GET_U32_LE( X[15], data, 60 );
 
 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
 
@@ -211,7 +212,7 @@ static void md5_process( md5_context *ctx, const unsigned char data[64] )
 static void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
 {
     size_t fill;
-    unsigned long left;
+    uint32_t left;
 
     if( ilen <= 0 )
         return;
@@ -219,10 +220,10 @@ static void md5_update( md5_context *ctx, const unsigned char *input, size_t ile
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
 
-    ctx->total[0] += (unsigned long) ilen;
+    ctx->total[0] += (uint32_t) ilen;
     ctx->total[0] &= 0xFFFFFFFF;
 
-    if( ctx->total[0] < (unsigned long) ilen )
+    if( ctx->total[0] < (uint32_t) ilen )
         ctx->total[1]++;
 
     if( left && ilen >= fill )
@@ -262,16 +263,16 @@ static const unsigned char md5_padding[64] =
  */
 static void md5_finish( md5_context *ctx, unsigned char output[16] )
 {
-    unsigned long last, padn;
-    unsigned long high, low;
+    uint32_t last, padn;
+    uint32_t high, low;
     unsigned char msglen[8];
 
     high = ( ctx->total[0] >> 29 )
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_ULONG_LE( low,  msglen, 0 );
-    PUT_ULONG_LE( high, msglen, 4 );
+    PUT_U32_LE( low,  msglen, 0 );
+    PUT_U32_LE( high, msglen, 4 );
 
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -279,10 +280,10 @@ static void md5_finish( md5_context *ctx, unsigned char output[16] )
     md5_update( ctx, (unsigned char *) md5_padding, padn );
     md5_update( ctx, msglen, 8 );
 
-    PUT_ULONG_LE( ctx->state[0], output,  0 );
-    PUT_ULONG_LE( ctx->state[1], output,  4 );
-    PUT_ULONG_LE( ctx->state[2], output,  8 );
-    PUT_ULONG_LE( ctx->state[3], output, 12 );
+    PUT_U32_LE( ctx->state[0], output,  0 );
+    PUT_U32_LE( ctx->state[1], output,  4 );
+    PUT_U32_LE( ctx->state[2], output,  8 );
+    PUT_U32_LE( ctx->state[3], output, 12 );
 }
 
 /*
diff --git a/lib/libalpm/sha2.c b/lib/libalpm/sha2.c
index 3632c13..366dc65 100644
--- a/lib/libalpm/sha2.c
+++ b/lib/libalpm/sha2.c
@@ -38,28 +38,29 @@
  *  * removal of SELF_TEST code
  *  * removal of ipad and opad from the sha2_context struct in sha2.h
  *  * increase the size of buffer for performance reasons
- *  * various static changes
+ *  * change 'unsigned long' to uint32_t
  */
 
 #include <stdio.h>
+#include <stdint.h>
 
 #include "sha2.h"
 
 /*
  * 32-bit integer manipulation macros (big endian)
  */
-#ifndef GET_ULONG_BE
-#define GET_ULONG_BE(n,b,i)                             \
+#ifndef GET_U32_BE
+#define GET_U32_BE(n,b,i)                               \
 {                                                       \
-    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
-        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
-        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
-        | ( (unsigned long) (b)[(i) + 3]       );       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
 }
 #endif
 
-#ifndef PUT_ULONG_BE
-#define PUT_ULONG_BE(n,b,i)                             \
+#ifndef PUT_U32_BE
+#define PUT_U32_BE(n,b,i)                               \
 {                                                       \
     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
@@ -106,25 +107,25 @@ static void sha2_starts( sha2_context *ctx, int is224 )
 
 static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
 {
-    unsigned long temp1, temp2, W[64];
-    unsigned long A, B, C, D, E, F, G, H;
-
-    GET_ULONG_BE( W[ 0], data,  0 );
-    GET_ULONG_BE( W[ 1], data,  4 );
-    GET_ULONG_BE( W[ 2], data,  8 );
-    GET_ULONG_BE( W[ 3], data, 12 );
-    GET_ULONG_BE( W[ 4], data, 16 );
-    GET_ULONG_BE( W[ 5], data, 20 );
-    GET_ULONG_BE( W[ 6], data, 24 );
-    GET_ULONG_BE( W[ 7], data, 28 );
-    GET_ULONG_BE( W[ 8], data, 32 );
-    GET_ULONG_BE( W[ 9], data, 36 );
-    GET_ULONG_BE( W[10], data, 40 );
-    GET_ULONG_BE( W[11], data, 44 );
-    GET_ULONG_BE( W[12], data, 48 );
-    GET_ULONG_BE( W[13], data, 52 );
-    GET_ULONG_BE( W[14], data, 56 );
-    GET_ULONG_BE( W[15], data, 60 );
+    uint32_t temp1, temp2, W[64];
+    uint32_t A, B, C, D, E, F, G, H;
+
+    GET_U32_BE( W[ 0], data,  0 );
+    GET_U32_BE( W[ 1], data,  4 );
+    GET_U32_BE( W[ 2], data,  8 );
+    GET_U32_BE( W[ 3], data, 12 );
+    GET_U32_BE( W[ 4], data, 16 );
+    GET_U32_BE( W[ 5], data, 20 );
+    GET_U32_BE( W[ 6], data, 24 );
+    GET_U32_BE( W[ 7], data, 28 );
+    GET_U32_BE( W[ 8], data, 32 );
+    GET_U32_BE( W[ 9], data, 36 );
+    GET_U32_BE( W[10], data, 40 );
+    GET_U32_BE( W[11], data, 44 );
+    GET_U32_BE( W[12], data, 48 );
+    GET_U32_BE( W[13], data, 52 );
+    GET_U32_BE( W[14], data, 56 );
+    GET_U32_BE( W[15], data, 60 );
 
 #define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
@@ -241,7 +242,7 @@ static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
 static void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
 {
     size_t fill;
-    unsigned long left;
+    uint32_t left;
 
     if( ilen <= 0 )
         return;
@@ -249,10 +250,10 @@ static void sha2_update( sha2_context *ctx, const unsigned char *input, size_t i
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
 
-    ctx->total[0] += (unsigned long) ilen;
+    ctx->total[0] += (uint32_t) ilen;
     ctx->total[0] &= 0xFFFFFFFF;
 
-    if( ctx->total[0] < (unsigned long) ilen )
+    if( ctx->total[0] < (uint32_t) ilen )
         ctx->total[1]++;
 
     if( left && ilen >= fill )
@@ -292,16 +293,16 @@ static const unsigned char sha2_padding[64] =
  */
 static void sha2_finish( sha2_context *ctx, unsigned char output[32] )
 {
-    unsigned long last, padn;
-    unsigned long high, low;
+    uint32_t last, padn;
+    uint32_t high, low;
     unsigned char msglen[8];
 
     high = ( ctx->total[0] >> 29 )
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_ULONG_BE( high, msglen, 0 );
-    PUT_ULONG_BE( low,  msglen, 4 );
+    PUT_U32_BE( high, msglen, 0 );
+    PUT_U32_BE( low,  msglen, 4 );
 
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -309,16 +310,16 @@ static void sha2_finish( sha2_context *ctx, unsigned char output[32] )
     sha2_update( ctx, (unsigned char *) sha2_padding, padn );
     sha2_update( ctx, msglen, 8 );
 
-    PUT_ULONG_BE( ctx->state[0], output,  0 );
-    PUT_ULONG_BE( ctx->state[1], output,  4 );
-    PUT_ULONG_BE( ctx->state[2], output,  8 );
-    PUT_ULONG_BE( ctx->state[3], output, 12 );
-    PUT_ULONG_BE( ctx->state[4], output, 16 );
-    PUT_ULONG_BE( ctx->state[5], output, 20 );
-    PUT_ULONG_BE( ctx->state[6], output, 24 );
+    PUT_U32_BE( ctx->state[0], output,  0 );
+    PUT_U32_BE( ctx->state[1], output,  4 );
+    PUT_U32_BE( ctx->state[2], output,  8 );
+    PUT_U32_BE( ctx->state[3], output, 12 );
+    PUT_U32_BE( ctx->state[4], output, 16 );
+    PUT_U32_BE( ctx->state[5], output, 20 );
+    PUT_U32_BE( ctx->state[6], output, 24 );
 
     if( ctx->is224 == 0 )
-        PUT_ULONG_BE( ctx->state[7], output, 28 );
+        PUT_U32_BE( ctx->state[7], output, 28 );
 }
 
 /*
-- 
1.7.8.1



More information about the pacman-dev mailing list