⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha.c

📁 SecuDe是一个由安全应用程序接口组成,对验证机制、证件处理、PEM、X.400报文处理和密钥管理提供支持。SecuDe提供DES、 RSA杂凑函数、密钥生成以及数字签名的生成和核实等多种密码机制。
💻 C
字号:
/* NIST proposed Secure Hash Standard.    Written 2 September 1992, Peter C. Gutmann.   This implementation placed in the public domain.    Modified 1 June 1993, Colin Plumb.   These modifications placed in the public domain.    Comments to pgut1@cs.aukuni.ac.nz */#include "sha.h" #include <string.h> /* The SHS 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 SHS Mysterious Constants */ #define K1      0x5A827999L     /* Rounds  0-19 */#define K2      0x6ED9EBA1L     /* Rounds 20-39 */#define K3      0x8F1BBCDCL     /* Rounds 40-59 */#define K4      0xCA62C1D6L     /* Rounds 60-79 */ /* SHS 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. */ #define expand(W,i) ( W[i & 15] ^= W[i-14 & 15] ^ W[i-8 & 15] ^ W[i-3 & 15] ) /* The prototype SHS 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 SHS values */ void shsInit(shsInfo)SHS_INFO *shsInfo;{        /* Set the h-vars to their initial values */        shsInfo->digest[ 0 ] = h0init;        shsInfo->digest[ 1 ] = h1init;        shsInfo->digest[ 2 ] = h2init;        shsInfo->digest[ 3 ] = h3init;        shsInfo->digest[ 4 ] = h4init;         /* Initialise bit count */#ifdef HAVE64        shsInfo->count = 0;#else        shsInfo->countLo = shsInfo->countHi = 0;#endif} /* Perform the SHS 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 shsInfo->data area */ void shsTransform(shsInfo)SHS_INFO *shsInfo;{        register WORD32 A, B, C, D, E;         /* Set up first buffer */        A = shsInfo->digest[ 0 ];        B = shsInfo->digest[ 1 ];        C = shsInfo->digest[ 2 ];        D = shsInfo->digest[ 3 ];        E = shsInfo->digest[ 4 ];         /* Heavy mangling, in 4 sub-rounds of 20 interations each. */        subRound( A, B, C, D, E, f1, K1, shsInfo->data[ 0] );        subRound( E, A, B, C, D, f1, K1, shsInfo->data[ 1] );        subRound( D, E, A, B, C, f1, K1, shsInfo->data[ 2] );        subRound( C, D, E, A, B, f1, K1, shsInfo->data[ 3] );        subRound( B, C, D, E, A, f1, K1, shsInfo->data[ 4] );        subRound( A, B, C, D, E, f1, K1, shsInfo->data[ 5] );        subRound( E, A, B, C, D, f1, K1, shsInfo->data[ 6] );        subRound( D, E, A, B, C, f1, K1, shsInfo->data[ 7] );        subRound( C, D, E, A, B, f1, K1, shsInfo->data[ 8] );        subRound( B, C, D, E, A, f1, K1, shsInfo->data[ 9] );        subRound( A, B, C, D, E, f1, K1, shsInfo->data[10] );        subRound( E, A, B, C, D, f1, K1, shsInfo->data[11] );        subRound( D, E, A, B, C, f1, K1, shsInfo->data[12] );        subRound( C, D, E, A, B, f1, K1, shsInfo->data[13] );        subRound( B, C, D, E, A, f1, K1, shsInfo->data[14] );        subRound( A, B, C, D, E, f1, K1, shsInfo->data[15] );        subRound( E, A, B, C, D, f1, K1, expand(shsInfo->data, 16) );        subRound( D, E, A, B, C, f1, K1, expand(shsInfo->data, 17) );        subRound( C, D, E, A, B, f1, K1, expand(shsInfo->data, 18) );        subRound( B, C, D, E, A, f1, K1, expand(shsInfo->data, 19) );         subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 20) );        subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 21) );        subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 22) );        subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 23) );        subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 24) );        subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 25) );        subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 26) );        subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 27) );        subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 28) );        subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 29) );        subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 30) );        subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 31) );        subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 32) );        subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 33) );        subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 34) );        subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 35) );        subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 36) );        subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 37) );        subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 38) );        subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 39) );         subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 40) );        subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 41) );        subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 42) );        subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 43) );        subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 44) );        subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 45) );        subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 46) );        subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 47) );        subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 48) );        subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 49) );        subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 50) );        subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 51) );        subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 52) );        subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 53) );        subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 54) );        subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 55) );        subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 56) );        subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 57) );        subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 58) );        subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 59) );         subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 60) );        subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 61) );        subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 62) );        subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 63) );        subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 64) );        subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 65) );        subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 66) );        subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 67) );        subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 68) );        subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 69) );        subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 70) );        subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 71) );        subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 72) );        subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 73) );        subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 74) );        subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 75) );        subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 76) );        subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 77) );        subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 78) );        subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 79) );         /* Build message digest */        shsInfo->digest[ 0 ] += A;        shsInfo->digest[ 1 ] += B;        shsInfo->digest[ 2 ] += C;        shsInfo->digest[ 3 ] += D;        shsInfo->digest[ 4 ] += E;} /* When run on a little-endian CPU we need to perform byte reversal on an   array of longwords.  It is possible to make the code endianness-   independant by fiddling around with data at the byte level, but this   makes for very slow code, so we rely on the user to sort out endianness   at compile time */ #ifdef LITTLE_ENDIAN static void byteReverse( buffer, byteCount )WORD32 *buffer;unsigned byteCount;{        WORD32 value;         byteCount /= sizeof(WORD32);        while ( byteCount-- ) {                value = *buffer;                value = ( value & 0xFF00FF00L ) >> 8  | \                        ( value & 0x00FF00FFL ) << 8;                *buffer++ = value << 16  |  value >> 16 ;        }} #else /* !LITTLE_ENDIAN */ #define byteReverse(buf, count)	/* nothing */ #endif /* !LITTLE_ENDIAN */ /* Update SHS for a block of data. */ void shsUpdate( shsInfo, buffer, count )SHS_INFO *shsInfo;BYTE *buffer;unsigned count;{        WORD32 t;         /* Update bitcount */ #ifdef HAVE64        t = ( (WORD32)shsInfo->count >> 3) & 0x3f;        shsInfo->count += (WORD64)count << 3;#else        t = shsInfo->countLo;        if ( ( shsInfo->countLo = t + ( (WORD32)count << 3) ) < t )                shsInfo->countHi++;     /* Carry from low to high */        shsInfo->countHi += count >> 29;         t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */#endif         /* Handle any leading odd-sized chunks */         if ( t ) {                BYTE *p = (BYTE *)shsInfo->data + t;                 t = 64-t;                if (count < t) {                        memcpy( p, buffer, count );                        return;                }                memcpy( p, buffer, t );                byteReverse( shsInfo->data, SHS_BLOCKSIZE );                shsTransform( shsInfo );                buffer += t;                count -= t;        }         /* Process data in SHS_BLOCKSIZE chunks */         while( count >= SHS_BLOCKSIZE ) {                memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );                byteReverse( shsInfo->data, SHS_BLOCKSIZE );                shsTransform( shsInfo );                buffer += SHS_BLOCKSIZE;                count -= SHS_BLOCKSIZE;        }         /* Handle any remaining bytes of data. */         memcpy( shsInfo->data, buffer, count );} /* Final wrapup - pad to 64-byte boundary with the bit pattern    1 0* (64-bit count of bits processed, MSB-first) */ void shsFinal( shsInfo )SHS_INFO *shsInfo;{        int count;        BYTE *p;         /* Compute number of bytes mod 64 */#ifdef HAVE64        count = (int)shsInfo->count;#else        count = (int)shsInfo->countLo;#endif        count = ( count >> 3 ) & 0x3F;         /* Set the first char of padding to 0x80.  This is safe since there is           always at least one byte free */        p = (BYTE *)shsInfo->data + count;        *p++ = 0x80;         /* Bytes of padding needed to make 64 bytes */        count = SHS_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( shsInfo->data, SHS_BLOCKSIZE );                shsTransform( shsInfo );                 /* Now fill the next block with 56 bytes */                memset( shsInfo->data, 0, SHS_BLOCKSIZE - 8 );        } else {                /* Pad block to 56 bytes */                memset( p, 0, count - 8 );        }        byteReverse( shsInfo->data, SHS_BLOCKSIZE-8 );         /* Append length in bits and transform */#if HAVE64        shsInfo->data[ 14 ] = (WORD32)( shsInfo->count >> 32 );        shsInfo->data[ 15 ] = (WORD32)shsInfo->count;#else        shsInfo->data[ 14 ] = shsInfo->countHi;        shsInfo->data[ 15 ] = shsInfo->countLo;#endif         shsTransform( shsInfo );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -