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

📄 mycryptlib.cpp

📁 提供加密的c/s 聊天程序。用到对称加密算法和非对称加密算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
*/
UINT MyCryptLib::BNFromOctets(DWORD a[], UINT nSize, const unsigned char *c, UINT nOctBytes)
{
	UINT i;
	int j, k;
	DWORD t;
	DWORD t2;
	BNSetZero(a, nSize);

	/* Read in octets, least significant first */
	/* i counts into big_d, j along c, and k is # bits to shift */
	for (i = 0, j = nOctBytes - 1; (i < nSize)&&(j >= 0); i++)
	{
		t = 0;
		for (k = 0; (j >= 0) && (k < (sizeof(DWORD)*8)); j--, k += 8)
		{
			t2=((DWORD)c[j]);
			t |= t2 << k;
		}
		a[i] = t;
	}

	return i;
}

/*
* Convert an big Number a into an array of octets, in big-endian order,
* padding to nbytes or truncating if necessary.
* Return number of octets required excluding leading zero bytes.
*/

UINT MyCryptLib::BNToOctets(const DWORD a[], UINT nSize, unsigned char *c, UINT nbytes)
{
	int j, k, len;
	DWORD t;
	UINT i, noctets, nbits;

	nbits = BNBitLength(a, nSize);
	noctets = (nbits + 7) / 8;

	len = (int)nbytes;

	for (i = 0, j = len - 1; i < nSize && j >= 0; i++)
	{
		t = a[i];
		for (k = 0; j >= 0 && k < (sizeof(DWORD)*8); j--, k += 8)
			c[j] = (unsigned char)(t >> k);
	}

	for ( ; j >= 0; j--)
		c[j] = 0;

	return noctets;	
}



UINT MyCryptLib::BNFromDecimal(DWORD a[], UINT nSize, const char *s,UINT nStringLength)
{


	BNSetZero(a, nSize);
	//  Create some temp storage for int values.
	UINT newlen = BNUiceil(nStringLength * 0.41524);	// log(10)/log(256)=0.41524 
	BYTE* ptmp=NULL;
	ptmp=new BYTE[newlen];

	memset(ptmp,0,newlen);
	if (ptmp==NULL) 
		return 0; //FAILED 

	// Go through zero-terminated string
	DWORD t=0;
	for (UINT i = 0; s[i]; i++)
	{
		t = s[i] - '0';
		if (t > 9 || t < 0) continue;
		for (UINT j = newlen; j > 0; j--)
		{
			t += (DWORD)(ptmp[j-1] * 10);
			ptmp[j-1] = (unsigned char)(t & 0xFF);
			t >>= 8;
		}
	}

	// now Convert bytes to big digits 
	UINT AcctualNumberofbytes = BNFromOctets(a, nSize, ptmp, newlen);

	// Clean up 
	delete[] ptmp;

	return AcctualNumberofbytes;
}

UINT MyCryptLib::BNFromHex(DWORD a[], UINT nSize, const char *s, UINT nStringLength)
{

	size_t newlen;
	BYTE  *newdigits;
	size_t n;
	unsigned long t;
	size_t i, j;

	BNSetZero(a, nSize);

	// temporary 
	n = strlen(s);
	newlen = BNUiceil(n * 0.5);	// log(16)/log(256)=0.5 
	newdigits = new BYTE[newlen];

	if (newdigits==NULL)
		return 0; 

	memset(newdigits,0,newlen);
	// Work through zero-terminated string 
	for ( i = 0; s[i]; i++ )
	{
		t = s[i];
		if ((t >= '0') && (t <= '9')) t = (t - '0');
		else if ((t >= 'a') && (t <= 'f')) t = (t - 'a' + 10);
		else if ((t >= 'A') && (t <= 'F')) t = (t - 'A' + 10);
		else continue;
		for (j = newlen; j > 0; j--)
		{
			t += (unsigned long)newdigits[j-1] << 4;
			newdigits[j-1] = (unsigned char)(t & 0xFF);
			t >>= 8;
		}
	}

	// Convert bytes to big digits 
	n = BNFromOctets(a, nSize, newdigits, newlen);

	// Clean up 
	delete[] newdigits;

	return n;


}


