#ifndef CRYPTOPP_INTEGER_H
#define CRYPTOPP_INTEGER_H
#include "cryptopp.h"
#include "cryptopp_misc.h"
#include <iosfwd>
NAMESPACE_BEGIN(CryptoPP)
class Integer
{
public:
class DivideByZero : public Exception
{
public:
DivideByZero() : Exception("Integer: division by zero") {}
};
class RandomNumberNotFound : public Exception
{
public:
RandomNumberNotFound() : Exception("Integer: random number not found") {}
};
enum Signedness {
UNSIGNED,
SIGNED};
enum RandomNumberType {
ANY,
PRIME};
Integer();
Integer(const Integer& t);
Integer(signed long value);
Integer(const char *str);
Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
Integer(BufferedTransformation &bt, unsigned int byteCount, Signedness s=UNSIGNED);
Integer(BufferedTransformation &bt);
Integer(RandomNumberGenerator &rng, unsigned int bitcount);
static const Integer &Zero();
static const Integer &One();
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
static Integer Power2(unsigned int e);
unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
unsigned int Encode(BufferedTransformation &bt, unsigned int outputLen, Signedness=UNSIGNED) const;
void DEREncode(BufferedTransformation &bt) const;
void DEREncodeAsOctetString(BufferedTransformation &bt, unsigned int length) const;
unsigned int OpenPGPEncode(byte *output, unsigned int bufferSize) const;
unsigned int OpenPGPEncode(BufferedTransformation &bt) const;
void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
void Decode(BufferedTransformation &bt, unsigned int inputLen, Signedness=UNSIGNED);
void BERDecode(const byte *input, unsigned int inputLen);
void BERDecode(BufferedTransformation &bt);
void BERDecodeAsOctetString(BufferedTransformation &bt, unsigned int length);
class OpenPGPDecodeErr : public Exception
{
public:
OpenPGPDecodeErr() : Exception("OpenPGP decode error") {}
};
void OpenPGPDecode(const byte *input, unsigned int inputLen);
void OpenPGPDecode(BufferedTransformation &bt);
bool IsConvertableToLong() const;
signed long ConvertToLong() const;
unsigned int BitCount() const;
unsigned int ByteCount() const;
unsigned int WordCount() const;
bool GetBit(unsigned int i) const;
byte GetByte(unsigned int i) const;
unsigned long GetBits(unsigned int i, unsigned int n) const;
bool IsZero() const {return !*this;}
bool NotZero() const {return !IsZero();}
bool IsNegative() const {return sign == NEGATIVE;}
bool NotNegative() const {return !IsNegative();}
bool IsPositive() const {return NotNegative() && NotZero();}
bool NotPositive() const {return !IsPositive();}
bool IsEven() const {return GetBit(0) == 0;}
bool IsOdd() const {return GetBit(0) == 1;}
Integer& operator=(const Integer& t);
Integer& operator+=(const Integer& t);
Integer& operator-=(const Integer& t);
Integer& operator*=(const Integer& t) {return *this = Times(t);}
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
Integer& operator/=(word t) {return *this = DividedBy(t);}
Integer& operator%=(word t) {return *this = Modulo(t);}
Integer& operator<<=(unsigned int);
Integer& operator>>=(unsigned int);
void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
void SetBit(unsigned int n, bool value=1);
void SetByte(unsigned int n, byte value);
void Negate();
void SetPositive() {sign = POSITIVE;}
void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
void swap(Integer &a);
bool operator!() const;
Integer operator+() const {return *this;}
Integer operator-() const;
Integer& operator++();
Integer& operator--();
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
int Compare(const Integer& a) const;
Integer Plus(const Integer &b) const;
Integer Minus(const Integer &b) const;
Integer Times(const Integer &b) const;
Integer DividedBy(const Integer &b) const;
Integer Modulo(const Integer &b) const;
Integer DividedBy(word b) const;
word Modulo(word b) const;
Integer operator>>(unsigned int n) const {return Integer(*this)>>=n;}
Integer operator<<(unsigned int n) const {return Integer(*this)<<=n;}
Integer AbsoluteValue() const;
Integer Doubled() const {return Plus(*this);}
Integer Squared() const {return Times(*this);}
Integer SquareRoot() const;
bool IsSquare() const;
bool IsUnit() const;
Integer MultiplicativeInverse() const;
friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
static void Divide(word &r, Integer &q, const Integer &a, word d);
static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
static Integer Gcd(const Integer &a, const Integer &n);
Integer InverseMod(const Integer &n) const;
word InverseMod(word n) const;
friend std::istream& operator>>(std::istream& in, Integer &a);
friend std::ostream& operator<<(std::ostream& out, const Integer &a);
private:
friend class ModularArithmetic;
friend class MontgomeryRepresentation;
friend class HalfMontgomeryRepresentation;
Integer(word value, unsigned int length);
int PositiveCompare(const Integer &t) const;
friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor);
enum Sign {POSITIVE=0, NEGATIVE=1};
SecWordBlock reg;
Sign sign;
};
NAMESPACE_END
inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;}
inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;}
inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;}
inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;}
inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;}
inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);}
inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
NAMESPACE_BEGIN(std)
template<> inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b)
{
a.swap(b);
}
NAMESPACE_END
#endif