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

📄 largeint.cpp

📁 rsa算法/// ////
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			sal ecx,dword ptr 2;
			
			sub eax,len; //求初始偏移。
			
			mov ebx,dword ptr 4; //偏移倍率
			mul ebx;		
			
			lea ebx,label0;
			add eax,ebx;
			clc;
			jmp eax;
	labelloop:
			popf;
	label0:
			rcr dword ptr [esi + ecx - 1*4],1;
			//label1:
			rcr dword ptr [esi + ecx - 2*4],1;
			//label2:
			rcr dword ptr [esi + ecx - 3*4],1;
			//label3:
			rcr dword ptr [esi + ecx - 4*4],1;
			//label4:
			rcr dword ptr [esi + ecx - 5*4],1;
			//label5:
			rcr dword ptr [esi + ecx - 6*4],1;
			//label6:
			rcr dword ptr [esi + ecx - 7*4],1;
			//label7:
			rcr dword ptr [esi + ecx - 8*4],1;
			//label8:
			rcr dword ptr [esi + ecx - 9*4],1;
			//label9:
			rcr dword ptr [esi + ecx - 10*4],1;
			//label10:
			rcr dword ptr [esi + ecx - 11*4],1;
			//label11:
			rcr dword ptr [esi + ecx - 12*4],1;
			//label12:
			rcr dword ptr [esi + ecx - 13*4],1;
			//label13:
			rcr dword ptr [esi + ecx - 14*4],1;
			//label14:
			rcr dword ptr [esi + ecx - 15*4],1;
			//label15:
			rcr dword ptr [esi + ecx - 16*4],1;
			//label16:
			pushf;
			sub ecx,dword ptr 64;
			jnz labelloop;
			popf;
			popad;
		}
		for( T_DWORD i = n._len-1; i > 0; i--)
		{
			if( n._data[i] == 0 ) //末尾是0
			{
				n._len--;
			}
			else break;
		}
	}
	
	void CLargeInt::RCL(CLargeInt& n)
	{
		T_DWORD	len = n._len; //len绝对不能<1,否则会出错。
		T_DWORD	*p1 = 0;
		
		n._data[len] = 0;
		n._len++;
		
		len++;
		p1 = n._data;
		
		__asm
		{
			pushad;		
			
			//载入计算地址
			mov esi,p1;
			
			mov eax,len;
			mov ecx,eax;
			
			sal eax,dword ptr 2;
			add esi,eax;
			
			add ecx,dword ptr 15;
			and ecx,dword ptr 0xFFFFFFF0;
			
			mov eax,ecx;
			sal ecx,dword ptr 2;
			
			neg ecx;
			
			sub eax,len; //求初始偏移。
			jz label0;
			
			mov ebx,dword ptr 4; //偏移倍率
			mul ebx;		
			
			lea ebx,label1;
			sub ebx,4;
			add eax,ebx;
			clc;
			jmp eax;
	labelloop:
			popf;
	label0:
			rcl dword ptr [esi + ecx + 0*4],1;
	label1:
			rcl dword ptr [esi + ecx + 1*4],1;
			//label2:
			rcl dword ptr [esi + ecx + 2*4],1;
			//label3:
			rcl dword ptr [esi + ecx + 3*4],1;
			//label4:
			rcl dword ptr [esi + ecx + 4*4],1;
			//label5:
			rcl dword ptr [esi + ecx + 5*4],1;
			//label6:
			rcl dword ptr [esi + ecx + 6*4],1;
			//label7:
			rcl dword ptr [esi + ecx + 7*4],1;
			//label8:
			rcl dword ptr [esi + ecx + 8*4],1;
			//label9:
			rcl dword ptr [esi + ecx + 9*4],1;
			//label10:
			rcl dword ptr [esi + ecx + 10*4],1;
			//label11:
			rcl dword ptr [esi + ecx + 11*4],1;
			//label12:
			rcl dword ptr [esi + ecx + 12*4],1;
			//label13:
			rcl dword ptr [esi + ecx + 13*4],1;
			//label14:
			rcl dword ptr [esi + ecx + 14*4],1;
			//label15:
			rcl dword ptr [esi + ecx + 15*4],1;
			//label16:
			pushf;
			add ecx,dword ptr 64;
			jnz labelloop;
			popf;
			popad;
		}
		for( T_DWORD i = n._len-1; i > 0; i--)
		{
			if( n._data[i] == 0 ) //末尾是0
			{
				n._len--;
			}
			else break;
		}
	}
	
	void CLargeInt::Mul(const CLargeInt& faciend,const CLargeInt& multiplier,CLargeInt& product)
	{
		CLargeInt temp;
		product._len = (faciend._len + multiplier._len);
		memset(product._data,0,product._len * 4	);
		
		for( T_DWORD i = 0; i <	multiplier._len; i++)
		{
			Mul(faciend,multiplier._data[i],temp);
			Add(product,temp,product,i);
		}
		for( i = product._len-1; i > 0;	i--)
		{
			if( product._data[i] ==	0 ) //末尾是0
			{
				product._len--;
			}
			else break;
		}
	}
	
	void CLargeInt::Div(const CLargeInt& dividend,T_DWORD divisor,CLargeInt& quotient,T_DWORD& residual)
	{
		T_DWORD	len; //len绝对不能<1,否则会出错。
		T_DWORD	*p1 = 0;
		T_DWORD	*p2 = 0;
		
		T_DWORD	*pr = &residual;
		
		len = dividend._len;
		quotient._len =	dividend._len;
		p1 = dividend._data;
		p2 = quotient._data;
		
		__asm
		{
			pushad;		
			
			//载入计算地址
			mov esi,p1;
			mov edi,p2;
			
			mov eax,len;
			mov ecx,eax;
			
			add ecx,dword ptr 7;
			and ecx,dword ptr 0xFFFFFFF8;
			
			mov eax,ecx;
			sal ecx,dword ptr 2;
			
			sub eax,len; //求初始偏移。
			
			mov ebx,dword ptr 0x0A;	//偏移倍率
			mul ebx;		
			
			lea edx,label0;
			add eax,edx;
			
			xor edx,edx;
			
			mov ebx,divisor;
			
			clc;
			jmp eax;
	labelloop:
			
	label0:
			mov eax,[esi + ecx - 1*4];
			div ebx;
			mov [edi + ecx - 1*4],eax;
			//label1:
			mov eax,[esi + ecx - 2*4];
			div ebx;
			mov [edi + ecx - 2*4],eax;
			//label2:
			mov eax,[esi + ecx - 3*4];
			div ebx;
			mov [edi + ecx - 3*4],eax;
			//label3:
			mov eax,[esi + ecx - 4*4];
			div ebx;
			mov [edi + ecx - 4*4],eax;
			//label4:
			mov eax,[esi + ecx - 5*4];
			div ebx;
			mov [edi + ecx - 5*4],eax;
			//label5:
			mov eax,[esi + ecx - 6*4];
			div ebx;
			mov [edi + ecx - 6*4],eax;
			//label6:
			mov eax,[esi + ecx - 7*4];
			div ebx;
			mov [edi + ecx - 7*4],eax;
			//label7:
			mov eax,[esi + ecx - 8*4];
			div ebx;
			mov [edi + ecx - 8*4],eax;
			//label8:
			sub ecx,dword ptr 32;
			jnz labelloop;
			
			//运行到这里说明已经计算完毕,最后保存余数。
			mov ecx,pr;
			mov [ecx],edx;
			popad;
		}
		
		for( T_DWORD i = quotient._len-1; i > 0; i--)
		{
			if( quotient._data[i] == 0 ) //末尾是0
			{
				quotient._len--;
			}
			else break;
		}
	}
	
	void CLargeInt::Div(const CLargeInt& dividend,const CLargeInt& divisor,CLargeInt& quotient,CLargeInt& residual)
	{
		if( dividend._len < divisor._len )
		{
			quotient._len =	1;
			quotient._data[0] = 0;
			Copy(dividend,residual);
		}
		else
		{
			if( divisor._len == 1)
			{			
				Div(dividend,divisor._data[0],quotient,residual._data[0]);
				residual._len =	1;
			}
			else
			{
				CLargeInt d,r;
				
				//满位算法
				T_DWORD	head = divisor._data[divisor._len-1];
				__asm
				{
					pushad;
					mov eax,head;
					bsr ecx,eax;
					mov edx,dword ptr 31;
					sub edx,ecx;
					mov ecx,edx;
					mov eax,dword ptr 0x01;
					sal eax,cl;
					mov head,eax;
					popad;
				}
				
				Mul(dividend,head,d);
				Mul(divisor,head,r);
				
				quotient._len =	d._len - r._len	+ 1;
				quotient._data[quotient._len - 1] = 0;
				
				T_DWORD	newhead	= r._data[r._len - 1];
				//以上处理的目的是使得被除数最高位的1移动到DWORD的最高位。
				//处理之后可以极大减少商的上下限之间的差距。
				
				T_DWORD	highpart = 0;
				T_DWORD	lowpart	 = 0;
				T_DWORD	max = 0,min = 0;
				T_DWORD	offset = 0;
				CLargeInt temp;
				for( T_DWORD i = d._len-1; i >=	r._len-1; i-- )
				{				
					offset = i - (r._len - 1);	
					lowpart	= d._data[i];
					
					__asm
					{//这段汇编代码的作用是求商的上下限。min & max
						pushad;
						mov edx,highpart;
						mov eax,lowpart;
						mov ecx,newhead;
						div ecx;
						mov max,eax;
						
						inc ecx;
						jz _mov;
						mov edx,highpart;
						mov eax,lowpart;
						div ecx;
						mov edx,eax;
	_mov:
						mov min,edx;
						popad;
					}
					
					if( max	== 0 )
					{
						highpart = d._data[i];
						quotient._data[offset] = 0;
					}
					else
					{
						Mul(r,max,temp);
						if( max	!= min )
						{
							while( !LargerEqual(d,temp,offset) )
							{//这里使用的其实是试商法,
								//由于max和min的差距已经很小,所以这里不再折半试商。
								max--;
								Sub(temp,r,temp);
							}
						}	
						
						quotient._data[offset] = max; //保存商。
						Sub(d,temp,d,offset); //求本阶的余数。
						highpart = d._data[i]; //载入余数。
					}
				}
				
				//清除高位的0。
				for( i = quotient._len-1; i > 0; i--)
				{
					if( quotient._data[i] == 0 ) //末尾是0
					{
						quotient._len--;
					}
					else break;
				}
				//除法完成,计算余数:
				Div(d,head,residual,newhead);
				
				if( newhead != 0 ) 
				{
					//余数不为0,说明出错。
					__asm int 3;
				}
			}
			
		}
	}
	
	void CLargeInt::ExpMod(const CLargeInt&	source,const CLargeInt&	exponent,const CLargeInt& modulo,CLargeInt& result)
	{
		CLargeInt n,e,r(1),temp,temp1;
		Copy(source,n);
		Copy(exponent,e);
		
		while( e._len >	1 || e._data[e._len - 1] > 1 )
		{
			if( e._data[0] &1 ) 
			{
				Mul(r,n,temp);
				Div(temp,modulo,temp1,r);
			}
			RCR(e);
			Mul(n,n,temp);
			Div(temp,modulo,temp1,n);
		}
		Mul(r,n,temp);
		Div(temp,modulo,temp1,result);
	}
	
	bool CLargeInt::RabinMillerTest(const CLargeInt& source,const CLargeInt& base)
	{
		CLargeInt m,temp(1);
		
		Sub(source,temp,m);
		
		T_DWORD	count =	0;
		while(!(m._data[0] & 0x01) ) 
		{
			count++;
			RCR(m);
		}
		/*
		这里注释掉的是旧的算法,可以用后面的等效算法取代。
		改变的算法使得计算ExpMod的次数由 count 减少到 1
		虽然理论上计算次数大大减少了,但是实际效果似乎只是减少了50%左右的运算量。
		
		  for( T_DWORD i = 0; i< count;	i++)
		  {
		  CLargeInt mod;
		  ExpMod(base,m,source,mod);
		  if( mod._data[0] == 1	&& mod._len == 1 ) 
		  {
		  return true;
		  }
		  else
		  {
		  Sub(source,mod,temp);
		  if(  temp._data[0] ==	1 && temp._len == 1) 
		  {
		  return true;
		  }
		  }
		  RCL(m);		
		  }
		*/
		
		CLargeInt mod;
		ExpMod(base,m,source,mod);
		if( mod._data[0] == 1 && mod._len == 1 ) 
		{
			return true;
		}
		else
		{
			Sub(source,mod,temp);
			if(  temp._data[0] == 1	&& temp._len ==	1) 
			{
				return true;
			}
		}
		for( T_DWORD i = 1; i< count; i++)
		{
			CLargeInt next,t;
			Mul(mod,mod,next);
			Div(next,source,t,mod);
			if( mod._data[0] == 1 && mod._len == 1 ) 
			{
				return true;
			}
			else
			{
				Sub(source,mod,temp);
				if(  temp._data[0] == 1	&& temp._len ==	1) 
				{
					return true;
				}
			}			
		}
		
		return false;
	}
	
	bool CLargeInt::RSACreate( const CLargeInt &p,const CLargeInt &	q,const	CLargeInt &e,CLargeInt &d,CLargeInt &n)
	{//由已知的P,Q,E计算N,D,完成RSA密钥生成。
		Mul(p,q,n);
		CLargeInt a(e),b(n);
		Sub(b,p,b);
		Sub(b,q,b);
		Add(b,1,b);
		
		if( !Coprime(b,e) ) return false;
		//求D的算法,通过辗转相除,最终求得需要的D值。
		CLargeInt k1,c1;
		Div(b,a,k1,c1);
		if( c1._len == 1 && c1._data[0]	== 0 ) return false;
		if( c1._len == 1 && c1._data[0]	== 1 ) 
		{ 
			CLargeInt temp;
			Sub(e,1,temp);
			Mul(temp,k1,d);
			Add(d,1,d);
			return true; 
		}
		
		CLargeInt k2,c2,ka2;
		Div(a,c1,k2,c2);
		if( c2._len == 1 && c2._data[0]	== 0 ) return false;
		Mul(k1,k2,ka2);
		Add(ka2,1,ka2);
		if( c2._len == 1 && c2._data[0]	== 1 ) { Copy(ka2,d); return true; }
		
		
		CLargeInt k3,c3,ka3;
		Div(c1,c2,k3,c3);
		if( c3._len == 1 && c3._data[0]	== 0 ) return false;
		Mul(k3,ka2,ka3);
		Add(ka3,k1,ka3);
		if( c3._len == 1 && c3._data[0]	== 1 ) 
		{ 
			Copy(ka3,d);
			
			CLargeInt temp,temp1,temp2;
			Mul(d,e,temp);
			Div(temp,b,temp1,temp2);
			Add(temp2,1,temp2);
			if( Equal(temp2,b) )
			{
				Mul(d,d,temp1);
				Div(temp1,b,temp2,d);
				Mul(d,e,temp1);
				Div(temp1,b,temp2,d);
			}
			return true; 
		}
		
		CLargeInt kn_2(k2),cn_2(c2),ka_2(ka2);
		CLargeInt kn_1(k3),cn_1(c3),ka_1(ka3);
		
		CLargeInt kn,cn,kan;
		do {
			Div(cn_2,cn_1,kn,cn);
			Mul(kn,ka_1,kan);
			Add(kan,ka_2,kan);
			
			if( cn._len == 1 && cn._data[0]	== 0 ) return false;
			if( cn._len == 1 && cn._data[0]	== 1 ) 
			{
				Copy(kan,d);
				
				CLargeInt temp,temp1,temp2;
				Mul(d,e,temp);
				Div(temp,b,temp1,temp2);
				Add(temp2,1,temp2);
				if( Equal(temp2,b) )
				{
					Mul(d,d,temp1);
					Div(temp1,b,temp2,d);
					Mul(d,e,temp1);
					Div(temp1,b,temp2,d);
				}
				return true; 
			}
			Copy(kn_1,kn_2);
			Copy(cn_1,cn_2);
			Copy(ka_1,ka_2);
			
			Copy(kn,kn_1);
			Copy(cn,cn_1);
			Copy(kan,ka_1);
			
		} while(true);
	}
	
	void CLargeInt::RSAEncode( const CLargeInt &n,const CLargeInt &d,const CLargeInt &m,CLargeInt &c)
	{
		ExpMod(m,d,n,c);
	}
	
	void CLargeInt::RSADecode( const CLargeInt &n,const CLargeInt &e,const CLargeInt &c,CLargeInt &m)
	{
		ExpMod(c,e,n,m);
	}
	
	typedef	unsigned __int64 ULONGLONG;
	inline ULONGLONG GetCycleCount()
	{
		__asm RDTSC
	}
	#include <windows.h>
	void CLargeInt::CreateRandom(CLargeInt &n,T_DWORD bitcount)
	{
		n._len = (bitcount + 31)/32;
		for( T_DWORD i = 0; i <	n._len;	i++ )
		{
			T_DWORD	byte[4];
			
			for( int b = 0;	b < 4; b++)
			{
				for( int j = 0;	j < 4 ;	j++)
				{
					Sleep(0);
				}
				byte[b]	= GetCycleCount()& 0xFF;
			}
			
			n._data[i] = (byte[0] << 24)
				| (byte[1] << 16)
				| (byte[2] << 8)
				| (byte[3] << 0);
		}
		n._data[0] |= 1;
		n._data[n._len - 1] |= 0x80000000;
		if( (bitcount &	31) )
		{
			n._data[n._len - 1] >>=	32 - (bitcount & 31);
		}	
	}
	
	bool CLargeInt::Coprime(const CLargeInt	&source,const CLargeInt	&target)
	{
		CLargeInt m(source),n(target),temp;
		while(true)
		{
			Div(m,n,temp,m);
			if( m._len == 1	&& m._data[0] == 1 ) return true;
			else if( m._len	== 1 &&	m._data[0] == 0	) return false;
			
			Div(n,m,temp,n);
			if( n._len == 1	&& n._data[0] == 1 ) return true;
			else if( n._len	== 1 &&	n._data[0] == 0	) return false;
		}
	}
}

⌨️ 快捷键说明

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