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