📄 misc.h
字号:
#ifndef CRYPTOPP_MISC_H
#define CRYPTOPP_MISC_H
#include "config.h"
#include <assert.h>
#include <string.h> // CodeWarrior doesn't have memory.h
#include <algorithm>
#include <string>
#ifdef INTEL_INTRINSICS
#include <stdlib.h>
#endif
NAMESPACE_BEGIN(CryptoPP)
// ************** misc functions ***************
#define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
// this one may be faster on a Pentium
// #define GETBYTE(x, y) (((byte *)&(x))[y])
unsigned int Parity(unsigned long);
unsigned int BytePrecision(unsigned long);
unsigned int BitPrecision(unsigned long);
unsigned long Crop(unsigned long, unsigned int size);
inline unsigned int bitsToBytes(unsigned int bitCount)
{
return ((bitCount+7)/(8));
}
inline unsigned int bytesToWords(unsigned int byteCount)
{
return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
}
inline unsigned int bitsToWords(unsigned int bitCount)
{
return ((bitCount+WORD_BITS-1)/(WORD_BITS));
}
void xorbuf(byte *buf, const byte *mask, unsigned int count);
void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count);
inline unsigned int RoundDownToMultipleOf(unsigned int n, unsigned int m)
{
return n - n%m;
}
inline unsigned int RoundUpToMultipleOf(unsigned int n, unsigned int m)
{
return RoundDownToMultipleOf(n+m-1, m);
}
template <class T>
inline bool IsAligned(const void *p)
{
return (unsigned int)p % sizeof(T) == 0;
}
inline bool CheckEndianess(bool highFirst)
{
#ifdef IS_LITTLE_ENDIAN
return !highFirst;
#else
return highFirst;
#endif
}
template <class T> // can't use <sstream> because GCC 2.95.2 doesn't have it
std::string IntToString(T a)
{
if (a == 0)
return "0";
bool negate = false;
if (a < 0)
{
negate = true;
a = -a;
}
std::string result;
while (a > 0)
{
result = char('0' + a % 10) + result;
a = a / 10;
}
if (negate)
result = "-" + result;
return result;
}
// ************** rotate functions ***************
template <class T> inline T rotlFixed(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return (x<<y) | (x>>(sizeof(T)*8-y));
}
template <class T> inline T rotrFixed(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return (x>>y) | (x<<(sizeof(T)*8-y));
}
template <class T> inline T rotlVariable(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return (x<<y) | (x>>(sizeof(T)*8-y));
}
template <class T> inline T rotrVariable(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return (x>>y) | (x<<(sizeof(T)*8-y));
}
template <class T> inline T rotlMod(T x, unsigned int y)
{
y %= sizeof(T)*8;
return (x<<y) | (x>>(sizeof(T)*8-y));
}
template <class T> inline T rotrMod(T x, unsigned int y)
{
y %= sizeof(T)*8;
return (x>>y) | (x<<(sizeof(T)*8-y));
}
#ifdef INTEL_INTRINSICS
template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return y ? _lrotl(x, y) : x;
}
template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return y ? _lrotr(x, y) : x;
}
template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return _lrotl(x, y);
}
template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return _lrotr(x, y);
}
template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
{
return _lrotl(x, y);
}
template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
{
return _lrotr(x, y);
}
#endif // #ifdef INTEL_INTRINSICS
#ifdef PPC_INTRINSICS
template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return y ? __rlwinm(x,y,0,31) : x;
}
template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return y ? __rlwinm(x,32-y,0,31) : x;
}
template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return (__rlwnm(x,y,0,31));
}
template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
{
assert(y < 32);
return (__rlwnm(x,32-y,0,31));
}
template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
{
return (__rlwnm(x,y,0,31));
}
template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
{
return (__rlwnm(x,32-y,0,31));
}
#endif // #ifdef PPC_INTRINSICS
// ************** endian reversal ***************
inline word16 byteReverse(word16 value)
{
return rotlFixed(value, 8U);
}
inline word32 byteReverse(word32 value)
{
#ifdef PPC_INTRINSICS
// PPC: load reverse indexed instruction
return (word32)__lwbrx(&value,0);
#elif defined(FAST_ROTATE)
// 5 instructions with rotate instruction, 9 without
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
#else
// 6 instructions with rotate instruction, 8 without
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
return rotlFixed(value, 16U);
#endif
}
#ifdef WORD64_AVAILABLE
inline word64 byteReverse(word64 value)
{
#ifdef SLOW_WORD64
return (word64(byteReverse(word32(value))) << 32) | byteReverse(word32(value>>32));
#else
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
return rotlFixed(value, 32U);
#endif
}
#endif
inline byte bitReverse(byte value)
{
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
return rotlFixed(value, 4);
}
inline word16 bitReverse(word16 value)
{
value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
return byteReverse(value);
}
inline word32 bitReverse(word32 value)
{
value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
return byteReverse(value);
}
#ifdef WORD64_AVAILABLE
inline word64 bitReverse(word64 value)
{
#ifdef SLOW_WORD64
return (word64(bitReverse(word32(value))) << 32) | bitReverse(word32(value>>32));
#else
value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
return byteReverse(value);
#endif
}
#endif
template <class T>
inline T bitReverse(T value)
{
if (sizeof(T) == 1)
return bitReverse((byte)value);
else if (sizeof(T) == 2)
return bitReverse((word16)value);
else if (sizeof(T) == 4)
return bitReverse((word32)value);
else
{
#ifdef WORD64_AVAILABLE
assert(sizeof(T) == 8);
return bitReverse((word64)value);
#else
assert(false);
return 0;
#endif
}
}
template <class T>
void byteReverse(T *out, const T *in, unsigned int byteCount)
{
unsigned int count = (byteCount+sizeof(T)-1)/sizeof(T);
for (unsigned int i=0; i<count; i++)
out[i] = byteReverse(in[i]);
}
template <class T>
inline void GetUserKeyLittleEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen)
{
const unsigned int U = sizeof(T);
assert(inlen <= outlen*U);
memcpy(out, in, inlen);
memset((byte *)out+inlen, 0, outlen*U-inlen);
#ifndef IS_LITTLE_ENDIAN
byteReverse(out, out, inlen);
#endif
}
template <class T>
inline void GetUserKeyBigEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen)
{
const unsigned int U = sizeof(T);
assert(inlen <= outlen*U);
memcpy(out, in, inlen);
memset((byte *)out+inlen, 0, outlen*U-inlen);
#ifdef IS_LITTLE_ENDIAN
byteReverse(out, out, inlen);
#endif
}
// Fetch 2 words from user's buffer into "a", "b" in LITTLE-endian order
template <class T>
inline void GetBlockLittleEndian(const byte *block, T &a, T &b)
{
#ifdef IS_LITTLE_ENDIAN
a = ((T *)block)[0];
b = ((T *)block)[1];
#else
a = byteReverse(((T *)block)[0]);
b = byteReverse(((T *)block)[1]);
#endif
}
// Put 2 words back into user's buffer in LITTLE-endian order
template <class T>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -