📄 sha.c
字号:
#pragma ident "@(#)sha.c 1.1 95/11/19 Sun Microsystems"/* --------------------------------- SHA.C ------------------------------- */#include <string.h>#include "sha.h"/* * NIST Secure Hash Algorithm. * * Written 2 September 1992, Peter C. Gutmann. * This implementation placed in the public domain. * * Modified 1 June 1993, Colin Plumb. * Modified for the new SHS based on Peter Gutmann's work, * 18 July 1994, Colin Plumb. * Gutmann's work. * Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb. * These modifications placed in the public domain. * * Comments to pgut1@cs.aukuni.ac.nz *//* * The SHA f()-functions. The f1 and f3 functions can be optimized to * save one boolean operation each - thanks to Rich Schroeppel, * rcs@cs.arizona.edu for discovering this *//*#define f1(x,y,z) ( (x & y) | (~x & z) ) // Rounds 0-19 */#define f1(x,y,z) ( z ^ (x & (y ^ z) ) ) /* Rounds 0-19 */#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 *//*#define f3(x,y,z) ( (x & y) | (x & z) | (y & z) ) // Rounds 40-59 */#define f3(x,y,z) ( (x & y) | (z & (x | y) ) ) /* Rounds 40-59 */#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 *//* * The SHA Mysterious Constants. * K1 = floor(sqrt(2) * 2^30) * K2 = floor(sqrt(3) * 2^30) * K3 = floor(sqrt(5) * 2^30) * K4 = floor(sqrt(10) * 2^30) */#define K1 0x5A827999L /* Rounds 0-19 */#define K2 0x6ED9EBA1L /* Rounds 20-39 */#define K3 0x8F1BBCDCL /* Rounds 40-59 */#define K4 0xCA62C1D6L /* Rounds 60-79 *//* SHA initial values */#define h0init 0x67452301L#define h1init 0xEFCDAB89L#define h2init 0x98BADCFEL#define h3init 0x10325476L#define h4init 0xC3D2E1F0L/* * Note that it may be necessary to add parentheses to these macros * if they are to be called with expressions as arguments. *//* 32-bit rotate left - kludged with shifts */#define ROTL(n,X) ( (X << n) | (X >> (32-n)) )/* * The initial expanding function * * The hash function is defined over an 80-word expanded input array W, * where the first 16 are copies of the input data, and the remaining 64 * are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This * implementation generates these values on the fly in a circular buffer. */#if SHA_VERSION/* The new ("corrected") SHA, FIPS 180.1 *//* Same as below, but then rotate left one bit */#define expand(W,i) (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], \ W[i&15] = ROTL(1, W[i&15]))#else/* The old (pre-correction) SHA, FIPS 180 */#define expand(W,i) (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15])#endif/* * The prototype SHA sub-round * * The fundamental sub-round is * a' = e + ROTL(5,a) + f(b, c, d) + k + data; * b' = a; * c' = ROTL(30,b); * d' = c; * e' = d; * ... but this is implemented by unrolling the loop 5 times and renaming * the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration. */#define subRound(a, b, c, d, e, f, k, data) \ ( e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b) )/* * The above code is replicated 20 times for each of the 4 functions, * using the next 20 values from the W[] array each time. *//* Initialize the SHA values */voidshaInit(struct SHAContext *sha){ /* Set the h-vars to their initial values */ sha->digest[0] = h0init; sha->digest[1] = h1init; sha->digest[2] = h2init; sha->digest[3] = h3init; sha->digest[4] = h4init; /* Initialise bit count */#ifdef HAVE64 sha->count = 0;#else sha->countLo = sha->countHi = 0;#endif}/* * Perform the SHA transformation. Note that this code, like MD5, seems to * break some optimizing compilers due to the complexity of the expressions * and the size of the basic block. It may be necessary to split it into * sections, e.g. based on the four subrounds * * Note that this corrupts the sha->data area */#ifndef ASMvoid shaTransform(struct SHAContext *sha){ register word32 A, B, C, D, E; /* Set up first buffer */ A = sha->digest[0]; B = sha->digest[1]; C = sha->digest[2]; D = sha->digest[3]; E = sha->digest[4]; /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ subRound( A, B, C, D, E, f1, K1, sha->data[ 0] ); subRound( E, A, B, C, D, f1, K1, sha->data[ 1] ); subRound( D, E, A, B, C, f1, K1, sha->data[ 2] ); subRound( C, D, E, A, B, f1, K1, sha->data[ 3] ); subRound( B, C, D, E, A, f1, K1, sha->data[ 4] ); subRound( A, B, C, D, E, f1, K1, sha->data[ 5] ); subRound( E, A, B, C, D, f1, K1, sha->data[ 6] ); subRound( D, E, A, B, C, f1, K1, sha->data[ 7] ); subRound( C, D, E, A, B, f1, K1, sha->data[ 8] ); subRound( B, C, D, E, A, f1, K1, sha->data[ 9] ); subRound( A, B, C, D, E, f1, K1, sha->data[10] ); subRound( E, A, B, C, D, f1, K1, sha->data[11] ); subRound( D, E, A, B, C, f1, K1, sha->data[12] ); subRound( C, D, E, A, B, f1, K1, sha->data[13] ); subRound( B, C, D, E, A, f1, K1, sha->data[14] ); subRound( A, B, C, D, E, f1, K1, sha->data[15] ); subRound( E, A, B, C, D, f1, K1, expand(sha->data, 16) ); subRound( D, E, A, B, C, f1, K1, expand(sha->data, 17) ); subRound( C, D, E, A, B, f1, K1, expand(sha->data, 18) ); subRound( B, C, D, E, A, f1, K1, expand(sha->data, 19) ); subRound( A, B, C, D, E, f2, K2, expand(sha->data, 20) ); subRound( E, A, B, C, D, f2, K2, expand(sha->data, 21) ); subRound( D, E, A, B, C, f2, K2, expand(sha->data, 22) ); subRound( C, D, E, A, B, f2, K2, expand(sha->data, 23) ); subRound( B, C, D, E, A, f2, K2, expand(sha->data, 24) ); subRound( A, B, C, D, E, f2, K2, expand(sha->data, 25) ); subRound( E, A, B, C, D, f2, K2, expand(sha->data, 26) ); subRound( D, E, A, B, C, f2, K2, expand(sha->data, 27) ); subRound( C, D, E, A, B, f2, K2, expand(sha->data, 28) ); subRound( B, C, D, E, A, f2, K2, expand(sha->data, 29) ); subRound( A, B, C, D, E, f2, K2, expand(sha->data, 30) ); subRound( E, A, B, C, D, f2, K2, expand(sha->data, 31) ); subRound( D, E, A, B, C, f2, K2, expand(sha->data, 32) ); subRound( C, D, E, A, B, f2, K2, expand(sha->data, 33) ); subRound( B, C, D, E, A, f2, K2, expand(sha->data, 34) ); subRound( A, B, C, D, E, f2, K2, expand(sha->data, 35) ); subRound( E, A, B, C, D, f2, K2, expand(sha->data, 36) ); subRound( D, E, A, B, C, f2, K2, expand(sha->data, 37) ); subRound( C, D, E, A, B, f2, K2, expand(sha->data, 38) ); subRound( B, C, D, E, A, f2, K2, expand(sha->data, 39) ); subRound( A, B, C, D, E, f3, K3, expand(sha->data, 40) ); subRound( E, A, B, C, D, f3, K3, expand(sha->data, 41) ); subRound( D, E, A, B, C, f3, K3, expand(sha->data, 42) ); subRound( C, D, E, A, B, f3, K3, expand(sha->data, 43) ); subRound( B, C, D, E, A, f3, K3, expand(sha->data, 44) ); subRound( A, B, C, D, E, f3, K3, expand(sha->data, 45) ); subRound( E, A, B, C, D, f3, K3, expand(sha->data, 46) ); subRound( D, E, A, B, C, f3, K3, expand(sha->data, 47) ); subRound( C, D, E, A, B, f3, K3, expand(sha->data, 48) ); subRound( B, C, D, E, A, f3, K3, expand(sha->data, 49) ); subRound( A, B, C, D, E, f3, K3, expand(sha->data, 50) ); subRound( E, A, B, C, D, f3, K3, expand(sha->data, 51) ); subRound( D, E, A, B, C, f3, K3, expand(sha->data, 52) ); subRound( C, D, E, A, B, f3, K3, expand(sha->data, 53) ); subRound( B, C, D, E, A, f3, K3, expand(sha->data, 54) ); subRound( A, B, C, D, E, f3, K3, expand(sha->data, 55) ); subRound( E, A, B, C, D, f3, K3, expand(sha->data, 56) ); subRound( D, E, A, B, C, f3, K3, expand(sha->data, 57) ); subRound( C, D, E, A, B, f3, K3, expand(sha->data, 58) ); subRound( B, C, D, E, A, f3, K3, expand(sha->data, 59) ); subRound( A, B, C, D, E, f4, K4, expand(sha->data, 60) ); subRound( E, A, B, C, D, f4, K4, expand(sha->data, 61) ); subRound( D, E, A, B, C, f4, K4, expand(sha->data, 62) ); subRound( C, D, E, A, B, f4, K4, expand(sha->data, 63) ); subRound( B, C, D, E, A, f4, K4, expand(sha->data, 64) ); subRound( A, B, C, D, E, f4, K4, expand(sha->data, 65) ); subRound( E, A, B, C, D, f4, K4, expand(sha->data, 66) ); subRound( D, E, A, B, C, f4, K4, expand(sha->data, 67) ); subRound( C, D, E, A, B, f4, K4, expand(sha->data, 68) ); subRound( B, C, D, E, A, f4, K4, expand(sha->data, 69) ); subRound( A, B, C, D, E, f4, K4, expand(sha->data, 70) ); subRound( E, A, B, C, D, f4, K4, expand(sha->data, 71) ); subRound( D, E, A, B, C, f4, K4, expand(sha->data, 72) ); subRound( C, D, E, A, B, f4, K4, expand(sha->data, 73) ); subRound( B, C, D, E, A, f4, K4, expand(sha->data, 74) ); subRound( A, B, C, D, E, f4, K4, expand(sha->data, 75) ); subRound( E, A, B, C, D, f4, K4, expand(sha->data, 76) ); subRound( D, E, A, B, C, f4, K4, expand(sha->data, 77) ); subRound( C, D, E, A, B, f4, K4, expand(sha->data, 78) ); subRound( B, C, D, E, A, f4, K4, expand(sha->data, 79) ); /* Build message digest */ sha->digest[0] += A; sha->digest[1] += B; sha->digest[2] += C; sha->digest[3] += D; sha->digest[4] += E;}#endif /* !ASM *//* * SHA is defined in big-endian form, so this converts the buffer from * bytes to words, independent of the machine's native endianness. * * Assuming a consistent byte ordering for the machine, this also * has the magic property of being self-inverse. It is used as * such. */static void byteReverse(word32 *buffer, unsigned byteCount){ word32 value; byteCount /= sizeof(word32); while ( byteCount-- ) { value = (word32)((unsigned)((word8 *)buffer)[0] << 8 | ((word8 *)buffer)[1]) << 16 | ((unsigned)((word8 *)buffer)[2] << 8 |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -