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