Ejemplo n.º 1
0
///
//Description:
//    calculate the full 512-bits block
//Parameters:
//Returns:
//    SHA-1 error code
///
int SHA1Context::calculateOneBlock(void)
{
    uint32_t      Temp;              //Temporary word value
    uint32_t      A, B, C, D, E;     //Word buffers
    uint32_t      W[80];             //Words that used in 80 loops

    //expand the block to 80 words
    for(int t = 0; t < 16; t++)
    {
        W[t] = block[t * 4] << 24;
        W[t] |= block[t * 4 + 1] << 16;
        W[t] |= block[t * 4 + 2] << 8;
        W[t] |= block[t * 4 + 3];
        //printf("%d:%d\n", t, W[t]);
    }
    for(int i = 16; i < 80; i++)	//calculate the next W[]
        W[i] = SHA1CircularShift(1, W[i-3]^W[i-8]^W[i-14]^W[i-16]);
    //init ABCDE
    A = H[0];
    B = H[1];
    C = H[2];
    D = H[3];
    E = H[4];
    //calculate the 80 words with last loop's return
    for(int t = 0; t < 80; t++)
    {
        Temp = SHA1CircularShift(5, A) + f[t/20](B, C, D) + E + W[t] + K[t/20];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = Temp;
    }
    //write the answer back
    H[0] += A;
    H[1] += B;
    H[2] += C;
    H[3] += D;
    H[4] += E;
    charsInCurrentBlock = 0;	//zero the variable charsInCurrentBlock when finished
    return shaSuccess;
}
Ejemplo n.º 2
0
void SHA1ProcessMessageBlock(SHA1Context *context) {
	const unsigned K[] = {0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
	int t;
	unsigned    temp, W[80], buf[5];
	unsigned &A=buf[0], &B=buf[1], &C=buf[2], &D=buf[3], &E=buf[4];

	for(t = 0; t < 16; t++)
		W[t] = (((unsigned) context->Message_Block[t * 4]) << 24) | (((unsigned) context->Message_Block[t * 4 + 1]) << 16) | (((unsigned) context->Message_Block[t * 4 + 2]) << 8) | ((unsigned) context->Message_Block[t * 4 + 3]);

	for(t = 16; t < 80; t++)
		W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);

	memcpy (buf, context->Message_Digest, sizeof(buf));
	for(t = 0; t < 20; t++) {
		temp =  (SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]) & 0xFFFFFFFF;
		E = D; D = C;
		C = SHA1CircularShift(30,B);
		B = A; A = temp;
	}

	for(t = 20; t < 40; t++) {
		temp = (SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]) & 0xFFFFFFFF;
		E = D; D = C;
		C = SHA1CircularShift(30,B);
		B = A; A = temp;
	}

	for(t = 40; t < 60; t++) {
		temp = (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]) & 0xFFFFFFFF;
		E = D; D = C;
		C = SHA1CircularShift(30,B);
		B = A; A = temp;
	}

	for(t = 60; t < 80; t++) {
		temp = (SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]) & 0xFFFFFFFF;
		E = D; D = C;
		C = SHA1CircularShift(30,B);
		B = A; A = temp;
	}

	for (t = 0; t < 5; t++)
		context->Message_Digest[t] = (context->Message_Digest[t] + buf[t]) & 0xFFFFFFFF;

	context->Message_Block_Index = 0;
}
Ejemplo n.º 3
0
static void SHA1ProcessMessageBlock(SHA1Context *context)
{
   const unsigned K[] =            /* Constants defined in SHA-1   */      
   {
      0x5A827999,
      0x6ED9EBA1,
      0x8F1BBCDC,
      0xCA62C1D6
   };
   int         t;                  /* Loop counter                 */
   unsigned    temp;               /* Temporary word value         */
   unsigned    W[80];              /* Word sequence                */
   unsigned    A, B, C, D, E;      /* Word buffers                 */

   /* Initialize the first 16 words in the array W */
   for(t = 0; t < 16; t++)
   {
      W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
      W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
      W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
      W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
   }

   for(t = 16; t < 80; t++)
      W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);

   A = context->Message_Digest[0];
   B = context->Message_Digest[1];
   C = context->Message_Digest[2];
   D = context->Message_Digest[3];
   E = context->Message_Digest[4];

   for(t = 0; t < 20; t++)
   {
      temp  =  SHA1CircularShift(5,A) +
         ((B & C) | ((~B) & D)) + E + W[t] + K[0];
      temp &= 0xFFFFFFFF;
      E     = D;
      D     = C;
      C     = SHA1CircularShift(30,B);
      B     = A;
      A     = temp;
   }

   for(t = 20; t < 40; t++)
   {
      temp  = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
      temp &= 0xFFFFFFFF;
      E     = D;
      D     = C;
      C     = SHA1CircularShift(30,B);
      B     = A;
      A     = temp;
   }

   for(t = 40; t < 60; t++)
   {
      temp  = SHA1CircularShift(5,A) +
         ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
      temp &= 0xFFFFFFFF;
      E     = D;
      D     = C;
      C     = SHA1CircularShift(30,B);
      B     = A;
      A     = temp;
   }

   for(t = 60; t < 80; t++)
   {
      temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
      temp &= 0xFFFFFFFF;
      E = D;
      D = C;
      C = SHA1CircularShift(30,B);
      B = A;
      A = temp;
   }

   context->Message_Digest[0] =
      (context->Message_Digest[0] + A) & 0xFFFFFFFF;
   context->Message_Digest[1] =
      (context->Message_Digest[1] + B) & 0xFFFFFFFF;
   context->Message_Digest[2] =
      (context->Message_Digest[2] + C) & 0xFFFFFFFF;
   context->Message_Digest[3] =
      (context->Message_Digest[3] + D) & 0xFFFFFFFF;
   context->Message_Digest[4] =
      (context->Message_Digest[4] + E) & 0xFFFFFFFF;

   context->Message_Block_Index = 0;
}
Ejemplo n.º 4
0
void SHA1ProcessMessageBlock(SHA1Context *context)
{
    UCHAR      t;                 /* Loop counter                */
    ULONG      temp;              /* Temporary word value        */
    ULONG      W[80];             /* Word sequence               */
    ULONG      A, B, C, D, E;     /* Word buffers                */

    /*
     *  Initialize the first 16 words in the array W
     */
    for(t = 0; t < 16; t++)
    {
/*        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
*/		W[t] = PCHAR2ULONG(context->Message_Block + t*4);
    }

    for(t = 16; t < 80; t++)
    {
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }

    A = context->Intermediate_Hash[0];
    B = context->Intermediate_Hash[1];
    C = context->Intermediate_Hash[2];
    D = context->Intermediate_Hash[3];
    E = context->Intermediate_Hash[4];

    for(t = 0; t < 20; t++)
    {
        temp =  SHA1CircularShift(5,A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);

        B = A;
        A = temp;
    }

    for(t = 20; t < 40; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 40; t < 60; t++)
    {
        temp = SHA1CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 60; t < 80; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    context->Intermediate_Hash[0] += A;
    context->Intermediate_Hash[1] += B;
    context->Intermediate_Hash[2] += C;
    context->Intermediate_Hash[3] += D;
    context->Intermediate_Hash[4] += E;

    context->Message_Block_Index = 0;
}
Ejemplo n.º 5
0
/*
 *  SHA1ProcessMessageBlock
 *
 *  Description:
 *      This function will process the next 512 bits of the message
 *      stored in the Message_Block array.
 *
 *  Parameters:
 *      None.
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:

 *      Many of the variable names in this code, especially the
 *      single character names, were used because those were the
 *      names used in the publication.
 *
 *
 */
void SHA1ProcessMessageBlock(SHA1Context *context)
{
    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
                            0x5A827999,
                            0x6ED9EBA1,
                            0x8F1BBCDC,
                            0xCA62C1D6
                            };
    int           t;                 /* Loop counter                */
    uint32_t      temp;              /* Temporary word value        */
    uint32_t      W[80];             /* Word sequence               */
    uint32_t      A, B, C, D, E;     /* Word buffers                */

    /*
     *  Initialize the first 16 words in the array W
     */
    for(t = 0; t < 16; t++)
    {
        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
    }

    for(t = 16; t < 80; t++)
    {
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }

    A = context->Intermediate_Hash[0];
    B = context->Intermediate_Hash[1];
    C = context->Intermediate_Hash[2];
    D = context->Intermediate_Hash[3];
    E = context->Intermediate_Hash[4];

    for(t = 0; t < 20; t++)
    {
        temp =  SHA1CircularShift(5,A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);

        B = A;
        A = temp;
    }

    for(t = 20; t < 40; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 40; t < 60; t++)
    {
        temp = SHA1CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 60; t < 80; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    context->Intermediate_Hash[0] += A;
    context->Intermediate_Hash[1] += B;
    context->Intermediate_Hash[2] += C;
    context->Intermediate_Hash[3] += D;
    context->Intermediate_Hash[4] += E;

    context->Message_Block_Index = 0;
}
Ejemplo n.º 6
0
void SHA1ProcessMessageBlock(SHA1Context *context)
{
	const unsigned K[] = {0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
	int         t;               
	unsigned    temp;            
	unsigned    W[80];           
	unsigned    A, B, C, D, E;   

	for(t = 0; t < 16; t++)
	{
		W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
		W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
		W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
		W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
	}

	for(t = 16; t < 80; t++)
	{
		W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
	}

	A = context->Message_Digest[0];
	B = context->Message_Digest[1];
	C = context->Message_Digest[2];
	D = context->Message_Digest[3];
	E = context->Message_Digest[4];

	for(t = 0; t < 20; t++)
	{
		temp =  SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
		temp &= 0xFFFFFFFF;
		E = D;
		D = C;
		C = SHA1CircularShift(30,B);
		B = A;
		A = temp;
	}

	for(t = 20; t < 40; t++)
	{
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
		temp &= 0xFFFFFFFF;
		E = D;
		D = C;
		C = SHA1CircularShift(30,B);
		B = A;
		A = temp;
	}

	for(t = 40; t < 60; t++)
	{
		temp = SHA1CircularShift(5,A) +
			((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
		temp &= 0xFFFFFFFF;
		E = D;
		D = C;
		C = SHA1CircularShift(30,B);
		B = A;
		A = temp;
	}

	for(t = 60; t < 80; t++)
	{
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
		temp &= 0xFFFFFFFF;
		E = D;
		D = C;
		C = SHA1CircularShift(30,B);
		B = A;
		A = temp;
	}

	context->Message_Digest[0] = (context->Message_Digest[0] + A) & 0xFFFFFFFF;
	context->Message_Digest[1] = (context->Message_Digest[1] + B) & 0xFFFFFFFF;
	context->Message_Digest[2] = (context->Message_Digest[2] + C) & 0xFFFFFFFF;
	context->Message_Digest[3] = (context->Message_Digest[3] + D) & 0xFFFFFFFF;
	context->Message_Digest[4] = (context->Message_Digest[4] + E) & 0xFFFFFFFF;

	context->Message_Block_Index = 0;
}
Ejemplo n.º 7
0
void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest)
{
	if (length > 16)
		return;

    UINT4 Message_Block_Index    = 0;

	union
	{
		unsigned char Message_Block[64];
		UINT4 Message_Block_W[16];
	};

	Message_Block_W[0] = 0x00000000;
	Message_Block_W[1] = 0x00000000;
	Message_Block_W[2] = 0x00000000;
	Message_Block_W[3] = 0x00000000;
	Message_Block_W[4] = 0x00000000;

	UINT4 Intermediate_Hash[5] = { H0, H1, H2, H3, H4 };
	
 	memcpy(Message_Block, pData, length);
	Message_Block_Index += length;

	//padMessage
	Message_Block[length] = 0x80;
	
	UINT4 W_15 = length << 3;
	
    int           t;                 /* Loop counter                */
    UINT4      temp;              /* Temporary word value        */
    UINT4      W[80];             /* Word sequence               */
    UINT4      A, B, C, D, E;     /* Word buffers                */

    /*
     *  Initialize the first 16 words in the array W
     */

	#define INIT_OLD(x) \
        W[x] = (Message_Block[(x) * 4] << 24) | \
        	(Message_Block[(x) * 4 + 1] << 16) | \
        	(Message_Block[(x) * 4 +2] << 8) | \
        	(Message_Block[(x) * 4 +3])

	#define INIT(x) W[x] = Message_Block_W[x];
	
	#define INIT_NULL(x) W[x] = 0;

	
	Endian_Reverse32(Message_Block_W[0]);
	INIT(0);

	#define INIT_NULL_1_14 \
		INIT_NULL(1);  INIT_NULL_2_14;

	#define INIT_NULL_2_14 \
		INIT_NULL(2);  INIT_NULL_3_14;

	#define INIT_NULL_3_14 \
		INIT_NULL(3);  INIT_NULL_4_14;

	#define INIT_NULL_4_14 \
		INIT_NULL(4); INIT_NULL_5_14;

	#define INIT_NULL_5_14 \
		INIT_NULL(5);  INIT_NULL(6);  INIT_NULL(7); \
		INIT_NULL(8);  INIT_NULL(9);  INIT_NULL(10); INIT_NULL(11); \
		INIT_NULL(12); INIT_NULL(13); INIT_NULL(14);

	#define ROTATE1_NULL_1_14 \
		ROTATE1_NULL;  ROTATE1_NULL_2_14;

	#define ROTATE1_NULL_2_14 \
		ROTATE1_NULL;  ROTATE1_NULL_3_14;

	#define ROTATE1_NULL_3_14 \
		ROTATE1_NULL;  ROTATE1_NULL_4_14;

	#define ROTATE1_NULL_4_14 \
		ROTATE1_NULL; ROTATE1_NULL_5_14;

	#define ROTATE1_NULL_5_14 \
		ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \
		ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \
		ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL;


	#define EXPAND(t) \
		W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); \

	#define EXPAND_3(t) W[t] = SHA1CircularShift(1,W[t-3]);
	#define EXPAND_16(t) W[t] = SHA1CircularShift(1,W[t-16]);
	#define EXPAND_3_8(t) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8]);


	if (length < 4) {
		INIT_NULL_1_14;
		W[15] = W_15;
		EXPAND_16(16);
		W[17] = 0;
		W[18] = W_15<<1;
	}
	else if (length < 8) {
		Endian_Reverse32(Message_Block_W[1]);
		INIT(1);
		INIT_NULL_2_14;
		W[15] = W_15;
		EXPAND_16(16);
		EXPAND_16(17);
		W[18] = W_15<<1;
	}
	else {
		Endian_Reverse32(Message_Block_W[1]);
		Endian_Reverse32(Message_Block_W[2]);
		Endian_Reverse32(Message_Block_W[3]);
		Endian_Reverse32(Message_Block_W[4]);
		INIT(1); INIT(2); INIT(3); INIT(4); 
		INIT_NULL_5_14;
		W[15] = W_15;
		EXPAND(16);
		EXPAND(17);
		EXPAND(18);
	}


	if (length < 12) {
		EXPAND_3(19);
	}
	else {
		EXPAND(19);
	}

	if (length < 16) {
		EXPAND_3(20);
	}
	else {
		EXPAND(20);
	}
	EXPAND_3(21); EXPAND_3(22);
	EXPAND(23);

	EXPAND(24); EXPAND(25); EXPAND_3_8(26);	EXPAND_3_8(27);
	EXPAND(28);	EXPAND(29);	EXPAND(30);	EXPAND(31);
	EXPAND(32);	EXPAND(33);	EXPAND(34);	EXPAND(35);
	EXPAND(36);	EXPAND(37);	EXPAND(38);	EXPAND(39);
	EXPAND(40);	EXPAND(41);	EXPAND(42);	EXPAND(43);
	EXPAND(44);	EXPAND(45);	EXPAND(46);	EXPAND(47);
	EXPAND(48);	EXPAND(49);	EXPAND(50);	EXPAND(51);
	EXPAND(52);	EXPAND(53);	EXPAND(54);	EXPAND(55);
	EXPAND(56);	EXPAND(57);	EXPAND(58);	EXPAND(59);
	EXPAND(60);	EXPAND(61);	EXPAND(62);	EXPAND(63);
	EXPAND(64);	EXPAND(65);	EXPAND(66);	EXPAND(67);
	EXPAND(68);	EXPAND(69);	EXPAND(70);	EXPAND(71);
	EXPAND(72);	EXPAND(73);	EXPAND(74);	EXPAND(75);
	EXPAND(76);	EXPAND(77);	EXPAND(78);	EXPAND(79);


	#define ROTATE1(t) \
			temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + W[t] + K0; \
			E = D; D = C; \
			C = SHA1CircularShift(30,B); \
			B = A; A = temp; \

	#define ROTATE1_NEW(a, b, c, d, e, x) \
			e += SHA1CircularShift(5,a) + F_00_19(b,c,d) + x + K0; \
			b = SHA1CircularShift(30,b);

	#define ROTATE1_W(w) \
			temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + w + K0; \
			E = D; D = C; \
			C = SHA1CircularShift(30,B); \
			B = A; A = temp;

	#define ROTATE1_NULL \
			temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + K0; \
			E = D; D = C; \
			C = SHA1CircularShift(30,B); \
			B = A; A = temp; \
			
	#define ROTATE2_NEW(a, b, c, d, e, x) \
			e += SHA1CircularShift(5,a) + F_20_39(b,c,d) + x + K1; \
			b = SHA1CircularShift(30,b);
	
	#define ROTATE2(t) \
		temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + W[t] + K1; \
        E = D; D = C; \
        C = SHA1CircularShift(30,B); \
        B = A; A = temp;

	#define ROTATE2_W(w) \
		temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + w + K1; \
        E = D; D = C; \
        C = SHA1CircularShift(30,B); \
        B = A; A = temp;

	#define ROTATE3(t) \
		temp = SHA1CircularShift(5,A) + F_40_59(B,C,D) + E + W[t] + K2; \
        E = D; D = C; \
        C = SHA1CircularShift(30,B); \
        B = A; A = temp;

	#define ROTATE4(t) \
		temp = SHA1CircularShift(5,A) + F_60_79(B,C,D) + E + W[t] + K3; \
		E = D; D = C; \
		C = SHA1CircularShift(30,B); \
		B = A; A = temp;

	A = H0;
    B = H1;
    C = H2;
    D = H3;
    E = H4;

	
	E = H2;
	//D = 2079550178;
	//C = 1506887872;
	B = 2679412915 + W[0];
	if (length < 4) {
		A = SHA1CircularShift(5,B) + 1722862861;
	}
	else {
		A = SHA1CircularShift(5,B) + 1722862861 + W[1];
	}

	if (length < 8) {
		temp = SHA1CircularShift(5,A) + ((((1506887872) ^ (2079550178)) & (B)) ^ (2079550178)) + H2 + K0;
	}
	else {
		temp = SHA1CircularShift(5,A) + (((572662306) & (B)) ^ (2079550178)) + H2 + K0 + W[2];
	}
	C = SHA1CircularShift(30,B);  //SHA1CircularShift(30,(2679412915 + W[0]));
	B = A;
	A = temp;
	
	if (length < 12) {
		temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0;
	}
	else {
		temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0 + W[3];
	}
	E = 1506887872;
	D = C;
	C = SHA1CircularShift(30,B);
	B = A;
	A = temp;

	if (length < 16) {
		temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0;
	}
	else {
		temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0 + W[4];
	}
	E = D;
	D = C;
	C = SHA1CircularShift(30,B);
	B = A;
	A = temp;

	ROTATE1_NULL_5_14;

	ROTATE1_NEW( A, B, C, D, E, W_15 );
    ROTATE1_NEW( E, A, B, C, D, W[16] );
    ROTATE1_NEW( D, E, A, B, C, W[17] );
    ROTATE1_NEW( C, D, E, A, B, W[18] );
    ROTATE1_NEW( B, C, D, E, A, W[19] );
	
    for(t = 20; t < 40; t++)
    {
		if (t == 21 && length < 8) {
			ROTATE2_W((length<<5)); // *32
		}
		else {
			ROTATE2(t);
		}
    }

    for(t = 40; t < 60; t++)
    {
  		ROTATE3(t);
    }

    for(t = 60; t < 80; t++)
    {
		ROTATE4(t);
    }

    Intermediate_Hash[0] += A;
    Intermediate_Hash[1] += B;
    Intermediate_Hash[2] += C;
    Intermediate_Hash[3] += D;
    Intermediate_Hash[4] += E;

	Endian_Reverse32(Intermediate_Hash[0]);
	Endian_Reverse32(Intermediate_Hash[1]);
	Endian_Reverse32(Intermediate_Hash[2]);
	Endian_Reverse32(Intermediate_Hash[3]);
	Endian_Reverse32(Intermediate_Hash[4]);

	memcpy(pDigest, Intermediate_Hash, 20);
}