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

📄 main.cpp

📁 能够生成1024位的RSA算法密钥对
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
			Z[k]=0;
		}
		Z[0]+=i-1;
		**********************************************************************/

		/**********************************************************************
		CopyBigNum2(Z,div);
		Z[0]+=len;
		for(k=Z[0];k>len;k--)
			Z[k]=Z[k-len];
		for(k=1;k<=len;k++)
			Z[k]=0;
		****************************************/
		bignum_mul(Z,divisor,temp);
		CopyBigNum(Z,temp);//Z=divisor*Z;
		
		bignum_substract(tempdividend,Z,temp);
		CopyBigNum(tempdividend,temp);//tempdividend=tempdividend-divisor*Z
	}
	CopyBigNum(remainder,tempdividend);

	if(iCmpResult==0)                     //能整除相等,余数和除数相等
	{
		memset(remainder,0,sizeof(BIGNUM));//余数为0
	}
}
/*
 * Compute the residue of a bignum, modulo a (max 16-bit) short.
 */
unsigned short bignum_mod_short(BIGNUM number, unsigned short modulus)
{
    unsigned __int64 mod, r;
    int i;

    r = 0;
    mod = modulus;
    for (i = number[0]; i > 0; i--)
		r = (r * (BIGNUM_TOP_BIT % mod) * 2 + number[i] % mod) % mod;
    return (unsigned short) r;
}
//蒙哥马利模乘乘模运算C=A*B*r^(-k) % N
//k为N在r进制下的位数
//于是我们可以得出r为任何值的蒙哥马利算法:
/*
N[0]*N[0]' %r =1,q=(C'[0]+A*B[0])*(r-N[0]') %r
r=2^32
m=r-N[0]'
C'=0
FOR i FROM 0 TO k
q=(C'[0]+A*B[0])*m %r
C'=(C'+A*B+q*N)/r
IF C'>=N C'=C'-N
RETURN C'*/

