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