- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# misc.h

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