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

📄 mycryptlib.cpp

📁 提供加密的c/s 聊天程序。用到对称加密算法和非对称加密算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// MyCryptLib.cpp: implementation of the MyCryptLib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SecureChat.h"
#include "MyCryptLib.h"

// For timeGetTime();timeBeginPeriod() timeEndPeriod()
#include  <Mmsystem.h>
#pragma comment( lib, "winmm" )


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyCryptLib::MyCryptLib()
{
	m_mtIndex=0;
	m_bSeeded=FALSE;
}

MyCryptLib::~MyCryptLib()
{

}


// Used to Speed up prime nr generator. 
const DWORD MyCryptLib::SMALL_PRIMES[] =  {
	3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 
	47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 
	103, 107, 109, 113,127, 131, 137, 139, 149, 151, 
	157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 
	211, 223, 227, 229,233, 239, 241, 251, 257, 263, 
	269, 271, 277, 281,283, 293, 307, 311, 313, 317, 
	331, 337, 347, 349,353, 359, 367, 373, 379, 383, 
	389, 397, 401, 409,419, 421, 431, 433, 439, 443, 
	449, 457, 461, 463,467, 479, 487, 491, 499, 503, 
	509, 521, 523, 541,547, 557, 563, 569, 571, 577, 
	587, 593, 599, 601,607, 613, 617, 619, 631, 641, 
	643, 647, 653, 659,661, 673, 677, 683, 691, 701, 
	709, 719, 727, 733,739, 743, 751, 757, 761, 769, 
	773, 787, 797, 809,811, 821, 823, 827, 829, 839, 
	853, 857, 859, 863,877, 881, 883, 887, 907, 911, 
	919, 929, 937, 941,947, 953, 967, 971, 977, 983, 
	991, 997,
};

const UINT MyCryptLib::_NUMBEROFPRIMES_=sizeof(MyCryptLib::SMALL_PRIMES)/sizeof(DWORD);


// SHA konstants. 
#ifdef SYSTEM_LITTLE_ENDIAN
const UINT MyCryptLib::_SHA_MASK_[4]={0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff};
const UINT MyCryptLib::_SHA_BITS_[4]={0x00000080, 0x00008000, 0x00800000, 0x80000000};
#else
const UINT MyCryptLib::_SHA_MASK_[4]={0x00000000, 0xff000000, 0xffff0000, 0xffffff00};
const UINT MyCryptLib::_SHA_BITS_[4]={0x80000000, 0x00800000, 0x00008000, 0x00000080};
#endif

/*
*	Add(DWORD C[], DWORD A[], DWORD B[], UINT nSize)
-----------------------------------------------------
*  Addition for very big numbers A,B,C
*  Assumes that A, B and C, have the same size. 
*  nSize = number of bytes. 
*  Adds A & B and put the result in C. 
*  Reference  Knuth, Donald. 1968. The Art of Computer Programming
*  Returns 0 if success 1 if overflow. 
*/

DWORD MyCryptLib::BNAdd(DWORD C[], const DWORD A[], const DWORD B[], const UINT nSize)
{	
	DWORD k=0; // carry 
	for (UINT i = 0; i < nSize; i++)
	{
		C[i] = A[i] + k;
		if(C[i]>=k)// detect overflow and set k
			k=0;
		else
			k=1;

		C[i] += B[i];
		if (C[i] < B[i]) // Detect overflow again. 
			k++;	
	}
	return k;
}


// Returns ceil(x) as a non-negative integer or 0 if x < 0 
UINT MyCryptLib::BNUiceil(double x)
{
	UINT c;
	if (x < 0) return 0;
	c = (UINT)x;
	if ((x - c) > 0.0)
		c++;
	return c;
}



/*
*	SHA1 Implementation algoritm from, the algorith is taken from 
*	Federal Information
*	Processing Standards Publication 180-1, 1995 April 17
*  http://www.itl.nist.gov/fipspubs/fip180-1.htm
*  
*/


/*
* Sha1Hash(unsigned char *_pOutDigest, const unsigned char *_pData,UINT nSize)
*
*
* Computes SH1 hash given data (_pData) of size nSize.  	
*  
* _pOutDigest is an buffer of size SHA1_DIGEST_SIZE (20) which will be filled with 
* the digestvalue. 
*
*
*/

void MyCryptLib::SHA1Hash(unsigned char *_pOutDigest, const unsigned char *_pData,UINT nSize)
{

	// Be safe
	if ( !_pOutDigest || !_pData )
		return;

	SHA1_STATETYPE csha1;
	memset(&csha1,0,sizeof(csha1));
	SHA1_Start(&csha1);
	SHA1_Hash(_pData,nSize,&csha1);
	SHA1_Finish(_pOutDigest,&csha1);
}


