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

📄 main.cpp

📁 能够生成1024位的RSA算法密钥对
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	CopyBigNum(X,A);
	for(i=iBitCount-2;i>=0;i--)
	{
		//x=x*x*R'%N
		Montgomery_r(X,X,N,temp);
		CopyBigNum(X,temp);
		byte=(unsigned char)(power[i/32+1]>>(i%32))&0x1;
		if(byte==1) 
		{
			//X=X*A'*R' %N
			Montgomery_r(A,X,N,temp);//A=A*R%N
			CopyBigNum(X,temp);
		}
	}
	Montgomery_r(X,ONEVALUE,N,temp);//A=A*R%N
	CopyBigNum(remainder,temp);
	return;
	//CopyBigNum(remainder,product);
	
}
/******************************************************************************/
/*                                                                            */
/*  函数:  实现2^32进制大数的幂模(调用二进制蒙哥马利算法)                     */
/*  语法:  powermode_r(BIGNUM base,BIGNUM power,BIGNUM N,BIGNUM remainder)    */
/*  输入:                                                                     */
/*         base:2^32进制大数                                                 */
/*         power: 2^32进制大数                                                */
/*         N: 2^32进制大数                                                    */
/*         remainder: 2^32进制大数                                            */
/*  输出:                                                                     */
/*         remainder:                                                        */
/*  返回:  void                                                               */
/*  算法:                                                                    */
/*                                                                            */
/*		设R=2**k %N,R'=2**(-k) %N,E=Sum[i=0 to n](E*2**i):                 */
/*		A'=A*R %N                                                             */
/*		X=A'                                                                  */
/*		FOR i FROM n-1 TO 0                                                   */
/*			X=X*X*R' %N                                                       */
/*			IF E=1 X=X*A'*R' %N                                               */
/*		X=X*1*R' %N                                                           */
/*		RETURN X                                                              */
/******************************************************************************/
//二进制的模幂(调用二进制蒙哥马利算法)
void powermode_2(BIGNUM base,BIGNUM power,BIGNUM m,BIGNUM remainder)
{
	int i;
	int iBitCount=0;
	unsigned char byte;
	BIGNUM R,r,R2;//R=2^(m的比特位数)
	BIGNUM A,X,temp,temp2,temp3;
	iBitCount=GetBigNumBitCount(m);
	if(base[0]==0)
	{
		remainder[0]=0;
		return;
	}
	memset(R,0,sizeof(BIGNUM));
	memset(R2,0,sizeof(BIGNUM));
	R[0]=((iBitCount+1)+31)/32;
	bignum_set_bit(R,iBitCount,1);//2^iBitCount

	//R2[0]=(2*(iBitCount+1)-1)/32+1;
	//bignum_set_bit(R2,2*(iBitCount+1)-1-1,1);//比特位从零位算起
	bignum_substract(R,m,r);//r=2^iBitCount-m

	bignum_mul(r,r,R2);//R2=r^2
	bignum_mod(R2,m,X);
	CopyBigNum(R2,X);//R2=R2%m

	/*BIGNUM product,quotient;
	bignum_mul(base,R,product);
	bignum_mod(product,divisor,temp);*/
	BIGNUM product;
	//Montgomery(base,X,divisor,A);//A=A*R%M

	iBitCount=GetBigNumBitCount(power);//指数
	Montgomery_2(base,R2,m,A);//A=A*R%M
	CopyBigNum(X,A);
	for(i=iBitCount-2;i>=0;i--)
	{

		
		//x=x*x*R'%N
		Montgomery_2(X,X,m,temp);
		CopyBigNum(X,temp);
		byte=(unsigned char)(power[i/32+1]>>(i%32))&0x1;
		if(byte==1)
		{
			//X=X*A'*R' %N
			Montgomery_2(X,A,m,temp);//A=A*R%N
			CopyBigNum(X,temp);
		}
	}
	//byte=(unsigned char)(power[i/32+1]>>(i%32))&0x1;
	
	Montgomery_2(ONEVALUE,X,m,temp);//A=A*R%N
	CopyBigNum(remainder,temp);
	return;
	//CopyBigNum(remainder,product);
	
}