/*	Computes y = x^e mod m */
/*	Binary left-to-right method */
int MyCryptLib::BNModExp(DWORD yout[], const DWORD x[], const DWORD e[], const DWORD m[], UINT nSize)
{
	// Be safe
	if ( nSize <= 0 ) 
		return -1;

	DWORD mask;
	UINT n;
	DWORD *t1, *t2, *t3, *tm, *y; //temporary variables 

	// Create some temporary variables
	const UINT nn = nSize * 2;

	t1 = BNAlloc(nn);
	if(t1==NULL)
	{
		return -1;
	}
	t2 = BNAlloc(nn);
	if(t2==NULL)
	{
		BNFree(&t1);
		return -1;
	}
	t3 = BNAlloc(nn);
	if(t3==NULL)
	{
		BNFree(&t1);
		BNFree(&t2);
		return -1;
	}
	tm = BNAlloc(nSize);
	if(tm==NULL)
	{
		BNFree(&t1);
		BNFree(&t2);
		BNFree(&t3);
		return -1;
	}
	y = BNAlloc(nSize);
	if(y==NULL)
	{
		BNFree(&t1);
		BNFree(&t2);
		BNFree(&t3);
		BNFree(&tm);
		return -1;
	}

	BNSetEqual(tm, m, nSize);

	//  Find second-most significant bit in e 
	n = BNSizeof(e, nSize);
	for (mask = _HIBITMASK_; mask > 0; mask >>= 1)
	{
		if (e[n-1] & mask)
			break;
	}

	// next bitmask 
	if ( mask==1 )
	{
		mask=_HIBITMASK_;
		n--;
	}else
		mask >>=1; 

	BNSetEqual(y, x, nSize);

	while ( n )
	{

		BNModSquareTmp(y, y, tm, nSize, t1, t2, t3);	
		if (mask & e[n-1])
			BNMultTmp(y, y, x, tm, nSize, t1, t2, t3);

		// Move to next bit
		// next bitmask 
		if ( mask==1 )
		{
			mask=_HIBITMASK_;
			n--;
		}else
			mask >>=1; 
	}

	BNSetEqual(yout, y, nSize);

	BNFree(&t1);
	BNFree(&t2);
	BNFree(&t3);
	BNFree(&tm);
	BNFree(&y);
	return 0;
}
// helper function for code cleannesss. 
inline int MyCryptLib::BNMultTmp(DWORD a[], const DWORD x[], const DWORD y[], DWORD m[], UINT nSize, DWORD temp[], DWORD tqq[], DWORD trr[])
{
	BNMultiply(temp, x, y, nSize);
	BNModuloTmp(a, temp, nSize * 2, m, nSize, tqq, trr);
	return 0; 
}

inline int MyCryptLib::BNModuloTmp(DWORD r[], const DWORD u[], UINT nUSize, DWORD v[], UINT nVSize, DWORD tqq[], DWORD trr[])
{
	BNDivide(tqq, trr, u, nUSize, v, nVSize);
	BNSetEqual(r, trr, nVSize);	
	return 0;
}

inline int MyCryptLib::BNModSquareTmp(DWORD a[], const DWORD x[], DWORD m[], UINT nSize, DWORD temp[], DWORD tqq[], DWORD trr[])
{
	//x*x
	BNSquare(temp, x, nSize);

	// Then modulo m
	BNModuloTmp(a, temp, nSize * 2, m, nSize, tqq, trr);
	return 0;
}


/*	
* Computes sw = x * x
* where:
* 	x is a Big multiprecision Number
*	w is a Big multiprecision Number of 2*nSize
*	nSize is the size of the number in bytes. 
*/

