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

Generated on Tue Sep 6 03:42:36 2005 for Crypto++ by  doxygen 1.4.4