📄 ssha.cpp
字号:
// ssha.cc// Scott McPeak's transmogrify of: // sha.cpp - modified by Wei Dai from Peter Gutmann's code // Copyright 1992 by Peter Gutmann. Distributed with permission. (dummy Terms of use; it's not our code)//#include "pch.h"#include "ssha.h"#ifdef __BORLANDC__ #pragma warn -aus // "'ident' is assigned a value that is never used"#endif// ------------- iterhash.cc derivatives ------------------// iterhash.cpp - written and placed in the public domain by Wei DaiIteratedHash32::IteratedHash32(unsigned int blockSize, unsigned int digestSize) : blockSize(blockSize), data(blockSize/sizeof(word32)), digest(digestSize/sizeof(word32)){}IteratedHash32::~IteratedHash32(){}void IteratedHash32::Update(const byte *input, unsigned int len){ word32 tmp = countLo; if ((countLo = tmp + ((word32)len << 3)) < tmp) countHi++; // Carry from low to high countHi += len >> 29; assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2 unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1); if (num != 0) { if ((num+len) >= blockSize) { memcpy((byte *)data.ptr+num, input, blockSize-num); HashBlock(data); input += (blockSize-num); len-=(blockSize - num); num=0; // drop through and do the rest } else { memcpy((byte *)data.ptr+num, input, len); return; } } // we now can process the input data in blocks of blockSize // chars and save the leftovers to this->data. if (len >= blockSize) { if ((unsigned int)input % sizeof(word32)) // test for alignment do { // copy input first if it's not aligned correctly memcpy(data, input, blockSize); HashBlock(data); input+=blockSize; len-=blockSize; } while (len >= blockSize); else do { HashBlock((word32 *)input); input+=blockSize; len-=blockSize; } while (len >= blockSize); } memcpy(data, input, len);}void IteratedHash32::PadLastBlock(unsigned int lastBlockSize, byte padFirst){ unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1); assert(num < blockSize); ((byte *)data.ptr)[num++]=padFirst; if (num <= lastBlockSize) memset((byte *)data.ptr+num, 0, lastBlockSize-num); else { memset((byte *)data.ptr+num, 0, blockSize-num); HashBlock(data); memset(data, 0, lastBlockSize); }}// provide empty definitions to avoid instantiation warningsvoid IteratedHash32::Init() {}void IteratedHash32::HashBlock(const word32 * /*input*/) {}// ------------- end of iterhash.cc derivatives ------------------// -------------------- generic hash --------------------------// transplanted from cryputil.cppDataBlock hashDataBlock(DataBlock const &data, HashModule &hash){ // prepare a buffer; query 'hash' to get digest size DataBlock ret(hash.DigestSize()); // compute the digest hash.CalculateDigest(ret.getData(), data.getDataC(), data.getDataLen()); ret.setDataLen(hash.DigestSize()); // return the digest return ret;}DataBlock Sha1(DataBlock const &data){ SHA sha; return hashDataBlock(data, sha);}SHA::SHA() : IteratedHash32(DATASIZE, DIGESTSIZE){ Init();}void SHA::Init(){ countLo = countHi = 0; digest.getElt(0) = 0x67452301L; digest.getElt(1) = 0xEFCDAB89L; digest.getElt(2) = 0x98BADCFEL; digest.getElt(3) = 0x10325476L; digest.getElt(4) = 0xC3D2E1F0L;}void SHA::HashBlock(const word32 *input){#ifdef SAFETP_BIG_ENDIAN Transform(digest, input);#else byteReverse(data.ptr, input, (unsigned int)DATASIZE); Transform(digest, data);#endif}void SHA::Final(byte *hash){ PadLastBlock(56); CorrectEndianess(data, data, 56); data.getElt(14) = countHi; data.getElt(15) = countLo; Transform(digest, data); CorrectEndianess(digest, digest, DIGESTSIZE); memcpy(hash, digest, DIGESTSIZE); Init(); // reinit for next use}/* The SHA f()-functions. The f1 and f3 functions can be optimized to save one bool 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 */#define K1 0x5A827999L /* Rounds 0-19 */#define K2 0x6ED9EBA1L /* Rounds 20-39 */#define K3 0x8F1BBCDCL /* Rounds 40-59 */#define K4 0xCA62C1D6L /* Rounds 60-79 *//* Note that it may be necessary to add parentheses to these macros if they are to be called with expressions as arguments *//* 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 - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this optimization. The updated SHA changes the expanding function by adding a rotate of 1 bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor for this information */#ifdef NEW_SHA #define expand(W,i) ( W[ i & 15 ] = rotl( (W[i&15] ^ W[i-14&15] ^ \ W[i-8&15] ^ W[i-3&15]), 1U) )#else #define expand(W,i) ( W[ i & 15 ] ^= W[ i - 14 & 15 ] ^ W[ i - 8 & 15 ] ^ W[ i - 3 & 15 ] )#endif /* NEW_SHA *//* 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. This code is then replicated 20 times for each of the 4 functions, using the next 20 values from the W[] array each time */#define subRound(a, b, c, d, e, f, k, data) \ ( e += rotl(a,5U) + f(b,c,d) + k + data, b = rotl(b,30U))/* 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 */void SHA::Transform( word32 *digest, const word32 *data ){ word32 eData[16]; memcpy( eData, data, DATASIZE ); register word32 A, B, C, D, E; A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; // Heavy mangling, in 4 sub-rounds of 20 interations each. subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); digest[0] += A; digest[1] += B; digest[2] += C; digest[3] += D; digest[4] += E; memset(eData, 0, DATASIZE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -