integer.h

Go to the documentation of this file.
00001 #ifndef CRYPTOPP_INTEGER_H
00002 #define CRYPTOPP_INTEGER_H
00003 
00004 /** \file */
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                 // _mm_free seems to be the only way to tell if the Processor Pack is installed or not
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 // SSE2 intrinsics work in GCC 3.3 or later
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        // used to initialize static variables
00071 {
00072         InitializeInteger();
00073 };
00074 
00075 //! multiple precision integer and basic arithmetics
00076 /*! This class can represent positive and negative integers
00077         with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)).
00078         \nosubgrouping
00079 */
00080 class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
00081 {
00082 public:
00083         //! \name ENUMS, EXCEPTIONS, and TYPEDEFS
00084         //@{
00085                 //! division by zero exception
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         //! \name CREATORS
00118         //@{
00119                 //! creates the zero integer
00120                 Integer();
00121 
00122                 //! copy constructor
00123                 Integer(const Integer& t);
00124 
00125                 //! convert from signed long
00126                 Integer(signed long value);
00127 
00128                 //! convert from lword
00129                 Integer(Sign s, lword value);
00130 
00131                 //! convert from two words
00132                 Integer(Sign s, word highWord, word lowWord);
00133 
00134                 //! convert from string
00135                 /*! str can be in base 2, 8, 10, or 16.  Base is determined by a
00136                         case insensitive suffix of 'h', 'o', or 'b'.  No suffix means base 10.
00137                 */
00138                 explicit Integer(const char *str);
00139                 explicit Integer(const wchar_t *str);
00140 
00141                 //! convert from big-endian byte array
00142                 Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED);
00143 
00144                 //! convert from big-endian form stored in a BufferedTransformation
00145                 Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED);
00146 
00147                 //! convert from BER encoded byte array stored in a BufferedTransformation object
00148                 explicit Integer(BufferedTransformation &bt);
00149 
00150                 //! create a random integer
00151                 /*! The random integer created is uniformly distributed over [0, 2**bitcount). */
00152                 Integer(RandomNumberGenerator &rng, size_t bitcount);
00153 
00154                 //! avoid calling constructors for these frequently used integers
00155                 static const Integer & CRYPTOPP_API Zero();
00156                 //! avoid calling constructors for these frequently used integers
00157                 static const Integer & CRYPTOPP_API One();
00158                 //! avoid calling constructors for these frequently used integers
00159                 static const Integer & CRYPTOPP_API Two();
00160 
00161                 //! create a random integer of special type
00162                 /*! Ideally, the random integer created should be uniformly distributed
00163                         over {x | min <= x <= max and x is of rnType and x % mod == equiv}.
00164                         However the actual distribution may not be uniform because sequential
00165                         search is used to find an appropriate number from a random starting
00166                         point.
00167                         May return (with very small probability) a pseudoprime when a prime
00168                         is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime
00169                         is declared in nbtheory.h).
00170                         \throw RandomNumberNotFound if the set is empty.
00171                 */
00172                 Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
00173 
00174                 //! return the integer 2**e
00175                 static Integer CRYPTOPP_API Power2(size_t e);
00176         //@}
00177 
00178         //! \name ENCODE/DECODE
00179         //@{
00180                 //! minimum number of bytes to encode this integer
00181                 /*! MinEncodedSize of 0 is 1 */
00182                 size_t MinEncodedSize(Signedness=UNSIGNED) const;
00183                 //! encode in big-endian format
00184                 /*! unsigned means encode absolute value, signed means encode two's complement if negative.
00185                         if outputLen < MinEncodedSize, the most significant bytes will be dropped
00186                         if outputLen > MinEncodedSize, the most significant bytes will be padded
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                 //! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object
00193                 void DEREncode(BufferedTransformation &bt) const;
00194 
00195                 //! encode absolute value as big-endian octet string
00196                 void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
00197 
00198                 //! encode absolute value in OpenPGP format, return length of output
00199                 size_t OpenPGPEncode(byte *output, size_t bufferSize) const;
00200                 //! encode absolute value in OpenPGP format, put result into a BufferedTransformation object
00201                 size_t OpenPGPEncode(BufferedTransformation &bt) const;
00202 
00203                 //!
00204                 void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED);
00205                 //! 
00206                 //* Precondition: bt.MaxRetrievable() >= inputLen
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                 //! decode nonnegative value as big-endian octet string
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         //! \name ACCESSORS
00230         //@{
00231                 //! return true if *this can be represented as a signed long
00232                 bool IsConvertableToLong() const;
00233                 //! return equivalent signed long if possible, otherwise undefined
00234                 signed long ConvertToLong() const;
00235 
00236                 //! number of significant bits = floor(log2(abs(*this))) + 1
00237                 unsigned int BitCount() const;
00238                 //! number of significant bytes = ceiling(BitCount()/8)
00239                 unsigned int ByteCount() const;
00240                 //! number of significant words = ceiling(ByteCount()/sizeof(word))
00241                 unsigned int WordCount() const;
00242 
00243                 //! return the i-th bit, i=0 being the least significant bit
00244                 bool GetBit(size_t i) const;
00245                 //! return the i-th byte
00246                 byte GetByte(size_t i) const;
00247                 //! return n lowest bits of *this >> i
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         //! \name MANIPULATORS
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                 //! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv}
00298                 /*! returns false if the set is empty */
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 &params = g_nullNameValuePairs);
00302                 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs)
00303                 {
00304                         if (!GenerateRandomNoThrow(rng, params))
00305                                 throw RandomNumberNotFound();
00306                 }
00307 
00308                 //! set the n-th bit to value
00309                 void SetBit(size_t n, bool value=1);
00310                 //! set the n-th byte to value
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         //! \name UNARY OPERATORS
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         //! \name BINARY OPERATORS
00343         //@{
00344                 //! signed comparison
00345                 /*! \retval -1 if *this < a
00346                         \retval  0 if *this = a
00347                         \retval  1 if *this > a
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         //! \name OTHER ARITHMETIC FUNCTIONS
00373         //@{
00374                 //!
00375                 Integer AbsoluteValue() const;
00376                 //!
00377                 Integer Doubled() const {return Plus(*this);}
00378                 //!
00379                 Integer Squared() const {return Times(*this);}
00380                 //! extract square root, if negative return 0, else return floor of square root
00381                 Integer SquareRoot() const;
00382                 //! return whether this integer is a perfect square
00383                 bool IsSquare() const;
00384 
00385                 //! is 1 or -1
00386                 bool IsUnit() const;
00387                 //! return inverse if 1 or -1, otherwise return 0
00388                 Integer MultiplicativeInverse() const;
00389 
00390                 //! modular multiplication
00391                 CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m);
00392                 //! modular exponentiation
00393                 CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m);
00394 
00395                 //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
00396                 static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
00397                 //! use a faster division algorithm when divisor is short
00398                 static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d);
00399 
00400                 //! returns same result as Divide(r, q, a, Power2(n)), but faster
00401                 static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
00402 
00403                 //! greatest common divisor
00404                 static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
00405                 //! calculate multiplicative inverse of *this mod n
00406                 Integer InverseMod(const Integer &n) const;
00407                 //!
00408                 word InverseMod(word n) const;
00409         //@}
00410 
00411         //! \name INPUT/OUTPUT
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 &quotient, const Integer &dividend, 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

Generated on Sat Dec 23 02:07:08 2006 for Crypto++ by  doxygen 1.5.1-p1