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