Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

misc.h

00001 #ifndef CRYPTOPP_MISC_H
00002 #define CRYPTOPP_MISC_H
00003 
00004 #include "config.h"
00005 #include <assert.h>
00006 #include <string.h>             // CodeWarrior doesn't have memory.h
00007 #include <algorithm>
00008 #include <string>
00009 
00010 #ifdef INTEL_INTRINSICS
00011 #include <stdlib.h>
00012 #endif
00013 
00014 NAMESPACE_BEGIN(CryptoPP)
00015 
00016 // ************** misc functions ***************
00017 
00018 #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
00019 // this one may be faster on a Pentium
00020 // #define GETBYTE(x, y) (((byte *)&(x))[y])
00021 
00022 unsigned int Parity(unsigned long);
00023 unsigned int BytePrecision(unsigned long);
00024 unsigned int BitPrecision(unsigned long);
00025 unsigned long Crop(unsigned long, unsigned int size);
00026 
00027 inline unsigned int bitsToBytes(unsigned int bitCount)
00028 {
00029         return ((bitCount+7)/(8));
00030 }
00031 
00032 inline unsigned int bytesToWords(unsigned int byteCount)
00033 {
00034         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00035 }
00036 
00037 inline unsigned int bitsToWords(unsigned int bitCount)
00038 {
00039         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00040 }
00041 
00042 void xorbuf(byte *buf, const byte *mask, unsigned int count);
00043 void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count);
00044 
00045 inline unsigned int RoundDownToMultipleOf(unsigned int n, unsigned int m)
00046 {
00047         return n - n%m;
00048 }
00049 
00050 inline unsigned int RoundUpToMultipleOf(unsigned int n, unsigned int m)
00051 {
00052         return RoundDownToMultipleOf(n+m-1, m);
00053 }
00054 
00055 template <class T>
00056 inline bool IsAligned(const void *p)
00057 {
00058         return (unsigned int)p % sizeof(T) == 0;
00059 }
00060 
00061 inline bool CheckEndianess(bool highFirst)
00062 {
00063 #ifdef IS_LITTLE_ENDIAN
00064         return !highFirst;
00065 #else
00066         return highFirst;
00067 #endif
00068 }
00069 
00070 template <class T>              // can't use <sstream> because GCC 2.95.2 doesn't have it
00071 std::string IntToString(T a)
00072 {
00073         if (a == 0)
00074                 return "0";
00075         bool negate = false;
00076         if (a < 0)
00077         {
00078                 negate = true;
00079                 a = -a;
00080         }
00081         std::string result;
00082         while (a > 0)
00083         {
00084                 result = char('0' + a % 10) + result;
00085                 a = a / 10;
00086         }
00087         if (negate)
00088                 result = "-" + result;
00089         return result;
00090 }
00091 
00092 // ************** rotate functions ***************
00093 
00094 template <class T> inline T rotlFixed(T x, unsigned int y)
00095 {
00096         assert(y < sizeof(T)*8);
00097         return (x<<y) | (x>>(sizeof(T)*8-y));
00098 }
00099 
00100 template <class T> inline T rotrFixed(T x, unsigned int y)
00101 {
00102         assert(y < sizeof(T)*8);
00103         return (x>>y) | (x<<(sizeof(T)*8-y));
00104 }
00105 
00106 template <class T> inline T rotlVariable(T x, unsigned int y)
00107 {
00108         assert(y < sizeof(T)*8);
00109         return (x<<y) | (x>>(sizeof(T)*8-y));
00110 }
00111 
00112 template <class T> inline T rotrVariable(T x, unsigned int y)
00113 {
00114         assert(y < sizeof(T)*8);
00115         return (x>>y) | (x<<(sizeof(T)*8-y));
00116 }
00117 
00118 template <class T> inline T rotlMod(T x, unsigned int y)
00119 {
00120         y %= sizeof(T)*8;
00121         return (x<<y) | (x>>(sizeof(T)*8-y));
00122 }
00123 
00124 template <class T> inline T rotrMod(T x, unsigned int y)
00125 {
00126         y %= sizeof(T)*8;
00127         return (x>>y) | (x<<(sizeof(T)*8-y));
00128 }
00129 
00130 #ifdef INTEL_INTRINSICS
00131 
00132 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00133 {
00134         assert(y < 32);
00135         return y ? _lrotl(x, y) : x;
00136 }
00137 
00138 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00139 {
00140         assert(y < 32);
00141         return y ? _lrotr(x, y) : x;
00142 }
00143 
00144 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00145 {
00146         assert(y < 32);
00147         return _lrotl(x, y);
00148 }
00149 
00150 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00151 {
00152         assert(y < 32);
00153         return _lrotr(x, y);
00154 }
00155 
00156 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00157 {
00158         return _lrotl(x, y);
00159 }
00160 
00161 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00162 {
00163         return _lrotr(x, y);
00164 }
00165 
00166 #endif // #ifdef INTEL_INTRINSICS
00167 
00168 #ifdef PPC_INTRINSICS
00169 
00170 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00171 {
00172         assert(y < 32);
00173         return y ? __rlwinm(x,y,0,31) : x;
00174 }
00175 
00176 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00177 {
00178         assert(y < 32);
00179         return y ? __rlwinm(x,32-y,0,31) : x;
00180 }
00181 
00182 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00183 {
00184         assert(y < 32);
00185         return (__rlwnm(x,y,0,31));
00186 }
00187 
00188 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00189 {
00190         assert(y < 32);
00191         return (__rlwnm(x,32-y,0,31));
00192 }
00193 
00194 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00195 {
00196         return (__rlwnm(x,y,0,31));
00197 }
00198 
00199 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00200 {
00201         return (__rlwnm(x,32-y,0,31));
00202 }
00203 
00204 #endif // #ifdef PPC_INTRINSICS
00205 
00206 // ************** endian reversal ***************
00207 
00208 inline word16 byteReverse(word16 value)
00209 {
00210         return rotlFixed(value, 8U);
00211 }
00212 
00213 inline word32 byteReverse(word32 value)
00214 {
00215 #ifdef PPC_INTRINSICS
00216         // PPC: load reverse indexed instruction
00217         return (word32)__lwbrx(&value,0);
00218 #elif defined(FAST_ROTATE)
00219         // 5 instructions with rotate instruction, 9 without
00220         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00221 #else
00222         // 6 instructions with rotate instruction, 8 without
00223         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00224         return rotlFixed(value, 16U);
00225 #endif
00226 }
00227 
00228 #ifdef WORD64_AVAILABLE
00229 inline word64 byteReverse(word64 value)
00230 {
00231 #ifdef SLOW_WORD64
00232         return (word64(byteReverse(word32(value))) << 32) | byteReverse(word32(value>>32));
00233 #else
00234         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00235         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00236         return rotlFixed(value, 32U);
00237 #endif
00238 }
00239 #endif
00240 
00241 inline byte bitReverse(byte value)
00242 {
00243         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00244         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00245         return rotlFixed(value, 4);
00246 }
00247 
00248 inline word16 bitReverse(word16 value)
00249 {
00250         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00251         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00252         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00253         return byteReverse(value);
00254 }
00255 
00256 inline word32 bitReverse(word32 value)
00257 {
00258         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00259         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00260         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00261         return byteReverse(value);
00262 }
00263 
00264 #ifdef WORD64_AVAILABLE
00265 inline word64 bitReverse(word64 value)
00266 {
00267 #ifdef SLOW_WORD64
00268         return (word64(bitReverse(word32(value))) << 32) | bitReverse(word32(value>>32));
00269 #else
00270         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00271         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00272         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00273         return byteReverse(value);
00274 #endif
00275 }
00276 #endif
00277 
00278 template <class T>
00279 inline T bitReverse(T value)
00280 {
00281         if (sizeof(T) == 1)
00282                 return bitReverse((byte)value);
00283         else if (sizeof(T) == 2)
00284                 return bitReverse((word16)value);
00285         else if (sizeof(T) == 4)
00286                 return bitReverse((word32)value);
00287         else
00288         {
00289 #ifdef WORD64_AVAILABLE
00290                 assert(sizeof(T) == 8);
00291                 return bitReverse((word64)value);
00292 #else
00293                 assert(false);
00294                 return 0;
00295 #endif
00296         }
00297 }
00298 
00299 template <class T>
00300 void byteReverse(T *out, const T *in, unsigned int byteCount)
00301 {
00302         unsigned int count = (byteCount+sizeof(T)-1)/sizeof(T);
00303         for (unsigned int i=0; i<count; i++)
00304                 out[i] = byteReverse(in[i]);
00305 }
00306 
00307 template <class T>
00308 inline void GetUserKeyLittleEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen)
00309 {
00310         const unsigned int U = sizeof(T);
00311         assert(inlen <= outlen*U);
00312         memcpy(out, in, inlen);
00313         memset((byte *)out+inlen, 0, outlen*U-inlen);
00314 #ifndef IS_LITTLE_ENDIAN
00315         byteReverse(out, out, inlen);
00316 #endif
00317 }
00318 
00319 template <class T>
00320 inline void GetUserKeyBigEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen)
00321 {
00322         const unsigned int U = sizeof(T);
00323         assert(inlen <= outlen*U);
00324         memcpy(out, in, inlen);
00325         memset((byte *)out+inlen, 0, outlen*U-inlen);
00326 #ifdef IS_LITTLE_ENDIAN
00327         byteReverse(out, out, inlen);
00328 #endif
00329 }
00330 
00331 // Fetch 2 words from user's buffer into "a", "b" in LITTLE-endian order
00332 template <class T>
00333 inline void GetBlockLittleEndian(const byte *block, T &a, T &b)
00334 {
00335 #ifdef IS_LITTLE_ENDIAN
00336         a = ((T *)block)[0];
00337         b = ((T *)block)[1];
00338 #else
00339         a = byteReverse(((T *)block)[0]);
00340         b = byteReverse(((T *)block)[1]);
00341 #endif
00342 }
00343 
00344 // Put 2 words back into user's buffer in LITTLE-endian order
00345 template <class T>
00346 inline void PutBlockLittleEndian(byte *block, T a, T b)
00347 {
00348 #ifdef IS_LITTLE_ENDIAN
00349         ((T *)block)[0] = a;
00350         ((T *)block)[1] = b;
00351 #else
00352         ((T *)block)[0] = byteReverse(a);
00353         ((T *)block)[1] = byteReverse(b);
00354 #endif
00355 }
00356 
00357 // Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order
00358 template <class T>
00359 inline void GetBlockLittleEndian(const byte *block, T &a, T &b, T &c, T &d)
00360 {
00361 #ifdef IS_LITTLE_ENDIAN
00362         a = ((T *)block)[0];
00363         b = ((T *)block)[1];
00364         c = ((T *)block)[2];
00365         d = ((T *)block)[3];
00366 #else
00367         a = byteReverse(((T *)block)[0]);
00368         b = byteReverse(((T *)block)[1]);
00369         c = byteReverse(((T *)block)[2]);
00370         d = byteReverse(((T *)block)[3]);
00371 #endif
00372 }
00373 
00374 // Put 4 words back into user's buffer in LITTLE-endian order
00375 template <class T>
00376 inline void PutBlockLittleEndian(byte *block, T a, T b, T c, T d)
00377 {
00378 #ifdef IS_LITTLE_ENDIAN
00379         ((T *)block)[0] = a;
00380         ((T *)block)[1] = b;
00381         ((T *)block)[2] = c;
00382         ((T *)block)[3] = d;
00383 #else
00384         ((T *)block)[0] = byteReverse(a);
00385         ((T *)block)[1] = byteReverse(b);
00386         ((T *)block)[2] = byteReverse(c);
00387         ((T *)block)[3] = byteReverse(d);
00388 #endif
00389 }
00390 
00391 // Fetch 2 words from user's buffer into "a", "b" in BIG-endian order
00392 template <class T>
00393 inline void GetBlockBigEndian(const byte *block, T &a, T &b)
00394 {
00395 #ifndef IS_LITTLE_ENDIAN
00396         a = ((T *)block)[0];
00397         b = ((T *)block)[1];
00398 #else
00399         a = byteReverse(((T *)block)[0]);
00400         b = byteReverse(((T *)block)[1]);
00401 #endif
00402 }
00403 
00404 // Put 2 words back into user's buffer in BIG-endian order
00405 template <class T>
00406 inline void PutBlockBigEndian(byte *block, T a, T b)
00407 {
00408 #ifndef IS_LITTLE_ENDIAN
00409         ((T *)block)[0] = a;
00410         ((T *)block)[1] = b;
00411 #else
00412         ((T *)block)[0] = byteReverse(a);
00413         ((T *)block)[1] = byteReverse(b);
00414 #endif
00415 }
00416 
00417 // Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order
00418 template <class T>
00419 inline void GetBlockBigEndian(const byte *block, T &a, T &b, T &c, T &d)
00420 {
00421 #ifndef IS_LITTLE_ENDIAN
00422         a = ((T *)block)[0];
00423         b = ((T *)block)[1];
00424         c = ((T *)block)[2];
00425         d = ((T *)block)[3];
00426 #else
00427         a = byteReverse(((T *)block)[0]);
00428         b = byteReverse(((T *)block)[1]);
00429         c = byteReverse(((T *)block)[2]);
00430         d = byteReverse(((T *)block)[3]);
00431 #endif
00432 }
00433 
00434 // Put 4 words back into user's buffer in BIG-endian order
00435 template <class T>
00436 inline void PutBlockBigEndian(byte *block, T a, T b, T c, T d)
00437 {
00438 #ifndef IS_LITTLE_ENDIAN
00439         ((T *)block)[0] = a;
00440         ((T *)block)[1] = b;
00441         ((T *)block)[2] = c;
00442         ((T *)block)[3] = d;
00443 #else
00444         ((T *)block)[0] = byteReverse(a);
00445         ((T *)block)[1] = byteReverse(b);
00446         ((T *)block)[2] = byteReverse(c);
00447         ((T *)block)[3] = byteReverse(d);
00448 #endif
00449 }
00450 
00451 template <class T>
00452 std::string WordToString(T value, bool highFirst = true)
00453 {
00454         if (!CheckEndianess(highFirst))
00455                 value = byteReverse(value);
00456 
00457         return std::string((char *)&value, sizeof(value));
00458 }
00459 
00460 template <class T>
00461 T StringToWord(const std::string &str, bool highFirst = true)
00462 {
00463         T value = 0;
00464         memcpy(&value, str.data(), STDMIN(sizeof(value), str.size()));
00465         return CheckEndianess(highFirst) ? value : byteReverse(value);
00466 }
00467 
00468 // ************** key length query ***************
00469 
00471 template <unsigned int N>
00472 class FixedKeyLength
00473 {
00474 public:
00475         enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N};
00477         static unsigned int KeyLength(unsigned int) {return KEYLENGTH;}
00478 };
00479 
00481 template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q=1>
00482 class VariableKeyLength
00483 {
00484 public:
00485         enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q};
00487         static unsigned int KeyLength(unsigned int n)
00488         {
00489                 assert(KEYLENGTH_MULTIPLE > 0 && MIN_KEYLENGTH % KEYLENGTH_MULTIPLE == 0 && MAX_KEYLENGTH % KEYLENGTH_MULTIPLE == 0);
00490                 if (n < MIN_KEYLENGTH)
00491                         return MIN_KEYLENGTH;
00492                 else if (n > MAX_KEYLENGTH)
00493                         return MAX_KEYLENGTH;
00494                 else
00495                         return RoundUpToMultipleOf(n, KEYLENGTH_MULTIPLE);
00496         }
00497 };
00498 
00500 template <class T>
00501 class SameKeyLengthAs
00502 {
00503 public:
00504         enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH};
00506         static unsigned int KeyLength(unsigned int keylength)
00507                 {return T::KeyLength(keylength);}
00508 };
00509 
00510 // ************** secure memory allocation ***************
00511 
00512 #ifdef SECALLOC_DEFAULT
00513 #define SecAlloc(type, number) (new type[(number)])
00514 #define SecFree(ptr, number) (memset((ptr), 0, (number)*sizeof(*(ptr))), delete [] (ptr))
00515 #else
00516 #define SecAlloc(type, number) (new type[(number)])
00517 #define SecFree(ptr, number) (delete [] (ptr))
00518 #endif
00519 
00521 template <class T> struct SecBlock
00522 {
00523         explicit SecBlock(unsigned int size=0)
00524                 : size(size) {ptr = SecAlloc(T, size);}
00525         SecBlock(const SecBlock<T> &t)
00526                 : size(t.size) {ptr = SecAlloc(T, size); memcpy(ptr, t.ptr, size*sizeof(T));}
00527         SecBlock(const T *t, unsigned int len)
00528                 : size(len) {ptr = SecAlloc(T, len); memcpy(ptr, t, len*sizeof(T));}
00529         ~SecBlock()
00530                 {SecFree(ptr, size);}
00531 
00532 #if defined(__GNUC__) || defined(__BCPLUSPLUS__)
00533         operator const void *() const
00534                 {return ptr;}
00535         operator void *()
00536                 {return ptr;}
00537 #endif
00538 #if defined(__GNUC__)   // reduce warnings
00539         operator const void *()
00540                 {return ptr;}
00541 #endif
00542 
00543         operator const T *() const
00544                 {return ptr;}
00545         operator T *()
00546                 {return ptr;}
00547 #if defined(__GNUC__)   // reduce warnings
00548         operator const T *()
00549                 {return ptr;}
00550 #endif
00551 
00552 // CodeWarrior defines _MSC_VER
00553 #if !defined(_MSC_VER) || defined(__MWERKS__)
00554         T *operator +(unsigned int offset)
00555                 {return ptr+offset;}
00556         const T *operator +(unsigned int offset) const
00557                 {return ptr+offset;}
00558         T& operator[](unsigned int index)
00559                 {assert(index<size); return ptr[index];}
00560         const T& operator[](unsigned int index) const
00561                 {assert(index<size); return ptr[index];}
00562 #endif
00563 
00564         const T* Begin() const
00565                 {return ptr;}
00566         T* Begin()
00567                 {return ptr;}
00568         const T* End() const
00569                 {return ptr+size;}
00570         T* End()
00571                 {return ptr+size;}
00572 
00573         unsigned int Size() const {return size;}
00574 
00575         void Assign(const T *t, unsigned int len)
00576         {
00577                 New(len);
00578                 memcpy(ptr, t, len*sizeof(T));
00579         }
00580 
00581         void Assign(const SecBlock<T> &t)
00582         {
00583                 New(t.size);
00584                 memcpy(ptr, t.ptr, size*sizeof(T));
00585         }
00586 
00587         SecBlock& operator=(const SecBlock<T> &t)
00588         {
00589                 Assign(t);
00590                 return *this;
00591         }
00592 
00593         bool operator==(const SecBlock<T> &t) const
00594         {
00595                 return size == t.size && memcmp(ptr, t.ptr, size*sizeof(T)) == 0;
00596         }
00597 
00598         bool operator!=(const SecBlock<T> &t) const
00599         {
00600                 return !operator==(t);
00601         }
00602 
00603         void New(unsigned int newSize)
00604         {
00605                 if (newSize != size)
00606                 {
00607                         T *newPtr = SecAlloc(T, newSize);
00608                         SecFree(ptr, size);
00609                         ptr = newPtr;
00610                         size = newSize;
00611                 }
00612         }
00613 
00614         void CleanNew(unsigned int newSize)
00615         {
00616                 if (newSize != size)
00617                 {
00618                         T *newPtr = SecAlloc(T, newSize);
00619                         SecFree(ptr, size);
00620                         ptr = newPtr;
00621                         size = newSize;
00622                 }
00623                 memset(ptr, 0, size*sizeof(T));
00624         }
00625 
00626         void Grow(unsigned int newSize)
00627         {
00628                 if (newSize > size)
00629                 {
00630                         T *newPtr = SecAlloc(T, newSize);
00631                         memcpy(newPtr, ptr, size*sizeof(T));
00632                         SecFree(ptr, size);
00633                         ptr = newPtr;
00634                         size = newSize;
00635                 }
00636         }
00637 
00638         void CleanGrow(unsigned int newSize)
00639         {
00640                 if (newSize > size)
00641                 {
00642                         T *newPtr = SecAlloc(T, newSize);
00643                         memcpy(newPtr, ptr, size*sizeof(T));
00644                         memset(newPtr+size, 0, (newSize-size)*sizeof(T));
00645                         SecFree(ptr, size);
00646                         ptr = newPtr;
00647                         size = newSize;
00648                 }
00649         }
00650 
00651         void Resize(unsigned int newSize)
00652         {
00653                 if (newSize != size)
00654                 {
00655                         T *newPtr = SecAlloc(T, newSize);
00656                         memcpy(newPtr, ptr, STDMIN(newSize, size)*sizeof(T));
00657                         SecFree(ptr, size);
00658                         ptr = newPtr;
00659                         size = newSize;
00660                 }
00661         }
00662 
00663         void swap(SecBlock<T> &b);
00664 
00665         unsigned int size;
00666         T *ptr;
00667 };
00668 
00669 template <class T> void SecBlock<T>::swap(SecBlock<T> &b)
00670 {
00671         std::swap(size, b.size);
00672         std::swap(ptr, b.ptr);
00673 }
00674 
00675 typedef SecBlock<byte> SecByteBlock;
00676 typedef SecBlock<word> SecWordBlock;
00677 
00678 NAMESPACE_END
00679 
00680 NAMESPACE_BEGIN(std)
00681 template <class T>
00682 inline void swap(CryptoPP::SecBlock<T> &a, CryptoPP::SecBlock<T> &b)
00683 {
00684         a.swap(b);
00685 }
00686 
00687 NAMESPACE_END
00688 
00689 #endif // MISC_H

Generated at Mon Jan 15 01:16:34 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000