00001 #ifndef CRYPTOPP_INTEGER_H
00002 #define CRYPTOPP_INTEGER_H
00003
00004
00005
00006 #include "cryptlib.h"
00007 #include "secblock.h"
00008
00009 #include <iosfwd>
00010 #include <algorithm>
00011
00012 #ifdef CRYPTOPP_X86ASM_AVAILABLE
00013
00014 #ifdef _M_IX86
00015 #if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500))
00016 #define SSE2_INTRINSICS_AVAILABLE
00017 #elif defined(_MSC_VER)
00018
00019 #include <malloc.h>
00020 #if defined(_mm_free)
00021 #define SSE2_INTRINSICS_AVAILABLE
00022 #endif
00023 #endif
00024 #endif
00025
00026
00027 #if defined(__SSE2__) && (__GNUC_MAJOR__ > 3 || __GNUC_MINOR__ > 2)
00028 #define SSE2_INTRINSICS_AVAILABLE
00029 #endif
00030
00031 #endif
00032
00033 NAMESPACE_BEGIN(CryptoPP)
00034
00035 #if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER)
00036
00037
00038
00039 template <class T>
00040 class AlignedAllocator : public AllocatorBase<T>
00041 {
00042 public:
00043 CRYPTOPP_INHERIT_ALLOCATOR_TYPES
00044
00045 pointer allocate(size_type n, const void *);
00046 void deallocate(void *p, size_type n);
00047 pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
00048 {
00049 return StandardReallocate(*this, p, oldSize, newSize, preserve);
00050 }
00051 };
00052
00053 template class CRYPTOPP_DLL AlignedAllocator<word>;
00054 typedef SecBlock<word, AlignedAllocator<word> > SecAlignedWordBlock;
00055
00056 #else
00057 typedef SecWordBlock SecAlignedWordBlock;
00058 #endif
00059
00060 void CRYPTOPP_DLL DisableSSE2();
00061
00062
00063
00064
00065
00066
00067 class CRYPTOPP_DLL Integer : public ASN1Object
00068 {
00069 public:
00070
00071
00072
00073 class DivideByZero : public Exception
00074 {
00075 public:
00076 DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {}
00077 };
00078
00079
00080 class RandomNumberNotFound : public Exception
00081 {
00082 public:
00083 RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
00084 };
00085
00086
00087 enum Sign {POSITIVE=0, NEGATIVE=1};
00088
00089
00090 enum Signedness {
00091
00092 UNSIGNED,
00093
00094 SIGNED};
00095
00096
00097 enum RandomNumberType {
00098
00099 ANY,
00100
00101 PRIME};
00102
00103
00104
00105
00106
00107 Integer();
00108
00109
00110 Integer(const Integer& t);
00111
00112
00113 Integer(signed long value);
00114
00115
00116 Integer(Sign s, lword value);
00117
00118
00119 Integer(Sign s, word highWord, word lowWord);
00120
00121
00122
00123
00124
00125 explicit Integer(const char *str);
00126 explicit Integer(const wchar_t *str);
00127
00128
00129 Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s=UNSIGNED);
00130
00131
00132 Integer(BufferedTransformation &bt, unsigned int byteCount, Signedness s=UNSIGNED);
00133
00134
00135 explicit Integer(BufferedTransformation &bt);
00136
00137
00138
00139 Integer(RandomNumberGenerator &rng, unsigned int bitcount);
00140
00141
00142 static const Integer &Zero();
00143
00144 static const Integer &One();
00145
00146 static const Integer &Two();
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
00160
00161
00162 static Integer Power2(unsigned int e);
00163
00164
00165
00166
00167
00168
00169 unsigned int MinEncodedSize(Signedness=UNSIGNED) const;
00170
00171
00172
00173
00174
00175 unsigned int Encode(byte *output, unsigned int outputLen, Signedness=UNSIGNED) const;
00176
00177 unsigned int Encode(BufferedTransformation &bt, unsigned int outputLen, Signedness=UNSIGNED) const;
00178
00179
00180 void DEREncode(BufferedTransformation &bt) const;
00181
00182
00183 void DEREncodeAsOctetString(BufferedTransformation &bt, unsigned int length) const;
00184
00185
00186 unsigned int OpenPGPEncode(byte *output, unsigned int bufferSize) const;
00187
00188 unsigned int OpenPGPEncode(BufferedTransformation &bt) const;
00189
00190
00191 void Decode(const byte *input, unsigned int inputLen, Signedness=UNSIGNED);
00192
00193
00194 void Decode(BufferedTransformation &bt, unsigned int inputLen, Signedness=UNSIGNED);
00195
00196
00197 void BERDecode(const byte *input, unsigned int inputLen);
00198
00199 void BERDecode(BufferedTransformation &bt);
00200
00201
00202 void BERDecodeAsOctetString(BufferedTransformation &bt, unsigned int length);
00203
00204 class OpenPGPDecodeErr : public Exception
00205 {
00206 public:
00207 OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {}
00208 };
00209
00210
00211 void OpenPGPDecode(const byte *input, unsigned int inputLen);
00212
00213 void OpenPGPDecode(BufferedTransformation &bt);
00214
00215
00216
00217
00218
00219 bool IsConvertableToLong() const;
00220
00221 signed long ConvertToLong() const;
00222
00223
00224 unsigned int BitCount() const;
00225
00226 unsigned int ByteCount() const;
00227
00228 unsigned int WordCount() const;
00229
00230
00231 bool GetBit(unsigned int i) const;
00232
00233 byte GetByte(unsigned int i) const;
00234
00235 unsigned long GetBits(unsigned int i, unsigned int n) const;
00236
00237
00238 bool IsZero() const {return !*this;}
00239
00240 bool NotZero() const {return !IsZero();}
00241
00242 bool IsNegative() const {return sign == NEGATIVE;}
00243
00244 bool NotNegative() const {return !IsNegative();}
00245
00246 bool IsPositive() const {return NotNegative() && NotZero();}
00247
00248 bool NotPositive() const {return !IsPositive();}
00249
00250 bool IsEven() const {return GetBit(0) == 0;}
00251
00252 bool IsOdd() const {return GetBit(0) == 1;}
00253
00254
00255
00256
00257
00258 Integer& operator=(const Integer& t);
00259
00260
00261 Integer& operator+=(const Integer& t);
00262
00263 Integer& operator-=(const Integer& t);
00264
00265 Integer& operator*=(const Integer& t) {return *this = Times(t);}
00266
00267 Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
00268
00269 Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
00270
00271 Integer& operator/=(word t) {return *this = DividedBy(t);}
00272
00273 Integer& operator%=(word t) {return *this = Modulo(t);}
00274
00275
00276 Integer& operator<<=(unsigned int);
00277
00278 Integer& operator>>=(unsigned int);
00279
00280
00281 void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
00282
00283 void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max);
00284
00285
00286 bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One());
00287
00288 bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs);
00289 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs)
00290 {
00291 if (!GenerateRandomNoThrow(rng, params))
00292 throw RandomNumberNotFound();
00293 }
00294
00295
00296 void SetBit(unsigned int n, bool value=1);
00297
00298 void SetByte(unsigned int n, byte value);
00299
00300
00301 void Negate();
00302
00303 void SetPositive() {sign = POSITIVE;}
00304
00305 void SetNegative() {if (!!(*this)) sign = NEGATIVE;}
00306
00307
00308 void swap(Integer &a);
00309
00310
00311
00312
00313
00314 bool operator!() const;
00315
00316 Integer operator+() const {return *this;}
00317
00318 Integer operator-() const;
00319
00320 Integer& operator++();
00321
00322 Integer& operator--();
00323
00324 Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
00325
00326 Integer operator--(int) {Integer temp = *this; --*this; return temp;}
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 int Compare(const Integer& a) const;
00337
00338
00339 Integer Plus(const Integer &b) const;
00340
00341 Integer Minus(const Integer &b) const;
00342
00343 Integer Times(const Integer &b) const;
00344
00345 Integer DividedBy(const Integer &b) const;
00346
00347 Integer Modulo(const Integer &b) const;
00348
00349 Integer DividedBy(word b) const;
00350
00351 word Modulo(word b) const;
00352
00353
00354 Integer operator>>(unsigned int n) const {return Integer(*this)>>=n;}
00355
00356 Integer operator<<(unsigned int n) const {return Integer(*this)<<=n;}
00357
00358
00359
00360
00361
00362 Integer AbsoluteValue() const;
00363
00364 Integer Doubled() const {return Plus(*this);}
00365
00366 Integer Squared() const {return Times(*this);}
00367
00368 Integer SquareRoot() const;
00369
00370 bool IsSquare() const;
00371
00372
00373 bool IsUnit() const;
00374
00375 Integer MultiplicativeInverse() const;
00376
00377
00378 CRYPTOPP_DLL friend Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
00379
00380 CRYPTOPP_DLL friend Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
00381
00382
00383 static void Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
00384
00385 static void Divide(word &r, Integer &q, const Integer &a, word d);
00386
00387
00388 static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
00389
00390
00391 static Integer Gcd(const Integer &a, const Integer &n);
00392
00393 Integer InverseMod(const Integer &n) const;
00394
00395 word InverseMod(word n) const;
00396
00397
00398
00399
00400
00401 friend CRYPTOPP_DLL std::istream& operator>>(std::istream& in, Integer &a);
00402
00403 friend CRYPTOPP_DLL std::ostream& operator<<(std::ostream& out, const Integer &a);
00404
00405
00406 private:
00407 friend class ModularArithmetic;
00408 friend class MontgomeryRepresentation;
00409 friend class HalfMontgomeryRepresentation;
00410
00411 Integer(word value, unsigned int length);
00412
00413 int PositiveCompare(const Integer &t) const;
00414 friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b);
00415 friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b);
00416 friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b);
00417 friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor);
00418
00419 SecAlignedWordBlock reg;
00420 Sign sign;
00421 };
00422
00423
00424 inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
00425
00426 inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;}
00427
00428 inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;}
00429
00430 inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;}
00431
00432 inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;}
00433
00434 inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;}
00435
00436 inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);}
00437
00438 inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
00439
00440 inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
00441
00442 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
00443
00444 inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
00445
00446 inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
00447
00448 inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
00449
00450 NAMESPACE_END
00451
00452 NAMESPACE_BEGIN(std)
00453 template<> inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b)
00454 {
00455 a.swap(b);
00456 }
00457 NAMESPACE_END
00458
00459 #endif