now-generated
[gnulib.git] / lib / sha.c
index 8fe8d61..fe3708c 100644 (file)
--- a/lib/sha.c
+++ b/lib/sha.c
@@ -234,24 +234,15 @@ sha_process_bytes (const void *buffer, size_t len, struct sha_ctx *ctx)
 #define K3 0x8f1bbcdcL
 #define K4 0xca62c1d6L
 
-/* Round functions.  Note that f2() is used in both rounds 2 and 4 */
-#define f1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
-#define f2(B,C,D) (B ^ C ^ D)
-#define f3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
-
-#if SHA_DEBUG
-char bin2hex[16]={'0','1','2','3','4','5','6','7',
-                 '8','9','a','b','c','d','e','f'};
-# define BH(x) bin2hex[x]
-# define PH(x) \
-      printf("%c%c%c%c%c%c%c%c\t", BH((x>>28)&0xf), \
-            BH((x>>24)&0xf), BH((x>>20)&0xf), BH((x>>16)&0xf),\
-            BH((x>>12)&0xf), BH((x>>8)&0xf), BH((x>>4)&0xf),\
-            BH(x&0xf));
-#endif
+/* Round functions.  Note that F2 is the same as F4.  */
+#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
+#define F2(B,C,D) (B ^ C ^ D)
+#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
+#define F4(B,C,D) (B ^ C ^ D)
 
 /* Process LEN bytes of BUFFER, accumulating context into CTX.
-   It is assumed that LEN % 64 == 0.  */
+   It is assumed that LEN % 64 == 0.
+   Most of this code comes from GnuPG's cipher/sha1.c.  */
 
 void
 sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx)
@@ -259,12 +250,12 @@ sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx)
   const md5_uint32 *words = buffer;
   size_t nwords = len / sizeof (md5_uint32);
   const md5_uint32 *endp = words + nwords;
-  md5_uint32 W[80];
-  md5_uint32 A = ctx->A;
-  md5_uint32 B = ctx->B;
-  md5_uint32 C = ctx->C;
-  md5_uint32 D = ctx->D;
-  md5_uint32 E = ctx->E;
+  md5_uint32 x[16];
+  md5_uint32 a = ctx->A;
+  md5_uint32 b = ctx->B;
+  md5_uint32 c = ctx->C;
+  md5_uint32 d = ctx->D;
+  md5_uint32 e = ctx->E;
 
   /* First increment the byte count.  RFC 1321 specifies the possible
      length of the file up to 2^64 bits.  Here we only compute the
@@ -273,65 +264,113 @@ sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx)
   if (ctx->total[0] < len)
     ++ctx->total[1];
 
+#define M(I) ( tm =   x[I&0x0f] ^ x[(I-14)&0x0f] \
+                   ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
+              , (x[I&0x0f] = rol(tm, 1)) )
+
+#define R(A,B,C,D,E,F,K,M)  do { E += rol( A, 5 )     \
+                                     + F( B, C, D )  \
+                                     + K             \
+                                     + M;            \
+                                B = rol( B, 30 );    \
+                              } while(0)
+
   while (words < endp)
     {
+      md5_uint32 tm;
       int t;
+      /* FIXME: see sha1.c for a better implementation.  */
       for (t = 0; t < 16; t++)
        {
-         W[t] = NOTSWAP (*words);
+         x[t] = NOTSWAP (*words);
          words++;
        }
 