//选择与模数n互素的基数R=2^k,n满足2^(k-1)≤n<2^k, n应为奇数。
//并且选择R'及n’,满足0< R'<n, 0< n’<n,使得 RR'-nn’=1
/*
M(m)
{
	k = ( m * n’ ) mod R;
	x = (m + k*n ) / R;
    if (x>=n) 
		x -= n;
    return x;
}
exp(C,E,n) 
{
            D=R-n;
            P=C*R mod n;
             i=0;
            while(true)
            {
                    if(E的当前二进制位Ei==1)
						D=M(D*P); //从低位到高位检测二进制位
                    i+=1;
                    if(i==E的二进制位数)
						break;
            		P=M(P*P);

        }
       return D*R^(-1) (mod n);
}

*/

//R=
void powermode4(BIGNUM base,BIGNUM power,BIGNUM n,BIGNUM remainder)
{
	int i;
	int iBitCount=0;
	unsigned char byte;
	BIGNUM R,R_,n_;
	BIGNUM temp;
	iBitCount=GetBigNumBitCount(base);
	if(base[0]==0)
	{
		remainder[0]=0;
		return;
	}
	memset(R,0,sizeof(BIGNUM));

	R[0]=base[0]+1;
	R[base[0]+1]=1;
	//R[0]=1;
	//R[1]=16;
	GetEuclidEquation(R,n,R_,n_);//R*R'-n*n'=1
	BIGNUM D,P,product;
	bignum_substract(R,n,D);//D=R-n
	 
	bignum_mul(base,R,product);
	bignum_mod(product,n,P);//p=base*R%n

	i=0;
	iBitCount=GetBigNumBitCount(power);//指数
	for(;;)
	{
		//byte=(unsigned char)(power[i/32+1]>>(i%32))&0x1;
		byte=bignum_get_bit(power,i);//从低位到高位检测二进制位
		if(byte)
		{
			bignum_mul(D,P,product);
			Montgomery4(product,R,n_,n,D);//D=M(D*P);
		}
		i++;
		if(i==iBitCount)
			break;
		bignum_mul(P,P,product);
		Montgomery4(product,R,n_,n,P);//P=M(P*P);
	}
	Montgomery4(D,R,n_,n,remainder);//D=M(D);
	//CopyBigNum(remainder,D);
}
///////////////////////////////////////////////////////////////////////////////
//利用线性同余生成随机数
//x[i+1]=(x[i]*a+b)%m
//a=0x5851f42d,0x4c957f2d,
//b=1
//m=2^64
///////////////////////////////////////////////////////////////////////////////
//初始化伪随机函数的种子(unsigned __int32)time(NULL)
void InitSeed(unsigned __int32 seed)
{
	SEED64[0]=1;
	SEED64[1]=seed;
}

/******************************************************************************/
/*                                                                            */
/*  函数:  生成一个数据类型为BIGNUM 的64比特位的伪随机数                      */
/*  语法:    GetSeed_64 (void);                                               */
/*  输入:     全局变量:SEED64,A64                                           */
/*         SEED64:随机数种子(全局变量)                                     */
/*         A64:线性同余公式的常参数 (全局变量)                              */
/*  输出:                                                                     */
/*         SEED64:随机数种子(全局变量)                                       */
/*  返回:  void                                                               */
/*x[i+1]=(x[i]*a+b)%m                                                         */
/******************************************************************************/

void GetRandomSeed_64 ()
{
	BIGNUM product,result;
	unsigned __int32 b=1;
	bignum_mul(SEED64,A64,product);//product=SEED64*A64
	bignum_Increment(product);//product=product+1
	result[0]=2;
	result[1]=product[1];
	result[2]=product[2];

	while(result[0]>0 &&result[result[0]]==0)
		result[0]--;
	/*if(product[2]==0)
	{
		if(sum[1]==0)
			result[0]=0;
		else
			result[0]=1;
	}*/
	CopyBigNum(SEED64,result);
}

