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
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
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
00071
00072
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
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
00118
00119
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
00133
#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00134
00135
00136
00137
00138 CRYPTOPP_DLL
unsigned int Parity(
unsigned long);
00139 CRYPTOPP_DLL
unsigned int BytePrecision(
unsigned long);
00140 CRYPTOPP_DLL
unsigned int BitPrecision(
unsigned long);
00141 CRYPTOPP_DLL
unsigned long 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 xorbuf(byte *buf,
const byte *mask,
unsigned int count);
00164 CRYPTOPP_DLL
void 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)
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)
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;
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);
00257 CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);
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
00270
00271
template <
class T>
inline T rotlFixed(T x,
unsigned int y)
00272 {
00273 assert(y <
sizeof(T)*8);
00274
return (x<<y) | (x>>(
sizeof(T)*8-y));
00275 }
00276
00277
template <
class T>
inline T rotrFixed(T x,
unsigned int y)
00278 {
00279 assert(y <
sizeof(T)*8);
00280
return (x>>y) | (x<<(
sizeof(T)*8-y));
00281 }
00282
00283
template <
class T>
inline T rotlVariable(T x,
unsigned int y)
00284 {
00285 assert(y <
sizeof(T)*8);
00286
return (x<<y) | (x>>(
sizeof(T)*8-y));
00287 }
00288
00289
template <
class T>
inline T rotrVariable(T x,
unsigned int y)
00290 {
00291 assert(y <
sizeof(T)*8);
00292
return (x>>y) | (x<<(
sizeof(T)*8-y));
00293 }
00294
00295
template <
class T>
inline T rotlMod(T x,
unsigned int y)
00296 {
00297 y %=
sizeof(T)*8;
00298
return (x<<y) | (x>>(
sizeof(T)*8-y));
00299 }
00300
00301
template <
class T>
inline T rotrMod(T x,
unsigned int y)
00302 {
00303 y %=
sizeof(T)*8;
00304
return (x>>y) | (x<<(
sizeof(T)*8-y));
00305 }
00306
00307
#ifdef INTEL_INTRINSICS
00308
00309
#pragma intrinsic(_lrotl, _lrotr)
00310
00311
template<>
inline word32 rotlFixed<word32>(word32 x,
unsigned int y)
00312 {
00313 assert(y < 32);
00314
return y ? _lrotl(x, y) : x;
00315 }
00316
00317
template<>
inline word32 rotrFixed<word32>(word32 x,
unsigned int y)
00318 {
00319 assert(y < 32);
00320
return y ? _lrotr(x, y) : x;
00321 }
00322
00323
template<>
inline word32 rotlVariable<word32>(word32 x,
unsigned int y)
00324 {
00325 assert(y < 32);
00326
return _lrotl(x, y);
00327 }
00328
00329
template<>
inline word32 rotrVariable<word32>(word32 x,
unsigned int y)
00330 {
00331 assert(y < 32);
00332
return _lrotr(x, y);
00333 }
00334
00335
template<>
inline word32 rotlMod<word32>(word32 x,
unsigned int y)
00336 {
00337
return _lrotl(x, y);
00338 }
00339
00340
template<>
inline word32 rotrMod<word32>(word32 x,
unsigned int y)
00341 {
00342
return _lrotr(x, y);
00343 }
00344
00345
#endif // #ifdef INTEL_INTRINSICS
00346
00347
#ifdef PPC_INTRINSICS
00348
00349
template<>
inline word32 rotlFixed<word32>(word32 x,
unsigned int y)
00350 {
00351 assert(y < 32);
00352
return y ? __rlwinm(x,y,0,31) : x;
00353 }
00354
00355
template<>
inline word32 rotrFixed<word32>(word32 x,
unsigned int y)
00356 {
00357 assert(y < 32);
00358
return y ? __rlwinm(x,32-y,0,31) : x;
00359 }
00360
00361
template<>
inline word32 rotlVariable<word32>(word32 x,
unsigned int y)
00362 {
00363 assert(y < 32);
00364
return (__rlwnm(x,y,0,31));
00365 }
00366
00367
template<>
inline word32 rotrVariable<word32>(word32 x,
unsigned int y)
00368 {
00369 assert(y < 32);
00370
return (__rlwnm(x,32-y,0,31));
00371 }
00372
00373
template<>
inline word32 rotlMod<word32>(word32 x,
unsigned int y)
00374 {
00375
return (__rlwnm(x,y,0,31));
00376 }
00377
00378
template<>
inline word32 rotrMod<word32>(word32 x,
unsigned int y)
00379 {
00380
return (__rlwnm(x,32-y,0,31));
00381 }
00382
00383
#endif // #ifdef PPC_INTRINSICS
00384
00385
00386
00387
template <
class T>
00388
inline unsigned int GetByte(ByteOrder order, T value,
unsigned int index)
00389 {
00390
if (order == LITTLE_ENDIAN_ORDER)
00391
return GETBYTE(value, index);
00392
else
00393
return GETBYTE(value,
sizeof(T)-index-1);
00394 }
00395
00396
inline byte ByteReverse(byte value)
00397 {
00398
return value;
00399 }
00400
00401
inline word16 ByteReverse(word16 value)
00402 {
00403
return rotlFixed(value, 8U);
00404 }
00405
00406
inline word32 ByteReverse(word32 value)
00407 {
00408
#ifdef PPC_INTRINSICS
00409
00410
return (word32)__lwbrx(&value,0);
00411
#elif defined(FAST_ROTATE)
00412
00413
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00414
#else
00415
00416 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00417
return rotlFixed(value, 16U);
00418
#endif
00419
}
00420
00421
#ifdef WORD64_AVAILABLE
00422
inline word64 ByteReverse(word64 value)
00423 {
00424
#ifdef CRYPTOPP_SLOW_WORD64
00425
return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00426
#else
00427
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00428 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00429
return rotlFixed(value, 32U);
00430
#endif
00431
}
00432
#endif
00433
00434
inline byte BitReverse(byte value)
00435 {
00436 value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00437 value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00438
return rotlFixed(value, 4);
00439 }
00440
00441
inline word16 BitReverse(word16 value)
00442 {
00443 value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00444 value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00445 value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00446
return ByteReverse(value);
00447 }
00448
00449
inline word32 BitReverse(word32 value)
00450 {
00451 value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00452 value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00453 value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00454
return ByteReverse(value);
00455 }
00456
00457
#ifdef WORD64_AVAILABLE
00458
inline word64 BitReverse(word64 value)
00459 {
00460
#ifdef CRYPTOPP_SLOW_WORD64
00461
return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00462
#else
00463
value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00464 value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00465 value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00466
return ByteReverse(value);
00467
#endif
00468
}
00469
#endif
00470
00471
template <
class T>
00472
inline T BitReverse(T value)
00473 {
00474
if (
sizeof(T) == 1)
00475
return (T)BitReverse((byte)value);
00476
else if (
sizeof(T) == 2)
00477
return (T)BitReverse((word16)value);
00478
else if (
sizeof(T) == 4)
00479
return (T)BitReverse((word32)value);
00480
else
00481 {
00482
#ifdef WORD64_AVAILABLE
00483
assert(
sizeof(T) == 8);
00484
return (T)BitReverse((word64)value);
00485
#else
00486
assert(
false);
00487
return 0;
00488
#endif
00489
}
00490 }
00491
00492
template <
class T>
00493
inline T ConditionalByteReverse(ByteOrder order, T value)
00494 {
00495
return NativeByteOrderIs(order) ? value : ByteReverse(value);
00496 }
00497
00498
template <
class T>
00499
void ByteReverse(T *out,
const T *in,
unsigned int byteCount)
00500 {
00501 assert(byteCount %
sizeof(T) == 0);
00502
unsigned int count = byteCount/
sizeof(T);
00503
for (
unsigned int i=0; i<count; i++)
00504 out[i] = ByteReverse(in[i]);
00505 }
00506
00507
template <
class T>
00508
inline void ConditionalByteReverse(ByteOrder order, T *out,
const T *in,
unsigned int byteCount)
00509 {
00510
if (!NativeByteOrderIs(order))
00511 ByteReverse(out, in, byteCount);
00512
else if (in != out)
00513 memcpy(out, in, byteCount);
00514 }
00515
00516
template <
class T>
00517
inline void GetUserKey(ByteOrder order, T *out,
unsigned int outlen,
const byte *in,
unsigned int inlen)
00518 {
00519
const unsigned int U =
sizeof(T);
00520 assert(inlen <= outlen*U);
00521 memcpy(out, in, inlen);
00522 memset((byte *)out+inlen, 0, outlen*U-inlen);
00523 ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00524 }
00525
00526
inline byte UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, byte*)
00527 {
00528
return block[0];
00529 }
00530
00531
inline word16 UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, word16*)
00532 {
00533
return (order == BIG_ENDIAN_ORDER)
00534 ? block[1] | (block[0] << 8)
00535 : block[0] | (block[1] << 8);
00536 }
00537
00538
inline word32 UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, word32*)
00539 {
00540
return (order == BIG_ENDIAN_ORDER)
00541 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00542 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00543 }
00544
00545
#ifdef WORD64_AVAILABLE
00546
inline word64 UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, word64*)
00547 {
00548
return (order == BIG_ENDIAN_ORDER)
00549 ?
00550 (word64(block[7]) |
00551 (word64(block[6]) << 8) |
00552 (word64(block[5]) << 16) |
00553 (word64(block[4]) << 24) |
00554 (word64(block[3]) << 32) |
00555 (word64(block[2]) << 40) |
00556 (word64(block[1]) << 48) |
00557 (word64(block[0]) << 56))
00558 :
00559 (word64(block[0]) |
00560 (word64(block[1]) << 8) |
00561 (word64(block[2]) << 16) |
00562 (word64(block[3]) << 24) |
00563 (word64(block[4]) << 32) |
00564 (word64(block[5]) << 40) |
00565 (word64(block[6]) << 48) |
00566 (word64(block[7]) << 56));
00567 }
00568
#endif
00569
00570
template <
class T>
00571
inline T UnalignedGetWord(ByteOrder order,
const byte *block, T*dummy=NULL)
00572 {
00573
return UnalignedGetWordNonTemplate(order, block, dummy);
00574 }
00575
00576
inline void UnalignedPutWord(ByteOrder order, byte *block, byte value,
const byte *xorBlock = NULL)
00577 {
00578 block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00579 }
00580
00581
inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value,
const byte *xorBlock = NULL)
00582 {
00583
if (order == BIG_ENDIAN_ORDER)
00584 {
00585 block[0] = GETBYTE(value, 1);
00586 block[1] = GETBYTE(value, 0);
00587 }
00588
else
00589 {
00590 block[0] = GETBYTE(value, 0);
00591 block[1] = GETBYTE(value, 1);
00592 }
00593
00594
if (xorBlock)
00595 {
00596 block[0] ^= xorBlock[0];
00597 block[1] ^= xorBlock[1];
00598 }
00599 }
00600
00601
inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value,
const byte *xorBlock = NULL)
00602 {
00603
if (order == BIG_ENDIAN_ORDER)
00604 {
00605 block[0] = GETBYTE(value, 3);
00606 block[1] = GETBYTE(value, 2);
00607 block[2] = GETBYTE(value, 1);
00608 block[3] = GETBYTE(value, 0);
00609 }
00610
else
00611 {
00612 block[0] = GETBYTE(value, 0);
00613 block[1] = GETBYTE(value, 1);
00614 block[2] = GETBYTE(value, 2);
00615 block[3] = GETBYTE(value, 3);
00616 }
00617
00618
if (xorBlock)
00619 {
00620 block[0] ^= xorBlock[0];
00621 block[1] ^= xorBlock[1];
00622 block[2] ^= xorBlock[2];
00623 block[3] ^= xorBlock[3];
00624 }
00625 }
00626
00627
#ifdef WORD64_AVAILABLE
00628
inline void UnalignedPutWord(ByteOrder order, byte *block, word64 value,
const byte *xorBlock = NULL)
00629 {
00630
if (order == BIG_ENDIAN_ORDER)
00631 {
00632 block[0] = GETBYTE(value, 7);
00633 block[1] = GETBYTE(value, 6);
00634 block[2] = GETBYTE(value, 5);
00635 block[3] = GETBYTE(value, 4);
00636 block[4] = GETBYTE(value, 3);
00637 block[5] = GETBYTE(value, 2);
00638 block[6] = GETBYTE(value, 1);
00639 block[7] = GETBYTE(value, 0);
00640 }
00641
else
00642 {
00643 block[0] = GETBYTE(value, 0);
00644 block[1] = GETBYTE(value, 1);
00645 block[2] = GETBYTE(value, 2);
00646 block[3] = GETBYTE(value, 3);
00647 block[4] = GETBYTE(value, 4);
00648 block[5] = GETBYTE(value, 5);
00649 block[6] = GETBYTE(value, 6);
00650 block[7] = GETBYTE(value, 7);
00651 }
00652
00653
if (xorBlock)
00654 {
00655 block[0] ^= xorBlock[0];
00656 block[1] ^= xorBlock[1];
00657 block[2] ^= xorBlock[2];
00658 block[3] ^= xorBlock[3];
00659 block[4] ^= xorBlock[4];
00660 block[5] ^= xorBlock[5];
00661 block[6] ^= xorBlock[6];
00662 block[7] ^= xorBlock[7];
00663 }
00664 }
00665
#endif
00666
00667
template <
class T>
00668
inline T GetWord(
bool assumeAligned, ByteOrder order,
const byte *block)
00669 {
00670
if (assumeAligned)
00671 {
00672 assert(IsAligned<T>(block));
00673
return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00674 }
00675
else
00676
return UnalignedGetWord<T>(order, block);
00677 }
00678
00679
template <
class T>
00680
inline void GetWord(
bool assumeAligned, ByteOrder order, T &result,
const byte *block)
00681 {
00682 result = GetWord<T>(assumeAligned, order, block);
00683 }
00684
00685
template <
class T>
00686
inline void PutWord(
bool assumeAligned, ByteOrder order, byte *block, T value,
const byte *xorBlock = NULL)
00687 {
00688
if (assumeAligned)
00689 {
00690 assert(IsAligned<T>(block));
00691
if (xorBlock)
00692 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
00693
else
00694 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
00695 }
00696
else
00697 UnalignedPutWord(order, block, value, xorBlock);
00698 }
00699
00700
template <
class T,
class B,
bool A=true>
00701
class GetBlock
00702 {
00703
public:
00704 GetBlock(
const void *block)
00705 : m_block((const byte *)block) {}
00706
00707
template <
class U>
00708
inline GetBlock<T, B, A> & operator()(U &x)
00709 {
00710 CRYPTOPP_COMPILE_ASSERT(
sizeof(U) >=
sizeof(T));
00711 x = GetWord<T>(A, B::ToEnum(), m_block);
00712 m_block +=
sizeof(T);
00713
return *
this;
00714 }
00715
00716
private:
00717
const byte *m_block;
00718 };
00719
00720
template <
class T,
class B,
bool A=true>
00721
class PutBlock
00722 {
00723
public:
00724 PutBlock(
const void *xorBlock,
void *block)
00725 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
00726
00727
template <
class U>
00728
inline PutBlock<T, B, A> & operator()(U x)
00729 {
00730 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
00731 m_block +=
sizeof(T);
00732
if (m_xorBlock)
00733 m_xorBlock +=
sizeof(T);
00734
return *
this;
00735 }
00736
00737
private:
00738
const byte *m_xorBlock;
00739 byte *m_block;
00740 };
00741
00742
template <
class T,
class B,
bool A=true>
00743
struct BlockGetAndPut
00744 {
00745
00746
static inline GetBlock<T, B, A> Get(
const void *block) {
return GetBlock<T, B, A>(block);}
00747
typedef PutBlock<T, B, A> Put;
00748 };
00749
00750
template <
class T>
00751 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
00752 {
00753
if (!NativeByteOrderIs(order))
00754 value = ByteReverse(value);
00755
00756
return std::string((
char *)&value,
sizeof(value));
00757 }
00758
00759
template <
class T>
00760 T StringToWord(
const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
00761 {
00762 T value = 0;
00763 memcpy(&value, str.data(), STDMIN(
sizeof(value), str.size()));
00764
return NativeByteOrderIs(order) ? value : ByteReverse(value);
00765 }
00766
00767
00768
00769
template <
bool overflow>
struct SafeShifter;
00770
00771
template<>
struct SafeShifter<true>
00772 {
00773
template <
class T>
00774
static inline T RightShift(T value,
unsigned int bits)
00775 {
00776
return 0;
00777 }
00778
00779
template <
class T>
00780
static inline T LeftShift(T value,
unsigned int bits)
00781 {
00782
return 0;
00783 }
00784 };
00785
00786
template<>
struct SafeShifter<false>
00787 {
00788
template <
class T>
00789
static inline T RightShift(T value,
unsigned int bits)
00790 {
00791
return value >> bits;
00792 }
00793
00794
template <
class T>
00795
static inline T LeftShift(T value,
unsigned int bits)
00796 {
00797
return value << bits;
00798 }
00799 };
00800
00801
template <
unsigned int bits,
class T>
00802
inline T SafeRightShift(T value)
00803 {
00804
return SafeShifter<(bits>=(8*
sizeof(T)))>::RightShift(value, bits);
00805 }
00806
00807
template <
unsigned int bits,
class T>
00808
inline T SafeLeftShift(T value)
00809 {
00810
return SafeShifter<(bits>=(8*
sizeof(T)))>::LeftShift(value, bits);
00811 }
00812
00813 NAMESPACE_END
00814
00815
#endif // MISC_H