//r=2^32进制
void Montgomery_r(BIGNUM A,BIGNUM B,BIGNUM N,BIGNUM remainder)
{
	unsigned i=0,j=0;
	BIGNUM product,temp;
	//BIGNUM A;//被乘数
	//BIGNUM B;//乘数
	BIGNUM C;//每次模余的和
	unsigned __int32 B0;
	unsigned __int32 C0;
	
	unsigned __int32 q;
	unsigned __int32 m;
	
	unsigned int iDataLength;
	unsigned __int64 b1;
	

	//CopyBigNum(A,A1);
	//CopyBigNum(B,B1);
	memset(C,0,sizeof(BIGNUM));//C'=0


	//*************************************************************************
	//求N_0;符合N[0]*N[0]' %r =1;
	//N0=n%2^32=N[1],r=2^32;N0x-ry=1=>ax-(2^32)*y=1
	unsigned __int64 r;
	unsigned __int32 N0,N_0;//N0=n%(2^32);
	unsigned __int32 x,y;
	N0=N[1];
	r=0x100000000;//b=2^32
	GetEuclidEquation2(N0,r,N_0,y);//N[0]*N[0]' %r =1
	//N_0=x;
	/************************************************************************/
	//N_0=N_;
	B0=B[1];//B0=B%(2^32+1)
	m=0xFFFFFFFF-N_0+1;//2^32-N_0;

	iDataLength=N[0];//N的r进制的位数
	for(i=1;i<=iDataLength;i++)
	{
		C0=C[1];//C0=C%(2^32+1);
		//q=(C'[0]+A[i]*B[0])*m %r
		
		b1=(i<=A[0] ? A[i]*B0:0);//保证A的长度和N对齐
		if((b1>>32)>=1)
			b1=(unsigned __int32)b1;//b1=A[i]*B[0] %r
		b1=C0+b1;
		if((b1>>32)>=1)
			b1=(unsigned __int32)b1;//b1=(C'[0]+A[i]*B[0]) %r
		b1=b1*m;
		if((b1>>32)>=1)
			b1=(unsigned __int32)b1;//(C'[0]+A[i]*B[0])*m %r
		q=(unsigned __int32)b1;

		//C'=(C'+A[i]*B+q*N)/r
		bignum_mul_long(B,A[i],product);//A[i]*B
		bignum_add(C,product,temp);//C=C+A[i]*B
		CopyBigNum(C,temp);

		bignum_mul_long(N,q,product);//q*N
		bignum_add(C,product,temp);//C=(C'+A[i]*B+q*N)
		CopyBigNum(C,temp);

		for(j=2;j<=C[0];++j)//C=C/r
		{
			C[j-1]=C[j];
		}
		C[C[0]]=0;
		C[0]--;
		
	}

	if(CompareBigNum(C,N)>=0)//IF C'>=N C'=C'-N
	{
			bignum_substract(C,N,remainder);
			return;
			//CopyBigNum(C,temp);
	}
	CopyBigNum(remainder,C);


}
//二进制
//A*B*2^(-k) mod m --->k为m的比特位数
void Montgomery_2(BIGNUM A,BIGNUM B,BIGNUM m,BIGNUM remainder)
{
	unsigned i=0;
	BIGNUM product,temp;
	//BIGNUM A;//被乘数
	//BIGNUM B;//乘数
	BIGNUM C;//每次模余的和

	//CopyBigNum(A,multiplicand);
	//CopyBigNum(B,multiplicator);
	memset(C,0,sizeof(BIGNUM));//C'=0
	unsigned int iBitCount=GetBigNumBitCount(m);//
	unsigned int iCarry=0;//是否能整除
	for(i=0;i<iBitCount;i++)
	{
		//bignum_mul_long(multiplicator,multiplicand[i],product);//A[i]*B+C
		if(bignum_get_bit(A,i))//A[i]=1;
		{
			CopyBigNum(product,B);
			bignum_add(C,product,temp);
			CopyBigNum(C,temp);
		}
		if(bignum_get_bit(C,0))//C为奇数
		{
			iCarry=1;
			bignum_add(C,m,temp);
			CopyBigNum(C,temp);
		}
		//if(i==iBitCount-1)
		//	break;
		bignum_rightshift2(C,1,temp);//C=C/2
		CopyBigNum(C,temp);
	}
	if(CompareBigNum(C,m)>=0)//IF C'>=N C'=C'-N
	{
			bignum_substract(C,m,temp);
			CopyBigNum(C,temp);
	}
	CopyBigNum(remainder,C);
}
//选择与模数n互素的基数R=2^k,n满足2k-1≤n<2k, n应为奇数。
//并且选择R'及n’,满足0< R'<n, 0< n’<n,使得 RR'-nn’=1。
//对于0≤m<Rn的任意整数,Montgomery给出求模乘法mR^(-1) mod n 的快速算法M(m):
/*
M(m)
{
k = ( m * n’ ) mod R;
x = (m + k*n ) / R;
    if (x>=n) x -= n;
      return x;
}
*/
void Montgomery4(BIGNUM m,BIGNUM R,BIGNUM n_,BIGNUM n,BIGNUM remainder)
{
	BIGNUM product,k,temp,quotient;
	/*if(CompareBigNum(m,n)>0)
	{
		bignum_mod(m,n,temp);
		CopyBigNum(m,temp);
	}*/
	bignum_mul(m,n_,product);//m*n'
	bignum_mod(product,R,k);//k=(m*n')%R

	bignum_mul(k,n,product);//(k*n)
	bignum_add(m,product,temp);//m+(k*n)
	bignum_div(temp,R,quotient,remainder);
	CopyBigNum(remainder,quotient);
	if(CompareBigNum(remainder,n)>=0)
	{
		bignum_substract(remainder,n,temp);
		CopyBigNum(remainder,temp);
		return;
	}
	
}
//乘模运算C=A*B % N
//A*B=A*(Sum[i=0 to n](B[i]*0x100000000^i))
//A*B % N = (Sum[i=0 to n]((A*B[i])*0x100000000^i)) % N
//void mulmode(BIGNUM A,BIGNUM B,BIGNUM divisor,BIGNUM remainder)
void mulmode(BIGNUM multiplicand,BIGNUM multiplicator,BIGNUM divisor,BIGNUM remainder)
{
	unsigned i=0,j=0;
	BIGNUM product,quotient,temp,tempRemainder;
	BIGNUM A;//被乘数
	BIGNUM B;//乘数
	BIGNUM C;//每次模余的和

	memset(C,0,sizeof(BIGNUM));
	
	CopyBigNum(A,multiplicand);
	CopyBigNum(B,multiplicator);
	for(i=1;i<=B[0];i++)
	{
		//C=C+A*B[i]*0x100000000^(i-1)%N
		bignum_mul_long(A,B[i],product);
		//k=product[0];

		
		for(j=product[0];j>=1 && i>1;--j)
		{
			product[j+i-1]=product[j];//每个数向右移n-1位(低位在前,高位在后)
		}
		for(j=1;j<i-1 ;j++)
		{
			product[j]=0;
		}
		product[0]+=i-1;

		bignum_div(product,divisor,quotient,tempRemainder);
		bignum_add(C,tempRemainder,temp);
		
		if(CompareBigNum(temp,divisor)>=0)
		{
			bignum_div(temp,divisor,quotient,tempRemainder);
			CopyBigNum(C,tempRemainder);
		}
		else
			CopyBigNum(C,temp);
		
	}
	CopyBigNum(remainder,C);
	//bignum_div(C,divisor,quotient,tempRemainder);
	//CopyBigNum(remainder,tempRemainder);//余数

}




