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) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
00026 #endif
00027 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
00028 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
00029
00030
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 CRYPTOPP_API Parity(unsigned long);
00139 CRYPTOPP_DLL unsigned int CRYPTOPP_API BytePrecision(unsigned long);
00140 CRYPTOPP_DLL unsigned int CRYPTOPP_API BitPrecision(unsigned long);
00141 CRYPTOPP_DLL unsigned long CRYPTOPP_API 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 CRYPTOPP_API xorbuf(byte *buf, const byte *mask, unsigned int count);
00164 CRYPTOPP_DLL void CRYPTOPP_API 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 inline void IncrementCounterByOne(byte *inout, unsigned int s)
00270 {
00271 for (int i=s-1, carry=1; i>=0 && carry; i--)
00272 carry = !++inout[i];
00273 }
00274
00275 inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
00276 {
00277 int i, carry;
00278 for (i=s-1, carry=1; i>=0 && carry; i--)
00279 carry = !(output[i] = input[i]+1);
00280 memcpy(output, input, i+1);
00281 }
00282
00283
00284
00285 template <class T> inline T rotlFixed(T x, unsigned int y)
00286 {
00287 assert(y < sizeof(T)*8);
00288 return (x<<y) | (x>>(sizeof(T)*8-y));
00289 }
00290
00291 template <class T> inline T rotrFixed(T x, unsigned int y)
00292 {
00293 assert(y < sizeof(T)*8);
00294 return (x>>y) | (x<<(sizeof(T)*8-y));
00295 }
00296
00297 template <class T> inline T rotlVariable(T x, unsigned int y)
00298 {
00299 assert(y < sizeof(T)*8);
00300 return (x<<y) | (x>>(sizeof(T)*8-y));
00301 }
00302
00303 template <class T> inline T rotrVariable(T x, unsigned int y)
00304 {
00305 assert(y < sizeof(T)*8);
00306 return (x>>y) | (x<<(sizeof(T)*8-y));
00307 }
00308
00309 template <class T> inline T rotlMod(T x, unsigned int y)
00310 {
00311 y %= sizeof(T)*8;
00312 return (x<<y) | (x>>(sizeof(T)*8-y));
00313 }
00314
00315 template <class T> inline T rotrMod(T x, unsigned int y)
00316 {
00317 y %= sizeof(T)*8;
00318 return (x>>y) | (x<<(sizeof(T)*8-y));
00319 }
00320
00321 #ifdef INTEL_INTRINSICS
00322
00323 #pragma intrinsic(_lrotl, _lrotr)
00324
00325 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00326 {
00327 assert(y < 32);
00328 return y ? _lrotl(x, y) : x;
00329 }
00330
00331 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00332 {
00333 assert(y < 32);
00334 return y ? _lrotr(x, y) : x;
00335 }
00336
00337 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00338 {
00339 assert(y < 32);
00340 return _lrotl(x, y);
00341 }
00342
00343 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00344 {
00345 assert(y < 32);
00346 return _lrotr(x, y);
00347 }
00348
00349 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00350 {
00351 return _lrotl(x, y);
00352 }
00353
00354 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00355 {
00356 return _lrotr(x, y);
00357 }
00358
00359 #endif // #ifdef INTEL_INTRINSICS
00360
00361 #ifdef PPC_INTRINSICS
00362
00363 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00364 {
00365 assert(y < 32);
00366 return y ? __rlwinm(x,y,0,31) : x;
00367 }
00368
00369 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00370 {
00371 assert(y < 32);
00372 return y ? __rlwinm(x,32-y,0,31) : x;
00373 }
00374
00375 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00376 {
00377 assert(y < 32);
00378 return (__rlwnm(x,y,0,31));
00379 }
00380
00381 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00382 {
00383 assert(y < 32);
00384 return (__rlwnm(x,32-y,0,31));
00385 }
00386
00387 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00388 {
00389 return (__rlwnm(x,y,0,31));
00390 }
00391
00392 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00393 {
00394 return (__rlwnm(x,32-y,0,31));
00395 }
00396
00397 #endif // #ifdef PPC_INTRINSICS
00398
00399
00400
00401 template <class T>
00402 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
00403 {
00404 if (order == LITTLE_ENDIAN_ORDER)
00405 return GETBYTE(value, index);
00406 else
00407 return GETBYTE(value, sizeof(T)-index-1);
00408 }
00409
00410 inline byte ByteReverse(byte value)
00411 {
00412 return value;
00413 }
00414
00415 inline word16 ByteReverse(word16 value)
00416 {
00417 return rotlFixed(value, 8U);
00418 }
00419
00420 inline word32 ByteReverse(word32 value)
00421 {
00422 #ifdef PPC_INTRINSICS
00423
00424 return (word32)__lwbrx(&value,0);
00425 #elif defined(FAST_ROTATE)
00426
00427 return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00428 #else
00429
00430 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00431 return rotlFixed(value, 16U);
00432 #endif
00433 }
00434
00435 #ifdef WORD64_AVAILABLE
00436 inline word64 ByteReverse(word64 value)
00437 {
00438 #ifdef CRYPTOPP_SLOW_WORD64
00439 return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00440 #else
00441 value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00442 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00443 return rotlFixed(value, 32U);
00444 #endif
00445 }
00446 #endif
00447
00448 inline byte BitReverse(byte value)
00449 {
00450 value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00451 value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00452 return rotlFixed(value, 4);
00453 }
00454
00455 inline word16 BitReverse(word16 value)
00456 {
00457 value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00458 value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00459 value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00460 return ByteReverse(value);
00461 }
00462
00463 inline word32 BitReverse(word32 value)
00464 {
00465 value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00466 value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00467 value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00468 return ByteReverse(value);
00469 }
00470
00471 #ifdef WORD64_AVAILABLE
00472 inline word64 BitReverse(word64 value)
00473 {
00474 #ifdef CRYPTOPP_SLOW_WORD64
00475 return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00476 #else
00477 value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00478 value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00479 value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00480 return ByteReverse(value);
00481 #endif
00482 }
00483 #endif
00484
00485 template <class T>
00486 inline T BitReverse(T value)
00487 {
00488 if (sizeof(T) == 1)
00489 return (T)BitReverse((byte)value);
00490 else if (sizeof(T) == 2)
00491 return (T)BitReverse((word16)value);
00492 else if (sizeof(T) == 4)
00493 return (T)BitReverse((word32)value);
00494 else
00495 {
00496 #ifdef WORD64_AVAILABLE
00497 assert(sizeof(T) == 8);
00498 return (T)BitReverse((word64)value);
00499 #else
00500 assert(false);
00501 return 0;
00502 #endif
00503 }
00504 }
00505
00506 template <class T>
00507 inline T ConditionalByteReverse(ByteOrder order, T value)
00508 {
00509 return NativeByteOrderIs(order) ? value : ByteReverse(value);
00510 }
00511
00512 template <class T>
00513 void ByteReverse(T *out, const T *in, unsigned int byteCount)
00514 {
00515 assert(byteCount % sizeof(T) == 0);
00516 unsigned int count = byteCount/sizeof(T);
00517 for (unsigned int i=0; i<count; i++)
00518 out[i] = ByteReverse(in[i]);
00519 }
00520
00521 template <class T>
00522 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, unsigned int byteCount)
00523 {
00524 if (!NativeByteOrderIs(order))
00525 ByteReverse(out, in, byteCount);
00526 else if (in != out)
00527 memcpy(out, in, byteCount);
00528 }
00529
00530 template <class T>
00531 inline void GetUserKey(ByteOrder order, T *out, unsigned int outlen, const byte *in, unsigned int inlen)
00532 {
00533 const unsigned int U = sizeof(T);
00534 assert(inlen <= outlen*U);
00535 memcpy(out, in, inlen);
00536 memset((byte *)out+inlen, 0, outlen*U-inlen);
00537 ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00538 }
00539
00540 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, byte*)
00541 {
00542 return block[0];
00543 }
00544
00545 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word16*)
00546 {
00547 return (order == BIG_ENDIAN_ORDER)
00548 ? block[1] | (block[0] << 8)
00549 : block[0] | (block[1] << 8);
00550 }
00551
00552 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word32*)
00553 {
00554 return (order == BIG_ENDIAN_ORDER)
00555 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00556 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00557 }
00558
00559 #ifdef WORD64_AVAILABLE
00560 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word64*)
00561 {
00562 return (order == BIG_ENDIAN_ORDER)
00563 ?
00564 (word64(block[7]) |
00565 (word64(block[6]) << 8) |
00566 (word64(block[5]) << 16) |
00567 (word64(block[4]) << 24) |
00568 (word64(block[3]) << 32) |
00569 (word64(block[2]) << 40) |
00570 (word64(block[1]) << 48) |
00571 (word64(block[0]) << 56))
00572 :
00573 (word64(block[0]) |
00574 (word64(block[1]) << 8) |
00575 (word64(block[2]) << 16) |
00576 (word64(block[3]) << 24) |
00577 (word64(block[4]) << 32) |
00578 (word64(block[5]) << 40) |
00579 (word64(block[6]) << 48) |
00580 (word64(block[7]) << 56));
00581 }
00582 #endif
00583
00584 template <class T>
00585 inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
00586 {
00587 return UnalignedGetWordNonTemplate(order, block, dummy);
00588 }
00589
00590 inline void UnalignedPutWord(ByteOrder order, byte *block, byte value, const byte *xorBlock = NULL)
00591 {
00592 block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00593 }
00594
00595 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = NULL)
00596 {
00597 if (order == BIG_ENDIAN_ORDER)
00598 {
00599 block[0] = GETBYTE(value, 1);
00600 block[1] = GETBYTE(value, 0);
00601 }
00602 else
00603 {
00604 block[0] = GETBYTE(value, 0);
00605 block[1] = GETBYTE(value, 1);
00606 }
00607
00608 if (xorBlock)
00609 {
00610 block[0] ^= xorBlock[0];
00611 block[1] ^= xorBlock[1];
00612 }
00613 }
00614
00615 inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const byte *xorBlock = NULL)
00616 {
00617 if (order == BIG_ENDIAN_ORDER)
00618 {
00619 block[0] = GETBYTE(value, 3);
00620 block[1] = GETBYTE(value, 2);
00621 block[2] = GETBYTE(value, 1);
00622 block[3] = GETBYTE(value, 0);
00623 }
00624 else
00625 {
00626 block[0] = GETBYTE(value, 0);
00627 block[1] = GETBYTE(value, 1);
00628 block[2] = GETBYTE(value, 2);
00629 block[3] = GETBYTE(value, 3);
00630 }
00631
00632 if (xorBlock)
00633 {
00634 block[0] ^= xorBlock[0];
00635 block[1] ^= xorBlock[1];
00636 block[2] ^= xorBlock[2];
00637 block[3] ^= xorBlock[3];
00638 }
00639 }
00640
00641 #ifdef WORD64_AVAILABLE
00642 inline void UnalignedPutWord(ByteOrder order, byte *block, word64 value, const byte *xorBlock = NULL)
00643 {
00644 if (order == BIG_ENDIAN_ORDER)
00645 {
00646 block[0] = GETBYTE(value, 7);
00647 block[1] = GETBYTE(value, 6);
00648 block[2] = GETBYTE(value, 5);
00649 block[3] = GETBYTE(value, 4);
00650 block[4] = GETBYTE(value, 3);
00651 block[5] = GETBYTE(value, 2);
00652 block[6] = GETBYTE(value, 1);
00653 block[7] = GETBYTE(value, 0);
00654 }
00655 else
00656 {
00657 block[0] = GETBYTE(value, 0);
00658 block[1] = GETBYTE(value, 1);
00659 block[2] = GETBYTE(value, 2);
00660 block[3] = GETBYTE(value, 3);
00661 block[4] = GETBYTE(value, 4);
00662 block[5] = GETBYTE(value, 5);
00663 block[6] = GETBYTE(value, 6);
00664 block[7] = GETBYTE(value, 7);
00665 }
00666
00667 if (xorBlock)
00668 {
00669 block[0] ^= xorBlock[0];
00670 block[1] ^= xorBlock[1];
00671 block[2] ^= xorBlock[2];
00672 block[3] ^= xorBlock[3];
00673 block[4] ^= xorBlock[4];
00674 block[5] ^= xorBlock[5];
00675 block[6] ^= xorBlock[6];
00676 block[7] ^= xorBlock[7];
00677 }
00678 }
00679 #endif
00680
00681 template <class T>
00682 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
00683 {
00684 if (assumeAligned)
00685 {
00686 assert(IsAligned<T>(block));
00687 return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00688 }
00689 else
00690 return UnalignedGetWord<T>(order, block);
00691 }
00692
00693 template <class T>
00694 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
00695 {
00696 result = GetWord<T>(assumeAligned, order, block);
00697 }
00698
00699 template <class T>
00700 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
00701 {
00702 if (assumeAligned)
00703 {
00704 assert(IsAligned<T>(block));
00705 if (xorBlock)
00706 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
00707 else
00708 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
00709 }
00710 else
00711 UnalignedPutWord(order, block, value, xorBlock);
00712 }
00713
00714 template <class T, class B, bool A=true>
00715 class GetBlock
00716 {
00717 public:
00718 GetBlock(const void *block)
00719 : m_block((const byte *)block) {}
00720
00721 template <class U>
00722 inline GetBlock<T, B, A> & operator()(U &x)
00723 {
00724 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
00725 x = GetWord<T>(A, B::ToEnum(), m_block);
00726 m_block += sizeof(T);
00727 return *this;
00728 }
00729
00730 private:
00731 const byte *m_block;
00732 };
00733
00734 template <class T, class B, bool A=true>
00735 class PutBlock
00736 {
00737 public:
00738 PutBlock(const void *xorBlock, void *block)
00739 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
00740
00741 template <class U>
00742 inline PutBlock<T, B, A> & operator()(U x)
00743 {
00744 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
00745 m_block += sizeof(T);
00746 if (m_xorBlock)
00747 m_xorBlock += sizeof(T);
00748 return *this;
00749 }
00750
00751 private:
00752 const byte *m_xorBlock;
00753 byte *m_block;
00754 };
00755
00756 template <class T, class B, bool A=true>
00757 struct BlockGetAndPut
00758 {
00759
00760 static inline GetBlock<T, B, A> Get(const void *block) {return GetBlock<T, B, A>(block);}
00761 typedef PutBlock<T, B, A> Put;
00762 };
00763
00764 template <class T>
00765 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
00766 {
00767 if (!NativeByteOrderIs(order))
00768 value = ByteReverse(value);
00769
00770 return std::string((char *)&value, sizeof(value));
00771 }
00772
00773 template <class T>
00774 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
00775 {
00776 T value = 0;
00777 memcpy(&value, str.data(), STDMIN(sizeof(value), str.size()));
00778 return NativeByteOrderIs(order) ? value : ByteReverse(value);
00779 }
00780
00781
00782
00783 template <bool overflow> struct SafeShifter;
00784
00785 template<> struct SafeShifter<true>
00786 {
00787 template <class T>
00788 static inline T RightShift(T value, unsigned int bits)
00789 {
00790 return 0;
00791 }
00792
00793 template <class T>
00794 static inline T LeftShift(T value, unsigned int bits)
00795 {
00796 return 0;
00797 }
00798 };
00799
00800 template<> struct SafeShifter<false>
00801 {
00802 template <class T>
00803 static inline T RightShift(T value, unsigned int bits)
00804 {
00805 return value >> bits;
00806 }
00807
00808 template <class T>
00809 static inline T LeftShift(T value, unsigned int bits)
00810 {
00811 return value << bits;
00812 }
00813 };
00814
00815 template <unsigned int bits, class T>
00816 inline T SafeRightShift(T value)
00817 {
00818 return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
00819 }
00820
00821 template <unsigned int bits, class T>
00822 inline T SafeLeftShift(T value)
00823 {
00824 return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
00825 }
00826
00827 NAMESPACE_END
00828
00829 #endif // MISC_H