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

📄 vlong.cpp

📁 椭圆曲线密码C实现的
💻 CPP
字号:
#include "stdafx.h"
#include "vlong.h"

#define PTLSIZE 550
const static int pt[PTLSIZE] =
{   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,  1009, 1013, 1019, 
	1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087,
	1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 
	1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 
	1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 
	1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381,
	1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 
	1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523,
	1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 
	1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 
	1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 
	1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 
	1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 
	1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 
	1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063,
	2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 
	2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 
	2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293,
	2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371,
	2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 
	2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 
	2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 
	2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 
	2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 
	2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 
	2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909,
	2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001,
	3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083,
	3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 
	3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 
	3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343,
	3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 
	3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 
	3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581,
    3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 
	3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 
	3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 
	3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 
	3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001
};
//利用费儿马定理证明一个素数
static int is_probable_prime( const vlong &p )
{
	// Test based on Fermats theorem a**(p-1) = 1 mod p for prime p
	// For 1000 bit numbers this can take quite a while
	const rep = 4;	
	vlong mod;
	const unsigned any[rep] = { 2,3,5,7 };
	for ( unsigned i=0; i<rep; i+=1 )
	{
		::modexp(any[i],p-1,p,mod);
		if( mod != vlong(1) )
			return 0;
	}
	return 1;
}

vlong::vlong ( int	x )
{
	if(x<0){	
		m_nNegative = 1;
	}else{
		m_nNegative = 0;
	}
	m_pValue= new uvlong(x);
	m_clint = m_pValue->m_clint;

}

vlong::vlong ( const vlong& x ) // copy constructor
{
  m_nNegative	=	x.m_nNegative;
  m_pValue		=	x.m_pValue;
  m_pValue->m_share += 1;
  m_clint = m_pValue->m_clint;
}

vlong::~vlong()
{
	if(m_pValue->m_share) { m_pValue->m_share -= 1;}else{	delete m_pValue;}

}

vlong& vlong::operator =(const vlong& x)
{
	copy_cl(m_clint,x.m_clint);
	m_nNegative = x.m_nNegative;
	return *this;
}

vlong& vlong::operator +=(const vlong& x)
{
	if ( m_nNegative == x.m_nNegative )
	{
		add_cl(m_clint, x.m_clint, m_clint );
	}else{ 	
		if(comp_cl(m_clint,x.m_clint) >= 0)
		{
			sub_cl( m_clint, x.m_clint, m_clint );
		}else{
			ULINT	tmp;
			copy_cl( tmp, x.m_clint);
			sub_cl( tmp, m_clint, m_clint );
			m_nNegative = x.m_nNegative; 
		}
	}
	
	return *this;
}

vlong& vlong::operator -=(const vlong& x)
{
	if ( m_nNegative != x.m_nNegative )
	{
		add_cl(m_clint, x.m_clint, m_clint );
	}else{
		if ( comp_cl(m_clint,x.m_clint) >= 0 )
		{
			sub_cl( m_clint, x.m_clint, m_clint );
		}else{
			ULINT	tmp;
			copy_cl( tmp, x.m_clint);
			sub_cl( tmp, m_clint, m_clint );
			m_nNegative = 1 - m_nNegative; 			
		}
	}
	return *this;
}

vlong	operator +( const vlong& x, const vlong& y )
{
	vlong	result = x;
	result	+= y;
	return result;
}


vlong	operator -( const vlong& x, const vlong& y )
{
	vlong	result = x;
	result	-= y;
	return result;
}

vlong	operator *( const vlong& x, const vlong& y )
{
	vlong result;
	int a = x.m_pValue->GetBits();
	int b = y.m_pValue->GetBits();
	
	mul_cl(x.m_clint,y.m_clint,result.m_clint,a+b);
	result.m_nNegative = x.m_nNegative ^ y.m_nNegative;
	return result;
}

vlong	operator /( const vlong& x, const vlong& y )
{
	vlong result;
	ULINT rem; 

	div_cl( x.m_clint, y.m_clint, result.m_clint, rem);
	result.m_nNegative = x.m_nNegative ^ y.m_nNegative;
	return result;
}


vlong	operator %( const vlong& x, const vlong& y )
{
	vlong	result;
	ULINT	divid;
	if(y.m_nNegative == 0)
	{
		div_cl( x.m_clint, y.m_clint, divid,result.m_clint );
		result.m_nNegative = x.m_nNegative; // not sure about this?
	}
	
	return result;
}

vlong::operator unsigned()
{
	int x= ( m_clint[0] > 2) ? 2 : m_clint[0];
	
	int n=0;
	for(int i = 1 ; i <= x ; i++ )
	{
		n += (m_clint[i]<<(BPU*(i-1)));
	}
	
	if(m_nNegative>0)
		n = -n;
	
	return n;
}

int comp_vl( const vlong  a,const vlong   b)
{
	if(a.m_nNegative < b.m_nNegative) { return +1; }
	if(a.m_nNegative > b.m_nNegative) { return -1; }
	int x = comp_cl(a.m_clint, b.m_clint );
	if(x == 0){ return 0; }
	
	if(( a.m_nNegative > 0  && x > 0 ) || ( a.m_nNegative == 0 && x < 0 )){
		return -1;
	}else{
		return +1;
	}
}

