00001
#ifndef CRYPTOPP_MISC_H
00002
#define CRYPTOPP_MISC_H
00003
00004
#include "cryptopp_config.h"
00005
#include "cryptlib.h"
00006
#include <assert.h>
00007
#include <string.h>
00008
#include <algorithm>
00009
#include <string>
00010
00011
#ifdef INTEL_INTRINSICS
00012
#include <stdlib.h>
00013
#endif
00014
00015 NAMESPACE_BEGIN(CryptoPP)
00016
00017
00018
00019 template <
bool b>
00020 struct CompileAssert
00021 {
00022
static char dummy[2*b-1];
00023 };
00024
00025
#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
00026
#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
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 Empty
00033 {
00034 };
00035
00036
template <
class BASE1,
class BASE2>
00037
class TwoBases :
public BASE1,
public BASE2
00038 {
00039 };
00040
00041
template <
class BASE1,
class BASE2,
class BASE3>
00042
class ThreeBases :
public BASE1,
public BASE2,
public BASE3
00043 {
00044 };
00045
00046
template <
class T>
00047
class ObjectHolder
00048 {
00049
protected:
00050 T m_object;
00051 };
00052
00053
class NotCopyable
00054 {
00055
public:
00056 NotCopyable() {}
00057
private:
00058 NotCopyable(
const NotCopyable &);
00059
void operator=(
const NotCopyable &);
00060 };
00061
00062
00063
00064
00065
template <
class _Tp>
inline const _Tp& STDMIN(
const _Tp& __a,
const _Tp& __b)
00066 {
00067
return __b < __a ? __b : __a;
00068 }
00069
00070
template <
class _Tp>
inline const _Tp& STDMAX(
const _Tp& __a,
const _Tp& __b)
00071 {
00072
return __a < __b ? __b : __a;
00073 }
00074
00075
#define RETURN_IF_NONZERO(x) unsigned int returnedValue = x; if (returnedValue) return returnedValue
00076
00077
00078
#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00079
00080
00081
00082
00083
unsigned int Parity(
unsigned long);
00084
unsigned int BytePrecision(
unsigned long);
00085
unsigned int BitPrecision(
unsigned long);
00086
unsigned long Crop(
unsigned long,
unsigned int size);
00087
00088
inline unsigned int BitsToBytes(
unsigned int bitCount)
00089 {
00090
return ((bitCount+7)/(8));
00091 }
00092
00093
inline unsigned int BytesToWords(
unsigned int byteCount)
00094 {
00095
return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00096 }
00097
00098
inline unsigned int BitsToWords(
unsigned int bitCount)
00099 {
00100
return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00101 }
00102
00103
void xorbuf(byte *buf,
const byte *mask,
unsigned int count);
00104
void xorbuf(byte *output,
const byte *input,
const byte *mask,
unsigned int count);
00105
00106
template <
class T>
00107
inline bool IsPowerOf2(T n)
00108 {
00109
return n > 0 && (n & (n-1)) == 0;
00110 }
00111
00112
template <
class T1,
class T2>
00113
inline T2 ModPowerOf2(T1 a, T2 b)
00114 {
00115 assert(IsPowerOf2(b));
00116
return T2(a) & (b-1);
00117 }
00118
00119
template <
class T>
00120
inline T RoundDownToMultipleOf(T n, T m)
00121 {
00122
return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
00123 }
00124
00125
template <
class T>
00126
inline T RoundUpToMultipleOf(T n, T m)
00127 {
00128
return RoundDownToMultipleOf(n+m-1, m);
00129 }
00130
00131
template <
class T>
00132
inline unsigned int GetAlignment(T *dummy=NULL)
00133 {
00134
#if (_MSC_VER >= 1300)
00135
return __alignof(T);
00136
#elif defined(__GNUC__)
00137
return __alignof__(T);
00138
#else
00139
return sizeof(T);
00140
#endif
00141
}
00142
00143
inline bool IsAlignedOn(
const void *p,
unsigned int alignment)
00144 {
00145
return IsPowerOf2(alignment) ? ModPowerOf2((
unsigned int)p, alignment) == 0 : (
unsigned int)p % alignment == 0;
00146 }
00147
00148
template <
class T>
00149
inline bool IsAligned(
const void *p, T *dummy=NULL)
00150 {
00151
return IsAlignedOn(p, GetAlignment<T>());
00152 }
00153
00154
#ifdef IS_LITTLE_ENDIAN
00155
typedef LittleEndian NativeByteOrder;
00156
#else
00157
typedef BigEndian NativeByteOrder;
00158
#endif
00159
00160
inline ByteOrder GetNativeByteOrder()
00161 {
00162
return NativeByteOrder::ToEnum();
00163 }
00164
00165
inline bool NativeByteOrderIs(ByteOrder order)
00166 {
00167
return order == GetNativeByteOrder();
00168 }
00169
00170
template <
class T>
00171 std::string IntToString(T a,
unsigned int base = 10)
00172 {
00173
if (a == 0)
00174
return "0";
00175
bool negate =
false;
00176
if (a < 0)
00177 {
00178 negate =
true;
00179 a = 0-a;
00180 }
00181 std::string result;
00182
while (a > 0)
00183 {
00184 T digit = a % base;
00185 result = char((digit < 10 ?
'0' : (
'a' - 10)) + digit) + result;
00186 a /= base;
00187 }
00188
if (negate)
00189 result =
"-" + result;
00190
return result;
00191 }
00192
00193
template <
class T1,
class T2>
00194
inline T1 SaturatingSubtract(T1 a, T2 b)
00195 {
00196 CRYPTOPP_COMPILE_ASSERT_INSTANCE(T1(-1)>0, 0);
00197 CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);
00198
return T1((a > b) ? (a - b) : 0);
00199 }
00200
00201
template <
class T>
00202
inline CipherDir GetCipherDir(
const T &obj)
00203 {
00204
return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
00205 }
00206
00207
00208
00209
template <
class T>
inline T rotlFixed(T x,
unsigned int y)
00210 {
00211 assert(y <
sizeof(T)*8);
00212
return (x<<y) | (x>>(
sizeof(T)*8-y));
00213 }
00214
00215
template <
class T>
inline T rotrFixed(T x,
unsigned int y)
00216 {
00217 assert(y <
sizeof(T)*8);
00218
return (x>>y) | (x<<(
sizeof(T)*8-y));
00219 }
00220
00221
template <
class T>
inline T rotlVariable(T x,
unsigned int y)
00222 {
00223 assert(y <
sizeof(T)*8);
00224
return (x<<y) | (x>>(
sizeof(T)*8-y));
00225 }
00226
00227
template <
class T>
inline T rotrVariable(T x,
unsigned int y)
00228 {
00229 assert(y <
sizeof(T)*8);
00230
return (x>>y) | (x<<(
sizeof(T)*8-y));
00231 }
00232
00233
template <
class T>
inline T rotlMod(T x,
unsigned int y)
00234 {
00235 y %=
sizeof(T)*8;
00236
return (x<<y) | (x>>(
sizeof(T)*8-y));
00237 }
00238
00239
template <
class T>
inline T rotrMod(T x,
unsigned int y)
00240 {
00241 y %=
sizeof(T)*8;
00242
return (x>>y) | (x<<(
sizeof(T)*8-y));
00243 }
00244
00245
#ifdef INTEL_INTRINSICS
00246
00247
#pragma intrinsic(_lrotl, _lrotr)
00248
00249
template<>
inline word32 rotlFixed<word32>(word32 x,
unsigned int y)
00250 {
00251 assert(y < 32);
00252
return y ? _lrotl(x, y) : x;
00253 }
00254
00255
template<>
inline word32 rotrFixed<word32>(word32 x,
unsigned int y)
00256 {
00257 assert(y < 32);
00258
return y ? _lrotr(x, y) : x;
00259 }
00260
00261
template<>
inline word32 rotlVariable<word32>(word32 x,
unsigned int y)
00262 {
00263 assert(y < 32);
00264
return _lrotl(x, y);
00265 }
00266
00267
template<>
inline word32 rotrVariable<word32>(word32 x,
unsigned int y)
00268 {
00269 assert(y < 32);
00270
return _lrotr(x, y);
00271 }
00272
00273
template<>
inline word32 rotlMod<word32>(word32 x,
unsigned int y)
00274 {
00275
return _lrotl(x, y);
00276 }
00277
00278
template<>
inline word32 rotrMod<word32>(word32 x,
unsigned int y)
00279 {
00280
return _lrotr(x, y);
00281 }
00282
00283
#endif // #ifdef INTEL_INTRINSICS
00284
00285
#ifdef PPC_INTRINSICS
00286
00287
template<>
inline word32 rotlFixed<word32>(word32 x,
unsigned int y)
00288 {
00289 assert(y < 32);
00290
return y ? __rlwinm(x,y,0,31) : x;
00291 }
00292
00293
template<>
inline word32 rotrFixed<word32>(word32 x,
unsigned int y)
00294 {
00295 assert(y < 32);
00296
return y ? __rlwinm(x,32-y,0,31) : x;
00297 }
00298
00299
template<>
inline word32 rotlVariable<word32>(word32 x,
unsigned int y)
00300 {
00301 assert(y < 32);
00302
return (__rlwnm(x,y,0,31));
00303 }
00304
00305
template<>
inline word32 rotrVariable<word32>(word32 x,
unsigned int y)
00306 {
00307 assert(y < 32);
00308
return (__rlwnm(x,32-y,0,31));
00309 }
00310
00311
template<>
inline word32 rotlMod<word32>(word32 x,
unsigned int y)
00312 {
00313
return (__rlwnm(x,y,0,31));
00314 }
00315
00316
template<>
inline word32 rotrMod<word32>(word32 x,
unsigned int y)
00317 {
00318
return (__rlwnm(x,32-y,0,31));
00319 }
00320
00321
#endif // #ifdef PPC_INTRINSICS
00322
00323
00324
00325
template <
class T>
00326
inline unsigned int GetByte(ByteOrder order, T value,
unsigned int index)
00327 {
00328
if (order == LITTLE_ENDIAN_ORDER)
00329
return GETBYTE(value, index);
00330
else
00331
return GETBYTE(value,
sizeof(T)-index-1);
00332 }
00333
00334
inline byte ByteReverse(byte value)
00335 {
00336
return value;
00337 }
00338
00339
inline word16 ByteReverse(word16 value)
00340 {
00341
return rotlFixed(value, 8U);
00342 }
00343
00344
inline word32 ByteReverse(word32 value)
00345 {
00346
#ifdef PPC_INTRINSICS
00347
00348
return (word32)__lwbrx(&value,0);
00349
#elif defined(FAST_ROTATE)
00350
00351
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00352
#else
00353
00354 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00355
return rotlFixed(value, 16U);
00356
#endif
00357
}
00358
00359
#ifdef WORD64_AVAILABLE
00360
inline word64 ByteReverse(word64 value)
00361 {
00362
#ifdef SLOW_WORD64
00363
return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00364
#else
00365
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00366 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00367
return rotlFixed(value, 32U);
00368
#endif
00369
}
00370
#endif
00371
00372
inline byte BitReverse(byte value)
00373 {
00374 value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00375 value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00376
return rotlFixed(value, 4);
00377 }
00378
00379
inline word16 BitReverse(word16 value)
00380 {
00381 value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00382 value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00383 value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00384
return ByteReverse(value);
00385 }
00386
00387
inline word32 BitReverse(word32 value)
00388 {
00389 value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00390 value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00391 value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00392
return ByteReverse(value);
00393 }
00394
00395
#ifdef WORD64_AVAILABLE
00396
inline word64 BitReverse(word64 value)
00397 {
00398
#ifdef SLOW_WORD64
00399
return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00400
#else
00401
value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00402 value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00403 value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00404
return ByteReverse(value);
00405
#endif
00406
}
00407
#endif
00408
00409
template <
class T>
00410
inline T BitReverse(T value)
00411 {
00412
if (
sizeof(T) == 1)
00413
return (T)BitReverse((byte)value);
00414
else if (
sizeof(T) == 2)
00415
return (T)BitReverse((word16)value);
00416
else if (
sizeof(T) == 4)
00417
return (T)BitReverse((word32)value);
00418
else
00419 {
00420
#ifdef WORD64_AVAILABLE
00421
assert(
sizeof(T) == 8);
00422
return (T)BitReverse((word64)value);
00423
#else
00424
assert(
false);
00425
return 0;
00426
#endif
00427
}
00428 }
00429
00430
template <
class T>
00431
inline T ConditionalByteReverse(ByteOrder order, T value)
00432 {
00433
return NativeByteOrderIs(order) ? value : ByteReverse(value);
00434 }
00435
00436
template <
class T>
00437
void ByteReverse(T *out,
const T *in,
unsigned int byteCount)
00438 {
00439 assert(byteCount %
sizeof(T) == 0);
00440
unsigned int count = byteCount/
sizeof(T);
00441
for (
unsigned int i=0; i<count; i++)
00442 out[i] = ByteReverse(in[i]);
00443 }
00444
00445
template <
class T>
00446
inline void ConditionalByteReverse(ByteOrder order, T *out,
const T *in,
unsigned int byteCount)
00447 {
00448
if (!NativeByteOrderIs(order))
00449 ByteReverse(out, in, byteCount);
00450
else if (in != out)
00451 memcpy(out, in, byteCount);
00452 }
00453
00454
template <
class T>
00455
inline void GetUserKey(ByteOrder order, T *out,
unsigned int outlen,
const byte *in,
unsigned int inlen)
00456 {
00457
const unsigned int U =
sizeof(T);
00458 assert(inlen <= outlen*U);
00459 memcpy(out, in, inlen);
00460 memset((byte *)out+inlen, 0, outlen*U-inlen);
00461 ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00462 }
00463
00464
inline byte UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, byte*)
00465 {
00466
return block[0];
00467 }
00468
00469
inline word16 UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, word16*)
00470 {
00471
return (order == BIG_ENDIAN_ORDER)
00472 ? block[1] | (block[0] << 8)
00473 : block[0] | (block[1] << 8);
00474 }
00475
00476
inline word32 UnalignedGetWordNonTemplate(ByteOrder order,
const byte *block, word32*)
00477 {
00478
return (order == BIG_ENDIAN_ORDER)
00479 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00480 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00481 }
00482
00483
template <
class T>
00484
inline T UnalignedGetWord(ByteOrder order,
const byte *block, T*dummy=NULL)
00485 {
00486
return UnalignedGetWordNonTemplate(order, block, dummy);
00487 }
00488
00489
inline void UnalignedPutWord(ByteOrder order, byte *block, byte value,
const byte *xorBlock = NULL)
00490 {
00491 block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00492 }
00493
00494
inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value,
const byte *xorBlock = NULL)
00495 {
00496
if (order == BIG_ENDIAN_ORDER)
00497 {
00498 block[0] = GETBYTE(value, 1);
00499 block[1] = GETBYTE(value, 0);
00500 }
00501
else
00502 {
00503 block[0] = GETBYTE(value, 0);
00504 block[1] = GETBYTE(value, 1);
00505 }
00506
00507
if (xorBlock)
00508 {
00509 block[0] ^= xorBlock[0];
00510 block[1] ^= xorBlock[1];
00511 }
00512 }
00513
00514
inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value,
const byte *xorBlock = NULL)
00515 {
00516
if (order == BIG_ENDIAN_ORDER)
00517 {
00518 block[0] = GETBYTE(value, 3);
00519 block[1] = GETBYTE(value, 2);
00520 block[2] = GETBYTE(value, 1);
00521 block[3] = GETBYTE(value, 0);
00522 }
00523
else
00524 {
00525 block[0] = GETBYTE(value, 0);
00526 block[1] = GETBYTE(value, 1);
00527 block[2] = GETBYTE(value, 2);
00528 block[3] = GETBYTE(value, 3);
00529 }
00530
00531
if (xorBlock)
00532 {
00533 block[0] ^= xorBlock[0];
00534 block[1] ^= xorBlock[1];
00535 block[2] ^= xorBlock[2];
00536 block[3] ^= xorBlock[3];
00537 }
00538 }
00539
00540
template <
class T>
00541
inline T GetWord(
bool assumeAligned, ByteOrder order,
const byte *block)
00542 {
00543
if (assumeAligned)
00544 {
00545 assert(IsAligned<T>(block));
00546
return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00547 }
00548
else
00549
return UnalignedGetWord<T>(order, block);
00550 }
00551
00552
template <
class T>
00553
inline void GetWord(
bool assumeAligned, ByteOrder order, T &result,
const byte *block)
00554 {
00555 result = GetWord<T>(assumeAligned, order, block);
00556 }
00557
00558
template <
class T>
00559
inline void PutWord(
bool assumeAligned, ByteOrder order, byte *block, T value,
const byte *xorBlock = NULL)
00560 {
00561
if (assumeAligned)
00562 {
00563 assert(IsAligned<T>(block));
00564
if (xorBlock)
00565 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
00566
else
00567 *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
00568 }
00569
else
00570 UnalignedPutWord(order, block, value, xorBlock);
00571 }
00572
00573
template <
class T,
class B,
bool A=true>
00574
class GetBlock
00575 {
00576
public:
00577 GetBlock(
const void *block)
00578 : m_block((const byte *)block) {}
00579
00580
template <
class U>
00581
inline GetBlock<T, B, A> & operator()(U &x)
00582 {
00583 CRYPTOPP_COMPILE_ASSERT(
sizeof(U) >=
sizeof(T));
00584 x = GetWord<T>(A, B::ToEnum(), m_block);
00585 m_block +=
sizeof(T);
00586
return *
this;
00587 }
00588
00589
private:
00590
const byte *m_block;
00591 };
00592
00593
template <
class T,
class B,
bool A=true>
00594
class PutBlock
00595 {
00596
public:
00597 PutBlock(
const void *xorBlock,
void *block)
00598 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
00599
00600
template <
class U>
00601
inline PutBlock<T, B, A> & operator()(U x)
00602 {
00603 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
00604 m_block +=
sizeof(T);
00605
if (m_xorBlock)
00606 m_xorBlock +=
sizeof(T);
00607
return *
this;
00608 }
00609
00610
private:
00611
const byte *m_xorBlock;
00612 byte *m_block;
00613 };
00614
00615
template <
class T,
class B,
bool A=true>
00616
struct BlockGetAndPut
00617 {
00618
00619
static inline GetBlock<T, B, A> Get(
const void *block) {
return GetBlock<T, B, A>(block);}
00620
typedef PutBlock<T, B, A> Put;
00621 };
00622
00623
template <
class T>
00624 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
00625 {
00626
if (!NativeByteOrderIs(order))
00627 value = ByteReverse(value);
00628
00629
return std::string((
char *)&value,
sizeof(value));
00630 }
00631
00632
template <
class T>
00633 T StringToWord(
const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
00634 {
00635 T value = 0;
00636 memcpy(&value, str.data(), STDMIN(
sizeof(value), str.size()));
00637
return NativeByteOrderIs(order) ? value : ByteReverse(value);
00638 }
00639
00640
00641
00642
template <
bool overflow>
struct SafeShifter;
00643
00644
template<>
struct SafeShifter<true>
00645 {
00646
template <
class T>
00647
static inline T RightShift(T value,
unsigned int bits)
00648 {
00649
return 0;
00650 }
00651
00652
template <
class T>
00653
static inline T LeftShift(T value,
unsigned int bits)
00654 {
00655
return 0;
00656 }
00657 };
00658
00659
template<>
struct SafeShifter<false>
00660 {
00661
template <
class T>
00662
static inline T RightShift(T value,
unsigned int bits)
00663 {
00664
return value >> bits;
00665 }
00666
00667
template <
class T>
00668
static inline T LeftShift(T value,
unsigned int bits)
00669 {
00670
return value << bits;
00671 }
00672 };
00673
00674
template <
unsigned int bits,
class T>
00675
inline T SafeRightShift(T value)
00676 {
00677
return SafeShifter<(bits>=(8*
sizeof(T)))>::RightShift(value, bits);
00678 }
00679
00680
template <
unsigned int bits,
class T>
00681
inline T SafeLeftShift(T value)
00682 {
00683
return SafeShifter<(bits>=(8*
sizeof(T)))>::LeftShift(value, bits);
00684 }
00685
00686 NAMESPACE_END
00687
00688
#endif // MISC_H