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 T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
00126 {
00127 CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
00128 assert(a>=0);
00129 assert(b>=0);
00130
00131 if (sizeof(T1)<=sizeof(T2))
00132 return b < (T2)a ? (T1)b : a;
00133 else
00134 return (T1)b < a ? (T1)b : a;
00135 }
00136
00137 template <class T> inline const T& STDMAX(const T& a, const T& b)
00138 {
00139 return a < b ? b : a;
00140 }
00141
00142 #define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
00143
00144
00145 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00146
00147
00148
00149
00150 template <class T>
00151 unsigned int Parity(T value)
00152 {
00153 for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
00154 value ^= value >> i;
00155 return (unsigned int)value&1;
00156 }
00157
00158 template <class T>
00159 unsigned int BytePrecision(const T &value)
00160 {
00161 if (!value)
00162 return 0;
00163
00164 unsigned int l=0, h=8*sizeof(value);
00165
00166 while (h-l > 8)
00167 {
00168 unsigned int t = (l+h)/2;
00169 if (value >> t)
00170 l = t;
00171 else
00172 h = t;
00173 }
00174
00175 return h/8;
00176 }
00177
00178 template <class T>
00179 unsigned int BitPrecision(const T &value)
00180 {
00181 if (!value)
00182 return 0;
00183
00184 unsigned int l=0, h=8*sizeof(value);
00185
00186 while (h-l > 1)
00187 {
00188 unsigned int t = (l+h)/2;
00189 if (value >> t)
00190 l = t;
00191 else
00192 h = t;
00193 }
00194
00195 return h;
00196 }
00197
00198 template <class T>
00199 inline T Crop(T value, size_t size)
00200 {
00201 if (size < 8*sizeof(value))
00202 return T(value & ((T(1) << size) - 1));
00203 else
00204 return value;
00205 }
00206
00207 template <class T1, class T2>
00208 inline bool SafeConvert(T1 from, T2 &to)
00209 {
00210 to = (T2)from;
00211 if (from != to || (from > 0 && to < 0))
00212 return false;
00213 return true;
00214 }
00215
00216 inline size_t BitsToBytes(size_t bitCount)
00217 {
00218 return ((bitCount+7)/(8));
00219 }
00220
00221 inline size_t BytesToWords(size_t byteCount)
00222 {
00223 return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00224 }
00225
00226 inline size_t BitsToWords(size_t bitCount)
00227 {
00228 return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00229 }
00230
00231 inline size_t BitsToDwords(size_t bitCount)
00232 {
00233 return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
00234 }
00235
00236 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
00237 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
00238
00239 template <class T>
00240 inline bool IsPowerOf2(const T &n)
00241 {
00242 return n > 0 && (n & (n-1)) == 0;
00243 }
00244
00245 template <class T1, class T2>
00246 inline T2 ModPowerOf2(const T1 &a, const T2 &b)
00247 {
00248 assert(IsPowerOf2(b));
00249 return T2(a) & (b-1);
00250 }
00251
00252 template <class T1, class T2>
00253 inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
00254 {
00255 if (IsPowerOf2(m))
00256 return n - ModPowerOf2(n, m);
00257 else
00258 return n - n%m;
00259 }
00260
00261 template <class T1, class T2>
00262 inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
00263 {
00264 if (n+m-1 < n)
00265 throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
00266 return RoundDownToMultipleOf(n+m-1, m);
00267 }
00268
00269 template <class T>
00270 inline unsigned int GetAlignment(T *dummy=NULL)
00271 {
00272 #if (_MSC_VER >= 1300)
00273 return __alignof(T);
00274 #elif defined(__GNUC__)
00275 return __alignof__(T);
00276 #else
00277 return sizeof(T);
00278 #endif
00279 }
00280
00281 inline bool IsAlignedOn(const void *p, unsigned int alignment)
00282 {
00283 return IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0;
00284 }
00285
00286 template <class T>
00287 inline bool IsAligned(const void *p, T *dummy=NULL)
00288 {
00289 return IsAlignedOn(p, GetAlignment<T>());
00290 }
00291
00292 #ifdef IS_LITTLE_ENDIAN
00293 typedef LittleEndian NativeByteOrder;
00294 #else
00295 typedef BigEndian NativeByteOrder;
00296 #endif
00297
00298 inline ByteOrder GetNativeByteOrder()
00299 {
00300 return NativeByteOrder::ToEnum();
00301 }
00302
00303 inline bool NativeByteOrderIs(ByteOrder order)
00304 {
00305 return order == GetNativeByteOrder();
00306 }
00307
00308 template <class T>
00309 std::string IntToString(T a, unsigned int base = 10)
00310 {
00311 if (a == 0)
00312 return "0";
00313 bool negate = false;
00314 if (a < 0)
00315 {
00316 negate = true;
00317 a = 0-a;
00318 }
00319 std::string result;
00320 while (a > 0)
00321 {
00322 T digit = a % base;
00323 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
00324 a /= base;
00325 }
00326 if (negate)
00327 result = "-" + result;
00328 return result;
00329 }
00330
00331 template <class T1, class T2>
00332 inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
00333 {
00334 CRYPTOPP_COMPILE_ASSERT_INSTANCE(T1(-1)>0, 0);
00335 CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);
00336 return T1((a > b) ? (a - b) : 0);
00337 }
00338
00339 template <class T>
00340 inline CipherDir GetCipherDir(const T &obj)
00341 {
00342 return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
00343 }
00344
00345 void CallNewHandler();
00346
00347 inline void IncrementCounterByOne(byte *inout, unsigned int s)
00348 {
00349 for (int i=s-1, carry=1; i>=0 && carry; i--)
00350 carry = !++inout[i];
00351 }
00352
00353 inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
00354 {
00355 int i, carry;
00356 for (i=s-1, carry=1; i>=0 && carry; i--)
00357 carry = !(output[i] = input[i]+1);
00358 memcpy(output, input, i+1);
00359 }
00360
00361
00362
00363 template <class T> inline T rotlFixed(T x, unsigned int y)
00364 {
00365 assert(y < sizeof(T)*8);
00366 return (x<<y) | (x>>(sizeof(T)*8-y));
00367 }
00368
00369 template <class T> inline T rotrFixed(T x, unsigned int y)
00370 {
00371 assert(y < sizeof(T)*8);
00372 return (x>>y) | (x<<(sizeof(T)*8-y));
00373 }
00374
00375 template <class T> inline T rotlVariable(T x, unsigned int y)
00376 {
00377 assert(y < sizeof(T)*8);
00378 return (x<<y) | (x>>(sizeof(T)*8-y));
00379 }
00380
00381 template <class T> inline T rotrVariable(T x, unsigned int y)
00382 {
00383 assert(y < sizeof(T)*8);
00384 return (x>>y) | (x<<(sizeof(T)*8-y));
00385 }
00386
00387 template <class T> inline T rotlMod(T x, unsigned int y)
00388 {
00389 y %= sizeof(T)*8;
00390 return (x<<y) | (x>>(sizeof(T)*8-y));
00391 }
00392
00393 template <class T> inline T rotrMod(T x, unsigned int y)
00394 {
00395 y %= sizeof(T)*8;
00396 return (x>>y) | (x<<(sizeof(T)*8-y));
00397 }
00398
00399 #ifdef INTEL_INTRINSICS
00400
00401 #pragma intrinsic(_lrotl, _lrotr)
00402
00403 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00404 {
00405 assert(y < 32);
00406 return y ? _lrotl(x, y) : x;
00407 }
00408
00409 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00410 {
00411 assert(y < 32);
00412 return y ? _lrotr(x, y) : x;
00413 }
00414
00415 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00416 {
00417 assert(y < 32);
00418 return _lrotl(x, y);
00419 }
00420
00421 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00422 {
00423 assert(y < 32);
00424 return _lrotr(x, y);
00425 }
00426
00427 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00428 {
00429 return _lrotl(x, y);
00430 }
00431
00432 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00433 {
00434 return _lrotr(x, y);
00435 }
00436
00437 #endif // #ifdef INTEL_INTRINSICS
00438
00439 #ifdef PPC_INTRINSICS
00440
00441 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00442 {
00443 assert(y < 32);
00444 return y ? __rlwinm(x,y,0,31) : x;
00445 }
00446
00447 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00448 {
00449 assert(y < 32);
00450 return y ? __rlwinm(x,32-y,0,31) : x;
00451 }
00452
00453 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00454 {
00455 assert(y < 32);
00456 return (__rlwnm(x,y,0,31));
00457 }
00458
00459 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00460 {
00461 assert(y < 32);
00462 return (__rlwnm(x,32-y,0,31));
00463 }
00464
00465 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00466 {
00467 return (__rlwnm(x,y,0,31));
00468 }
00469
00470 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00471 {
00472 return (__rlwnm(x,32-y,0,31));
00473 }
00474
00475 #endif // #ifdef PPC_INTRINSICS
00476
00477
00478
00479 template <class T>
00480 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
00481 {
00482 if (order == LITTLE_ENDIAN_ORDER)
00483 return GETBYTE(value, index);
00484 else
00485 return GETBYTE(value, sizeof(T)-index-1);
00486 }
00487
00488 inline byte ByteReverse(byte value)
00489 {
00490 return value;
00491 }
00492
00493 inline word16 ByteReverse(word16 value)
00494 {
00495 return rotlFixed(value, 8U);
00496 }
00497
00498 inline word32 ByteReverse(word32 value)
00499 {
00500 #ifdef PPC_INTRINSICS
00501
00502 return (word32)__lwbrx(&value,0);
00503 #elif defined(FAST_ROTATE)
00504
00505 return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00506 #else
00507
00508 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00509 return rotlFixed(value, 16U);
00510 #endif
00511 }
00512
00513 #ifdef WORD64_AVAILABLE
00514 inline word64 ByteReverse(word64 value)
00515 {
00516 #ifdef CRYPTOPP_SLOW_WORD64
00517 return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00518 #else
00519 value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00520 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00521 return rotlFixed(value, 32U);
00522 #endif
00523 }
00524 #endif
00525
00526 inline byte BitReverse(byte value)
00527 {
00528 value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00529 value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00530 return rotlFixed(value, 4);
00531 }
00532
00533 inline word16 BitReverse(word16 value)
00534 {
00535 value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00536 value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00537 value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00538 return ByteReverse(value);
00539 }
00540
00541 inline word32 BitReverse(word32 value)
00542 {
00543 value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00544 value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00545 value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00546 return ByteReverse(value);
00547 }
00548
00549 #ifdef WORD64_AVAILABLE
00550 inline word64 BitReverse(word64 value)
00551 {
00552 #ifdef CRYPTOPP_SLOW_WORD64
00553 return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00554 #else
00555 value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00556 value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00557 value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00558 return ByteReverse(value);
00559 #endif
00560 }
00561 #endif
00562
00563 template <class T>
00564 inline T BitReverse(T value)
00565 {
00566 if (sizeof(T) == 1)
00567 return (T)BitReverse((byte)value);
00568 else if (sizeof(T) == 2)
00569 return (T)BitReverse((word16)value);
00570 else if (sizeof(T) == 4)
00571 return (T)BitReverse((word32)value);
00572 else
00573 {
00574 #ifdef WORD64_AVAILABLE
00575 assert(sizeof(T) == 8);
00576 return (T)BitReverse((word64)value);
00577 #else
00578 assert(false);
00579 return 0;
00580 #endif
00581 }
00582 }
00583
00584 template <class T>
00585 inline T ConditionalByteReverse(ByteOrder order, T value)
00586 {
00587 return NativeByteOrderIs(order) ? value : ByteReverse(value);
00588 }
00589
00590 template <class T>
00591 void ByteReverse(T *out, const T *in, size_t byteCount)
00592 {
00593 assert(byteCount % sizeof(T) == 0);
00594 size_t count = byteCount/sizeof(T);
00595 for (size_t i=0; i<count; i++)
00596 out[i] = ByteReverse(in[i]);
00597 }
00598
00599 template <class T>
00600 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
00601 {
00602 if (!NativeByteOrderIs(order))
00603 ByteReverse(out, in, byteCount);
00604 else if (in != out)
00605 memcpy(out, in, byteCount);
00606 }
00607
00608 template <class T>
00609 inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
00610 {
00611 const size_t U = sizeof(T);
00612 assert(inlen <= outlen*U);
00613 memcpy(out, in, inlen);
00614 memset((byte *)out+inlen, 0, outlen*U-inlen);
00615 ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00616 }
00617
00618 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, byte*)
00619 {
00620 return block[0];
00621 }
00622
00623 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word16*)
00624 {
00625 return (order == BIG_ENDIAN_ORDER)
00626 ? block[1] | (block[0] << 8)
00627 : block[0] | (block[1] << 8);
00628 }
00629
00630 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word32*)
00631 {
00632 return (order == BIG_ENDIAN_ORDER)
00633 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00634 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00635 }
00636
00637 #ifdef WORD64_AVAILABLE
00638 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word64*)
00639 {
00640 return (order == BIG_ENDIAN_ORDER)
00641 ?
00642 (word64(block[7]) |
00643 (word64(block[6]) << 8) |
00644 (word64(block[5]) << 16) |
00645 (word64(block[4]) << 24) |
00646 (word64(block[3]) << 32) |
00647 (word64(block[2]) << 40) |
00648 (word64(block[1]) << 48) |
00649 (word64(block[0]) << 56))
00650 :
00651 (word64(block[0]) |
00652 (word64(block[1]) << 8) |
00653 (word64(block[2]) << 16) |
00654 (word64(block[3]) << 24) |
00655 (word64(block[4]) << 32) |
00656 (word64(block[5]) << 40) |
00657 (word64(block[6]) << 48) |
00658 (word64(block[7]) << 56));
00659 }
00660 #endif
00661
00662 template <class T>
00663 inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
00664 {
00665 return UnalignedGetWordNonTemplate(order, block, dummy);
00666 }
00667
00668 inline void UnalignedPutWord(ByteOrder order, byte *block, byte value, const byte *xorBlock = NULL)
00669 {
00670 block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00671 }
00672
00673 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = NULL)
00674 {
00675 if (order == BIG_ENDIAN_ORDER)
00676 {
00677 block[0] = GETBYTE(value, 1);
00678 block[1] = GETBYTE(value, 0);
00679 }
00680 else
00681 {
00682 block[0] = GETBYTE(value, 0);
00683 block[1] = GETBYTE(value, 1);
00684 }
00685
00686 if (xorBlock)
00687 {
00688 block[0] ^= xorBlock[0];
00689 block[1] ^= xorBlock[1];
00690 }
00691 }
00692
00693 inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const byte *xorBlock = NULL)
00694 {
00695 if (order == BIG_ENDIAN_ORDER)
00696 {
00697 block[0] = GETBYTE(value, 3);
00698 block[1] = GETBYTE(value, 2);
00699 block[2] = GETBYTE(value, 1);
00700 block[3] = GETBYTE(value, 0);
00701 }
00702 else
00703 {
00704 block[0] = GETBYTE(value, 0);
00705 block[1] = GETBYTE(value, 1);
00706 block[2] = GETBYTE(value, 2);
00707 block[3] = GETBYTE(value, 3);
00708 }
00709
00710 if (xorBlock)
00711 {
00712 block[0] ^= xorBlock[0];
00713 block[1] ^= xorBlock[1];
00714 block[2] ^= xorBlock[2];
00715 block[3] ^= xorBlock[3];
00716 }
00717 }
00718
00719 #ifdef WORD64_AVAILABLE
00720 inline void UnalignedPutWord(ByteOrder order, byte *block, word64 value, const byte *xorBlock = NULL)
00721 {
00722 if (order == BIG_ENDIAN_ORDER)
00723 {
00724 block[0] = GETBYTE(value, 7);
00725 block[1] = GETBYTE(value, 6);
00726 block[2] = GETBYTE(value, 5);
00727 block[3] = GETBYTE(value, 4);
00728 block[4] = GETBYTE(value, 3);
00729 block[5] = GETBYTE(value, 2);
00730 block[6] = GETBYTE(value, 1);
00731 block[7] = GETBYTE(value, 0);
00732 }
00733 else
00734 {
00735 block[0] = GETBYTE(value, 0);
00736 block[1] = GETBYTE(value, 1);
00737 block[2] = GETBYTE(value, 2);
00738 block[3] = GETBYTE(value, 3);
00739 block[4] = GETBYTE(value, 4);
00740 block[5] = GETBYTE(value, 5);
00741 block[6] = GETBYTE(value, 6);
00742 block[7] = GETBYTE(value, 7);
00743 }
00744
00745 if (xorBlock)
00746 {
00747 block[0] ^= xorBlock[0];
00748 block[1] ^= xorBlock[1];
00749 block[2] ^= xorBlock[2];
00750 block[3] ^= xorBlock[3];
00751 block[4] ^= xorBlock[4];
00752 block[5] ^= xorBlock[5];
00753 block[6] ^= xorBlock[6];
00754 block[7] ^= xorBlock[7];
00755 }
00756 }
00757 #endif
00758
00759 template <class T>
00760 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
00761 {
00762 if (assumeAligned)
00763 {
00764 assert(IsAligned<T>(block));
00765 return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00766 }
00767 else
00768 return UnalignedGetWord<T>(order, block);
00769 }
00770
00771 template <class T>
00772 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
00773 {
00774 result = GetWord<T>(assumeAligned, order, block);
00775 }
00776
00777 template <class T>
00778 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
00779 {
00780 if (assumeAligned)
00781 {
00782 assert(IsAligned<T>(block));
00783 if (xorBlock)
00784 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
00785 else
00786 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
00787 }
00788 else
00789 UnalignedPutWord(order, block, value, xorBlock);
00790 }
00791
00792 template <class T, class B, bool A=true>
00793 class GetBlock
00794 {
00795 public:
00796 GetBlock(const void *block)
00797 : m_block((const byte *)block) {}
00798
00799 template <class U>
00800 inline GetBlock<T, B, A> & operator()(U &x)
00801 {
00802 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
00803 x = GetWord<T>(A, B::ToEnum(), m_block);
00804 m_block += sizeof(T);
00805 return *this;
00806 }
00807
00808 private:
00809 const byte *m_block;
00810 };
00811
00812 template <class T, class B, bool A=true>
00813 class PutBlock
00814 {
00815 public:
00816 PutBlock(const void *xorBlock, void *block)
00817 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
00818
00819 template <class U>
00820 inline PutBlock<T, B, A> & operator()(U x)
00821 {
00822 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
00823 m_block += sizeof(T);
00824 if (m_xorBlock)
00825 m_xorBlock += sizeof(T);
00826 return *this;
00827 }
00828
00829 private:
00830 const byte *m_xorBlock;
00831 byte *m_block;
00832 };
00833
00834 template <class T, class B, bool A=true>
00835 struct BlockGetAndPut
00836 {
00837
00838 static inline GetBlock<T, B, A> Get(const void *block) {return GetBlock<T, B, A>(block);}
00839 typedef PutBlock<T, B, A> Put;
00840 };
00841
00842 template <class T>
00843 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
00844 {
00845 if (!NativeByteOrderIs(order))
00846 value = ByteReverse(value);
00847
00848 return std::string((char *)&value, sizeof(value));
00849 }
00850
00851 template <class T>
00852 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
00853 {
00854 T value = 0;
00855 memcpy(&value, str.data(), UnsignedMin(str.size(), sizeof(value)));
00856 return NativeByteOrderIs(order) ? value : ByteReverse(value);
00857 }
00858
00859
00860
00861 template <bool overflow> struct SafeShifter;
00862
00863 template<> struct SafeShifter<true>
00864 {
00865 template <class T>
00866 static inline T RightShift(T value, unsigned int bits)
00867 {
00868 return 0;
00869 }
00870
00871 template <class T>
00872 static inline T LeftShift(T value, unsigned int bits)
00873 {
00874 return 0;
00875 }
00876 };
00877
00878 template<> struct SafeShifter<false>
00879 {
00880 template <class T>
00881 static inline T RightShift(T value, unsigned int bits)
00882 {
00883 return value >> bits;
00884 }
00885
00886 template <class T>
00887 static inline T LeftShift(T value, unsigned int bits)
00888 {
00889 return value << bits;
00890 }
00891 };
00892
00893 template <unsigned int bits, class T>
00894 inline T SafeRightShift(T value)
00895 {
00896 return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
00897 }
00898
00899 template <unsigned int bits, class T>
00900 inline T SafeLeftShift(T value)
00901 {
00902 return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
00903 }
00904
00905 NAMESPACE_END
00906
00907 #endif // MISC_H