void MyCryptLib::SHA1_Transform(SHA1_STATETYPE* _pcsha1)
{

	UINT   w[80], i, a, b, c, d, e, t;

	for (i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
		w[i] = SHA_BLOCK32(_pcsha1->wbuf[i]);

	for (i = SHA1_BLOCK_SIZE / 4; i < 80; ++i)
		w[i] = rotate32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);

	a = _pcsha1->hash[0];
	b = _pcsha1->hash[1];
	c = _pcsha1->hash[2];
	d = _pcsha1->hash[3];
	e = _pcsha1->hash[4];

	for(i = 0; i < 20; ++i)
	{
		sha_round(F0to19, 0x5a827999);    
	}

	for(i = 20; i < 40; ++i)
	{
		sha_round(F20to39, 0x6ed9eba1);
	}

	for(i = 40; i < 60; ++i)
	{
		sha_round(F40to59, 0x8f1bbcdc);
	}

	for(i = 60; i < 80; ++i)
	{
		sha_round(F60to79, 0xca62c1d6);
	}

	_pcsha1->hash[0] += a; 
	_pcsha1->hash[1] += b; 
	_pcsha1->hash[2] += c; 
	_pcsha1->hash[3] += d; 
	_pcsha1->hash[4] += e;

}
void MyCryptLib::SHA1_Start(SHA1_STATETYPE *_pcsha1)
{

	_pcsha1->hash[0] = 0x67452301;
	_pcsha1->hash[1] = 0xefcdab89;
	_pcsha1->hash[2] = 0x98badcfe;
	_pcsha1->hash[3] = 0x10325476;
	_pcsha1->hash[4] = 0xc3d2e1f0;
	_pcsha1->count[0] = 0;
	_pcsha1->count[1] = 0;
}

void MyCryptLib::SHA1_Finish(unsigned char* _pShaValue, SHA1_STATETYPE* _pcsha1)
{
	UINT    i = (UINT)(_pcsha1->count[0] & (SHA1_BLOCK_SIZE - 1));
	_pcsha1->wbuf[i >> 2] = (_pcsha1->wbuf[i >> 2] & _SHA_MASK_[i & 3]) | _SHA_BITS_[i & 3];

	if(i > SHA1_BLOCK_SIZE - 9)
	{
		if(i < 60) _pcsha1->wbuf[15] = 0;
		SHA1_Transform(_pcsha1);
		i = 0;
	}
	else   
		i = (i >> 2) + 1;

	while(i < 14) 
		_pcsha1->wbuf[i++] = 0;


	_pcsha1->wbuf[14] = SHA_BLOCK32((_pcsha1->count[1] << 3) | (_pcsha1->count[0] >> 29));
	_pcsha1->wbuf[15] = SHA_BLOCK32(_pcsha1->count[0] << 3);

	SHA1_Transform(_pcsha1);


	for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
		_pShaValue[i] = (unsigned char)(_pcsha1->hash[i >> 2] >> 8 * (~i & 3));
}


void MyCryptLib::SHA1_Hash(const unsigned char *_pData, unsigned int _iSize, SHA1_STATETYPE* _pcsha1)
{
	UINT ipos = (UINT)(_pcsha1->count[0] & (SHA1_BLOCK_SIZE - 1));
	UINT ispace = SHA1_BLOCK_SIZE - ipos;
	unsigned char *pData=(unsigned char *)_pData;
	if((_pcsha1->count[0] += _iSize) < _iSize)
		++(_pcsha1->count[1]);
	while(_iSize >= ispace)     
	{
		memcpy(((unsigned char*)_pcsha1->wbuf) + ipos, pData, ispace);
		ipos = 0; 
		_iSize -= ispace; 
		pData += ispace; 
		ispace = SHA1_BLOCK_SIZE; 
		SHA1_Transform(_pcsha1);
	}	
	memcpy(((unsigned char*)_pcsha1->wbuf) + ipos, pData, _iSize);
}



/*
*	BNAdddw(DWORD w[], const DWORD u[], DWORD v, UINT nSize)
-----------------------------------------------------
*  Addition for very big numbers w,u
*  w=u+v. 
*  nSize = number of bytes. 
*  Reference  Knuth, Donald. 1968. The Art of Computer Programming
*  Returns 0 if success 1 if overflow. 
*/
inline DWORD MyCryptLib::BNAdddw(DWORD w[], const DWORD u[], DWORD v, UINT nSize)
{
	DWORD k=0;
	w[0] = u[0] + v;
	k=(w[0] >= v) ? 0:1;	
	for (UINT j = 1; j < nSize; j++)
	{
		w[j] = u[j] + k;
		k=(w[j] >= k) ? 0:1;
	}
	return k;	
}

