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