inline int MyCryptLib::BNSquare(DWORD w[], const DWORD x[], UINT nSize)
{
	DWORD k, p[2], u[2], cbit, carry;
	UINT i, j, t, i2, cpos;
	t = nSize;

	i2 = t << 1;

	for (i = 0; i < i2; i++)
		w[i] = 0;

	carry = 0;
	cpos = i2-1;

	for (i = 0; i < t; i++)
	{

		i2 = i << 1; 
		BNMultiplyHelper(p, x[i], x[i]);
		p[0] += w[i2];

		if (p[0] < w[i2])
			p[1]++;
		k = 0;	
		if ( i2 == cpos && carry )
		{
			p[1] += carry;
			if (p[1] < carry)
				k++;
			carry = 0;
		}

		u[0] = p[1];
		u[1] = k;
		w[i2] = p[0];

		k = 0;
		for ( j = i+1; j < t; j++ )
		{
			BNMultiplyHelper(p, x[j], x[i]);
			cbit = (p[0] & _HIBITMASK_) != 0;
			k =  (p[1] & _HIBITMASK_) != 0;
			p[0] <<= 1;
			p[1] <<= 1;
			p[1] |= cbit;

			p[0] += u[0];
			if (p[0] < u[0])
			{
				p[1]++;
				if (p[1] == 0)
					k++;
			}
			p[1] += u[1];
			if (p[1] < u[1])
				k++;

			p[0] += w[i+j];
			if (p[0] < w[i+j])
			{
				p[1]++;
				if (p[1] == 0)
					k++;
			}
			if ((i+j) == cpos && carry)
			{
				p[1] += carry;
				if (p[1] < carry)
					k++;
				carry = 0;
			}
			u[0] = p[1];
			u[1] = k;
			w[i+j] = p[0];
		}

		carry = u[1];
		w[i+t] = u[0];
		cpos = i+t;
	}	
	return 0;
}

//	Computes inv = u^(-1) mod v 
//  This function is not 100% correct, I have to check it later. 
int MyCryptLib::BNModInv(DWORD inv[], const DWORD u[], const DWORD v[], UINT nSize)
{
	DWORD *u1, *u3, *v1, *v3, *t1, *t3, *q, *w;
	u1=u3=v1=v3=t1=t3=q=w=NULL;
	int bIterations;
	int result;

	// Allocate temp storage
	u1 = BNAlloc(nSize);
	if ( u1==NULL )
	{
		return -1;
	}
	u3 = BNAlloc(nSize);
	if ( u3==NULL )
	{
		BNFree(&u1);
		return -1;
	}
	v1 = BNAlloc(nSize);
	if ( v1==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		return -1;
	}
	v3 = BNAlloc(nSize);
	if ( v3==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		BNFree(&v1);
		return -1;
	}


	t1 = BNAlloc(nSize);

	if ( t1==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		BNFree(&v1);
		BNFree(&v3);
		return -1;
	}

	t3 = BNAlloc(nSize);
	if ( t3==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		BNFree(&v1);
		BNFree(&v3);
		BNFree(&t1);
		return -1;
	}

	q  = BNAlloc(nSize);
	if ( q==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		BNFree(&v1);
		BNFree(&v3);
		BNFree(&t1);
		BNFree(&t3);
		return -1;
	}
	w  = BNAlloc(2 * nSize);
	if ( w==NULL )
	{
		BNFree(&u1);
		BNFree(&u3);
		BNFree(&v1);
		BNFree(&v3);
		BNFree(&t1);
		BNFree(&t3);
		BNFree(&q);
		return -1;
	}

	// Init 
	BNSetEqualdw(u1, 1, nSize);		 // u1 = 1 

	BNSetEqual(u3, u, nSize);		 // u3 = u 
	BNSetZero(v1, nSize);			 // v1 = 0 
	BNSetEqual(v3, v, nSize);		 // v3 = v 

	bIterations = 1;	
	while ( !BNIsZero(v3, nSize) )		
	{					
		BNDivide(q, t3, u3, nSize, v3, nSize);

		BNMultiply(w, q, v1, nSize);	

		// what if the real sizeof(w+u1)> nSize ???
		//ASSERT(BNSizeof(w,nSize*2)>nSize);

		BNAdd(t1, u1, w, nSize);		

		// Swap 
		BNSetEqual(u1, v1, nSize);
		BNSetEqual(v1, t1, nSize);
		BNSetEqual(u3, v3, nSize);
		BNSetEqual(v3, t3, nSize);
		bIterations = -bIterations;
	}

	if (bIterations < 0)
		BNSubtract(inv, v, u1, nSize);	
	else
		BNSetEqual(inv, u1, nSize);	


	if (BNComparedw(u3, 1, nSize) != 0)
	{
		result = 1;
		BNSetZero(inv, nSize);
	}
	else
		result = 0;

	// Free the memory 
	BNSetZero(u1, nSize);
	BNSetZero(v1, nSize);
	BNSetZero(t1, nSize);
	BNSetZero(u3, nSize);
	BNSetZero(v3, nSize);
	BNSetZero(t3, nSize);
	BNSetZero(q, nSize);
	BNSetZero(w, 2*nSize);
	BNFree(&u1);
	BNFree(&v1);
	BNFree(&t1);
	BNFree(&u3);
	BNFree(&v3);
	BNFree(&t3);
	BNFree(&q);
	BNFree(&w);
	return 0;

}

