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

📄 sha256.cpp

📁 加密解密,安全工具!很有意思的代码
💻 CPP
字号:
/******************************************************************* * *	Copyright (c) 1994-2005 Jetico, Inc., Finland *	All rights reserved. * *	File: sha256.cpp *	Revision:  *	Created: *	Description: implementation of SHA-256 (SHA-2) Secure Hash Algorithm * *******************************************************************///#include "stdafx.h"//#include <windows.h>#include <stddef.h>#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <bc_types.h>#include "sha256.h"/* Initial hash values */#define A_init 0x6a09e667	#define B_init 0xbb67ae85	#define C_init 0x3c6ef372	#define D_init 0xa54ff53a	#define E_init 0x510e527f	#define F_init 0x9b05688c	#define G_init 0x1f83d9ab	#define H_init 0x5be0cd19	static const DWORD CONST_K[64] = {	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};/* SHA-256's set of functions * * * According to SHA-2 specification: * * Ch(x,y,z)  = (x & y) ^ ((~x) & z) * Maj(x,y,z) = (x & y) ^ (x & z) ^ (y & z) * * SHA-2 specification states: "Each of the algorithm include Ch and Maj * functions; the Exclusive-OR operation (^) in these functions may be replaced  * by a bitwise OR operation (|) and produce identical results". Hence * * Ch(x,y,z)  = (x & y) | ((~x) & z) * Maj(x,y,z) = (x & y) | (x & z) ^ (y & z) * * * According to Rich Schroeppel:  *    (X & Y) | (~X & Z) == Z ^ (X & (Y ^ Z)) // the last does not require ~ operation * And obvious enough: *    (X & Y) | (X & Z) | (Y & Z) == (X & (Y | Z)) | (Y & Z) */#define Ch(X,Y,Z)  ((Z) ^ ((X) & ((Y) ^ (Z))))#define Maj(X,Y,Z) (((X) & ((Y) | (Z))) | ((Y) & (Z)))/*  * Shift and Rotate and Rotate right  */#define SHR(number_bits, variable) ((variable) >> (number_bits))#define ROTR(number_bits,variable) (((variable) >> (number_bits)) | ((variable) << (32 - (number_bits))))/* * SHA-256 SUM functions */#define SUM_0_256(x)  (ROTR(2,  (x)) ^ ROTR(13, (x)) ^ ROTR(22, (x)))#define SUM_1_256(x)  (ROTR(6,  (x)) ^ ROTR(11, (x)) ^ ROTR(25, (x)))#define sum_0_256(x)  (ROTR(7,  (x)) ^ ROTR(18, (x)) ^ SHR(3 ,  (x)))#define sum_1_256(x)  (ROTR(17, (x)) ^ ROTR(19, (x)) ^ SHR(10,  (x)))static void SHA256_UpdateDigest( DWORD *Digest, DWORD *MessageBlock ) {	DWORD  a, b, c, d, e, f, g, h, tmp0, tmp1, sum0, sum1;	DWORD T1, T2, *W;	int   i;	a = Digest[0];	b = Digest[1];	c = Digest[2];	d = Digest[3];	e = Digest[4];	f = Digest[5];	g = Digest[6];	h = Digest[7];	W = MessageBlock;	for (i=0; i<16; i++)	{		W[i] = *MessageBlock++;		T1 = h + SUM_1_256(e) + Ch(e, f, g) + CONST_K[i] + W[i];				T2 = SUM_0_256(a) + Maj(a, b, c);		h = g;		g = f;		f = e;		e = d + T1;		d = c;		c = b;		b = a;		a = T1 + T2;	}	// i starts from 17 == 10001	for ( ; i<64; i++ )	{		tmp0 = W[ (i+1) & 0x0f ];  // W[i-15]		sum0 = sum_0_256( tmp0 );		tmp1 = W[ (i+14) & 0x0f ]; // W[i-2]		sum1 = sum_1_256(tmp1);		W[ i & 0x0f ] += sum1 + W[ (i+9) & 0x0f ] + sum0; // W[ (i+9) & 0x0f ] is the same as W[ t - 7 ] in SHA-256 specification		T1 = h + SUM_1_256(e) + Ch(e, f, g) + CONST_K[i] + W[ i & 0x0f ];		// T2 and further calculation is the same as in the loop 0 < i < 16		T2 = SUM_0_256(a) + Maj(a, b, c);		h = g;		g = f;		f = e;		e = d + T1;		d = c;		c = b;		b = a;		a = T1 + T2;	}	/* Calculate new Message Digest */	Digest[0] = (Digest[0] + a) & 0xffffffff;	Digest[1] = (Digest[1] + b) & 0xffffffff;	Digest[2] = (Digest[2] + c) & 0xffffffff;	Digest[3] = (Digest[3] + d) & 0xffffffff;	Digest[4] = (Digest[4] + e) & 0xffffffff;	Digest[5] = (Digest[5] + f) & 0xffffffff;	Digest[6] = (Digest[6] + g) & 0xffffffff;	Digest[7] = (Digest[7] + h) & 0xffffffff;}/************************************************************************ * * Two useful functions:  * ReverseDWORDs         - worries about Big and Little Endians * copyDigestToByteArray - may be, we want to copy digest from Context to  *                         independent byte array *************************************************************************/static void copyDigestToByteArray(DWORD *dwInp, byte *bOut ){   int i, j;  for(i = 0, j = 0; j < 32; i++, j += 4) /* 32 - is the SHA-256 Digest length in bytes */   { bOut[j+3] = (byte)( dwInp[i]        & 0xff);     bOut[j+2] = (byte)((dwInp[i] >> 8)  & 0xff);     bOut[j+1] = (byte)((dwInp[i] >> 16) & 0xff);     bOut[j]   = (byte)((dwInp[i] >> 24) & 0xff);   }}/* The function automatically defines if we are Big or Little Endian */static void ReverseDWORDs( DWORD *Data, int Number_of_DWORDs ){ int i;  DWORD dwTmp;  if((*(DWORD *)("ABCD") >> 24) == 'A') return; // Nothing to do  for(i=0; i<Number_of_DWORDs; i++)  { dwTmp = (Data[i] << 16) | (Data[i] >> 16);    Data[i] = ((dwTmp & 0xFF00FF00L) >> 8) | ((dwTmp & 0x00FF00FFL) << 8);  }}/************************************************************************* *  * SHA256_Init() initializes a context of the message digest calculations. * The memory to store the context is reserved before and the pointer  * on the context's memory stored in FSHashAlgorithm element  * *************************************************************************/int SHA256_Init(void   *context){  SHA256Context *sha_ctx = (SHA256Context *)context;    sha_ctx->digest[0] = A_init;  sha_ctx->digest[1] = B_init;  sha_ctx->digest[2] = C_init;  sha_ctx->digest[3] = D_init;  sha_ctx->digest[4] = E_init;  sha_ctx->digest[5] = F_init;  sha_ctx->digest[6] = G_init;  sha_ctx->digest[7] = H_init;  /* Initialise bit count */  sha_ctx->countLo = sha_ctx->countHi = 0;  memset( sha_ctx->data, 0, 64 );  return SHA256_ERROR_NO;}/************************************************************************* *  * SHA256_Process() is called multiple times (if needed) until our message  * buffer is not empty * *************************************************************************/int SHA256_Process(void   *context,                    byte    *data,                    size_t  length){  DWORD         dwTmp, dataCount, len;  byte          *bPtr, *msgPtr;  SHA256Context *sha_ctx = (SHA256Context *)context;  /* Update byte count */  /* Check if the overflow occured in the countLo */  dwTmp = sha_ctx->countLo;  if ((sha_ctx->countLo = dwTmp + length) < dwTmp)     (sha_ctx->countHi)++;  /* If the previous Message was not multiply of 64 bytes,   * we store remain of the previous Message in SHA_CTX->data[] array.   * Calculate, how many bytes we currently store in SHA_CTX->data[]   */    /* calculate in dataCount number of BUSY bytes in sha_ctx->data buffer */  dataCount = dwTmp & 0x3F;   msgPtr = data;  len = length;  if (dataCount)  {      bPtr = (byte *)sha_ctx->data + dataCount;     /* calculate in dataCount number of FREE bytes in sha_ctx->data buffer */     dataCount = 64 - dataCount;   /* 64 bytes == 512 bites == SHA-256 block size */     if ( length < dataCount )     {         memcpy( bPtr, data, length );        return SHA256_ERROR_NO;     }     	 /* in dataCount - number of free bytes in sha_ctx->data buffer */     memcpy( bPtr, data, dataCount );     ReverseDWORDs( sha_ctx->data, 16 );	 SHA256_UpdateDigest( sha_ctx->digest, sha_ctx->data );     msgPtr += dataCount;     len    -= dataCount;  }  /* Process data in 64-bytes (512 bites) blocks */  while( len >= 64 )   { memcpy( sha_ctx->data, msgPtr, 64 );     ReverseDWORDs( sha_ctx->data, 16 );     SHA256_UpdateDigest( sha_ctx->digest, sha_ctx->data );     msgPtr += 64;     len -= 64;   }  /* Save remaining bytes of Message. */  if (len > 0) memcpy( sha_ctx->data, msgPtr, len );  return SHA256_ERROR_NO;}/*************************************************************************** * * SHA256_Final(): All message buffer is transformed using SHA256_Process(). * To get the final Message Digest, we have to call SHA256_Final() * ***************************************************************************/int SHA256_Final(void *context, byte *digest) /* 'digest' array must be >= 32 bytes */{  DWORD         count;  byte          *dataPtr;  SHA256Context *sha_ctx = (SHA256Context *)context;  /* Calculate number of BUSY bytes in sha_ctx->data buffer */  count = sha_ctx->countLo & 0x3F;  /* Set the first char of padding to 0x80.  This is safe since there is always at least one byte free */  dataPtr = (byte *)sha_ctx->data + count;  *dataPtr++ = 0x80;  /* Calculate number of FREE bytes in sha_ctx->data buffer */  count = 63 - count; /* sha_ctx->data is 64 bytes, but we already used one byte for 0x80 */  /*   If count is more than 8, it means that we have the place for    * 2 DWORDS to place the length of message.    *    If no, we have to pad the current 64-byte block by 0, re-calculate    * digest, then fill the first 56 bytes in sha_ctx->data by 0, place    * the length of Message to the last 8 bytes and calculate final Digest   */  if( count < 8 )  {      memset( dataPtr, 0, count );     ReverseDWORDs( sha_ctx->data, 16 );     SHA256_UpdateDigest( sha_ctx->digest, sha_ctx->data );	 /* prepare to calculate final digest, where the length will be written in last 8 bytes */     memset( sha_ctx->data, 0, 56 );   }  else if (count > 8)	  memset(dataPtr, 0, count - 8);  // size of digest is in bits, hence, we should multiply count by 8 or shift left on 3  sha_ctx->data[14] = (((sha_ctx->countHi) << 3) & 0xffffffff) | (((sha_ctx->countLo) >> 29) & 0x7);  sha_ctx->data[15] =  ((sha_ctx->countLo) << 3) & 0xffffffff;  ReverseDWORDs( sha_ctx->data, 14 ); // Do not reverse last 8 bytes (or 2 DWORDs)  SHA256_UpdateDigest( sha_ctx->digest, sha_ctx->data );  copyDigestToByteArray( sha_ctx->digest, digest );   return SHA256_ERROR_NO;}/************************************************************************* * *   SHA256_Update() - call the function if (and only if) the size of byte  *  array "data" is equal to the block size of SHA-256 algorithm, i.e.  *  512 bits == 64 bytes * *************************************************************************/int SHA256_Update(void *context, byte *data){   SHA256Context *sha_ctx;  sha_ctx = (SHA256Context *)context;   /* 16 * sizeof(DWORD) == 64 bytes */  memcpy( sha_ctx->data, data, 16 );     ReverseDWORDs( sha_ctx->data, 16 );  SHA256_UpdateDigest( sha_ctx->digest, sha_ctx->data );  return SHA256_ERROR_NO;}/*************************************************************************** * *   SHA256_Allocate() - allocates memory needed for SHA256Context structure * ***************************************************************************/int SHA256_Allocate(void **context){  *context = malloc(sizeof(SHA256Context));    if (*context)   { 	  return SHA256_ERROR_NO;  }  return SHA256_ERROR_INTERNAL_ERROR;}/********************************************************************** *  * SHA256_Free() - Frees resources allocated in SHA256_Allocate * **********************************************************************/int SHA256_Free(void **context){  free(*context);  *context = 0;  return SHA256_ERROR_NO;}/************************************************************************ *  * SHA256_MakeDigest() - Helpful function if the whole message is in the  * memory and we have to create digest for it. * ************************************************************************/int SHA256_MakeDigest( byte *message, int messageLength, byte *digest ){	SHA256Context *context;  	if ( SHA256_Allocate((void **)(&context)) != SHA256_ERROR_NO )		return SHA256_ERROR_INTERNAL_ERROR;    if ( SHA256_Init(context) != SHA256_ERROR_NO)	{	SHA256_Free((void **)(&context));		return SHA256_ERROR_INTERNAL_ERROR;	}    if ( SHA256_Process(context, message, messageLength) != SHA256_ERROR_NO )	{	SHA256_Free((void **)(&context));		return SHA256_ERROR_INTERNAL_ERROR;	}    if ( SHA256_Final(context, digest) != SHA256_ERROR_NO )	{	SHA256_Free((void **)(&context));		return SHA256_ERROR_INTERNAL_ERROR;	}    SHA256_Free((void **)(&context));	return SHA256_ERROR_NO;}

⌨️ 快捷键说明

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