-      /* SHA1 Data expansion */
-      for (t = 16; t < 80; t++)
-       {
-         md5_uint32 x = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
-         W[t] = rol (x, 1);
-       }
-
-      /* SHA1 main loop (t=0 to 79)
-         This is broken down into four subloops in order to use
-         the correct round function and constant */
-      for (t = 0; t < 20; t++)
-       {
-         md5_uint32 tmp = rol (A, 5) + f1 (B, C, D) + E + W[t] + K1;
-         E = D;
-         D = C;
-         C = rol (B, 30);
-         B = A;
-         A = tmp;
-       }
-      for (; t < 40; t++)
-       {
-         md5_uint32 tmp = rol (A, 5) + f2 (B, C, D) + E + W[t] + K2;
-         E = D;
-         D = C;
-         C = rol (B, 30);
-         B = A;
-         A = tmp;
-       }
-      for (; t < 60; t++)
-       {
-         md5_uint32 tmp = rol (A, 5) + f3 (B, C, D) + E + W[t] + K3;
-         E = D;
-         D = C;
-         C = rol (B, 30);
-         B = A;
-         A = tmp;
-       }
-      for (; t < 80; t++)
-       {
-         md5_uint32 tmp = rol (A, 5) + f2 (B, C, D) + E + W[t] + K4;
-         E = D;
-         D = C;
-         C = rol (B, 30);
-         B = A;
-         A = tmp;
-       }
-      A = ctx->A += A;
-      B = ctx->B += B;
-      C = ctx->C += C;
-      D = ctx->D += D;
-      E = ctx->E += E;
+      R( a, b, c, d, e, F1, K1, x[ 0] );
+      R( e, a, b, c, d, F1, K1, x[ 1] );
+      R( d, e, a, b, c, F1, K1, x[ 2] );
+      R( c, d, e, a, b, F1, K1, x[ 3] );
+      R( b, c, d, e, a, F1, K1, x[ 4] );
+      R( a, b, c, d, e, F1, K1, x[ 5] );
+      R( e, a, b, c, d, F1, K1, x[ 6] );
+      R( d, e, a, b, c, F1, K1, x[ 7] );
+      R( c, d, e, a, b, F1, K1, x[ 8] );
+      R( b, c, d, e, a, F1, K1, x[ 9] );
+      R( a, b, c, d, e, F1, K1, x[10] );
+      R( e, a, b, c, d, F1, K1, x[11] );
+      R( d, e, a, b, c, F1, K1, x[12] );
+      R( c, d, e, a, b, F1, K1, x[13] );
+      R( b, c, d, e, a, F1, K1, x[14] );
+      R( a, b, c, d, e, F1, K1, x[15] );
+      R( e, a, b, c, d, F1, K1, M(16) );
+      R( d, e, a, b, c, F1, K1, M(17) );
+      R( c, d, e, a, b, F1, K1, M(18) );
+      R( b, c, d, e, a, F1, K1, M(19) );
+      R( a, b, c, d, e, F2, K2, M(20) );
+      R( e, a, b, c, d, F2, K2, M(21) );
+      R( d, e, a, b, c, F2, K2, M(22) );
+      R( c, d, e, a, b, F2, K2, M(23) );
+      R( b, c, d, e, a, F2, K2, M(24) );
+      R( a, b, c, d, e, F2, K2, M(25) );
+      R( e, a, b, c, d, F2, K2, M(26) );
+      R( d, e, a, b, c, F2, K2, M(27) );
+      R( c, d, e, a, b, F2, K2, M(28) );
+      R( b, c, d, e, a, F2, K2, M(29) );
+      R( a, b, c, d, e, F2, K2, M(30) );
+      R( e, a, b, c, d, F2, K2, M(31) );
+      R( d, e, a, b, c, F2, K2, M(32) );
+      R( c, d, e, a, b, F2, K2, M(33) );
+      R( b, c, d, e, a, F2, K2, M(34) );
+      R( a, b, c, d, e, F2, K2, M(35) );
+      R( e, a, b, c, d, F2, K2, M(36) );
+      R( d, e, a, b, c, F2, K2, M(37) );
+      R( c, d, e, a, b, F2, K2, M(38) );
+      R( b, c, d, e, a, F2, K2, M(39) );
+      R( a, b, c, d, e, F3, K3, M(40) );
+      R( e, a, b, c, d, F3, K3, M(41) );
+      R( d, e, a, b, c, F3, K3, M(42) );
+      R( c, d, e, a, b, F3, K3, M(43) );
+      R( b, c, d, e, a, F3, K3, M(44) );
+      R( a, b, c, d, e, F3, K3, M(45) );
+      R( e, a, b, c, d, F3, K3, M(46) );
+      R( d, e, a, b, c, F3, K3, M(47) );
+      R( c, d, e, a, b, F3, K3, M(48) );
+      R( b, c, d, e, a, F3, K3, M(49) );
+      R( a, b, c, d, e, F3, K3, M(50) );
+      R( e, a, b, c, d, F3, K3, M(51) );
+      R( d, e, a, b, c, F3, K3, M(52) );
+      R( c, d, e, a, b, F3, K3, M(53) );
+      R( b, c, d, e, a, F3, K3, M(54) );
+      R( a, b, c, d, e, F3, K3, M(55) );
+      R( e, a, b, c, d, F3, K3, M(56) );
+      R( d, e, a, b, c, F3, K3, M(57) );
+      R( c, d, e, a, b, F3, K3, M(58) );
+      R( b, c, d, e, a, F3, K3, M(59) );
+      R( a, b, c, d, e, F4, K4, M(60) );
+      R( e, a, b, c, d, F4, K4, M(61) );
+      R( d, e, a, b, c, F4, K4, M(62) );
+      R( c, d, e, a, b, F4, K4, M(63) );
+      R( b, c, d, e, a, F4, K4, M(64) );
+      R( a, b, c, d, e, F4, K4, M(65) );
+      R( e, a, b, c, d, F4, K4, M(66) );
+      R( d, e, a, b, c, F4, K4, M(67) );
+      R( c, d, e, a, b, F4, K4, M(68) );
+      R( b, c, d, e, a, F4, K4, M(69) );
+      R( a, b, c, d, e, F4, K4, M(70) );
+      R( e, a, b, c, d, F4, K4, M(71) );
+      R( d, e, a, b, c, F4, K4, M(72) );
+      R( c, d, e, a, b, F4, K4, M(73) );
+      R( b, c, d, e, a, F4, K4, M(74) );
+      R( a, b, c, d, e, F4, K4, M(75) );
+      R( e, a, b, c, d, F4, K4, M(76) );
+      R( d, e, a, b, c, F4, K4, M(77) );
+      R( c, d, e, a, b, F4, K4, M(78) );
+      R( b, c, d, e, a, F4, K4, M(79) );
+
+      a = ctx->A += a;
+      b = ctx->B += b;
+      c = ctx->C += c;
+      d = ctx->D += d;
+      e = ctx->E += e;
     }
 }