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