/*
*	BNSubtract(DWORD C[], DWORD A[], DWORD B[], UINT nSize)
-----------------------------------------------------
*  Subtraction  for very big numbers A,B,C
*  Assumes that A, B and C, have the same size. 
*  nSize = number of bytes. 
*  Calculates C = A - B where A >= B
*  Reference  Knuth, Donald. 1968. The Art of Computer Programming
*  Returns 0 if success 1 if overflow. 
*/

DWORD MyCryptLib::BNSubtract(DWORD C[], const DWORD A[], const DWORD B[],const UINT nSize)
{
	DWORD  k=0;
	for (UINT i = 0; i < nSize; i++)
	{
		C[i] = A[i] - k;
		if (C[i] > _MAXIMUMNR_ - k) // detect underflow (borrow) 
			k = 1;
		else
			k = 0;
		C[i] -= B[i];
		if (C[i] > _MAXIMUMNR_  - B[i])
			k++;
	}	
	return k;
}

/*
*	BNSubtract(DWORD w[], const DWORD u[], DWORD v, UINT nSize)
-----------------------------------------------------
*  Subtraction  for very big numbers u to an normal DWORD. 
*  Assumes that w,u, have the same size. 
*  nSize = number of bytes. 
*  Calculates w=u-v
*  Reference  Knuth, Donald. 1968. The Art of Computer Programming
*  Returns 0 if success 1 if overflow. 
*/



DWORD MyCryptLib::BNSubtractdw(DWORD w[], const DWORD u[], DWORD v, UINT nSize)
{
	DWORD k=0;
	w[0] = u[0] - v;
	if (w[0] > _MAXIMUMNR_- v)
		k = 1;
	else
		k = 0;
	for (UINT j = 1; j < nSize; j++)
	{
		w[j] = u[j] - k;
		if (w[j] > _MAXIMUMNR_ - k)
			k = 1;
		else
			k = 0;
	}	
	return k;	
}


CString MyCryptLib::BNPrint(const DWORD *p, UINT nSize)
{
	CString stmp="";
	CString sRet="";
	// Trim leading zeroes 
	while (nSize--)
	{
		if (p[nSize] != 0)
			break;
	}
	nSize++;

	// Catch empty len to show 0 
	if ( nSize==0 ) 
		nSize=1;

	while ( nSize-- )
	{

		stmp.Format("%08lx ", p[nSize]);
		sRet+=stmp;
	}

	return sRet;
}


CString MyCryptLib::BNPrintC(const DWORD *p, UINT nSize)
{
	CString stmp="";
	CString sRet;
	sRet.Format("[%i] = {\r\n",nSize);
	int iNrPrinted=0;
	for ( UINT i=0; i<nSize; i++ )
	{

		stmp.Format("0x%08lx, ", p[i]);
		iNrPrinted++;
		sRet+=stmp;
		if(iNrPrinted%6==0)
			sRet+="\r\n";
	}
	sRet+="};";
	return sRet;	
}

/*
*	Returns an CString version of the number
*
*/
CString MyCryptLib::BNToString(const DWORD *a, UINT nSize,UINT nBase)
{

	// Is the number is Zero 
	if ( BNIsZero(a, nSize) )
		return "0";

	CString sRet=""; // return String 

	const char DEC_DIGITS[] = "0123456789";
	const char HEX_DIGITS[] = "0123456789abcdef";
	const char *cdigits;
	double dFactor=0.0;

	// Setup the data according to nBase
	switch (nBase)
	{
	case 10:
		cdigits = DEC_DIGITS;
		dFactor = 2.40824;	/* log(256)/log(10)=2.40824 */
		break;
	case 16:
		cdigits = HEX_DIGITS;
		dFactor = 2.0;	/* log(256)/log(16)=2.0 */
		break;
	default:
		return "Base must be 10 or 16";
	}
	// Convert to 8 bits octtlets (is easier to handle)
	UINT nbytes = nSize * sizeof(DWORD);
	BYTE* pOct=NULL;
	pOct=new BYTE[nbytes];
	// be safe
	if ( pOct==NULL )
		return "Not enough memory: pOct=new BYTE[nbytes] Failed..";
	memset(pOct,0,nbytes);
	UINT NumberOfOctNeeded= BNToOctets(a,nSize,pOct,nbytes);

	// Create temporary place
	UINT NewOctLength=BNUiceil(NumberOfOctNeeded*dFactor);
	BYTE* pNewOct=new BYTE[NewOctLength];
	// Be safe 
	if ( pNewOct==NULL )
	{
		delete[] pOct;
		return "Not enough memory: pNewOct=new BYTE[NewOctLength] Failed..";
	}
	memset(pNewOct,0,NewOctLength);
	// Transform 
	UINT t=0;
	UINT i=0;
	for (i  = 0; i < nbytes; i++)
	{
		t = pOct[i];
		for (UINT j = NewOctLength; j > 0; j--)
		{
			t += (unsigned long)(pNewOct[j-1] * 256);
			pNewOct[j-1] = (unsigned char)(t % nBase);
			t /= nBase;
		}
	}

	// Find index of leading significant digit 
	UINT isig=0;
	for ( isig = 0; isig < NewOctLength; isig++ )
		if (pNewOct[isig])
			break;
	// number of charachters needed.. 	
	UINT nchars = NewOctLength - isig;

	for(i=0;i<nchars;i++)
		sRet+=cdigits[pNewOct[isig+i]];


	delete[] pOct;
	delete[] pNewOct;
	return sRet;
}



