131 lines
4.0 KiB
C
131 lines
4.0 KiB
C
|
|
#ifndef __BIGINT_H
|
||
|
|
#define __BIGINT_H
|
||
|
|
|
||
|
|
class bigint;
|
||
|
|
class bigint_value;
|
||
|
|
|
||
|
|
class bigint_unit // Provides storage allocation and index checking
|
||
|
|
{
|
||
|
|
friend class bigint_value;
|
||
|
|
friend class bigint;
|
||
|
|
|
||
|
|
public:
|
||
|
|
bigint_unit();
|
||
|
|
~bigint_unit();
|
||
|
|
|
||
|
|
public:
|
||
|
|
void clear(); // set n to zero
|
||
|
|
unsigned get( unsigned i ) const; // get ith unsigned
|
||
|
|
void set( unsigned i, unsigned x ); // set ith unsigned
|
||
|
|
void reserve( unsigned x ); // storage hint
|
||
|
|
void fast_mul( bigint_unit & x, bigint_unit & y, unsigned n ); // Time critical routine
|
||
|
|
|
||
|
|
private:
|
||
|
|
unsigned n; // used units (read-only)
|
||
|
|
unsigned * a; // array of units
|
||
|
|
unsigned z; // units allocated
|
||
|
|
};
|
||
|
|
|
||
|
|
class bigint_value : public bigint_unit
|
||
|
|
{
|
||
|
|
friend class bigint;
|
||
|
|
|
||
|
|
public:
|
||
|
|
bigint_value();
|
||
|
|
|
||
|
|
public:
|
||
|
|
int is_zero() const;
|
||
|
|
unsigned bit( unsigned i ) const;
|
||
|
|
void setbit( unsigned i );
|
||
|
|
void clearbit( unsigned i );
|
||
|
|
unsigned bits() const;
|
||
|
|
int cf( bigint_value& x ) const;
|
||
|
|
int product( bigint_value &x ) const;
|
||
|
|
void shl();
|
||
|
|
int shr(); // result is carry
|
||
|
|
void shr( unsigned n );
|
||
|
|
void add( bigint_value& x );
|
||
|
|
void _xor( bigint_value& x );
|
||
|
|
void _and( bigint_value& x );
|
||
|
|
void subtract( bigint_value& x );
|
||
|
|
void init( unsigned x );
|
||
|
|
void copy( bigint_value& x );
|
||
|
|
unsigned to_unsigned(); // Unsafe conversion to unsigned
|
||
|
|
void mul( bigint_value& x, bigint_value& y );
|
||
|
|
void divide( bigint_value& x, bigint_value& y, bigint_value& rem );
|
||
|
|
|
||
|
|
private:
|
||
|
|
unsigned share; // share count, used by bigint to delay physical copying
|
||
|
|
};
|
||
|
|
|
||
|
|
class bigint // very long integer - can be used like long
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
// Construction and
|
||
|
|
bigint ( unsigned x = 0 );
|
||
|
|
bigint ( const bigint & x );
|
||
|
|
~bigint();
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Standard arithmetic operators
|
||
|
|
friend bigint operator +( const bigint& x, const bigint& y );
|
||
|
|
friend bigint operator -( const bigint& x, const bigint& y );
|
||
|
|
friend bigint operator *( const bigint& x, const bigint& y );
|
||
|
|
friend bigint operator /( const bigint& x, const bigint& y );
|
||
|
|
friend bigint operator %( const bigint& x, const bigint& y );
|
||
|
|
friend bigint operator ^( const bigint& x, const bigint& y );
|
||
|
|
friend bigint pow2( unsigned n );
|
||
|
|
friend bigint operator &( const bigint& x, const bigint& y );
|
||
|
|
|
||
|
|
friend bigint operator <<( const bigint& x, unsigned n );
|
||
|
|
|
||
|
|
bigint & operator +=( const bigint& x );
|
||
|
|
bigint & operator -=( const bigint& x );
|
||
|
|
bigint & operator >>=( unsigned n );
|
||
|
|
|
||
|
|
// Standard comparison operators
|
||
|
|
friend int operator !=( const bigint& x, const bigint& y );
|
||
|
|
friend int operator ==( const bigint& x, const bigint& y );
|
||
|
|
friend int operator >=( const bigint& x, const bigint& y );
|
||
|
|
friend int operator <=( const bigint& x, const bigint& y );
|
||
|
|
friend int operator > ( const bigint& x, const bigint& y );
|
||
|
|
friend int operator < ( const bigint& x, const bigint& y );
|
||
|
|
|
||
|
|
// Absolute value
|
||
|
|
friend bigint abs( const bigint & x );
|
||
|
|
|
||
|
|
// conversion operations
|
||
|
|
friend unsigned to_unsigned( const bigint &x );
|
||
|
|
bigint & operator =(const bigint& x);
|
||
|
|
|
||
|
|
// Bit operations
|
||
|
|
unsigned bits() const;
|
||
|
|
unsigned bit(unsigned i) const;
|
||
|
|
void setbit(unsigned i);
|
||
|
|
void clearbit(unsigned i);
|
||
|
|
bigint & operator ^=( const bigint& x );
|
||
|
|
bigint & operator &=( const bigint& x );
|
||
|
|
bigint & ror( unsigned n ); // single bit rotate
|
||
|
|
bigint & rol( unsigned n ); // single bit rotate
|
||
|
|
friend int product( const bigint & x, const bigint & y ); // parity of x&y
|
||
|
|
|
||
|
|
void load( const unsigned * a, unsigned n ); // load value, a[0] is lsw
|
||
|
|
void store( unsigned * a, unsigned n ) const; // low level save, a[0] is lsw
|
||
|
|
|
||
|
|
private:
|
||
|
|
bigint_value * value;
|
||
|
|
int negative;
|
||
|
|
int cf( const bigint & x ) const;
|
||
|
|
void docopy();
|
||
|
|
friend class monty;
|
||
|
|
};
|
||
|
|
|
||
|
|
bigint modexp( const bigint & x, const bigint & e, const bigint & m ); // m must be odd
|
||
|
|
bigint gcd( const bigint & X, const bigint & Y ); // greatest common denominator
|
||
|
|
bigint modinv( const bigint & a, const bigint & m ); // modular inverse
|
||
|
|
bigint lucas ( const bigint & P, const bigint & Z, const bigint & k, const bigint & p ); // P^2 - 4Z != 0
|
||
|
|
bigint sqrt( const bigint & g, const bigint & p ); // square root mod p
|
||
|
|
bigint pow2( unsigned n );
|
||
|
|
|
||
|
|
#endif
|