Crypt-RSA-Yandex

 view release on metacpan or  search on metacpan

CP_RSA.cpp  view on Meta::CPAN

	void copy( vlong_value& x );
	operator unsigned(); // Unsafe conversion to unsigned
	vlong_value();
	void mul( vlong_value& x, vlong_value& y );
	void divide( vlong_value& x, vlong_value& y, vlong_value& rem );
};

unsigned flex_unit::get( unsigned i ) const
{
	if ( i >= n ) return 0;
	return a[i];
}

void flex_unit::clear()
{
	n = 0;
}

flex_unit::flex_unit()
{
	z = 0;
	a = 0;
	n = 0;
}

flex_unit::~flex_unit()
{
	unsigned i=z;
	while (i) { i-=1; a[i] = 0; } // burn
	delete [] a;
}

void flex_unit::reserve( unsigned x )
{
	if (x > z)
	{
		unsigned * na = new unsigned[x];
		for (unsigned i=0;i<n;i+=1) na[i] = a[i];
		delete [] a;
		a = na;
		z = x;
	}
}

void flex_unit::set( unsigned i, unsigned x )
{
	if ( i < n )
	{
		a[i] = x;
		if (x==0) while (n && a[n-1]==0) n-=1; // normalise
	}
	else if ( x )
	{
		reserve(i+1);
		for (unsigned j=n;j<i;j+=1) a[j] = 0;
		a[i] = x;
		n = i+1;
	}
}

// Macros for doing double precision multiply
#define BPU ( 8*sizeof(unsigned) )		 // Number of bits in an unsigned
#define lo(x) ( (x) & ((1<<(BPU/2))-1) ) // lower half of unsigned
#define hi(x) ( (x) >> (BPU/2) )		 // upper half
#define lh(x) ( (x) << (BPU/2) )		 // make upper half

void flex_unit::fast_mul( flex_unit &x, flex_unit &y, unsigned keep )
{
	// *this = (x*y) % (2**keep)
	unsigned i,j,limit = (keep+BPU-1)/BPU; // size of result in words
	reserve(limit); for (i=0; i<limit; i+=1) a[i] = 0;
	unsigned min = x.n; if (min>limit) min = limit;
	for (i=0; i<min; i+=1)
	{
		unsigned m = x.a[i];
		unsigned c = 0; // carry
		unsigned min = i+y.n; if (min>limit) min = limit;
		for ( j=i; j<min; j+=1 )
		{
			// This is the critical loop
			// Machine dependent code could help here
			// c:a[j] = a[j] + c + m*y.a[j-i];
			unsigned w, v = a[j], p = y.a[j-i];
			v += c; c = ( v < c );
			w = lo(p)*lo(m); v += w; c += ( v < w );
			w = lo(p)*hi(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
			w = hi(p)*lo(m); c += hi(w); w = lh(w); v += w; c += ( v < w );
			c += hi(p) * hi(m);
			a[j] = v;
		}
		while ( c && j<limit )
		{
			a[j] += c;
			c = a[j] < c;
			j += 1;
		}
	}

	// eliminate unwanted bits
	keep %= BPU; if (keep) a[limit-1] &= (1<<keep)-1;

	// calculate n
	while (limit && a[limit-1]==0) limit-=1;
	n = limit;
};

vlong_value::operator unsigned()
{
	return get(0);
}

int vlong_value::is_zero() const
{
	return n==0;
}

int vlong_value::test( unsigned i ) const
{ return ( get(i/BPU) & (1<<(i%BPU)) ) != 0; }

unsigned vlong_value::bits() const
{



( run in 0.735 second using v1.01-cache-2.11-cpan-39bf76dae61 )