00001 #ifndef CRYPTOPP_INTEGER_H
00002 #define CRYPTOPP_INTEGER_H
00003
00006 #include "cryptlib.h"
00007 #include "misc.h"
00008
00009 #include <iosfwd>
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00014
00018 class Integer
00019 {
00020 public:
00022
00023
00024 class DivideByZero : public Exception
00025 {
00026 public:
00027 DivideByZero() : Exception("Integer: division by zero") {}
00028 };
00029
00031 class RandomNumberNotFound : public Exception
00032 {
00033 public:
00034 RandomNumberNotFound() : Exception("Integer: random number not found") {}
00035 };
00036
00038 enum Signedness {
00040 UNSIGNED,
00042 SIGNED};
00043
00045 enum RandomNumberType {
00047 ANY,
00049 PRIME};
00051
00053
00054
00055 Integer();
00056
00058 Integer(const Integer& t);
00059
00061 Integer(signed long value);
00062
00064
00067 Integer(const char *str);
00068
00070 Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
00071
00073 Integer(BufferedTransformation &bt, unsigned int byteCount, Signedness s=UNSIGNED);
00074
00076 Integer(BufferedTransformation &bt);
00077
00079
00080 Integer(RandomNumberGenerator &rng, unsigned int bitcount);
00081
00083 static const Integer &Zero();
00085 static const Integer &One();
00086
00088
00098 Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
00099
00101 static Integer Power2(unsigned int e);
00103
00105
00106
00107
00108 unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
00110
00114 unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
00116 unsigned int Encode(BufferedTransformation &bt, unsigned int outputLen, Signedness=UNSIGNED) const;
00117
00119 void DEREncode(BufferedTransformation &bt) const;
00120
00122 void DEREncodeAsOctetString(BufferedTransformation &bt, unsigned int length) const;
00123
00125 unsigned int OpenPGPEncode(byte *output, unsigned int bufferSize) const;
00127 unsigned int OpenPGPEncode(BufferedTransformation &bt) const;
00128
00130 void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
00132
00133 void Decode(BufferedTransformation &bt, unsigned int inputLen, Signedness=UNSIGNED);
00134
00136 void BERDecode(const byte *input, unsigned int inputLen);
00138 void BERDecode(BufferedTransformation &bt);
00139
00141 void BERDecodeAsOctetString(BufferedTransformation &bt, unsigned int length);
00142
00143 class OpenPGPDecodeErr : public Exception
00144 {
00145 public:
00146 OpenPGPDecodeErr() : Exception("OpenPGP decode error") {}
00147 };
00148
00150 void OpenPGPDecode(const byte *input, unsigned int inputLen);
00152 void OpenPGPDecode(BufferedTransformation &bt);
00154
00156
00157
00158 bool IsConvertableToLong() const;
00160 signed long ConvertToLong() const;
00161
00163 unsigned int BitCount() const;
00165 unsigned int ByteCount() const;
00167 unsigned int WordCount() const;
00168
00170 bool GetBit(unsigned int i) const;
00172 byte GetByte(unsigned int i) const;
00174 unsigned long GetBits(unsigned int i, unsigned int n) const;
00175
00177 bool IsZero() const {return !*this;}
00179 bool NotZero() const {return !IsZero();}
00181 bool IsNegative() const {return sign == NEGATIVE;}
00183 bool NotNegative() const {return !IsNegative();}
00185 bool IsPositive() const {return NotNegative() && NotZero();}
00187 bool NotPositive() const {return !IsPositive();}
00189 bool IsEven() const {return GetBit(0) == 0;}
00191 bool IsOdd() const {return GetBit(0) == 1;}
00193
00195
00196
00197 Integer& operator=(const Integer& t);
00198
00200 Integer& operator+=(const Integer& t);
00202 Integer& operator-=(const Integer& t);
00204 Integer& operator*=(const Integer& t) {return *this = Times(t);}
00206 Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
00208 Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
00210 Integer& operator/=(word t) {return *this = DividedBy(t);}
00212 Integer& operator%=(word t) {return *this = Modulo(t);}
00213
00215 Integer& operator<<=(unsigned int);
00217 Integer& operator>>=(unsigned int);
00218
00220 void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
00222 void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
00224
00225 bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
00226
00228 void SetBit(unsigned int n, bool value=1);
00230 void SetByte(unsigned int n, byte value);
00231
00233 void Negate();
00235 void SetPositive() {sign = POSITIVE;}
00237 void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
00238
00240 void swap(Integer &a);
00242
00244
00245
00246 bool operator!() const;
00248 Integer operator+() const {return *this;}
00250 Integer operator-() const;
00252 Integer& operator++();
00254 Integer& operator--();
00256 Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
00258 Integer operator--(int) {Integer temp = *this; --*this; return temp;}
00260
00262
00263
00264
00268 int Compare(const Integer& a) const;
00269
00271 Integer Plus(const Integer &b) const;
00273 Integer Minus(const Integer &b) const;
00275 Integer Times(const Integer &b) const;
00277 Integer DividedBy(const Integer &b) const;
00279 Integer Modulo(const Integer &b) const;
00281 Integer DividedBy(word b) const;
00283 word Modulo(word b) const;
00284
00286 Integer operator>>(unsigned int n) const {return Integer(*this)>>=n;}
00288 Integer operator<<(unsigned int n) const {return Integer(*this)<<=n;}
00290
00292
00293
00294 Integer AbsoluteValue() const;
00296 Integer Doubled() const {return Plus(*this);}
00298 Integer Squared() const {return Times(*this);}
00300 Integer SquareRoot() const;
00302 bool IsSquare() const;
00303
00305 bool IsUnit() const;
00307 Integer MultiplicativeInverse() const;
00308
00310 friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
00312 friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
00313
00315 static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
00317 static void Divide(word &r, Integer &q, const Integer &a, word d);
00318
00320 static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
00321
00323 static Integer Gcd(const Integer &a, const Integer &n);
00325 Integer InverseMod(const Integer &n) const;
00327 word InverseMod(word n) const;
00329
00331
00332
00333 friend std::istream& operator>>(std::istream& in, Integer &a);
00335 friend std::ostream& operator<<(std::ostream& out, const Integer &a);
00337
00338 private:
00339 friend class ModularArithmetic;
00340 friend class MontgomeryRepresentation;
00341 friend class HalfMontgomeryRepresentation;
00342
00343 Integer(word value, unsigned int length);
00344
00345 int PositiveCompare(const Integer &t) const;
00346 friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
00347 friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
00348 friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
00349 friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor);
00350
00351 enum Sign {POSITIVE=0, NEGATIVE=1};
00352
00353 SecWordBlock reg;
00354 Sign sign;
00355 };
00356
00357 NAMESPACE_END
00358
00359
00360
00361
00363 inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
00365 inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;}
00367 inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;}
00369 inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;}
00371 inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;}
00373 inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;}
00375 inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);}
00377 inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
00379 inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
00381 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
00383 inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
00385 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
00387 inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
00388
00389 NAMESPACE_BEGIN(std)
00390 template<> inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b)
00391 {
00392 a.swap(b);
00393 }
00394 NAMESPACE_END
00395
00396 #endif