//幂模运算D=C^E % N
/*************************************************************************
void powermode(BIGNUM base,BIGNUM power,BIGNUM divisor,BIGNUM remainder)
{
	int i;
	int iBitCount=0;

	char *pszBinary;
	
	if(base[0]==0)
	{
		remainder[0]=0;
		return;
	}
	iBitCount=GetBigNumBitCount(power);
	pszBinary=new char[iBitCount+1];
	
	if(pszBinary==NULL)
	{
		remainder[0]=0;
		return;
	}
	BigNumToBinary(power,pszBinary,iBitCount+1);//把幂(指数)转为二进制
	//printf("二进制=%s\n",pszBinary);
	BIGNUM product,temp,quotient;
	memset(product,0,sizeof(BIGNUM));
	//D=1
	product[0]=1;
	product[1]=1;

	for(i=0;i<iBitCount;i++)
	{
		//D=D*D % N
		if(i>0)
		{
			bignum_mul(product,product,temp);
			CopyBigNum(product,temp);
			//bignum_div(product,divisor,quotient,remainder);
			bignum_mod(product,divisor,remainder);

			CopyBigNum(product,remainder);
			
			//mulmode(product,product,divisor,remainder);
			//CopyBigNum(product,remainder);
		}
					
		if(pszBinary[i]=='1')
		{

			//D=D*C % N
			bignum_mul(product,base,temp);
			CopyBigNum(product,temp);
			//bignum_div(product,divisor,quotient,remainder);
			bignum_mod(product,divisor,remainder);
			//mulmode(product,base,divisor,remainder);

			CopyBigNum(product,remainder);
		}
		if(product[0]==0)
			break;
	}
	CopyBigNum(remainder,product);
	delete[] pszBinary;
}
******************************************************************************/
void powermode(BIGNUM base,BIGNUM power,BIGNUM divisor,BIGNUM remainder)
{
	int i;
	int iBitCount=0;
	unsigned char byte;
	if(base[0]==0)
	{
		remainder[0]=0;
		return;
	}
	iBitCount=GetBigNumBitCount(power);

	BIGNUM product,temp,quotient;
	memset(product,0,sizeof(BIGNUM));
	//D=1
	product[0]=1;
	product[1]=1;

	for(i=iBitCount-1;i>=0;i--)
	{

			byte=(unsigned char)(power[i/32+1]>>(i%32))&0x1;
			//if(CompareBigNum(product,ONEVALUE)>0)
			if(product[1]>1)
			{
				bignum_mul(product,product,temp);
				CopyBigNum(product,temp);

				//bignum_mod(product,divisor,remainder);
				bignum_divmod(product,divisor,NULL,remainder);
				CopyBigNum(product,remainder);
			}
			if(byte==1) 
			{

				//D=D*C % N
				//if(CompareBigNum(product,ONEVALUE)==0)
				if(product[0]==1 &&(product[1]==1))
				{
					CopyBigNum(product,base);//因为base<divisor
					continue;
				}
				else
				{
					bignum_mul(product,base,temp);
					CopyBigNum(product,temp);
					//bignum_mod(product,divisor,remainder);
					bignum_divmod(product,divisor,NULL,remainder);
					CopyBigNum(product,remainder);
				}
			}
			if(product[0]==0)
			{
				//CopyBigNum(remainder,product);
				return;
			}

			
	}
	return;
	//CopyBigNum(remainder,product);
	
}

