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