unsigned __int32 GetRandom_32 ()
{
	unsigned __int32 lValue=0;
	unsigned int len;
	GetRandomSeed_64();
	len=SEED64[0];
	switch(len)
	{
	case 2:
	case 1:
		lValue=SEED64[len];
		break;
	//default:
	//	lValue=0;
	}
	return lValue;
}
/******************************************************************************/
/*                                                                            */
/*  函数:  生成一个数据类型为BIGNUM 的比特长度为iBitCount的伪随机数            */
/*             (首先需要调用 InitSeed()函数初始化伪随机数种子)                */
/*  语法:  void GetRandom(BIGNUM dest,int iBitCount);                          */
/*  输入:                                                                     */
/*         iBitCount:伪随机数的比特长度                                      */
/*  输出:                                                                     */
/*         dest:比特长度为iBitCount的伪随机数                                */
/*  返回:  void                                                               */
/*                                                                            */
/******************************************************************************/
void GetRandom(BIGNUM dest,int iBitCount)
{
	unsigned __int32 lValue=0;
	unsigned int i,len;
	
	unsigned int quotient;//随机数有几个64位的
	unsigned int remainder;//随机数减去64位比特倍数的余数(小于64位比特)

	memset(dest,0,sizeof(BIGNUM));
	if(iBitCount<=0)
	{
		return;
	}
	quotient=iBitCount/64;
	remainder=iBitCount%64;

	for(i=1;i<=quotient;++i)
	{
		GetRandomSeed_64();
		dest[i*2-1]=SEED64[1];
		dest[i*2]=SEED64[2];
	}
	len=quotient*2;
	if(remainder>0)
	{
		GetRandomSeed_64();
		/*************************
		unsigned __int64 randNum64;
		randNum64=(((__int64)SEED64[2])<<32)+SEED64[1];
		randNum64<<=(64-remainder);
		randNum64|=0x8000000000000000;//二进制最高位保证为1
		randNum64>>=(64-remainder);
		dest[len+1]=(unsigned __int32)randNum64;
		dest[len+2]=(unsigned __int32)(randNum64>>32);
		if(dest[len+2]==0)
		{
			dest[0]=len+1;
		}
		else
			dest[0]=len+2;
		**************************************************/
		if(remainder>32)//32<remainder<64
		{
			
			dest[len+1]=SEED64[1];
			lValue=SEED64[2];
			lValue=lValue<<(64-remainder);
			lValue=lValue|0x80000000;//二进制最高位保证为1
			lValue>>=(64-remainder);
			dest[len+2]=lValue;
			dest[0]=len+2;
		}
		else if(remainder<32)
		{
			lValue=SEED64[2];
			lValue=lValue<<(64-remainder);
			lValue=lValue|0x80000000;//二进制最高位保证为1
			lValue>>=(64-remainder);
			dest[len+1]=lValue;
			dest[0]=len+1;
		}
		else
		{
			lValue=SEED64[2];
			lValue|=0x80000000;//二进制最高位保证为1
			dest[len+1]=lValue;
			dest[0]=len+1;
		}
	}
	else
	{
		dest[len]|=0x80000000;
		dest[0]=len;
	}
}