/******************************************************************************/
/*                                                                            */
/*  函数:  实现2^32进制大数的幂模(调用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^32)**k %N,R'=(2^32)**(-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                                                              */
/******************************************************************************/
//r=2^32进制
void powermode_r(BIGNUM base,BIGNUM power,BIGNUM N,BIGNUM remainder)
{
	int i;
	int iBitCount=0;
	unsigned char byte;
	BIGNUM R,r,R2;
	BIGNUM A,X,temp,temp2,temp3;
	iBitCount=GetBigNumBitCount(power);
	if(base[0]==0)
	{
		remainder[0]=0;
		return;
	}
	memset(R,0,sizeof(BIGNUM));
	memset(R2,0,sizeof(BIGNUM));
	if(base[0]==1)
	{
		R[0]=1;
		R[1]=1;
		R2[0]=1;
		R2[1]=1;
	}
	else
	{
		R[0]=base[0]+1;
		R[R[0]]=1;//R=(2^32)^(base[0]+1)

		//unsigned long t1=0;
		//unsigned long t2=0;
		//t1= GetTickCount();
		//*********************************************************************
		//求R2=R*R的方法1
		bignum_substract(R,N,r);
		bignum_mul(r,r,R2);
		//unsigned long t3=0;
		//unsigned long t4=0;
		//***************************************
		//计算模除的方法1
		//t3= GetTickCount();
		bignum_mod(R2,N,X);
		//t4= GetTickCount();
		//t4-=t3;
		//printf("==========1)计算模除R2/N耗时%lu\n\n",t4);
		//***************************************
		//计算模除的方法2(改进后的模除算法)
		//t3= GetTickCount();
		//bignum_divmod(R2,N,NULL,temp);
		//t4= GetTickCount();
		//t4-=t3;
		//printf("==========2)计算模除R2/N耗时%lu\n\n",t4);


		CopyBigNum(R2,X);	
		//t2= GetTickCount();
		//t2-=t1;
		//printf("==(方法1)计算R2耗时%lu\n",t2);
		//*********************************************************************
		//求R2=R*R的方法2
		/*t1= GetTickCount();
		R2[0]=2*R[0]-1;
		R2[R2[0]]=1;//R2=R*R
		bignum_mod(R2,N,X);
		CopyBigNum(R2,X);	
		t2= GetTickCount();
		t2-=t1;
		printf("==(方法2)计算R2耗时%lu\n",t2);
		***************************************************/
	}

	Montgomery_r(base,R2,N,A);//A=A*R*R%N

⌨️ 快捷键说明

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