mux/src/sha1.cpp

Go to the documentation of this file.
00001 #include "copyright.h"
00002 #include "autoconf.h"
00003 #include "config.h"
00004 #include "externs.h"
00005 #include "sha1.h"
00006 
00007 void SHA1_Init(SHA1_CONTEXT *p)
00008 {
00009     p->H[0] = 0x67452301;
00010     p->H[1] = 0xEFCDAB89;
00011     p->H[2] = 0x98BADCFE;
00012     p->H[3] = 0x10325476;
00013     p->H[4] = 0xC3D2E1F0;
00014     p->nTotal = 0;
00015     p->nblock = 0;
00016 }
00017 
00018 #ifdef WIN32
00019 #define ROTL(d,n) _lrotl(d,n)
00020 #else // WIN32
00021 #define ROTL(d,n) (((d) << (n)) | ((d) >> (32-(n))))
00022 #endif // WIN32
00023 
00024 #define Ch(x,y,z)      (((x) & (y)) ^ (~(x) & (z)))
00025 #define Parity(x,y,z)  ((x) ^ (y) ^ (z))
00026 #define Maj(x,y,z)     (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00027 
00028 static void SHA1_HashBlock(SHA1_CONTEXT *p)
00029 {
00030     int t;
00031     UINT32 W[80];
00032 
00033     // Prepare Message Schedule, {W sub t}.
00034     //
00035     int j;
00036     for (t = 0, j = 0; t <= 15; t++, j += 4)
00037     {
00038         W[t] = (p->block[j  ] << 24)
00039              | (p->block[j+1] << 16)
00040              | (p->block[j+2] <<  8)
00041              | (p->block[j+3]      );
00042     }
00043     for (t = 16; t <= 79; t++)
00044     {
00045         W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
00046     }
00047 
00048     UINT32 a = p->H[0];
00049     UINT32 b = p->H[1];
00050     UINT32 c = p->H[2];
00051     UINT32 d = p->H[3];
00052     UINT32 e = p->H[4];
00053 
00054     UINT32 T;
00055     for (t =  0; t <= 19; t++)
00056     {
00057         T = ROTL(a,5) + Ch(b,c,d) + e + 0x5A827999 + W[t];
00058         e = d;
00059         d = c;
00060         c = ROTL(b,30);
00061         b = a;
00062         a = T;
00063     }
00064     for (t = 20; t <= 39; t++)
00065     {
00066         T = ROTL(a,5) + Parity(b,c,d) + e + 0x6ED9EBA1 + W[t];
00067         e = d;
00068         d = c;
00069         c = ROTL(b,30);
00070         b = a;
00071         a = T;
00072     }
00073     for (t = 40; t <= 59; t++)
00074     {
00075         T = ROTL(a,5) + Maj(b,c,d) + e + 0x8F1BBCDC + W[t];
00076         e = d;
00077         d = c;
00078         c = ROTL(b,30);
00079         b = a;
00080         a = T;
00081     }
00082     for (t = 60; t <= 79; t++)
00083     {
00084         T = ROTL(a,5) + Parity(b,c,d) + e + 0xCA62C1D6 + W[t];
00085         e = d;
00086         d = c;
00087         c = ROTL(b,30);
00088         b = a;
00089         a = T;
00090     }
00091 
00092     p->H[0] += a;
00093     p->H[1] += b;
00094     p->H[2] += c;
00095     p->H[3] += d;
00096     p->H[4] += e;
00097 }
00098 
00099 void SHA1_Compute(SHA1_CONTEXT *p, size_t n, const char *buf)
00100 {
00101     while (n)
00102     {
00103         size_t m = sizeof(p->block) - p->nblock;
00104         if (n < m)
00105         {
00106             m = n;
00107         }
00108         memcpy(p->block + p->nblock, buf, m);
00109         buf += m;
00110         n -= m;
00111         p->nblock += m;
00112         p->nTotal += m;
00113 
00114         if (p->nblock == sizeof(p->block))
00115         {
00116             SHA1_HashBlock(p);
00117             p->nblock = 0;
00118         }
00119     }
00120 }
00121 
00122 void SHA1_Final(SHA1_CONTEXT *p)
00123 {
00124     p->block[p->nblock++] = 0x80;
00125     if (sizeof(p->block) - sizeof(UINT64) <= p->nblock)
00126     {
00127         memset(p->block + p->nblock, 0, sizeof(p->block) - p->nblock);
00128         SHA1_HashBlock(p);
00129         memset(p->block, 0, sizeof(p->block) - sizeof(UINT64));
00130     }
00131     else
00132     {
00133         memset(p->block + p->nblock, 0, sizeof(p->block) - p->nblock - sizeof(UINT64));
00134     }
00135     p->nTotal *= 8;
00136 
00137     p->block[sizeof(p->block) - 8] = (UINT8)(p->nTotal >> 56) & 0xFF;
00138     p->block[sizeof(p->block) - 7] = (UINT8)(p->nTotal >> 48) & 0xFF;
00139     p->block[sizeof(p->block) - 6] = (UINT8)(p->nTotal >> 40) & 0xFF;
00140     p->block[sizeof(p->block) - 5] = (UINT8)(p->nTotal >> 32) & 0xFF;
00141     p->block[sizeof(p->block) - 4] = (UINT8)(p->nTotal >> 24) & 0xFF;
00142     p->block[sizeof(p->block) - 3] = (UINT8)(p->nTotal >> 16) & 0xFF;
00143     p->block[sizeof(p->block) - 2] = (UINT8)(p->nTotal >>  8) & 0xFF;
00144     p->block[sizeof(p->block) - 1] = (UINT8)(p->nTotal      ) & 0xFF;
00145     SHA1_HashBlock(p);
00146 }
00147 
00148 #if 0
00149 
00150 //#define TEST_STRING "abc"
00151 #define TEST_STRING "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
00152 int main(int argc, char *argv[])
00153 {
00154     char buffer[] = TEST_STRING;
00155 
00156     SHA1_CONTEXT shac;
00157     SHA1_Init(&shac);
00158     SHA1_Compute(&shac, strlen(TEST_STRING), buffer);
00159     SHA1_Final(&shac);
00160 
00161     int i;
00162     for (i = 0; i < 5; i++)
00163     {
00164         printf("%08X", shac.H[i]);
00165     }
00166     return 1;
00167 }
00168 
00169 #endif

Generated on Mon May 28 04:40:11 2007 for MUX by  doxygen 1.4.7