bool  modinv1(const vlong &e, const vlong &m, vlong &u, vlong &v )
{
	//u*a+v*b=(a,b)
	vlong	a,b;
	vlong	s,t,zero,g,w;//u,v,
	vlong	q,r;
	
	zero = ushort(0);
	
	if(m>e)
	{
		a = m;
		b = e;
	}else{
		if(m<e){
			a = e;
			b = m;
		}else{
			return false;
		}
	}
	
	s = 1; u = 0;
	t = 0; v = 1;
	do{
		//a = q*b+r
		if(b == vlong(0) )
			return false;
		q = a/b;
		r = a%b;
		
        if(r !=vlong(0) )
		{
			a = b;		b = r;
			w = u;		u = s-q*u; 
			s = w;		w = v;
			v = t-q*v;	t = w;
		}else{
			g = b;
			break;
		}
	}while(1);
	
	if(u<vlong(0)) { u = (m>e) ? u+e : u+m; }
	if(v<vlong(0)) { v = (m>e) ? v+m : v+e; }
	
	
	return true;
}

bool modinv2(const vlong &e, const vlong &m, vlong &d)
{
	vlong j,b,c,x,y;
	c.m_pValue->gcd(*e.m_pValue,*m.m_pValue) ;
	if( c != vlong(1))
		return false;

	b=m;j=1;c=e;d = 0;
	
	vlong t(0);
	while ( c != t )
	{
		if(c == vlong(0))
			return false;
		x = b / c;
		y = b - x*c;
		b = c;
		c = y;
		y = j;
		j = d - j*x;
		d = y;
	}
	if ( d < t )
		d += m;

	if( ((e*d)%m)!= vlong(1))//(e*d)%m
		return false;

	return true;
}

//产生随机大数
bool    randval(vlong &out,unsigned int bitlen)//len 输入随即数得二进制位数
{
	if(bitlen <= 0 )
		return false;

	out = 0;
	srand(GetTickCount());
	
	unsigned  len	= bitlen/16;
	unsigned  j		= bitlen%16;  
	
	for(unsigned i = 1; i <=  len; i ++ )
	{
		out.m_clint[i] = rand()%0x010000;
		out.m_clint[0] = i;
	}
	
	if(j == 0)	
	{
		out.m_clint[i-1] |= 1 << 0xf;
	}else{	
		out.m_clint[i] = rand()%0x010000;
		out.m_clint[i] &= (0xffff>>(16-j));
		out.m_clint[i] |= 1 << (j-1);
		out.m_clint[0] += 1;  
	}
	out.m_clint[1] |= 0x01;

	return true;
}
/*
bool  findprime(vlong &p,unsigned int bitlen)
{
//	if( bitlen<16 || bitlen>(CLINTMAXDIGIT*BPU)/4)
//		MessageBox(NULL,"素数长度不在合法范围之内!","错误" ,MB_ICONERROR | MB_OK);
	
	vlong	p_1,p_1_div_2,lp,a,tmp;
	int		i,k=0;
	int		end = PTLSIZE;
	// 产生一个随机大数(奇数) p

Next:	++k;
		if(!randval(p,bitlen))
			return false;

		// 再用 Lehmann 方法测试
		p_1	 =	p; 
		p_1	-=	1;
		p_1_div_2 = p_1/vlong(2) ;

		for( i = 0; i < 15; ++i )// 产生一个小随机大数 A
		{   
			while(1)
			{
				a = (rand() & 0x0fffffff);
				if(a < p_1)
					break;
			}
			tmp.modexp(a,p_1_div_2,p);			
			//思考:当p为素数时,tmp的值为1或p_1??
			if(( tmp != vlong(1) ) && (tmp != p_1))
			{   
				goto Next;
			}	
		}

		return true;

}
*/
bool  findprime(vlong &p,unsigned int bitlen)
{
	int i,SS = PTLSIZE*5,tested = 0; 
	unsigned char * b = new unsigned char[SS];
	vlong pl,r;
	
	if(!randval(p,bitlen))
		return false;
    while (1)
	{
		for (i=0;i<SS;i+=1)
			b[i] = 1;
		for (i=0;i<PTLSIZE;i+=1)
		{
			pl = pt[i];
			r = p % vlong(pl); 
			
			if (r) r = pl - r;
			
			while ( r < vlong(SS) )
			{
				b[r] = 0;
				r += pl;
			}
		}
		
		for (i=0;i<SS;i+=1)
		{
			if ( b[i] )
			{
				tested += 1;
				if ( is_probable_prime(p) )
				{
					goto end;
				}
			}
			p += 1;
		}
	}
end :
	delete []b;
	return true;

}

bool modexp( const vlong & m, const vlong & e, const vlong & mod , vlong & result)
{
	if(result.m_pValue != NULL)
		result.m_pValue->modexp(*m.m_pValue, *e.m_pValue, *mod.m_pValue);

	return true;
}

⌨️ 快捷键说明

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