void GetRandom2(BIGNUM dest,int iBitCount)
{
	unsigned __int32 lValue=0;
	unsigned int i,len;
	
	unsigned int quotient;//随机数有几个64位的
	unsigned int remainder;//随机数减去64位比特倍数的余数(小于64位比特)

	memset(dest,0,sizeof(BIGNUM));
	if(iBitCount<=0)
	{
		return;
	}
	quotient=iBitCount/64;
	remainder=iBitCount%64;

	for(i=1;i<=quotient;++i)
	{
		GetRandomSeed_64();
		dest[i*2-1]=SEED64[1];
		dest[i*2]=SEED64[2];
	}
	len=quotient*2;
	if(remainder>0)
	{
		GetRandomSeed_64();
		/*************************
		unsigned __int64 randNum64;
		randNum64=(((__int64)SEED64[2])<<32)+SEED64[1];
		randNum64<<=(64-remainder);
		randNum64|=0x8000000000000000;//二进制最高位保证为1
		randNum64>>=(64-remainder);
		dest[len+1]=(unsigned __int32)randNum64;
		dest[len+2]=(unsigned __int32)(randNum64>>32);
		if(dest[len+2]==0)
		{
			dest[0]=len+1;
		}
		else
			dest[0]=len+2;
		**************************************************/
		if(remainder>32)//32<remainder<64
		{
			
			dest[len+1]=SEED64[1];
			lValue=SEED64[2];
			lValue=lValue<<(64-remainder);
			//lValue=lValue|0x80000000;//二进制最高位保证为1
			lValue>>=(64-remainder);
			dest[len+2]=lValue;
			dest[0]=len+2;
		}
		else if(remainder<32)
		{
			lValue=SEED64[2];
			lValue=lValue<<(64-remainder);
			//lValue=lValue|0x80000000;//二进制最高位保证为1
			lValue>>=(64-remainder);
			dest[len+1]=lValue;
			dest[0]=len+1;
		}
		else
		{
			lValue=SEED64[2];
			//lValue|=0x80000000;//二进制最高位保证为1
			dest[len+1]=lValue;
			dest[0]=len+1;
		}
	}
	else
	{
		//dest[len]|=|0x80000000;
		dest[0]=len;
	}
}
/******************************************************************************
//*****************************************************************************
Rabin-Miller素数测试,通过测试返回1,否则返回0。
n是待测素数。
注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4

数论学家利用费马小定理( a^(p-1)%p=1,其中p是质数,a是整数 )研究出了多种素数测试方法,目

前最快的算法是拉宾米勒测试算法,测试N是素数的过程如下:
(1)计算奇数M,使得N=(2^j)*M+1
(2)选择随机数A<N
(3)对于任意i<j,若A^((2^i)*M) MOD N = N-1,则N通过随机数A的测试
(4)或者,若A^M MOD N = 1,则N通过随机数A的测试
(5)让A取不同的值对N进行5次测试,若全部通过则判定N为素数
    若N 通过一次测试,则N 不是素数的概率为 25%,若N 通过t 次测试,则N 不是素数的概率为

1/4^t。事实上取t 为5 时,N 不是素数的概率为 1/128,N 为素数的概率已经大于99.99%。
    在实际应用中,可首先用300—500个小素数对N 进行测试,以提高拉宾米勒测试通过的概率,从

而提高测试速度。而在生成随机素数时,选取的随机数最好让 j=0,则可省去步骤(3) 的测试,进

一步提高测试速度。
//*****************************************************************************
******************************************************************************/
/******************************************************************************/
/*                                                                            */
/*  函数:  拉宾米勒测试算法                                                   */
/*                                                                            */
/*  语法:  long RabinMillerKernel(BIGNUM n,int iLoop)                         */
/*  输入:                                                                     */
/*         n:2^32进制的大数                                                  */
/*         iLoop:测试的次数                                                  */
/*  输出:                                                                     */
/*         ---                                                                */
/*  返回:                                                                     */
/*        1:测试通过                                                         */
/*        0:测试不通过                                                       */
/*                                                                            */
/******************************************************************************/
long RabinMillerKernel(BIGNUM n,int iLoop)
{
	
	BIGNUM m,v,v2,n_1;
	BIGNUM result;
	int i,j,iBitCount;
	BIGNUM quotient,remainder;

	memset(result,0,sizeof(BIGNUM));//结果清零初始化
	j=0;

	
	
	//0、先计算出m、j,使得n-1=m*2^j,其中m是正数,j是非负整数
	//一个正奇数一定可以分解为n-1=m*2^j
	/*
	bignum_substract2(n,1,n_1);//m=n-1
	CopyBigNum(m,n_1);//余数
	while(m[1]%2==0&& m[0]!=0)//偶数而且非零值就继续循环
	{
		
		++j;
		//division(m,TWOVALUE,quotient,remainder);//m/2
		bignum_rightshift2(m,1,quotient);//移位速度较快
		CopyBigNum(m,quotient);
	}*/

	CopyBigNum(m,n);

	//在n-1中找到第一个比特位为1的位数

	for (j = 0; bignum_get_bit(m, j) == !j; j++)
		continue;	
	bignum_rightshift2(m,j,quotient);
	CopyBigNum(m,quotient);

	CopyBigNum(n_1,n);
	bignum_Decrement(n_1);//n_1=n-1

	//CopyBigNum(m,n_1);//令j=0
	//1、随

⌨️ 快捷键说明

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