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