int MyCryptLib::BNGcd(DWORD g[], const DWORD x[], const DWORD y[], UINT nSize)
{
	DWORD *yy, *xx;	
	yy = BNAlloc(nSize);

	if( yy==NULL )
		return -1;

	xx = BNAlloc(nSize);

	if( xx==NULL )
	{
		BNFree(&yy);
		return -1;
	}

	BNSetZero(yy, nSize);
	BNSetZero(xx, nSize);
	BNSetEqual(xx, x, nSize);
	BNSetEqual(yy, y, nSize);
	BNSetEqual(g, yy, nSize);		

	while ( !BNIsZero(xx, nSize) )	
	{
		BNSetEqual(g, xx, nSize);
		BNMod(xx, yy, nSize, xx, nSize);	
		BNSetEqual(yy, g, nSize);	
	}
	BNSetZero(xx, nSize);
	BNSetZero(yy, nSize);
	BNFree(&xx);
	BNFree(&yy);

	return 0;	// gcd = g 
}


/*	Returns true if w is a probable prime using the
*  Rabin-Miller Probabilistic Primality Test.
*  Carries out t iterations specified by user.
*
* DSS Standard recommends using t >= 50
* Ferguson & Schneier recommend t = 64 for prob error < 2^-128
* In practice, most random composites are caught in the first
* round or two and so specifying a large t will only affect
* the final check.
*
*/


int MyCryptLib::BNRabinMiller(const DWORD w[], UINT nSize, UINT t)
{

	DWORD *m, *a, *b, *z, *w1, *j;
	DWORD maxrand;
	int failed;
	BOOL bisprime;
	UINT i;

	// Catch w <= 1 
	if (BNComparedw(w, 1, nSize) <= 0) 
		return 0;

	// Allocate temp storage..

	m = BNAlloc(nSize);
	if ( m==NULL ) 
	{
		return FALSE;
	}
	a = BNAlloc(nSize);
	if ( a==NULL )  
	{
		BNFree(&m);
		return FALSE;
	}
	b = BNAlloc(nSize);
	if ( b==NULL ) 
	{
		BNFree(&m);
		BNFree(&a);
		return FALSE;
	}
	z = BNAlloc(nSize);
	if ( z==NULL ) 
	{
		BNFree(&m);
		BNFree(&a);
		BNFree(&b);
		return FALSE;
	}
	w1 = BNAlloc(nSize);
	if ( w1==NULL ) 
	{
		BNFree(&m);
		BNFree(&a);
		BNFree(&b);
		BNFree(&z);
		return FALSE;
	}
	j = BNAlloc(nSize);
	if ( j==NULL ) 
	{
		BNFree(&m);
		BNFree(&a);
		BNFree(&b);
		BNFree(&z);
		BNFree(&w1);

⌨️ 快捷键说明

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