Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

misc.h

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 // ************** compile-time assertion ***************
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 // ************** misc classes ***************
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 /*! This function safely initializes a static object in a multithreaded environment without using locks.
00071         It may leak memory when two threads try to initialize the static object at the same time
00072         but this should be acceptable since each static object is only initialized once per session.
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         // VC60 workaround: use "..." to prevent this function from being inlined
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 // ************** misc functions ***************
00118 
00119 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
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 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
00145 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00146 // these may be faster on other CPUs/compilers
00147 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
00148 // #define GETBYTE(x, y) (((byte *)&(x))[y])
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) // VC60 workaround
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)     // VC60 workaround
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;        // VC .NET does not like -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);  // T1 is unsigned type
00335         CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);  // T2 is unsigned type
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 // ************** rotate functions ***************
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 // ************** endian reversal ***************
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         // PPC: load reverse indexed instruction
00502         return (word32)__lwbrx(&value,0);
00503 #elif defined(FAST_ROTATE)
00504         // 5 instructions with rotate instruction, 9 without
00505         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00506 #else
00507         // 6 instructions with rotate instruction, 8 without
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         // function needed because of C++ grammatical ambiguity between expression-statements and declarations
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 // ************** help remove warning on g++ ***************
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

Generated on Tue Aug 16 08:38:42 2005 for Crypto++ by  doxygen 1.3.9.1