/*
*	Returns True if a == b else false
*/
int MyCryptLib::BNIsEqual(const DWORD a[], const DWORD b[], UINT nSize)
{
	if ( nSize <= 0 ) 
		return FALSE;

	while ( nSize-- )
	{
		if ( a[nSize] != b[nSize] )
			return FALSE;	
	}	
	return TRUE;
}

/*
*	Makes A=0
*/
void MyCryptLib::BNSetZero(DWORD A[], UINT nSize)
{
	while ( nSize-- )
		A[nSize] = 0;
}


/*
*	Return True if a==0
*/
int MyCryptLib::BNIsZero(const DWORD a[], UINT nSize)
{
	if (nSize == 0) 
		return FALSE;

	for (UINT i = 0; i < nSize; i++)	
	{
		if (a[i] != 0)
			return FALSE;	
	}

	return TRUE;
}

/*
*	Makes a=b
*/

void MyCryptLib::BNSetEqual(DWORD a[], const DWORD b[], UINT nSize)
{
	for (UINT i = 0; i < nSize; i++)
	{
		a[i] = b[i];
	}	
}

/*
* Makes a=d
* Where d is an normal DWORD. 
*/
void MyCryptLib::BNSetEqualdw(DWORD a[], const DWORD d, UINT nSize)
{
	if(nSize<=0)
		return;
	BNSetZero(a,nSize);
	a[0]=d;
}


int MyCryptLib::BNCompare(const DWORD a[], const DWORD b[], UINT nSize)
{
	if ( nSize <= 0 ) 
		return 0;
	while (nSize--)
	{
		if (a[nSize] > b[nSize])
			return 1;	// Grater than 
		if (a[nSize] < b[nSize])
			return -1;	// Less Than 
	}
	return 0;// equal 
}

/* Returns sign of (a - b) where b is an DWORD */
inline int MyCryptLib::BNComparedw(const DWORD a[], DWORD b, UINT nSize)
{

	// Be Safe 
	if (nSize == 0) return (b ? -1 : 0);

	for (UINT i = 1; i < nSize; i++)
	{
		if (a[i] != 0)
			return 1;	// Greater than 
	}

	if ( a[0] < b) 
		return -1;	// Less than 
	else if ( a[0] > b )
		return 1;		// Greater 

	return 0; //equal  	
}


/*  BNShiftLeft(DWORD a[], const DWORD *b, DWORD x, DWORD nSize)
*	Computes a = b << x 
*  returns carry 
*/
inline DWORD MyCryptLib::BNShiftLeft(DWORD a[], const DWORD *b, UINT x, UINT nSize)
{
	DWORD mask, carry, nextcarry;
	UINT i=0;

	if ( x >= sizeof(DWORD)*8 )
		return 0;

	mask = _HIBITMASK_;
	for (i = 1; i < x; i++)
	{
		mask = (mask >> 1) | mask;
	}
	if (x == 0) mask = 0x0;

	UINT y = (sizeof(DWORD)*8) - x;
	carry = 0;
	for (i = 0; i < nSize; i++)
	{
		nextcarry = (b[i] & mask) >> y;
		a[i] = b[i] << x | carry;
		carry = nextcarry;
	}

	return carry;
}


/* BNShiftRight(DWORD a[], const DWORD *b, DWORD x, DWORD nSize)
* Computes a = b >> x 
* returns carry 
*
*/
inline DWORD MyCryptLib::BNShiftRight(DWORD a[], const DWORD *b, DWORD x, DWORD nSize)
{

⌨️ 快捷键说明

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