- Main Page
- Namespaces
- Classes
- Files

# misc.h

    00001 #ifndef CRYPTOPP_MISC_H
    00002 #define CRYPTOPP_MISC_H
    00003
    00004 #include "cryptlib.h"
    00005 #include "smartptr.h"
    00006 #include <string.h>             // for memcpy and memmove
    00007
    00008 #ifdef _MSC_VER
    00009         #include <stdlib.h>
    00010         #if _MSC_VER >= 1400
    00011                 // VC2005 workaround: disable declarations that conflict with winnt.h
    00012                 #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
    00013                 #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
    00014                 #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3
    00015                 #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4
    00016                 #include <intrin.h>
    00017                 #undef _interlockedbittestandset
    00018                 #undef _interlockedbittestandreset
    00019                 #undef _interlockedbittestandset64
    00020                 #undef _interlockedbittestandreset64
    00021                 #define CRYPTOPP_FAST_ROTATE(x) 1
    00022         #elif _MSC_VER >= 1300
    00023                 #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
    00024         #else
    00025                 #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
    00026         #endif
    00027 #elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
    00028         (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
    00029         #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
    00030 #elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)     // depend on GCC's peephole optimization to generate rotate instructions
    00031         #define CRYPTOPP_FAST_ROTATE(x) 1
    00032 #else
    00033         #define CRYPTOPP_FAST_ROTATE(x) 0
    00034 #endif
    00035
    00036 #ifdef __BORLANDC__
    00037 #include <mem.h>
    00038 #endif
    00039
    00040 #if defined(__GNUC__) && defined(__linux__)
    00041 #define CRYPTOPP_BYTESWAP_AVAILABLE
    00042 #include <byteswap.h>
    00043 #endif
    00044
    00045 NAMESPACE_BEGIN(CryptoPP)
    00046
    00047 // ************** compile-time assertion ***************
    00048
    00049 template <bool b>
    00050 struct CompileAssert
    00051 {
    00052         static char dummy[2*b-1];
    00053 };
    00054
    00055 #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
    00056 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
    00057 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
    00058 #else
    00059 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
    00060 #endif
    00061 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
    00062 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
    00063
    00064 // ************** misc classes ***************
    00065
    00066 class CRYPTOPP_DLL Empty
    00067 {
    00068 };
    00069
    00070 //! _
    00071 template <class BASE1, class BASE2>
    00072 class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
    00073 {
    00074 };
    00075
    00076 //! _
    00077 template <class BASE1, class BASE2, class BASE3>
    00078 class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
    00079 {
    00080 };
    00081
    00082 template <class T>
    00083 class ObjectHolder
    00084 {
    00085 protected:
    00086         T m_object;
    00087 };
    00088
    00089 class NotCopyable
    00090 {
    00091 public:
    00092         NotCopyable() {}
    00093 private:
    00094     NotCopyable(const NotCopyable &);
    00095     void operator=(const NotCopyable &);
    00096 };
    00097
    00098 template <class T>
    00099 struct NewObject
    00100 {
    00101         T* operator()() const {return new T;}
    00102 };
    00103
    00104 /*! This function safely initializes a static object in a multithreaded environment without using locks.
    00105         It may leak memory when two threads try to initialize the static object at the same time
    00106         but this should be acceptable since each static object is only initialized once per session.
    00107 */
    00108 template <class T, class F = NewObject<T>, int instance=0>
    00109 class Singleton
    00110 {
    00111 public:
    00112         Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
    00113
    00114         // prevent this function from being inlined
    00115         CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
    00116
    00117 private:
    00118         F m_objectFactory;
    00119 };
    00120
    00121 template <class T, class F, int instance>
    00122 const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
    00123 {
    00124         static simple_ptr<T> s_pObject;
    00125         static char s_objectState = 0;
    00126
    00127 retry:
    00128         switch (s_objectState)
    00129         {
    00130         case 0:
    00131                 s_objectState = 1;
    00132                 try
    00133                 {
    00134                         s_pObject.m_p = m_objectFactory();
    00135                 }
    00136                 catch(...)
    00137                 {
    00138                         s_objectState = 0;
    00139                         throw;
    00140                 }
    00141                 s_objectState = 2;
    00142                 break;
    00143         case 1:
    00144                 goto retry;
    00145         default:
    00146                 break;
    00147         }
    00148         return *s_pObject.m_p;
    00149 }
    00150
    00151 // ************** misc functions ***************
    00152
    00153 #if (!__STDC_WANT_SECURE_LIB__)
    00154 inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
    00155 {
    00156         if (count > sizeInBytes)
    00157                 throw InvalidArgument("memcpy_s: buffer overflow");
    00158         memcpy(dest, src, count);
    00159 }
    00160
    00161 inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
    00162 {
    00163         if (count > sizeInBytes)
    00164                 throw InvalidArgument("memmove_s: buffer overflow");
    00165         memmove(dest, src, count);
    00166 }
    00167 #endif
    00168
    00169 inline void * memset_z(void *ptr, int value, size_t num)
    00170 {
    00171 // avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
    00172 #if CRYPTOPP_GCC_VERSION >= 30001
    00173         if (__builtin_constant_p(num) && num==0)
    00174                 return ptr;
    00175 #endif
    00176         return memset(ptr, value, num);
    00177 }
    00178
    00179 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
    00180 template <class T> inline const T& STDMIN(const T& a, const T& b)
    00181 {
    00182         return b < a ? b : a;
    00183 }
    00184
    00185 template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
    00186 {
    00187         CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
    00188         assert(a==0 || a>0);    // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
    00189         assert(b>=0);
    00190
    00191         if (sizeof(T1)<=sizeof(T2))
    00192                 return b < (T2)a ? (T1)b : a;
    00193         else
    00194                 return (T1)b < a ? (T1)b : a;
    00195 }
    00196
    00197 template <class T> inline const T& STDMAX(const T& a, const T& b)
    00198 {
    00199         return a < b ? b : a;
    00200 }
    00201
    00202 #define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
    00203
    00204 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
    00205 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
    00206 // these may be faster on other CPUs/compilers
    00207 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
    00208 // #define GETBYTE(x, y) (((byte *)&(x))[y])
    00209
    00210 #define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
    00211
    00212 template <class T>
    00213 unsigned int Parity(T value)
    00214 {
    00215         for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
    00216                 value ^= value >> i;
    00217         return (unsigned int)value&1;
    00218 }
    00219
    00220 template <class T>
    00221 unsigned int BytePrecision(const T &value)
    00222 {
    00223         if (!value)
    00224                 return 0;
    00225
    00226         unsigned int l=0, h=8*sizeof(value);
    00227
    00228         while (h-l > 8)
    00229         {
    00230                 unsigned int t = (l+h)/2;
    00231                 if (value >> t)
    00232                         l = t;
    00233                 else
    00234                         h = t;
    00235         }
    00236
    00237         return h/8;
    00238 }
    00239
    00240 template <class T>
    00241 unsigned int BitPrecision(const T &value)
    00242 {
    00243         if (!value)
    00244                 return 0;
    00245
    00246         unsigned int l=0, h=8*sizeof(value);
    00247
    00248         while (h-l > 1)
    00249         {
    00250                 unsigned int t = (l+h)/2;
    00251                 if (value >> t)
    00252                         l = t;
    00253                 else
    00254                         h = t;
    00255         }
    00256
    00257         return h;
    00258 }
    00259
    00260 template <class T>
    00261 inline T Crop(T value, size_t size)
    00262 {
    00263         if (size < 8*sizeof(value))
    00264         return T(value & ((T(1) << size) - 1));
    00265         else
    00266                 return value;
    00267 }
    00268
    00269 template <class T1, class T2>
    00270 inline bool SafeConvert(T1 from, T2 &to)
    00271 {
    00272         to = (T2)from;
    00273         if (from != to || (from > 0) != (to > 0))
    00274                 return false;
    00275         return true;
    00276 }
    00277
    00278 inline size_t BitsToBytes(size_t bitCount)
    00279 {
    00280         return ((bitCount+7)/(8));
    00281 }
    00282
    00283 inline size_t BytesToWords(size_t byteCount)
    00284 {
    00285         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
    00286 }
    00287
    00288 inline size_t BitsToWords(size_t bitCount)
    00289 {
    00290         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
    00291 }
    00292
    00293 inline size_t BitsToDwords(size_t bitCount)
    00294 {
    00295         return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
    00296 }
    00297
    00298 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
    00299 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
    00300
    00301 CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
    00302
    00303 template <class T>
    00304 inline bool IsPowerOf2(const T &n)
    00305 {
    00306         return n > 0 && (n & (n-1)) == 0;
    00307 }
    00308
    00309 template <class T1, class T2>
    00310 inline T2 ModPowerOf2(const T1 &a, const T2 &b)
    00311 {
    00312         assert(IsPowerOf2(b));
    00313         return T2(a) & (b-1);
    00314 }
    00315
    00316 template <class T1, class T2>
    00317 inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
    00318 {
    00319         if (IsPowerOf2(m))
    00320                 return n - ModPowerOf2(n, m);
    00321         else
    00322                 return n - n%m;
    00323 }
    00324
    00325 template <class T1, class T2>
    00326 inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
    00327 {
    00328         if (n+m-1 < n)
    00329                 throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
    00330         return RoundDownToMultipleOf(n+m-1, m);
    00331 }
    00332
    00333 template <class T>
    00334 inline unsigned int GetAlignmentOf(T *dummy=NULL)       // VC60 workaround
    00335 {
    00336 #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
    00337         if (sizeof(T) < 16)
    00338                 return 1;
    00339 #endif
    00340
    00341 #if (_MSC_VER >= 1300)
    00342         return __alignof(T);
    00343 #elif defined(__GNUC__)
    00344         return __alignof__(T);
    00345 #elif CRYPTOPP_BOOL_SLOW_WORD64
    00346         return UnsignedMin(4U, sizeof(T));
    00347 #else
    00348         return sizeof(T);
    00349 #endif
    00350 }
    00351
    00352 inline bool IsAlignedOn(const void *p, unsigned int alignment)
    00353 {
    00354         return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
    00355 }
    00356
    00357 template <class T>
    00358 inline bool IsAligned(const void *p, T *dummy=NULL)     // VC60 workaround
    00359 {
    00360         return IsAlignedOn(p, GetAlignmentOf<T>());
    00361 }
    00362
    00363 #ifdef IS_LITTLE_ENDIAN
    00364         typedef LittleEndian NativeByteOrder;
    00365 #else
    00366         typedef BigEndian NativeByteOrder;
    00367 #endif
    00368
    00369 inline ByteOrder GetNativeByteOrder()
    00370 {
    00371         return NativeByteOrder::ToEnum();
    00372 }
    00373
    00374 inline bool NativeByteOrderIs(ByteOrder order)
    00375 {
    00376         return order == GetNativeByteOrder();
    00377 }
    00378
    00379 template <class T>
    00380 std::string IntToString(T a, unsigned int base = 10)
    00381 {
    00382         if (a == 0)
    00383                 return "0";
    00384         bool negate = false;
    00385         if (a < 0)
    00386         {
    00387                 negate = true;
    00388                 a = 0-a;        // VC .NET does not like -a
    00389         }
    00390         std::string result;
    00391         while (a > 0)
    00392         {
    00393                 T digit = a % base;
    00394                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
    00395                 a /= base;
    00396         }
    00397         if (negate)
    00398                 result = "-" + result;
    00399         return result;
    00400 }
    00401
    00402 template <class T1, class T2>
    00403 inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
    00404 {
    00405         return T1((a > b) ? (a - b) : 0);
    00406 }
    00407
    00408 template <class T>
    00409 inline CipherDir GetCipherDir(const T &obj)
    00410 {
    00411         return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
    00412 }
    00413
    00414 CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
    00415
    00416 inline void IncrementCounterByOne(byte *inout, unsigned int s)
    00417 {
    00418         for (int i=s-1, carry=1; i>=0 && carry; i--)
    00419                 carry = !++inout[i];
    00420 }
    00421
    00422 inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
    00423 {
    00424         int i, carry;
    00425         for (i=s-1, carry=1; i>=0 && carry; i--)
    00426                 carry = ((output[i] = input[i]+1) == 0);
    00427         memcpy_s(output, s, input, i+1);
    00428 }
    00429
    00430 // ************** rotate functions ***************
    00431
    00432 template <class T> inline T rotlFixed(T x, unsigned int y)
    00433 {
    00434         assert(y < sizeof(T)*8);
    00435         return T((x<<y) | (x>>(sizeof(T)*8-y)));
    00436 }
    00437
    00438 template <class T> inline T rotrFixed(T x, unsigned int y)
    00439 {
    00440         assert(y < sizeof(T)*8);
    00441         return T((x>>y) | (x<<(sizeof(T)*8-y)));
    00442 }
    00443
    00444 template <class T> inline T rotlVariable(T x, unsigned int y)
    00445 {
    00446         assert(y < sizeof(T)*8);
    00447         return T((x<<y) | (x>>(sizeof(T)*8-y)));
    00448 }
    00449
    00450 template <class T> inline T rotrVariable(T x, unsigned int y)
    00451 {
    00452         assert(y < sizeof(T)*8);
    00453         return T((x>>y) | (x<<(sizeof(T)*8-y)));
    00454 }
    00455
    00456 template <class T> inline T rotlMod(T x, unsigned int y)
    00457 {
    00458         y %= sizeof(T)*8;
    00459         return T((x<<y) | (x>>(sizeof(T)*8-y)));
    00460 }
    00461
    00462 template <class T> inline T rotrMod(T x, unsigned int y)
    00463 {
    00464         y %= sizeof(T)*8;
    00465         return T((x>>y) | (x<<(sizeof(T)*8-y)));
    00466 }
    00467
    00468 #ifdef _MSC_VER
    00469
    00470 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
    00471 {
    00472         assert(y < 8*sizeof(x));
    00473         return y ? _lrotl(x, y) : x;
    00474 }
    00475
    00476 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
    00477 {
    00478         assert(y < 8*sizeof(x));
    00479         return y ? _lrotr(x, y) : x;
    00480 }
    00481
    00482 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
    00483 {
    00484         assert(y < 8*sizeof(x));
    00485         return _lrotl(x, y);
    00486 }
    00487
    00488 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
    00489 {
    00490         assert(y < 8*sizeof(x));
    00491         return _lrotr(x, y);
    00492 }
    00493
    00494 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
    00495 {
    00496         return _lrotl(x, y);
    00497 }
    00498
    00499 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
    00500 {
    00501         return _lrotr(x, y);
    00502 }
    00503
    00504 #endif // #ifdef _MSC_VER
    00505
    00506 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
    00507 // Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
    00508
    00509 template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
    00510 {
    00511         assert(y < 8*sizeof(x));
    00512         return y ? _rotl64(x, y) : x;
    00513 }
    00514
    00515 template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
    00516 {
    00517         assert(y < 8*sizeof(x));
    00518         return y ? _rotr64(x, y) : x;
    00519 }
    00520
    00521 template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
    00522 {
    00523         assert(y < 8*sizeof(x));
    00524         return _rotl64(x, y);
    00525 }
    00526
    00527 template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
    00528 {
    00529         assert(y < 8*sizeof(x));
    00530         return _rotr64(x, y);
    00531 }
    00532
    00533 template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
    00534 {
    00535         return _rotl64(x, y);
    00536 }
    00537
    00538 template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
    00539 {
    00540         return _rotr64(x, y);
    00541 }
    00542
    00543 #endif // #if _MSC_VER >= 1310
    00544
    00545 #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
    00546 // Intel C++ Compiler 10.0 gives undefined externals with these
    00547
    00548 template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
    00549 {
    00550         assert(y < 8*sizeof(x));
    00551         return y ? _rotl16(x, y) : x;
    00552 }
    00553
    00554 template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
    00555 {
    00556         assert(y < 8*sizeof(x));
    00557         return y ? _rotr16(x, y) : x;
    00558 }
    00559
    00560 template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
    00561 {
    00562         assert(y < 8*sizeof(x));
    00563         return _rotl16(x, y);
    00564 }
    00565
    00566 template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
    00567 {
    00568         assert(y < 8*sizeof(x));
    00569         return _rotr16(x, y);
    00570 }
    00571
    00572 template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
    00573 {
    00574         return _rotl16(x, y);
    00575 }
    00576
    00577 template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
    00578 {
    00579         return _rotr16(x, y);
    00580 }
    00581
    00582 template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
    00583 {
    00584         assert(y < 8*sizeof(x));
    00585         return y ? _rotl8(x, y) : x;
    00586 }
    00587
    00588 template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
    00589 {
    00590         assert(y < 8*sizeof(x));
    00591         return y ? _rotr8(x, y) : x;
    00592 }
    00593
    00594 template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
    00595 {
    00596         assert(y < 8*sizeof(x));
    00597         return _rotl8(x, y);
    00598 }
    00599
    00600 template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
    00601 {
    00602         assert(y < 8*sizeof(x));
    00603         return _rotr8(x, y);
    00604 }
    00605
    00606 template<> inline byte rotlMod<byte>(byte x, unsigned int y)
    00607 {
    00608         return _rotl8(x, y);
    00609 }
    00610
    00611 template<> inline byte rotrMod<byte>(byte x, unsigned int y)
    00612 {
    00613         return _rotr8(x, y);
    00614 }
    00615
    00616 #endif // #if _MSC_VER >= 1400
    00617
    00618 #if (defined(__MWERKS__) && TARGET_CPU_PPC)
    00619
    00620 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
    00621 {
    00622         assert(y < 32);
    00623         return y ? __rlwinm(x,y,0,31) : x;
    00624 }
    00625
    00626 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
    00627 {
    00628         assert(y < 32);
    00629         return y ? __rlwinm(x,32-y,0,31) : x;
    00630 }
    00631
    00632 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
    00633 {
    00634         assert(y < 32);
    00635         return (__rlwnm(x,y,0,31));
    00636 }
    00637
    00638 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
    00639 {
    00640         assert(y < 32);
    00641         return (__rlwnm(x,32-y,0,31));
    00642 }
    00643
    00644 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
    00645 {
    00646         return (__rlwnm(x,y,0,31));
    00647 }
    00648
    00649 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
    00650 {
    00651         return (__rlwnm(x,32-y,0,31));
    00652 }
    00653
    00654 #endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
    00655
    00656 // ************** endian reversal ***************
    00657
    00658 template <class T>
    00659 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
    00660 {
    00661         if (order == LITTLE_ENDIAN_ORDER)
    00662                 return GETBYTE(value, index);
    00663         else
    00664                 return GETBYTE(value, sizeof(T)-index-1);
    00665 }
    00666
    00667 inline byte ByteReverse(byte value)
    00668 {
    00669         return value;
    00670 }
    00671
    00672 inline word16 ByteReverse(word16 value)
    00673 {
    00674 #ifdef CRYPTOPP_BYTESWAP_AVAILABLE
    00675         return bswap_16(value);
    00676 #elif defined(_MSC_VER) && _MSC_VER >= 1300
    00677         return _byteswap_ushort(value);
    00678 #else
    00679         return rotlFixed(value, 8U);
    00680 #endif
    00681 }
    00682
    00683 inline word32 ByteReverse(word32 value)
    00684 {
    00685 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
    00686         __asm__ ("bswap %0" : "=r" (value) : "0" (value));
    00687         return value;
    00688 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
    00689         return bswap_32(value);
    00690 #elif defined(__MWERKS__) && TARGET_CPU_PPC
    00691         return (word32)__lwbrx(&value,0);
    00692 #elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
    00693         return _byteswap_ulong(value);
    00694 #elif CRYPTOPP_FAST_ROTATE(32)
    00695         // 5 instructions with rotate instruction, 9 without
    00696         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
    00697 #else
    00698         // 6 instructions with rotate instruction, 8 without
    00699         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
    00700         return rotlFixed(value, 16U);
    00701 #endif
    00702 }
    00703
    00704 inline word64 ByteReverse(word64 value)
    00705 {
    00706 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
    00707         __asm__ ("bswap %0" : "=r" (value) : "0" (value));
    00708         return value;
    00709 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
    00710         return bswap_64(value);
    00711 #elif defined(_MSC_VER) && _MSC_VER >= 1300
    00712         return _byteswap_uint64(value);
    00713 #elif CRYPTOPP_BOOL_SLOW_WORD64
    00714         return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
    00715 #else
    00716         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
    00717         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
    00718         return rotlFixed(value, 32U);
    00719 #endif
    00720 }
    00721
    00722 inline byte BitReverse(byte value)
    00723 {
    00724         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
    00725         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
    00726         return rotlFixed(value, 4U);
    00727 }
    00728
    00729 inline word16 BitReverse(word16 value)
    00730 {
    00731         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
    00732         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
    00733         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
    00734         return ByteReverse(value);
    00735 }
    00736
    00737 inline word32 BitReverse(word32 value)
    00738 {
    00739         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
    00740         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
    00741         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
    00742         return ByteReverse(value);
    00743 }
    00744
    00745 inline word64 BitReverse(word64 value)
    00746 {
    00747 #if CRYPTOPP_BOOL_SLOW_WORD64
    00748         return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
    00749 #else
    00750         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
    00751         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
    00752         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
    00753         return ByteReverse(value);
    00754 #endif
    00755 }
    00756
    00757 template <class T>
    00758 inline T BitReverse(T value)
    00759 {
    00760         if (sizeof(T) == 1)
    00761                 return (T)BitReverse((byte)value);
    00762         else if (sizeof(T) == 2)
    00763                 return (T)BitReverse((word16)value);
    00764         else if (sizeof(T) == 4)
    00765                 return (T)BitReverse((word32)value);
    00766         else
    00767         {
    00768                 assert(sizeof(T) == 8);
    00769                 return (T)BitReverse((word64)value);
    00770         }
    00771 }
    00772
    00773 template <class T>
    00774 inline T ConditionalByteReverse(ByteOrder order, T value)
    00775 {
    00776         return NativeByteOrderIs(order) ? value : ByteReverse(value);
    00777 }
    00778
    00779 template <class T>
    00780 void ByteReverse(T *out, const T *in, size_t byteCount)
    00781 {
    00782         assert(byteCount % sizeof(T) == 0);
    00783         size_t count = byteCount/sizeof(T);
    00784         for (size_t i=0; i<count; i++)
    00785                 out[i] = ByteReverse(in[i]);
    00786 }
    00787
    00788 template <class T>
    00789 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
    00790 {
    00791         if (!NativeByteOrderIs(order))
    00792                 ByteReverse(out, in, byteCount);
    00793         else if (in != out)
    00794                 memcpy_s(out, byteCount, in, byteCount);
    00795 }
    00796
    00797 template <class T>
    00798 inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
    00799 {
    00800         const size_t U = sizeof(T);
    00801         assert(inlen <= outlen*U);
    00802         memcpy_s(out, outlen*U, in, inlen);
    00803         memset_z((byte *)out+inlen, 0, outlen*U-inlen);
    00804         ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
    00805 }
    00806
    00807 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
    00808 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
    00809 {
    00810         return block[0];
    00811 }
    00812
    00813 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
    00814 {
    00815         return (order == BIG_ENDIAN_ORDER)
    00816                 ? block[1] | (block[0] << 8)
    00817                 : block[0] | (block[1] << 8);
    00818 }
    00819
    00820 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
    00821 {
    00822         return (order == BIG_ENDIAN_ORDER)
    00823                 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
    00824                 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
    00825 }
    00826
    00827 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
    00828 {
    00829         return (order == BIG_ENDIAN_ORDER)
    00830                 ?
    00831                 (word64(block[7]) |
    00832                 (word64(block[6]) <<  8) |
    00833                 (word64(block[5]) << 16) |
    00834                 (word64(block[4]) << 24) |
    00835                 (word64(block[3]) << 32) |
    00836                 (word64(block[2]) << 40) |
    00837                 (word64(block[1]) << 48) |
    00838                 (word64(block[0]) << 56))
    00839                 :
    00840                 (word64(block[0]) |
    00841                 (word64(block[1]) <<  8) |
    00842                 (word64(block[2]) << 16) |
    00843                 (word64(block[3]) << 24) |
    00844                 (word64(block[4]) << 32) |
    00845                 (word64(block[5]) << 40) |
    00846                 (word64(block[6]) << 48) |
    00847                 (word64(block[7]) << 56));
    00848 }
    00849
    00850 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
    00851 {
    00852         block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
    00853 }
    00854
    00855 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
    00856 {
    00857         if (order == BIG_ENDIAN_ORDER)
    00858         {
    00859                 if (xorBlock)
    00860                 {
    00861                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00862                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00863                 }
    00864                 else
    00865                 {
    00866                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00867                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00868                 }
    00869         }
    00870         else
    00871         {
    00872                 if (xorBlock)
    00873                 {
    00874                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00875                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00876                 }
    00877                 else
    00878                 {
    00879                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00880                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00881                 }
    00882         }
    00883 }
    00884
    00885 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
    00886 {
    00887         if (order == BIG_ENDIAN_ORDER)
    00888         {
    00889                 if (xorBlock)
    00890                 {
    00891                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00892                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00893                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00894                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00895                 }
    00896                 else
    00897                 {
    00898                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00899                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00900                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00901                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00902                 }
    00903         }
    00904         else
    00905         {
    00906                 if (xorBlock)
    00907                 {
    00908                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00909                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00910                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00911                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00912                 }
    00913                 else
    00914                 {
    00915                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00916                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00917                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00918                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00919                 }
    00920         }
    00921 }
    00922
    00923 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
    00924 {
    00925         if (order == BIG_ENDIAN_ORDER)
    00926         {
    00927                 if (xorBlock)
    00928                 {
    00929                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
    00930                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
    00931                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
    00932                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
    00933                         block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00934                         block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00935                         block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00936                         block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00937                 }
    00938                 else
    00939                 {
    00940                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
    00941                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
    00942                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
    00943                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
    00944                         block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00945                         block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00946                         block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00947                         block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00948                 }
    00949         }
    00950         else
    00951         {
    00952                 if (xorBlock)
    00953                 {
    00954                         block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00955                         block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00956                         block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00957                         block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00958                         block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
    00959                         block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
    00960                         block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
    00961                         block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
    00962                 }
    00963                 else
    00964                 {
    00965                         block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
    00966                         block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
    00967                         block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
    00968                         block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
    00969                         block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
    00970                         block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
    00971                         block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
    00972                         block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
    00973                 }
    00974         }
    00975 }
    00976 #endif  // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
    00977
    00978 template <class T>
    00979 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
    00980 {
    00981 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
    00982         if (!assumeAligned)
    00983                 return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
    00984         assert(IsAligned<T>(block));
    00985 #endif
    00986         return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
    00987 }
    00988
    00989 template <class T>
    00990 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
    00991 {
    00992         result = GetWord<T>(assumeAligned, order, block);
    00993 }
    00994
    00995 template <class T>
    00996 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
    00997 {
    00998 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
    00999         if (!assumeAligned)
    01000                 return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
    01001         assert(IsAligned<T>(block));
    01002         assert(IsAligned<T>(xorBlock));
    01003 #endif
    01004         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
    01005 }
    01006
    01007 template <class T, class B, bool A=false>
    01008 class GetBlock
    01009 {
    01010 public:
    01011         GetBlock(const void *block)
    01012                 : m_block((const byte *)block) {}
    01013
    01014         template <class U>
    01015         inline GetBlock<T, B, A> & operator()(U &x)
    01016         {
    01017                 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
    01018                 x = GetWord<T>(A, B::ToEnum(), m_block);
    01019                 m_block += sizeof(T);
    01020                 return *this;
    01021         }
    01022
    01023 private:
    01024         const byte *m_block;
    01025 };
    01026
    01027 template <class T, class B, bool A=false>
    01028 class PutBlock
    01029 {
    01030 public:
    01031         PutBlock(const void *xorBlock, void *block)
    01032                 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
    01033
    01034         template <class U>
    01035         inline PutBlock<T, B, A> & operator()(U x)
    01036         {
    01037                 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
    01038                 m_block += sizeof(T);
    01039                 if (m_xorBlock)
    01040                         m_xorBlock += sizeof(T);
    01041                 return *this;
    01042         }
    01043
    01044 private:
    01045         const byte *m_xorBlock;
    01046         byte *m_block;
    01047 };
    01048
    01049 template <class T, class B, bool GA=false, bool PA=false>
    01050 struct BlockGetAndPut
    01051 {
    01052         // function needed because of C++ grammatical ambiguity between expression-statements and declarations
    01053         static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
    01054         typedef PutBlock<T, B, PA> Put;
    01055 };
    01056
    01057 template <class T>
    01058 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
    01059 {
    01060         if (!NativeByteOrderIs(order))
    01061                 value = ByteReverse(value);
    01062
    01063         return std::string((char *)&value, sizeof(value));
    01064 }
    01065
    01066 template <class T>
    01067 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
    01068 {
    01069         T value = 0;
    01070         memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
    01071         return NativeByteOrderIs(order) ? value : ByteReverse(value);
    01072 }
    01073
    01074 // ************** help remove warning on g++ ***************
    01075
    01076 template <bool overflow> struct SafeShifter;
    01077
    01078 template<> struct SafeShifter<true>
    01079 {
    01080         template <class T>
    01081         static inline T RightShift(T value, unsigned int bits)
    01082         {
    01083                 return 0;
    01084         }
    01085
    01086         template <class T>
    01087         static inline T LeftShift(T value, unsigned int bits)
    01088         {
    01089                 return 0;
    01090         }
    01091 };
    01092
    01093 template<> struct SafeShifter<false>
    01094 {
    01095         template <class T>
    01096         static inline T RightShift(T value, unsigned int bits)
    01097         {
    01098                 return value >> bits;
    01099         }
    01100
    01101         template <class T>
    01102         static inline T LeftShift(T value, unsigned int bits)
    01103         {
    01104                 return value << bits;
    01105         }
    01106 };
    01107
    01108 template <unsigned int bits, class T>
    01109 inline T SafeRightShift(T value)
    01110 {
    01111         return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
    01112 }
    01113
    01114 template <unsigned int bits, class T>
    01115 inline T SafeLeftShift(T value)
    01116 {
    01117         return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
    01118 }
    01119
    01120 // ************** use one buffer for multiple data members ***************
    01121
    01122 #define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);}     size_t SS1() {return       sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01123 #define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01124 #define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01125 #define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01126 #define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01127 #define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01128 #define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01129 #define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
    01130 #define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate;
    01131
    01132 NAMESPACE_END
    01133
    01134 #endif