📄 sha.c
字号:
((word8 *)buffer)[3]); *buffer++ = value; }}/* Update SHA for a block of data. */voidshaUpdate(struct SHAContext *sha, word8 const *buffer, unsigned count){ word32 t; /* Update bitcount */#ifdef HAVE64 t = (word32)sha->count & 0x3f; sha->count += count;#else t = sha->countLo; if ( ( sha->countLo = t + count ) < t ) sha->countHi++; /* Carry from low to high */ t &= 0x3f; /* Bytes already in sha->data */#endif /* Handle any leading odd-sized chunks */ if (t) { word8 *p = (word8 *)sha->data + t; t = 64-t; if (count < t) { memcpy(p, buffer, count); return; } memcpy(p, buffer, t); byteReverse(sha->data, SHA_BLOCKSIZE); shaTransform(sha); buffer += t; count -= t; } /* Process data in SHA_BLOCKSIZE chunks */ while (count >= SHA_BLOCKSIZE) { memcpy(sha->data, buffer, SHA_BLOCKSIZE); byteReverse(sha->data, SHA_BLOCKSIZE); shaTransform(sha); buffer += SHA_BLOCKSIZE; count -= SHA_BLOCKSIZE; } /* Handle any remaining bytes of data. */ memcpy(sha->data, buffer, count);}/* Final wrapup - pad to 64-byte boundary with the bit pattern 1 0* (64-bit count of bits processed, MSB-first) */voidshaFinal(struct SHAContext *sha, word8 *hash){ int count; word8 *p; /* Compute number of bytes mod 64 */#ifdef HAVE64 count = (int)sha->count & 0x3F;#else count = (int)sha->countLo & 0x3F;#endif /* * Set the first char of padding to 0x80. * This is safe since there is always at least one byte free */ p = (word8 *)sha->data + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = SHA_BLOCKSIZE - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(sha->data, SHA_BLOCKSIZE); shaTransform(sha); /* Now fill the next block with 56 bytes */ memset(sha->data, 0, SHA_BLOCKSIZE-8); } else { /* Pad block to 56 bytes */ memset(p, 0, count-8); } byteReverse(sha->data, SHA_BLOCKSIZE-8); /* Append length in *bits* and transform */#if HAVE64 sha->data[14] = (word32)(sha->count >> 29); sha->data[15] = (word32)sha->count << 3;#else sha->data[14] = sha->countHi << 3 | sha->countLo >> 29; sha->data[15] = sha->countLo << 3;#endif shaTransform(sha); /* Store output hash in buffer */ byteReverse(sha->digest, SHA_DIGESTSIZE); memcpy(hash, sha->digest, SHA_DIGESTSIZE); memset(sha, 0, sizeof(*sha));}#if 0/* ----------------------------- SHA Test code --------------------------- */#include <stdio.h>#include <stdlib.h> /* For exit() */#include <time.h>/* Size of buffer for SHA speed test data */#define TEST_BLOCK_SIZE ( SHA_DIGESTSIZE * 100 )/* Number of bytes of test data to process */#define TEST_BYTES 10000000L#define TEST_BLOCKS ( TEST_BYTES / TEST_BLOCK_SIZE )#if SHA_VERSIONstatic char const *shaTestResults[] = { "A9993E364706816ABA3E25717850C26C9CD0D89D", "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" };#elsestatic char const *shaTestResults[] = { "0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880", "D2516EE1ACFA5BAF33DFC1C471E438449EF134C8", "3232AFFA48628A26653B5AAA44541FD90D690603", "3232AFFA48628A26653B5AAA44541FD90D690603", "3232AFFA48628A26653B5AAA44541FD90D690603" };#endifstatic intcompareSHAresults(word8 *hash, int level){ char buf[41]; int i; for (i = 0; i < SHA_DIGESTSIZE; i++) sprintf(buf+2*i, "%02X", hash[i]); if (strcmp(buf, shaTestResults[level-1]) == 0) { printf("Test %d passed, result = %s\n", level, buf); return 0; } else { printf("Error in SHA implementation: Test %d failed\n", level); printf(" Result = %s\n", buf); printf("Expected = %s\n", shaTestResults[level-1]); return -1; }}intmain(void){ struct SHAContext sha; word8 data[TEST_BLOCK_SIZE]; word8 hash[SHA_DIGESTSIZE]; time_t seconds; long i; word32 t; /* Check that LITTLE_ENDIAN is set correctly */ t = 0x12345678;#if LITTLE_ENDIAN if (*(word8 *)&t != 0x78) { puts("Error: Define BIG_ENDIAN in SHA.H and recompile"); exit(-1); }#elif BIG_ENDIAN if (*(word8 *)&t != 0x12) { puts("Error: Define LITTLE_ENDIAN in SHA.H and recompile"); exit(-1); }#endif /* * Test output data (these are the only test data given in the * Secure Hash Standard document, but chances are if it works * for this it'll work for anything) */ shaInit(&sha); shaUpdate(&sha, (word8 *)"abc", 3); shaFinal(&sha, hash); if (compareSHAresults(hash, 1) < 0) exit (-1); shaInit(&sha); shaUpdate(&sha, (word8 *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); shaFinal(&sha, hash); if (compareSHAresults(hash, 2) < 0) exit (-1); /* 1,000,000 bytes of ASCII 'a' (0x61), by 64's */ shaInit(&sha); for (i = 0; i < 15625; i++) shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64); shaFinal(&sha, hash); if (compareSHAresults(hash, 3) < 0) exit (-1); /* 1,000,000 bytes of ASCII 'a' (0x61), by 25's */ shaInit(&sha); for (i = 0; i < 40000; i++) shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25); shaFinal(&sha, hash); if (compareSHAresults(hash, 4) < 0) exit (-1); /* 1,000,000 bytes of ASCII 'a' (0x61), by 125's */ shaInit(&sha); for (i = 0; i < 8000; i++) shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125); shaFinal(&sha, hash); if (compareSHAresults(hash, 5) < 0) exit (-1); /* Now perform time trial, generating MD for 10MB of data. First, initialize the test data */ memset(data, 0, TEST_BLOCK_SIZE); /* Get start time */ printf("SHA time trial. Processing %ld characters...\n", TEST_BYTES); seconds = time((time_t *)0); /* Calculate SHA message digest in TEST_BLOCK_SIZE byte blocks */ shaInit(&sha); for (i = TEST_BLOCKS; i > 0; i--) shaUpdate(&sha, data, TEST_BLOCK_SIZE); shaFinal(&sha, hash); /* Get finish time and print difference */ seconds = time((time_t *)0) - seconds; printf("Seconds to process test input: %ld\n", seconds); printf("Characters processed per second: %ld\n", TEST_BYTES / seconds); return 0;}#endif /* Test driver */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -