misc.h

00001 #ifndef CRYPTOPP_MISC_H
00002 #define CRYPTOPP_MISC_H
00003 
00004 #include "cryptlib.h"
00005 #include "smartptr.h"
00006 
00007 #ifdef _MSC_VER
00008         #include <stdlib.h>
00009         #if _MSC_VER >= 1400
00010                 // VC2005 workaround: disable declarations that conflict with winnt.h
00011                 #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
00012                 #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
00013                 #include <intrin.h>
00014                 #undef _interlockedbittestandset
00015                 #undef _interlockedbittestandreset
00016                 #define CRYPTOPP_FAST_ROTATE(x) 1
00017         #elif _MSC_VER >= 1300
00018                 #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
00019         #else
00020                 #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
00021         #endif
00022 #elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
00023         (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
00024         #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
00025 #elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)     // depend on GCC's peephole optimization to generate rotate instructions
00026         #define CRYPTOPP_FAST_ROTATE(x) 1
00027 #else
00028         #define CRYPTOPP_FAST_ROTATE(x) 0
00029 #endif
00030 
00031 #ifdef __BORLANDC__
00032 #include <mem.h>
00033 #endif
00034 
00035 #if defined(__GNUC__) && defined(__linux__)
00036 #define CRYPTOPP_BYTESWAP_AVAILABLE
00037 #include <byteswap.h>
00038 #endif
00039 
00040 NAMESPACE_BEGIN(CryptoPP)
00041 
00042 // ************** compile-time assertion ***************
00043 
00044 template <bool b>
00045 struct CompileAssert
00046 {
00047         static char dummy[2*b-1];
00048 };
00049 
00050 #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
00051 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
00052 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
00053 #else
00054 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
00055 #endif
00056 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
00057 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
00058 
00059 // ************** misc classes ***************
00060 
00061 class CRYPTOPP_DLL Empty
00062 {
00063 };
00064 
00065 //! _
00066 template <class BASE1, class BASE2>
00067 class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
00068 {
00069 };
00070 
00071 //! _
00072 template <class BASE1, class BASE2, class BASE3>
00073 class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
00074 {
00075 };
00076 
00077 template <class T>
00078 class ObjectHolder
00079 {
00080 protected:
00081         T m_object;
00082 };
00083 
00084 class NotCopyable
00085 {
00086 public:
00087         NotCopyable() {}
00088 private:
00089     NotCopyable(const NotCopyable &);
00090     void operator=(const NotCopyable &);
00091 };
00092 
00093 template <class T>
00094 struct NewObject
00095 {
00096         T* operator()() const {return new T;}
00097 };
00098 
00099 /*! This function safely initializes a static object in a multithreaded environment without using locks.
00100         It may leak memory when two threads try to initialize the static object at the same time
00101         but this should be acceptable since each static object is only initialized once per session.
00102 */
00103 template <class T, class F = NewObject<T>, int instance=0>
00104 class Singleton
00105 {
00106 public:
00107         Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
00108 
00109         // prevent this function from being inlined
00110         CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
00111 
00112 private:
00113         F m_objectFactory;
00114 };
00115 
00116 template <class T, class F, int instance>
00117 const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
00118 {
00119         static simple_ptr<T> s_pObject;
00120         static char s_objectState = 0;
00121 
00122 retry:
00123         switch (s_objectState)
00124         {
00125         case 0:
00126                 s_objectState = 1;
00127                 try
00128                 {
00129                         s_pObject.m_p = m_objectFactory();
00130                 }
00131                 catch(...)
00132                 {
00133                         s_objectState = 0;
00134                         throw;
00135                 }
00136                 s_objectState = 2;
00137                 break;
00138         case 1:
00139                 goto retry;
00140         default:
00141                 break;
00142         }
00143         return *s_pObject.m_p;
00144 }
00145 
00146 // ************** misc functions ***************
00147 
00148 #if (!__STDC_WANT_SECURE_LIB__)
00149 inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
00150 {
00151         if (count > sizeInBytes)
00152                 throw InvalidArgument("memcpy_s: buffer overflow");
00153         memcpy(dest, src, count);
00154 }
00155 
00156 inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
00157 {
00158         if (count > sizeInBytes)
00159                 throw InvalidArgument("memmove_s: buffer overflow");
00160         memmove(dest, src, count);
00161 }
00162 #endif
00163 
00164 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
00165 template <class T> inline const T& STDMIN(const T& a, const T& b)
00166 {
00167         return b < a ? b : a;
00168 }
00169 
00170 template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
00171 {
00172         CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
00173         assert(a==0 || a>0);    // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
00174         assert(b>=0);
00175 
00176         if (sizeof(T1)<=sizeof(T2))
00177                 return b < (T2)a ? (T1)b : a;
00178         else
00179                 return (T1)b < a ? (T1)b : a;
00180 }
00181 
00182 template <class T> inline const T& STDMAX(const T& a, const T& b)
00183 {
00184         return a < b ? b : a;
00185 }
00186 
00187 #define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
00188 
00189 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
00190 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00191 // these may be faster on other CPUs/compilers
00192 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
00193 // #define GETBYTE(x, y) (((byte *)&(x))[y])
00194 
00195 #define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
00196 
00197 template <class T>
00198 unsigned int Parity(T value)
00199 {
00200         for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
00201                 value ^= value >> i;
00202         return (unsigned int)value&1;
00203 }
00204 
00205 template <class T>
00206 unsigned int BytePrecision(const T &value)
00207 {
00208         if (!value)
00209                 return 0;
00210 
00211         unsigned int l=0, h=8*sizeof(value);
00212 
00213         while (h-l > 8)
00214         {
00215                 unsigned int t = (l+h)/2;
00216                 if (value >> t)
00217                         l = t;
00218                 else
00219                         h = t;
00220         }
00221 
00222         return h/8;
00223 }
00224 
00225 template <class T>
00226 unsigned int BitPrecision(const T &value)
00227 {
00228         if (!value)
00229                 return 0;
00230 
00231         unsigned int l=0, h=8*sizeof(value);
00232 
00233         while (h-l > 1)
00234         {
00235                 unsigned int t = (l+h)/2;
00236                 if (value >> t)
00237                         l = t;
00238                 else
00239                         h = t;
00240         }
00241 
00242         return h;
00243 }
00244 
00245 template <class T>
00246 inline T Crop(T value, size_t size)
00247 {
00248         if (size < 8*sizeof(value))
00249         return T(value & ((T(1) << size) - 1));
00250         else
00251                 return value;
00252 }
00253 
00254 template <class T1, class T2>
00255 inline bool SafeConvert(T1 from, T2 &to)
00256 {
00257         to = (T2)from;
00258         if (from != to || (from > 0) != (to > 0))
00259                 return false;
00260         return true;
00261 }
00262 
00263 inline size_t BitsToBytes(size_t bitCount)
00264 {
00265         return ((bitCount+7)/(8));
00266 }
00267 
00268 inline size_t BytesToWords(size_t byteCount)
00269 {
00270         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00271 }
00272 
00273 inline size_t BitsToWords(size_t bitCount)
00274 {
00275         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00276 }
00277 
00278 inline size_t BitsToDwords(size_t bitCount)
00279 {
00280         return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
00281 }
00282 
00283 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
00284 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
00285 
00286 template <class T>
00287 inline bool IsPowerOf2(const T &n)
00288 {
00289         return n > 0 && (n & (n-1)) == 0;
00290 }
00291 
00292 template <class T1, class T2>
00293 inline T2 ModPowerOf2(const T1 &a, const T2 &b)
00294 {
00295         assert(IsPowerOf2(b));
00296         return T2(a) & (b-1);
00297 }
00298 
00299 template <class T1, class T2>
00300 inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
00301 {
00302         if (IsPowerOf2(m))
00303                 return n - ModPowerOf2(n, m);
00304         else
00305                 return n - n%m;
00306 }
00307 
00308 template <class T1, class T2>
00309 inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
00310 {
00311         if (n+m-1 < n)
00312                 throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
00313         return RoundDownToMultipleOf(n+m-1, m);
00314 }
00315 
00316 template <class T>
00317 inline unsigned int GetAlignmentOf(T *dummy=NULL)       // VC60 workaround
00318 {
00319 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86
00320         if (sizeof(T) < 16)
00321                 return 1;                       // alignment not needed on x86 and x64
00322 #endif
00323 
00324 #if (_MSC_VER >= 1300)
00325         return __alignof(T);
00326 #elif defined(__GNUC__)
00327         return __alignof__(T);
00328 #elif defined(CRYPTOPP_SLOW_WORD64)
00329         return UnsignedMin(4U, sizeof(T));
00330 #else
00331         return sizeof(T);
00332 #endif
00333 }
00334 
00335 inline bool IsAlignedOn(const void *p, unsigned int alignment)
00336 {
00337         return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
00338 }
00339 
00340 template <class T>
00341 inline bool IsAligned(const void *p, T *dummy=NULL)     // VC60 workaround
00342 {
00343         return IsAlignedOn(p, GetAlignmentOf<T>());
00344 }
00345 
00346 #ifdef IS_LITTLE_ENDIAN
00347         typedef LittleEndian NativeByteOrder;
00348 #else
00349         typedef BigEndian NativeByteOrder;
00350 #endif
00351 
00352 inline ByteOrder GetNativeByteOrder()
00353 {
00354         return NativeByteOrder::ToEnum();
00355 }
00356 
00357 inline bool NativeByteOrderIs(ByteOrder order)
00358 {
00359         return order == GetNativeByteOrder();
00360 }
00361 
00362 template <class T>
00363 std::string IntToString(T a, unsigned int base = 10)
00364 {
00365         if (a == 0)
00366                 return "0";
00367         bool negate = false;
00368         if (a < 0)
00369         {
00370                 negate = true;
00371                 a = 0-a;        // VC .NET does not like -a
00372         }
00373         std::string result;
00374         while (a > 0)
00375         {
00376                 T digit = a % base;
00377                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
00378                 a /= base;
00379         }
00380         if (negate)
00381                 result = "-" + result;
00382         return result;
00383 }
00384 
00385 template <class T1, class T2>
00386 inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
00387 {
00388         return T1((a > b) ? (a - b) : 0);
00389 }
00390 
00391 template <class T>
00392 inline CipherDir GetCipherDir(const T &obj)
00393 {
00394         return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
00395 }
00396 
00397 CRYPTOPP_DLL void CallNewHandler();
00398 
00399 inline void IncrementCounterByOne(byte *inout, unsigned int s)
00400 {
00401         for (int i=s-1, carry=1; i>=0 && carry; i--)
00402                 carry = !++inout[i];
00403 }
00404 
00405 inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
00406 {
00407         int i, carry;
00408         for (i=s-1, carry=1; i>=0 && carry; i--)
00409                 carry = ((output[i] = input[i]+1) == 0);
00410         memcpy_s(output, s, input, i+1);
00411 }
00412 
00413 // ************** rotate functions ***************
00414 
00415 template <class T> inline T rotlFixed(T x, unsigned int y)
00416 {
00417         assert(y < sizeof(T)*8);
00418         return T((x<<y) | (x>>(sizeof(T)*8-y)));
00419 }
00420 
00421 template <class T> inline T rotrFixed(T x, unsigned int y)
00422 {
00423         assert(y < sizeof(T)*8);
00424         return T((x>>y) | (x<<(sizeof(T)*8-y)));
00425 }
00426 
00427 template <class T> inline T rotlVariable(T x, unsigned int y)
00428 {
00429         assert(y < sizeof(T)*8);
00430         return T((x<<y) | (x>>(sizeof(T)*8-y)));
00431 }
00432 
00433 template <class T> inline T rotrVariable(T x, unsigned int y)
00434 {
00435         assert(y < sizeof(T)*8);
00436         return T((x>>y) | (x<<(sizeof(T)*8-y)));
00437 }
00438 
00439 template <class T> inline T rotlMod(T x, unsigned int y)
00440 {
00441         y %= sizeof(T)*8;
00442         return T((x<<y) | (x>>(sizeof(T)*8-y)));
00443 }
00444 
00445 template <class T> inline T rotrMod(T x, unsigned int y)
00446 {
00447         y %= sizeof(T)*8;
00448         return T((x>>y) | (x<<(sizeof(T)*8-y)));
00449 }
00450 
00451 #ifdef _MSC_VER
00452 
00453 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00454 {
00455         assert(y < 8*sizeof(x));
00456         return y ? _lrotl(x, y) : x;
00457 }
00458 
00459 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00460 {
00461         assert(y < 8*sizeof(x));
00462         return y ? _lrotr(x, y) : x;
00463 }
00464 
00465 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00466 {
00467         assert(y < 8*sizeof(x));
00468         return _lrotl(x, y);
00469 }
00470 
00471 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00472 {
00473         assert(y < 8*sizeof(x));
00474         return _lrotr(x, y);
00475 }
00476 
00477 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00478 {
00479         return _lrotl(x, y);
00480 }
00481 
00482 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00483 {
00484         return _lrotr(x, y);
00485 }
00486 
00487 #if _MSC_VER >= 1300
00488 
00489 template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
00490 {
00491         assert(y < 8*sizeof(x));
00492         return y ? _rotl64(x, y) : x;
00493 }
00494 
00495 template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
00496 {
00497         assert(y < 8*sizeof(x));
00498         return y ? _rotr64(x, y) : x;
00499 }
00500 
00501 template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
00502 {
00503         assert(y < 8*sizeof(x));
00504         return _rotl64(x, y);
00505 }
00506 
00507 template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
00508 {
00509         assert(y < 8*sizeof(x));
00510         return _rotr64(x, y);
00511 }
00512 
00513 template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
00514 {
00515         return _rotl64(x, y);
00516 }
00517 
00518 template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
00519 {
00520         return _rotr64(x, y);
00521 }
00522 
00523 #endif // #if _MSC_VER >= 1310
00524 
00525 #if _MSC_VER >= 1400 && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000)
00526 
00527 template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
00528 {
00529         assert(y < 8*sizeof(x));
00530         return y ? _rotl16(x, y) : x;
00531 }
00532 
00533 template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
00534 {
00535         assert(y < 8*sizeof(x));
00536         return y ? _rotr16(x, y) : x;
00537 }
00538 
00539 template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
00540 {
00541         assert(y < 8*sizeof(x));
00542         return _rotl16(x, y);
00543 }
00544 
00545 template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
00546 {
00547         assert(y < 8*sizeof(x));
00548         return _rotr16(x, y);
00549 }
00550 
00551 template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
00552 {
00553         return _rotl16(x, y);
00554 }
00555 
00556 template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
00557 {
00558         return _rotr16(x, y);
00559 }
00560 
00561 template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
00562 {
00563         assert(y < 8*sizeof(x));
00564         return y ? _rotl8(x, y) : x;
00565 }
00566 
00567 template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
00568 {
00569         assert(y < 8*sizeof(x));
00570         return y ? _rotr8(x, y) : x;
00571 }
00572 
00573 template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
00574 {
00575         assert(y < 8*sizeof(x));
00576         return _rotl8(x, y);
00577 }
00578 
00579 template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
00580 {
00581         assert(y < 8*sizeof(x));
00582         return _rotr8(x, y);
00583 }
00584 
00585 template<> inline byte rotlMod<byte>(byte x, unsigned int y)
00586 {
00587         return _rotl8(x, y);
00588 }
00589 
00590 template<> inline byte rotrMod<byte>(byte x, unsigned int y)
00591 {
00592         return _rotr8(x, y);
00593 }
00594 
00595 #endif // #if _MSC_VER >= 1400
00596 
00597 #endif // #ifdef _MSC_VER
00598 
00599 #if (defined(__MWERKS__) && TARGET_CPU_PPC)
00600 
00601 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00602 {
00603         assert(y < 32);
00604         return y ? __rlwinm(x,y,0,31) : x;
00605 }
00606 
00607 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00608 {
00609         assert(y < 32);
00610         return y ? __rlwinm(x,32-y,0,31) : x;
00611 }
00612 
00613 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00614 {
00615         assert(y < 32);
00616         return (__rlwnm(x,y,0,31));
00617 }
00618 
00619 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00620 {
00621         assert(y < 32);
00622         return (__rlwnm(x,32-y,0,31));
00623 }
00624 
00625 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00626 {
00627         return (__rlwnm(x,y,0,31));
00628 }
00629 
00630 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00631 {
00632         return (__rlwnm(x,32-y,0,31));
00633 }
00634 
00635 #endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
00636 
00637 // ************** endian reversal ***************
00638 
00639 template <class T>
00640 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
00641 {
00642         if (order == LITTLE_ENDIAN_ORDER)
00643                 return GETBYTE(value, index);
00644         else
00645                 return GETBYTE(value, sizeof(T)-index-1);
00646 }
00647 
00648 inline byte ByteReverse(byte value)
00649 {
00650         return value;
00651 }
00652 
00653 inline word16 ByteReverse(word16 value)
00654 {
00655 #ifdef CRYPTOPP_BYTESWAP_AVAILABLE
00656         return bswap_16(value);
00657 #elif defined(_MSC_VER) && _MSC_VER >= 1300
00658         return _byteswap_ushort(value);
00659 #else
00660         return rotlFixed(value, 8U);
00661 #endif
00662 }
00663 
00664 inline word32 ByteReverse(word32 value)
00665 {
00666 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
00667         __asm__ ("bswap %0" : "=r" (value) : "0" (value));
00668         return value;
00669 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
00670         return bswap_32(value);
00671 #elif defined(__MWERKS__) && TARGET_CPU_PPC
00672         return (word32)__lwbrx(&value,0);
00673 #elif defined(_MSC_VER) && _MSC_VER >= 1300
00674         return _byteswap_ulong(value);
00675 #elif CRYPTOPP_FAST_ROTATE(32)
00676         // 5 instructions with rotate instruction, 9 without
00677         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00678 #else
00679         // 6 instructions with rotate instruction, 8 without
00680         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00681         return rotlFixed(value, 16U);
00682 #endif
00683 }
00684 
00685 #ifdef WORD64_AVAILABLE
00686 inline word64 ByteReverse(word64 value)
00687 {
00688 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
00689         __asm__ ("bswap %0" : "=r" (value) : "0" (value));
00690         return value;
00691 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
00692         return bswap_64(value);
00693 #elif defined(_MSC_VER) && _MSC_VER >= 1300
00694         return _byteswap_uint64(value);
00695 #elif defined(CRYPTOPP_SLOW_WORD64)
00696         return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00697 #else
00698         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00699         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00700         return rotlFixed(value, 32U);
00701 #endif
00702 }
00703 #endif
00704 
00705 inline byte BitReverse(byte value)
00706 {
00707         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00708         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00709         return rotlFixed(value, 4U);
00710 }
00711 
00712 inline word16 BitReverse(word16 value)
00713 {
00714         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00715         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00716         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00717         return ByteReverse(value);
00718 }
00719 
00720 inline word32 BitReverse(word32 value)
00721 {
00722         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00723         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00724         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00725         return ByteReverse(value);
00726 }
00727 
00728 #ifdef WORD64_AVAILABLE
00729 inline word64 BitReverse(word64 value)
00730 {
00731 #ifdef CRYPTOPP_SLOW_WORD64
00732         return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00733 #else
00734         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00735         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00736         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00737         return ByteReverse(value);
00738 #endif
00739 }
00740 #endif
00741 
00742 template <class T>
00743 inline T BitReverse(T value)
00744 {
00745         if (sizeof(T) == 1)
00746                 return (T)BitReverse((byte)value);
00747         else if (sizeof(T) == 2)
00748                 return (T)BitReverse((word16)value);
00749         else if (sizeof(T) == 4)
00750                 return (T)BitReverse((word32)value);
00751         else
00752         {
00753 #ifdef WORD64_AVAILABLE
00754                 assert(sizeof(T) == 8);
00755                 return (T)BitReverse((word64)value);
00756 #else
00757                 assert(false);
00758                 return 0;
00759 #endif
00760         }
00761 }
00762 
00763 template <class T>
00764 inline T ConditionalByteReverse(ByteOrder order, T value)
00765 {
00766         return NativeByteOrderIs(order) ? value : ByteReverse(value);
00767 }
00768 
00769 template <class T>
00770 void ByteReverse(T *out, const T *in, size_t byteCount)
00771 {
00772         assert(byteCount % sizeof(T) == 0);
00773         size_t count = byteCount/sizeof(T);
00774         for (size_t i=0; i<count; i++)
00775                 out[i] = ByteReverse(in[i]);
00776 }
00777 
00778 template <class T>
00779 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
00780 {
00781         if (!NativeByteOrderIs(order))
00782                 ByteReverse(out, in, byteCount);
00783         else if (in != out)
00784                 memcpy_s(out, byteCount, in, byteCount);
00785 }
00786 
00787 template <class T>
00788 inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
00789 {
00790         const size_t U = sizeof(T);
00791         assert(inlen <= outlen*U);
00792         memcpy(out, in, inlen);
00793         memset((byte *)out+inlen, 0, outlen*U-inlen);
00794         ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00795 }
00796 
00797 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00798 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
00799 {
00800         return block[0];
00801 }
00802 
00803 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
00804 {
00805         return (order == BIG_ENDIAN_ORDER)
00806                 ? block[1] | (block[0] << 8)
00807                 : block[0] | (block[1] << 8);
00808 }
00809 
00810 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
00811 {
00812         return (order == BIG_ENDIAN_ORDER)
00813                 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00814                 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00815 }
00816 
00817 #ifdef WORD64_AVAILABLE
00818 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
00819 {
00820         return (order == BIG_ENDIAN_ORDER)
00821                 ?
00822                 (word64(block[7]) |
00823                 (word64(block[6]) <<  8) |
00824                 (word64(block[5]) << 16) |
00825                 (word64(block[4]) << 24) |
00826                 (word64(block[3]) << 32) |
00827                 (word64(block[2]) << 40) |
00828                 (word64(block[1]) << 48) |
00829                 (word64(block[0]) << 56))
00830                 :
00831                 (word64(block[0]) |
00832                 (word64(block[1]) <<  8) |
00833                 (word64(block[2]) << 16) |
00834                 (word64(block[3]) << 24) |
00835                 (word64(block[4]) << 32) |
00836                 (word64(block[5]) << 40) |
00837                 (word64(block[6]) << 48) |
00838                 (word64(block[7]) << 56));
00839 }
00840 #endif
00841 
00842 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
00843 {
00844         block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00845 }
00846 
00847 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
00848 {
00849         if (order == BIG_ENDIAN_ORDER)
00850         {
00851                 if (xorBlock)
00852                 {
00853                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00854                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00855                 }
00856                 else
00857                 {
00858                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00859                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00860                 }
00861         }
00862         else
00863         {
00864                 if (xorBlock)
00865                 {
00866                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00867                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00868                 }
00869                 else
00870                 {
00871                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00872                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00873                 }
00874         }
00875 }
00876 
00877 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
00878 {
00879         if (order == BIG_ENDIAN_ORDER)
00880         {
00881                 if (xorBlock)
00882                 {
00883                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00884                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00885                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00886                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00887                 }
00888                 else
00889                 {
00890                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00891                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00892                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00893                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00894                 }
00895         }
00896         else
00897         {
00898                 if (xorBlock)
00899                 {
00900                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00901                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00902                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00903                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00904                 }
00905                 else
00906                 {
00907                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00908                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00909                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00910                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00911                 }
00912         }
00913 }
00914 
00915 #ifdef WORD64_AVAILABLE
00916 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
00917 {
00918         if (order == BIG_ENDIAN_ORDER)
00919         {
00920                 if (xorBlock)
00921                 {
00922                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00923                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00924                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00925                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00926                         block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00927                         block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00928                         block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00929                         block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00930                 }
00931                 else
00932                 {
00933                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00934                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00935                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00936                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00937                         block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00938                         block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00939                         block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00940                         block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00941                 }
00942         }
00943         else
00944         {
00945                 if (xorBlock)
00946                 {
00947                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00948                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00949                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00950                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00951                         block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00952                         block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00953                         block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00954                         block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00955                 }
00956                 else
00957                 {
00958                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00959                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00960                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00961                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00962                         block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00963                         block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00964                         block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00965                         block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00966                 }
00967         }
00968 }
00969 #endif
00970 #endif  // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00971 
00972 template <class T>
00973 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
00974 {
00975 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00976         if (!assumeAligned)
00977                 return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
00978         assert(IsAligned<T>(block));
00979 #endif
00980         return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00981 }
00982 
00983 template <class T>
00984 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
00985 {
00986         result = GetWord<T>(assumeAligned, order, block);
00987 }
00988 
00989 template <class T>
00990 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
00991 {
00992 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00993         if (!assumeAligned)
00994                 return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
00995         assert(IsAligned<T>(block));
00996         assert(IsAligned<T>(xorBlock));
00997 #endif
00998         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
00999 }
01000 
01001 template <class T, class B, bool A=true>
01002 class GetBlock
01003 {
01004 public:
01005         GetBlock(const void *block)
01006                 : m_block((const byte *)block) {}
01007 
01008         template <class U>
01009         inline GetBlock<T, B, A> & operator()(U &x)
01010         {
01011                 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
01012                 x = GetWord<T>(A, B::ToEnum(), m_block);
01013                 m_block += sizeof(T);
01014                 return *this;
01015         }
01016 
01017 private:
01018         const byte *m_block;
01019 };
01020 
01021 template <class T, class B, bool A=false>
01022 class PutBlock
01023 {
01024 public:
01025         PutBlock(const void *xorBlock, void *block)
01026                 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
01027 
01028         template <class U>
01029         inline PutBlock<T, B, A> & operator()(U x)
01030         {
01031                 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
01032                 m_block += sizeof(T);
01033                 if (m_xorBlock)
01034                         m_xorBlock += sizeof(T);
01035                 return *this;
01036         }
01037 
01038 private:
01039         const byte *m_xorBlock;
01040         byte *m_block;
01041 };
01042 
01043 template <class T, class B, bool GA=true, bool PA=false>
01044 struct BlockGetAndPut
01045 {
01046         // function needed because of C++ grammatical ambiguity between expression-statements and declarations
01047         static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
01048         typedef PutBlock<T, B, PA> Put;
01049 };
01050 
01051 template <class T>
01052 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
01053 {
01054         if (!NativeByteOrderIs(order))
01055                 value = ByteReverse(value);
01056 
01057         return std::string((char *)&value, sizeof(value));
01058 }
01059 
01060 template <class T>
01061 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
01062 {
01063         T value = 0;
01064         memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
01065         return NativeByteOrderIs(order) ? value : ByteReverse(value);
01066 }
01067 
01068 // ************** help remove warning on g++ ***************
01069 
01070 template <bool overflow> struct SafeShifter;
01071 
01072 template<> struct SafeShifter<true>
01073 {
01074         template <class T>
01075         static inline T RightShift(T value, unsigned int bits)
01076         {
01077                 return 0;
01078         }
01079 
01080         template <class T>
01081         static inline T LeftShift(T value, unsigned int bits)
01082         {
01083                 return 0;
01084         }
01085 };
01086 
01087 template<> struct SafeShifter<false>
01088 {
01089         template <class T>
01090         static inline T RightShift(T value, unsigned int bits)
01091         {
01092                 return value >> bits;
01093         }
01094 
01095         template <class T>
01096         static inline T LeftShift(T value, unsigned int bits)
01097         {
01098                 return value << bits;
01099         }
01100 };
01101 
01102 template <unsigned int bits, class T>
01103 inline T SafeRightShift(T value)
01104 {
01105         return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
01106 }
01107 
01108 template <unsigned int bits, class T>
01109 inline T SafeLeftShift(T value)
01110 {
01111         return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
01112 }
01113 
01114 NAMESPACE_END
01115 
01116 #endif

Generated on Fri Jun 1 11:11:22 2007 for Crypto++ by  doxygen 1.5.2