added codes of Hash
This commit is contained in:
parent
af510a6cfc
commit
863293fbc8
317
inc/hgl/util/hash/Hash.h
Normal file
317
inc/hgl/util/hash/Hash.h
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
#ifndef HGL_UTIL_HASH_INCLUDE
|
||||||
|
#define HGL_UTIL_HASH_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/String.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Hash算法枚举
|
||||||
|
*/
|
||||||
|
enum class HASH ///Hash算法枚举
|
||||||
|
{
|
||||||
|
Adler32, ///<一种较CRC32更为安全的快速HASH算法
|
||||||
|
CRC32, ///<最快速的HASH算法,但最不安全,仅用于低安全性的简单验证
|
||||||
|
MD4, ///<较MD5在安全性下稍弱。但仍未被攻破,且较MD5更快
|
||||||
|
MD5, ///<最常用的HASH算法
|
||||||
|
|
||||||
|
SHA1, ///<较MD5更为安全,但计算较慢
|
||||||
|
SHA1LE, ///<SHA1改版
|
||||||
|
SHA256,
|
||||||
|
SHA512,
|
||||||
|
|
||||||
|
ENUM_CLASS_RANGE(Adler32,SHA512)
|
||||||
|
};//enum HASH
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash编码结构模板
|
||||||
|
*/
|
||||||
|
template<int SIZE> struct HashCode
|
||||||
|
{
|
||||||
|
unsigned char code[SIZE];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using CharArray=T[(SIZE<<1)+1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
HashCode()
|
||||||
|
{
|
||||||
|
hgl_zero(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int size(){return SIZE;}
|
||||||
|
|
||||||
|
const unsigned char operator[](int index)const
|
||||||
|
{
|
||||||
|
return code[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyFrom(const void *ptr)
|
||||||
|
{
|
||||||
|
memcpy(code,ptr,SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromString(const char *str)
|
||||||
|
{
|
||||||
|
ParseHexStr(code,str,SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ToUpperString(T *str,const T gap_char=0) const
|
||||||
|
{
|
||||||
|
ToUpperHexStr<T>(str,code,SIZE,gap_char);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ToLowerString(T *str,const T gap_char=0) const
|
||||||
|
{
|
||||||
|
ToLowerHexStr<T>(str,code,SIZE,gap_char);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int CompFunc(const HashCode<SIZE> &hash)const
|
||||||
|
{
|
||||||
|
const unsigned char *s=code;
|
||||||
|
const unsigned char *t=hash.code;
|
||||||
|
|
||||||
|
for(int i=0;i<SIZE;i++)
|
||||||
|
{
|
||||||
|
if(*s!=*t)
|
||||||
|
return(*s-*t);
|
||||||
|
|
||||||
|
s++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompOperator(const HashCode<SIZE> &,CompFunc)
|
||||||
|
};//template<int SIZE> struct HashCode
|
||||||
|
|
||||||
|
using HashCodeCRC32 =HashCode<4> ;
|
||||||
|
using HashCodeAdler32 =HashCode<4> ;
|
||||||
|
using HashCodeMD5 =HashCode<16> ;
|
||||||
|
using HashCodeMD4 =HashCode<16> ;
|
||||||
|
using HashCodeSHA1 =HashCode<20> ;
|
||||||
|
using HashCodeSHA1LE =HashCode<20> ;
|
||||||
|
using HashCodeSHA256 =HashCode<32> ;
|
||||||
|
using HashCodeSHA512 =HashCode<64> ;
|
||||||
|
|
||||||
|
const int hash_code_bytes[]={4,4,16,16,20,20,32,64}; //hash码长度
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 散列值计算功能基类
|
||||||
|
*/
|
||||||
|
class Hash ///散列值计算功能基类
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Hash()=default;
|
||||||
|
|
||||||
|
virtual void GetName(UTF8String &)const=0; ///<取得HASH算法的名称
|
||||||
|
virtual void GetName(UTF16String &)const=0; ///<取得HASH算法的名称
|
||||||
|
virtual const int GetHashBytes()const=0; ///<取得HASH码字节长度(MD4/MD5为16,SHA1为20)
|
||||||
|
|
||||||
|
virtual void Init()=0; ///<初始化散列值计算
|
||||||
|
virtual void Update(const void *,uint)=0; ///<提交新的数据
|
||||||
|
virtual void Final(void *)=0; ///<结束并取得结果
|
||||||
|
};//class Hash
|
||||||
|
|
||||||
|
template<HASH ha> Hash *CreateHash(); ///<创建一个hash值计算类实例
|
||||||
|
|
||||||
|
#define HGL_CREATE_HASH_FUNC(name) Hash *Create##name##Hash(); \
|
||||||
|
template<> inline Hash *CreateHash<HASH::name>(){return Create##name##Hash();}
|
||||||
|
|
||||||
|
HGL_CREATE_HASH_FUNC(Adler32)
|
||||||
|
HGL_CREATE_HASH_FUNC(CRC32)
|
||||||
|
HGL_CREATE_HASH_FUNC(MD4)
|
||||||
|
HGL_CREATE_HASH_FUNC(MD5)
|
||||||
|
HGL_CREATE_HASH_FUNC(SHA1)
|
||||||
|
HGL_CREATE_HASH_FUNC(SHA1LE)
|
||||||
|
HGL_CREATE_HASH_FUNC(SHA256)
|
||||||
|
HGL_CREATE_HASH_FUNC(SHA512)
|
||||||
|
|
||||||
|
#undef HGL_CREATE_HASH_FUNC
|
||||||
|
|
||||||
|
inline Hash *CreateHash(HASH ha)
|
||||||
|
{
|
||||||
|
ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(HASH,ha)
|
||||||
|
|
||||||
|
using CreateHashFunc=Hash *(*)();
|
||||||
|
|
||||||
|
const CreateHashFunc func[(size_t)HASH::RANGE_SIZE]=
|
||||||
|
{
|
||||||
|
CreateAdler32Hash,
|
||||||
|
CreateCRC32Hash,
|
||||||
|
CreateMD4Hash,
|
||||||
|
CreateMD5Hash,
|
||||||
|
CreateSHA1Hash,
|
||||||
|
CreateSHA1LEHash,
|
||||||
|
CreateSHA256Hash,
|
||||||
|
CreateSHA512Hash
|
||||||
|
};
|
||||||
|
|
||||||
|
return func[(size_t)ha]();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算一段数据的Hash值
|
||||||
|
* @param data 数据指针
|
||||||
|
* @param size 数据长度
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_code 计算后的hash值存放处
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
template<HASH ha> bool CountHash(const void *data,int size,void *hash_code)
|
||||||
|
{
|
||||||
|
if(!data||size<=0||!hash_code)return(false);
|
||||||
|
|
||||||
|
Hash *h=CreateHash<ha>();
|
||||||
|
|
||||||
|
if(!h)return(false);
|
||||||
|
|
||||||
|
h->Init();
|
||||||
|
h->Update(data,size);
|
||||||
|
h->Final(hash_code);
|
||||||
|
|
||||||
|
delete h;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算一段数据的Hash值
|
||||||
|
* @param data 数据指针
|
||||||
|
* @param size 数据长度
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_code 计算后的hash值存放处
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
inline bool CountHash(const void *data,int size,HASH ha,void *hash_code)
|
||||||
|
{
|
||||||
|
ENUM_CLASS_RANGE_ERROR_RETURN_FALSE(HASH,ha)
|
||||||
|
if(!data||size<=0||!hash_code)return(false);
|
||||||
|
|
||||||
|
using CountHashFunc=bool (*)(const void *,int size,void *);
|
||||||
|
|
||||||
|
const CountHashFunc func[(size_t)HASH::RANGE_SIZE]=
|
||||||
|
{
|
||||||
|
CountHash<HASH::Adler32 >,
|
||||||
|
CountHash<HASH::CRC32 >,
|
||||||
|
CountHash<HASH::MD4 >,
|
||||||
|
CountHash<HASH::MD5 >,
|
||||||
|
CountHash<HASH::SHA1 >,
|
||||||
|
CountHash<HASH::SHA1LE >,
|
||||||
|
CountHash<HASH::SHA256 >,
|
||||||
|
CountHash<HASH::SHA512 >
|
||||||
|
};
|
||||||
|
|
||||||
|
return func[(size_t)ha](data,size,hash_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算一段数据的Hash值
|
||||||
|
* @param data 数据指针
|
||||||
|
* @param size 数据长度
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_str 计算后的hash值存放处
|
||||||
|
* @param litter 小写字母
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
template<HASH ha> bool CountHashStr(const void *data,int size,UTF8String &hash_str,bool litter=true)
|
||||||
|
{
|
||||||
|
if(!data||size<=0)return(false);
|
||||||
|
|
||||||
|
Hash *h=CreateHash<ha>();
|
||||||
|
|
||||||
|
if(!h)return(false);
|
||||||
|
|
||||||
|
const int hash_bytes=hash_code_bytes[(size_t)ha];
|
||||||
|
|
||||||
|
uint8 *hash_code=new uint8[hash_bytes];
|
||||||
|
char *hash_code_str=new char[1+(hash_bytes<<1)];
|
||||||
|
|
||||||
|
h->Init();
|
||||||
|
h->Update(data,size);
|
||||||
|
h->Final(hash_code);
|
||||||
|
|
||||||
|
delete h;
|
||||||
|
|
||||||
|
DataToHexStr(hash_code_str,hash_code,hash_bytes,litter?LowerHexChar:UpperHexChar);
|
||||||
|
|
||||||
|
hash_str.SetInstance(hash_code_str,hash_bytes<<1);
|
||||||
|
|
||||||
|
delete[] hash_code;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算一段数据的Hash值
|
||||||
|
* @param data 数据指针
|
||||||
|
* @param size 数据长度
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_str 计算后的hash值存放处
|
||||||
|
* @param litter 小写字母
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
inline bool CountHash(const void *data,int size,HASH ha,UTF8String &hash_str,bool litter=true)
|
||||||
|
{
|
||||||
|
ENUM_CLASS_RANGE_ERROR_RETURN_FALSE(HASH,ha)
|
||||||
|
if(!data||size<=0)return(false);
|
||||||
|
|
||||||
|
using CountHashFunc=bool (*)(const void *,int size,UTF8String &,bool);
|
||||||
|
|
||||||
|
const CountHashFunc func[(size_t)HASH::RANGE_SIZE]=
|
||||||
|
{
|
||||||
|
CountHashStr<HASH::Adler32 >,
|
||||||
|
CountHashStr<HASH::CRC32 >,
|
||||||
|
CountHashStr<HASH::MD4 >,
|
||||||
|
CountHashStr<HASH::MD5 >,
|
||||||
|
CountHashStr<HASH::SHA1 >,
|
||||||
|
CountHashStr<HASH::SHA1LE >,
|
||||||
|
CountHashStr<HASH::SHA256 >,
|
||||||
|
CountHashStr<HASH::SHA512 >
|
||||||
|
};
|
||||||
|
|
||||||
|
return func[(size_t)ha](data,size,hash_str,litter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HGL_COUNT_HASH_FUNC(name) inline bool Count##name(const void *data, int size, HashCode##name &hc) { return CountHash<HASH::name>(data, size, &hc); } \
|
||||||
|
inline bool Count##name(const void *data, int size, UTF8String &hash_str, bool litter = true) { return CountHashStr<HASH::name>(data, size, hash_str, litter); } \
|
||||||
|
inline bool Count##name(const UTF8String &str, UTF8String &hash_str, bool litter = true) { return CountHashStr<HASH::name>(str.c_str(), str.Length(), hash_str, litter); }
|
||||||
|
|
||||||
|
HGL_COUNT_HASH_FUNC(Adler32)
|
||||||
|
HGL_COUNT_HASH_FUNC(CRC32)
|
||||||
|
HGL_COUNT_HASH_FUNC(MD4)
|
||||||
|
HGL_COUNT_HASH_FUNC(MD5)
|
||||||
|
HGL_COUNT_HASH_FUNC(SHA1)
|
||||||
|
HGL_COUNT_HASH_FUNC(SHA1LE)
|
||||||
|
HGL_COUNT_HASH_FUNC(SHA256)
|
||||||
|
HGL_COUNT_HASH_FUNC(SHA512)
|
||||||
|
|
||||||
|
#undef HGL_COUNT_HASH_FUNC
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得一个文件的hash值
|
||||||
|
* @param filename 文件名
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_code 计算后的hash存放处
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
bool GetFileHash(const OSString &filename,HASH ha,void *hash_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得一个文件的hash值
|
||||||
|
* @param filename 文件名
|
||||||
|
* @param ha hash算法
|
||||||
|
* @param hash_str 计算后的hash值存放处
|
||||||
|
* @param litter 小写字母
|
||||||
|
* @return 是否计算成功
|
||||||
|
*/
|
||||||
|
bool GetFileHash(const OSString &filename,HASH ha,UTF8String &hash_str,bool litter=true);
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
||||||
|
#endif//HGL_UTIL_HASH_INCLUDE
|
55
inc/hgl/util/hash/SHA1LE.h
Normal file
55
inc/hgl/util/hash/SHA1LE.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef HGL_ALGORITHM_HASH_SHA1LE_INCLUDE
|
||||||
|
#define HGL_ALGORITHM_HASH_SHA1LE_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* SHA1-LE Hash算法<br>
|
||||||
|
* 算法保持SHA1不变,改动如下:<br>
|
||||||
|
* 1.去掉了因BigEndian设计造成的LittleEndian处理器需要做大小头转换的部分
|
||||||
|
* 2.可自定义起始因子
|
||||||
|
* 3.可动态修改扰乱因子
|
||||||
|
*/
|
||||||
|
class SHA1LE:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 20
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 digest[5]; // Message digest
|
||||||
|
uint32 countLo; // 64-bit bit count
|
||||||
|
uint32 countHi;
|
||||||
|
uint32 data[16]; // SHA data buffer
|
||||||
|
uint32 slop; // # of bytes saved in data[]
|
||||||
|
|
||||||
|
uint32 K[4];
|
||||||
|
|
||||||
|
uint32 W[80];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void sha1_transform();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="SHA1LE";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("SHA1LE");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override {return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init(const uint32 *start_digest,const uint32 *mysterious_constants); ///<开始一次新的HASH计算,并指定初始因子和扰乱因子
|
||||||
|
void Init()override; ///<开始一次新的HASH计算,并使用缺省初始因子和扰乱因子
|
||||||
|
|
||||||
|
void SetMark(const uint32 *mysterious_constants); ///<更新扰乱因子
|
||||||
|
|
||||||
|
void Update(const void *input,uint count)override; ///<添加新的HASH数据
|
||||||
|
void Final(void *result)override; ///<结束本次HASH计算
|
||||||
|
};//class SHA1LE
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
||||||
|
#endif//HGL_ALGORITHM_HASH_SHA1LE_INCLUDE
|
@ -78,9 +78,32 @@ SET(CMD_SOURCE ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/cmd/CmdParse.h
|
|||||||
SOURCE_GROUP("Command Line" FILES ${CMD_SOURCE})
|
SOURCE_GROUP("Command Line" FILES ${CMD_SOURCE})
|
||||||
#SOURCE_GROUP("Time" FILES ${TIME_SOURCE})
|
#SOURCE_GROUP("Time" FILES ${TIME_SOURCE})
|
||||||
|
|
||||||
|
|
||||||
|
option(CM_UTIL_SUPPORT_HASH "Build HASH module" ON)
|
||||||
|
|
||||||
|
IF(CM_UTIL_SUPPORT_HASH)
|
||||||
|
SET(HASH_HEADER_FILES ${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/hash/Hash.h
|
||||||
|
${CMUTIL_ROOT_INCLUDE_PATH}/hgl/util/hash/SHA1LE.h)
|
||||||
|
|
||||||
|
SET(HASH_SOURCE_FILES hash/adler32.cpp
|
||||||
|
hash/crc32.cpp
|
||||||
|
hash/Hash.cpp
|
||||||
|
hash/md4.cpp
|
||||||
|
hash/md5.cpp
|
||||||
|
hash/sha1.cpp
|
||||||
|
hash/sha1le.cpp
|
||||||
|
hash/sha256.cpp
|
||||||
|
hash/sha512.cpp)
|
||||||
|
|
||||||
|
SOURCE_GROUP("HASH" FILES ${HASH_HEADER_FILES} ${HASH_SOURCE_FILES})
|
||||||
|
ENDIF(CM_UTIL_SUPPORT_HASH)
|
||||||
|
|
||||||
add_cm_library(CMUtil "CM" ${CMD_SOURCE}
|
add_cm_library(CMUtil "CM" ${CMD_SOURCE}
|
||||||
# ${TIME_SOURCE}
|
# ${TIME_SOURCE}
|
||||||
|
|
||||||
${XML_PARSE_SOURCE}
|
${XML_PARSE_SOURCE}
|
||||||
${JSON_TOOL_SOURCE}
|
${JSON_TOOL_SOURCE}
|
||||||
|
|
||||||
|
${HASH_HEADER_FILES}
|
||||||
|
${HASH_SOURCE_FILES}
|
||||||
)
|
)
|
||||||
|
43
src/hash/Hash.cpp
Normal file
43
src/hash/Hash.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
#include<hgl/io/FileInputStream.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
bool GetFileHash(const OSString &filename,HASH ha,void *hash_code)
|
||||||
|
{
|
||||||
|
Hash *hash=CreateHash(ha);
|
||||||
|
|
||||||
|
if(!hash)return(false);
|
||||||
|
|
||||||
|
io::FileInputStream fp;
|
||||||
|
|
||||||
|
if(fp.Open(filename)==false)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
int filesize=fp.GetSize();
|
||||||
|
int pos=0,size;
|
||||||
|
uint8 data[HGL_SIZE_1MB];
|
||||||
|
|
||||||
|
hash->Init();
|
||||||
|
|
||||||
|
while(pos<filesize)
|
||||||
|
{
|
||||||
|
size=HGL_SIZE_1MB;
|
||||||
|
if(pos+size>filesize)size=filesize-pos;
|
||||||
|
|
||||||
|
fp.Read(data,size);
|
||||||
|
|
||||||
|
hash->Update(data,size);
|
||||||
|
pos+=size;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash->Final(hash_code);
|
||||||
|
fp.Close();
|
||||||
|
delete hash;
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
150
src/hash/adler32.cpp
Normal file
150
src/hash/adler32.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||||
|
#define NMAX 5552
|
||||||
|
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||||
|
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||||
|
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||||
|
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||||
|
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||||
|
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||||
|
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||||
|
#define NO_DIVIDE //不使用除法
|
||||||
|
#ifdef NO_DIVIDE
|
||||||
|
# define MOD(a) \
|
||||||
|
do { \
|
||||||
|
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||||
|
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||||
|
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||||
|
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||||
|
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||||
|
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||||
|
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||||
|
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||||
|
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||||
|
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||||
|
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||||
|
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||||
|
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||||
|
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||||
|
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||||
|
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||||
|
if (a >= BASE) a -= BASE; \
|
||||||
|
} while (0)
|
||||||
|
# define MOD4(a) \
|
||||||
|
do { \
|
||||||
|
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||||
|
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||||
|
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||||
|
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||||
|
if (a >= BASE) a -= BASE; \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
# define MOD(a) a %= BASE
|
||||||
|
# define MOD4(a) a %= BASE
|
||||||
|
#endif
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Adler32校检码计算
|
||||||
|
* @param adler 初始码
|
||||||
|
* @param buf 待校验数据指针
|
||||||
|
* @param len 待校验数据长度
|
||||||
|
* @return 校检码
|
||||||
|
*/
|
||||||
|
uint32 CountAdler32(uint32 adler,const uint8 *buf,uint32 len)
|
||||||
|
{
|
||||||
|
uint32 sum2;
|
||||||
|
uint32 n;
|
||||||
|
/* split Adler-32 into component sums */
|
||||||
|
sum2 = (adler >> 16) & 0xffff;
|
||||||
|
adler &= 0xffff;
|
||||||
|
/* in case user likes doing a byte at a time, keep it fast */
|
||||||
|
if (len == 1) {
|
||||||
|
adler += buf[0];
|
||||||
|
if (adler >= BASE)
|
||||||
|
adler -= BASE;
|
||||||
|
sum2 += adler;
|
||||||
|
if (sum2 >= BASE)
|
||||||
|
sum2 -= BASE;
|
||||||
|
return adler | (sum2 << 16);
|
||||||
|
}
|
||||||
|
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||||
|
if (buf == 0)
|
||||||
|
return 1L;
|
||||||
|
/* in case short lengths are provided, keep it somewhat fast */
|
||||||
|
if (len < 16) {
|
||||||
|
while (len--) {
|
||||||
|
adler += *buf++;
|
||||||
|
sum2 += adler;
|
||||||
|
}
|
||||||
|
if (adler >= BASE)
|
||||||
|
adler -= BASE;
|
||||||
|
MOD4(sum2); /* only added so many BASE's */
|
||||||
|
return adler | (sum2 << 16);
|
||||||
|
}
|
||||||
|
/* do length NMAX blocks -- requires just one modulo operation */
|
||||||
|
while (len >= NMAX) {
|
||||||
|
len -= NMAX;
|
||||||
|
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||||
|
do {
|
||||||
|
DO16(buf); /* 16 sums unrolled */
|
||||||
|
buf += 16;
|
||||||
|
} while (--n);
|
||||||
|
MOD(adler);
|
||||||
|
MOD(sum2);
|
||||||
|
}
|
||||||
|
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||||
|
if (len) { /* avoid modulos if none remaining */
|
||||||
|
while (len >= 16) {
|
||||||
|
len -= 16;
|
||||||
|
DO16(buf);
|
||||||
|
buf += 16;
|
||||||
|
}
|
||||||
|
while (len--) {
|
||||||
|
adler += *buf++;
|
||||||
|
sum2 += adler;
|
||||||
|
}
|
||||||
|
MOD(adler);
|
||||||
|
MOD(sum2);
|
||||||
|
}
|
||||||
|
/* return recombined sums */
|
||||||
|
return adler | (sum2 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Adler32:public Hash
|
||||||
|
{
|
||||||
|
uint32 result;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str=U8_TEXT("Adler32");}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("Adler32");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return 4;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
result=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint inputLen)override
|
||||||
|
{
|
||||||
|
result=CountAdler32(result,(const uint8 *)input,inputLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *digest)override
|
||||||
|
{
|
||||||
|
*(uint32 *)digest=result;
|
||||||
|
}
|
||||||
|
};//class Adler32
|
||||||
|
|
||||||
|
Hash *CreateAdler32Hash(){return(new Adler32);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
98
src/hash/crc32.cpp
Normal file
98
src/hash/crc32.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const uint32 crc32_tab[] = {
|
||||||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||||
|
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||||
|
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||||
|
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||||
|
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||||
|
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||||
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||||
|
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||||
|
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||||
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||||
|
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||||
|
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||||
|
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||||
|
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||||
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||||
|
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||||
|
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||||
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||||
|
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||||
|
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||||
|
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||||
|
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||||
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||||
|
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||||
|
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||||
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||||
|
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||||
|
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
|
};
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
uint32 CountCRC32(uint32 crc, const uint8 *buf, uint32 size)
|
||||||
|
{
|
||||||
|
const uint8 *p;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
crc = crc ^ ~0U;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||||
|
|
||||||
|
return crc ^ ~0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CRC32:public Hash
|
||||||
|
{
|
||||||
|
uint32 result;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str=U8_TEXT("CRC32");}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("CRC32");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return 4;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
result=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint inputLen)override
|
||||||
|
{
|
||||||
|
result=CountCRC32(result,(const uint8 *)input,inputLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *digest)override
|
||||||
|
{
|
||||||
|
*(uint32 *)digest=result;
|
||||||
|
}
|
||||||
|
};//class CRC32
|
||||||
|
|
||||||
|
Hash *CreateCRC32Hash(){return(new CRC32);}
|
||||||
|
}//namespace util
|
||||||
|
}//namepace hgl
|
227
src/hash/md4.cpp
Normal file
227
src/hash/md4.cpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
#include<hgl/type/DataType.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/* Constants for MD4Transform routine. */
|
||||||
|
#define S11 3
|
||||||
|
#define S12 7
|
||||||
|
#define S13 11
|
||||||
|
#define S14 19
|
||||||
|
#define S21 3
|
||||||
|
#define S22 5
|
||||||
|
#define S23 9
|
||||||
|
#define S24 13
|
||||||
|
#define S31 3
|
||||||
|
#define S32 9
|
||||||
|
#define S33 11
|
||||||
|
#define S34 15
|
||||||
|
|
||||||
|
/* F, G and H are basic MD4 functions. */
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
|
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
|
||||||
|
/* ROTATE_LEFT rotates x left n bits. */
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||||
|
/* Rotation is separate from addition to prevent recomputation */
|
||||||
|
#define FF(a, b, c, d, x, s) { \
|
||||||
|
(a) += F ((b), (c), (d)) + (x); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, x, s) { \
|
||||||
|
(a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, x, s) { \
|
||||||
|
(a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void md4_encode(unsigned char* output, const uint32* input, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
{
|
||||||
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
|
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void md4_decode(uint32* output, const unsigned char* input, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
output[i] = ((uint32)input[j]) | (((uint32)input[j+1]) << 8) |
|
||||||
|
(((uint32)input[j+2]) << 16) | (((uint32)input[j+3]) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
void md4_transform (uint32 state[4], const unsigned char block[64])
|
||||||
|
{
|
||||||
|
uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
|
md4_decode(x, block, 64);
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||||
|
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||||
|
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||||
|
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||||
|
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||||
|
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||||
|
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||||
|
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||||
|
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||||
|
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||||
|
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||||
|
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||||
|
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||||
|
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||||
|
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||||
|
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||||
|
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||||
|
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||||
|
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||||
|
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||||
|
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||||
|
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||||
|
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||||
|
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||||
|
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||||
|
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||||
|
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||||
|
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||||
|
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||||
|
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||||
|
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||||
|
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||||
|
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||||
|
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||||
|
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||||
|
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||||
|
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||||
|
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||||
|
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||||
|
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||||
|
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||||
|
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||||
|
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||||
|
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||||
|
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||||
|
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||||
|
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
memset(x, 0, sizeof(x));
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
class MD4:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 state[4]; // state (ABCD)
|
||||||
|
uint32 count[2]; // number of bits, modulo 2^64 (lsb first)
|
||||||
|
uchar buffer[64]; // input buffer
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="MD4";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("MD4");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
count[0] = count[1] = 0;
|
||||||
|
state[0] = 0x67452301;
|
||||||
|
state[1] = 0xefcdab89;
|
||||||
|
state[2] = 0x98badcfe;
|
||||||
|
state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint inputLen)override
|
||||||
|
{
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
index = (unsigned int)((count[0] >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Update number of bits */
|
||||||
|
if ((count[0] += ((uint32) inputLen << 3)) < ((uint32) inputLen << 3))
|
||||||
|
count[1]++;
|
||||||
|
count[1] += ((uint32) inputLen >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
/* Transform as many times as possible. */
|
||||||
|
if (inputLen >= partLen)
|
||||||
|
{
|
||||||
|
memcpy(&buffer[index], input, partLen);
|
||||||
|
md4_transform(state, buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||||
|
md4_transform(state, ((uchar *)input)+i);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
memcpy(&buffer[index], ((uchar *)input)+i, inputLen-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *digest)override
|
||||||
|
{
|
||||||
|
static const unsigned char PADDING[64] =
|
||||||
|
{
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
unsigned char bits[8];
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
/* Save number of bits */
|
||||||
|
md4_encode(bits, count, 8);
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64. */
|
||||||
|
index = (unsigned int)((count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
Update(PADDING, padLen);
|
||||||
|
|
||||||
|
/* Append length (before padding) */
|
||||||
|
Update(bits, 8);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
md4_encode((uchar *)digest, state, 16);
|
||||||
|
}
|
||||||
|
};//class MD4
|
||||||
|
|
||||||
|
Hash *CreateMD4Hash(){return(new MD4);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
258
src/hash/md5.cpp
Normal file
258
src/hash/md5.cpp
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/* Constants for MD5Transform routine. */
|
||||||
|
#define S11 7
|
||||||
|
#define S12 12
|
||||||
|
#define S13 17
|
||||||
|
#define S14 22
|
||||||
|
#define S21 5
|
||||||
|
#define S22 9
|
||||||
|
#define S23 14
|
||||||
|
#define S24 20
|
||||||
|
#define S31 4
|
||||||
|
#define S32 11
|
||||||
|
#define S33 16
|
||||||
|
#define S34 23
|
||||||
|
#define S41 6
|
||||||
|
#define S42 10
|
||||||
|
#define S43 15
|
||||||
|
#define S44 21
|
||||||
|
|
||||||
|
/* F, G, H and I are basic MD5 functions. */
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||||
|
|
||||||
|
/* ROTATE_LEFT rotates x left n bits. */
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
|
||||||
|
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||||
|
Rotation is separate from addition to prevent recomputation. */
|
||||||
|
#define FF(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += F ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += G ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += H ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define II(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += I ((b), (c), (d)) + (x) + (uint32)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void md5_encode(unsigned char* output, const uint32* input, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
{
|
||||||
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
|
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void md5_decode(uint32* output, const unsigned char* input, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
output[i] = ((uint32)input[j]) | (((uint32)input[j+1]) << 8) |
|
||||||
|
(((uint32)input[j+2]) << 16) | (((uint32)input[j+3]) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
void md5_transform (uint32 state[4], const unsigned char block[64])
|
||||||
|
{
|
||||||
|
uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
|
md5_decode(x, block, 64);
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||||
|
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||||
|
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||||
|
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||||
|
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||||
|
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||||
|
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||||
|
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||||
|
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||||
|
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||||
|
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||||
|
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||||
|
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||||
|
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||||
|
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||||
|
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||||
|
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||||
|
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||||
|
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||||
|
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||||
|
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||||
|
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||||
|
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||||
|
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||||
|
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||||
|
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||||
|
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||||
|
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||||
|
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||||
|
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||||
|
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||||
|
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||||
|
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||||
|
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||||
|
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||||
|
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||||
|
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||||
|
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||||
|
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||||
|
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||||
|
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||||
|
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||||
|
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||||
|
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||||
|
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||||
|
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||||
|
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||||
|
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||||
|
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||||
|
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||||
|
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||||
|
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||||
|
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||||
|
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||||
|
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||||
|
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||||
|
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||||
|
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||||
|
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||||
|
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||||
|
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||||
|
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
memset(x, 0, sizeof(x));
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
class MD5:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 state[4];
|
||||||
|
uint32 count[2];
|
||||||
|
uchar buffer[64];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="MD5";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("MD5");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
count[0] = count[1] = 0;
|
||||||
|
state[0] = 0x67452301;
|
||||||
|
state[1] = 0xefcdab89;
|
||||||
|
state[2] = 0x98badcfe;
|
||||||
|
state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint inputLen)override
|
||||||
|
{
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
index = (unsigned int)((count[0] >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Update number of bits */
|
||||||
|
if ((count[0] += ((uint32) inputLen << 3)) < ((uint32) inputLen << 3))
|
||||||
|
count[1]++;
|
||||||
|
count[1] += ((uint32) inputLen >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
/* Transform as many times as possible. */
|
||||||
|
if (inputLen >= partLen)
|
||||||
|
{
|
||||||
|
memcpy(&buffer[index], input, partLen);
|
||||||
|
md5_transform(state, buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||||
|
md5_transform(state, ((uchar *)input)+i);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
memcpy(&buffer[index], ((uchar *)input)+i,inputLen-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *digest)override
|
||||||
|
{
|
||||||
|
static const unsigned char PADDING[64] =
|
||||||
|
{
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
unsigned char bits[8];
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
/* Save number of bits */
|
||||||
|
md5_encode(bits, count, 8);
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64. */
|
||||||
|
index = (unsigned int)((count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
Update(PADDING, padLen);
|
||||||
|
|
||||||
|
/* Append length (before padding) */
|
||||||
|
Update(bits, 8);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
md5_encode((uchar *)digest, state, 16);
|
||||||
|
}
|
||||||
|
};//class MD5
|
||||||
|
|
||||||
|
Hash *CreateMD5Hash(){return(new MD5);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
250
src/hash/sha1.cpp
Normal file
250
src/hash/sha1.cpp
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
#include<hgl/Endian.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/* The SHA f()-functions */
|
||||||
|
#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */
|
||||||
|
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
|
||||||
|
#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */
|
||||||
|
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
|
||||||
|
|
||||||
|
/* The SHA Mysterious Constants */
|
||||||
|
#define K1 0x5A827999L /* Rounds 0-19 */
|
||||||
|
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
|
||||||
|
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
|
||||||
|
#define K4 0xCA62C1D6L /* Rounds 60-79 */
|
||||||
|
|
||||||
|
#define S(n,X) ( ( ((uint32)X) << n ) | ( ((uint32)X) >> ( 32 - n ) ) )
|
||||||
|
|
||||||
|
/* The initial expanding function */
|
||||||
|
#define expand(count) W[ count ] = S(1,(W[ count - 3 ] ^ W[ count - 8 ] ^ W[ count - 14 ] ^ W[ count - 16 ])) /* to make this SHA-1 */
|
||||||
|
|
||||||
|
/* The four SHA sub-rounds */
|
||||||
|
#define subRound1(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound2(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound3(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound4(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
class SHA1:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 20
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 digest[5]; // Message digest
|
||||||
|
uint32 countLo; // 64-bit bit count
|
||||||
|
uint32 countHi;
|
||||||
|
uint32 data[16]; // SHA data buffer
|
||||||
|
uint32 slop; // # of bytes saved in data[]
|
||||||
|
|
||||||
|
uint32 W[80];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void sha1_transform()
|
||||||
|
{
|
||||||
|
uint32 temp;
|
||||||
|
uint32 A, B, C, D, E;
|
||||||
|
|
||||||
|
/* Step A. Copy the data buffer into the local work buffer */
|
||||||
|
hgl_cpy(W,data,16);
|
||||||
|
|
||||||
|
/* Step B. Expand the 16 words into 64 temporary data words */
|
||||||
|
expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
|
||||||
|
expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 );
|
||||||
|
expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 );
|
||||||
|
expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 );
|
||||||
|
expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 );
|
||||||
|
expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 );
|
||||||
|
expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 );
|
||||||
|
expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 );
|
||||||
|
expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 );
|
||||||
|
expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 );
|
||||||
|
expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 );
|
||||||
|
expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 );
|
||||||
|
expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 );
|
||||||
|
|
||||||
|
/* Step C. Set up first buffer */
|
||||||
|
A = digest[ 0 ];
|
||||||
|
B = digest[ 1 ];
|
||||||
|
C = digest[ 2 ];
|
||||||
|
D = digest[ 3 ];
|
||||||
|
E = digest[ 4 ];
|
||||||
|
|
||||||
|
/* Step D. Serious mangling, divided into four sub-rounds */
|
||||||
|
subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 );
|
||||||
|
subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 );
|
||||||
|
subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 );
|
||||||
|
subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 );
|
||||||
|
subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 );
|
||||||
|
|
||||||
|
subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 );
|
||||||
|
subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 );
|
||||||
|
subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 );
|
||||||
|
subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 );
|
||||||
|
subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 );
|
||||||
|
|
||||||
|
subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 );
|
||||||
|
subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 );
|
||||||
|
subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 );
|
||||||
|
subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 );
|
||||||
|
subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 );
|
||||||
|
|
||||||
|
subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 );
|
||||||
|
subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 );
|
||||||
|
subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 );
|
||||||
|
subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 );
|
||||||
|
subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 );
|
||||||
|
|
||||||
|
/* Step E. Build message digest */
|
||||||
|
digest[ 0 ] += A;
|
||||||
|
digest[ 1 ] += B;
|
||||||
|
digest[ 2 ] += C;
|
||||||
|
digest[ 3 ] += D;
|
||||||
|
digest[ 4 ] += E;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="SHA1";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("SHA1");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
digest[0] = 0x67452301L;
|
||||||
|
digest[1] = 0xEFCDAB89L;
|
||||||
|
digest[2] = 0x98BADCFEL;
|
||||||
|
digest[3] = 0x10325476L;
|
||||||
|
digest[4] = 0xC3D2E1F0L;
|
||||||
|
countLo = 0;
|
||||||
|
countHi = 0;
|
||||||
|
slop = 0;
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint count)override
|
||||||
|
{
|
||||||
|
const uint8 *buffer=(const uint8 *)input;
|
||||||
|
uint size;
|
||||||
|
|
||||||
|
/* Update bitcount */
|
||||||
|
if ((countLo + ((uint32) count << 3)) < countLo)
|
||||||
|
countHi++; /* Carry from low to high bitCount */
|
||||||
|
countLo += ((uint32) count << 3);
|
||||||
|
countHi += ((uint32 ) count >> 29);
|
||||||
|
|
||||||
|
/* Process data in BLOCK_SIZE chunks */
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
size=BLOCK_SIZE-slop;
|
||||||
|
if(size>count)
|
||||||
|
size=count;
|
||||||
|
|
||||||
|
memcpy(data,buffer,size);
|
||||||
|
|
||||||
|
slop+=size;
|
||||||
|
buffer+=size;
|
||||||
|
count-=size;
|
||||||
|
|
||||||
|
if (slop == BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
/* transform this one block */
|
||||||
|
ToBigEndian<uint32>(data, BLOCK_SIZE>>2);
|
||||||
|
sha1_transform();
|
||||||
|
slop = 0 ; /* no slop left */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *result)override
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
uint32 lowBitcount = countLo;
|
||||||
|
uint32 highBitcount = countHi;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
count = (int) ((countLo >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Set the first char of padding to 0x80. This is safe since there is
|
||||||
|
always at least one byte free */
|
||||||
|
((uint8*) data)[count++] = 0x80;
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64 */
|
||||||
|
if (count > 56)
|
||||||
|
{
|
||||||
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
|
memset((uint8*) &data + count, 0, 64 - count);
|
||||||
|
ToBigEndian<uint32>(data, BLOCK_SIZE>>2);
|
||||||
|
sha1_transform();
|
||||||
|
|
||||||
|
/* Now fill the next block with 56 bytes */
|
||||||
|
memset(&data, 0, 56);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pad block to 56 bytes */
|
||||||
|
memset((uint8*) &data + count, 0, 56 - count);
|
||||||
|
}
|
||||||
|
ToBigEndian<uint32>(data, BLOCK_SIZE>>2);
|
||||||
|
|
||||||
|
/* Append length in bits and transform */
|
||||||
|
data[14] = highBitcount;
|
||||||
|
data[15] = lowBitcount;
|
||||||
|
|
||||||
|
sha1_transform();
|
||||||
|
ToBigEndian<uint32>(data, BLOCK_SIZE>>2);
|
||||||
|
|
||||||
|
uint8 *hash=(uint8 *)result;
|
||||||
|
for (count = 0; count < DIGEST_SIZE; count++)
|
||||||
|
hash[count] = (uint8) ((digest[count>>2]) >> (8*(3-(count & 0x3)))) & 0xff;
|
||||||
|
}
|
||||||
|
};//class SHA1
|
||||||
|
|
||||||
|
Hash *CreateSHA1Hash(){return(new SHA1);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
227
src/hash/sha1le.cpp
Normal file
227
src/hash/sha1le.cpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#include<hgl/util/hash/SHA1LE.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/* The SHA f()-functions */
|
||||||
|
#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */
|
||||||
|
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
|
||||||
|
#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */
|
||||||
|
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
|
||||||
|
|
||||||
|
#define S(n,X) ( ( ((uint32)X) << n ) | ( ((uint32)X) >> ( 32 - n ) ) )
|
||||||
|
|
||||||
|
/* The initial expanding function */
|
||||||
|
#define expand(count) W[ count ] = S(1,(W[ count - 3 ] ^ W[ count - 8 ] ^ W[ count - 14 ] ^ W[ count - 16 ])) /* to make this SHA-1 */
|
||||||
|
|
||||||
|
/* The four SHA sub-rounds */
|
||||||
|
#define subRound1(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K[0]; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound2(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K[1]; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound3(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K[2]; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define subRound4(count) \
|
||||||
|
{ \
|
||||||
|
temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K[3]; \
|
||||||
|
E = D; \
|
||||||
|
D = C; \
|
||||||
|
C = S( 30, B ); \
|
||||||
|
B = A; \
|
||||||
|
A = temp; \
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
void SHA1LE::sha1_transform()
|
||||||
|
{
|
||||||
|
uint32 temp;
|
||||||
|
uint32 A, B, C, D, E;
|
||||||
|
|
||||||
|
/* Step A. Copy the data buffer into the local work buffer */
|
||||||
|
hgl_cpy(W,data,16);
|
||||||
|
|
||||||
|
/* Step B. Expand the 16 words into 64 temporary data words */
|
||||||
|
expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
|
||||||
|
expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 );
|
||||||
|
expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 );
|
||||||
|
expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 );
|
||||||
|
expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 );
|
||||||
|
expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 );
|
||||||
|
expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 );
|
||||||
|
expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 );
|
||||||
|
expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 );
|
||||||
|
expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 );
|
||||||
|
expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 );
|
||||||
|
expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 );
|
||||||
|
expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 );
|
||||||
|
|
||||||
|
/* Step C. Set up first buffer */
|
||||||
|
A = digest[ 0 ];
|
||||||
|
B = digest[ 1 ];
|
||||||
|
C = digest[ 2 ];
|
||||||
|
D = digest[ 3 ];
|
||||||
|
E = digest[ 4 ];
|
||||||
|
|
||||||
|
/* Step D. Serious mangling, divided into four sub-rounds */
|
||||||
|
subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 );
|
||||||
|
subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 );
|
||||||
|
subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 );
|
||||||
|
subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 );
|
||||||
|
subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 );
|
||||||
|
|
||||||
|
subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 );
|
||||||
|
subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 );
|
||||||
|
subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 );
|
||||||
|
subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 );
|
||||||
|
subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 );
|
||||||
|
|
||||||
|
subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 );
|
||||||
|
subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 );
|
||||||
|
subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 );
|
||||||
|
subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 );
|
||||||
|
subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 );
|
||||||
|
|
||||||
|
subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 );
|
||||||
|
subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 );
|
||||||
|
subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 );
|
||||||
|
subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 );
|
||||||
|
subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 );
|
||||||
|
|
||||||
|
/* Step E. Build message digest */
|
||||||
|
digest[ 0 ] += A;
|
||||||
|
digest[ 1 ] += B;
|
||||||
|
digest[ 2 ] += C;
|
||||||
|
digest[ 3 ] += D;
|
||||||
|
digest[ 4 ] += E;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA1LE::SetMark(const uint32 *mysterious_constants)
|
||||||
|
{
|
||||||
|
hgl_cpy(K,mysterious_constants,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA1LE::Init(const uint32 *_start_digest,const uint32 *mysterious_constants)
|
||||||
|
{
|
||||||
|
hgl_cpy(digest,_start_digest,5);
|
||||||
|
|
||||||
|
SetMark(mysterious_constants);
|
||||||
|
|
||||||
|
countLo = 0;
|
||||||
|
countHi = 0;
|
||||||
|
slop = 0;
|
||||||
|
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA1LE::Init()
|
||||||
|
{
|
||||||
|
constexpr uint32 d[5]={0x01234567L,0x89ABCDEFL,0xFEDCBA98L,0x76543210L,0x0F1E2D3CL};
|
||||||
|
constexpr uint32 k[4]={0x5A827999L,0x6ED9EBA1L,0x8F1BBCDCL,0xCA62C1D6L};
|
||||||
|
|
||||||
|
Init(d,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA1LE::Update(const void *input,uint count)
|
||||||
|
{
|
||||||
|
const uint8 *buffer=(const uint8 *)input;
|
||||||
|
uint size;
|
||||||
|
|
||||||
|
/* Update bitcount */
|
||||||
|
if ((countLo + ((uint32) count << 3)) < countLo)
|
||||||
|
countHi++; /* Carry from low to high bitCount */
|
||||||
|
|
||||||
|
countLo += ((uint32) count << 3);
|
||||||
|
countHi += ((uint32 ) count >> 29);
|
||||||
|
|
||||||
|
/* Process data in BLOCK_SIZE chunks */
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
size=BLOCK_SIZE-slop;
|
||||||
|
if(size>count)
|
||||||
|
size=count;
|
||||||
|
|
||||||
|
memcpy(data,buffer,size);
|
||||||
|
|
||||||
|
slop+=size;
|
||||||
|
buffer+=size;
|
||||||
|
count-=size;
|
||||||
|
|
||||||
|
if (slop == BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
/* transform this one block */
|
||||||
|
sha1_transform();
|
||||||
|
slop = 0 ; /* no slop left */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA1LE::Final(void *result)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
uint32 lowBitcount = countLo;
|
||||||
|
uint32 highBitcount = countHi;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
count = (int) ((countLo >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Set the first char of padding to 0x80. This is safe since there is
|
||||||
|
always at least one byte free */
|
||||||
|
((uint8*) data)[count++] = 0x80;
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64 */
|
||||||
|
if (count > 56)
|
||||||
|
{
|
||||||
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
|
memset((uint8*) &data + count, 0, 64 - count);
|
||||||
|
sha1_transform();
|
||||||
|
|
||||||
|
/* Now fill the next block with 56 bytes */
|
||||||
|
memset(&data, 0, 56);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pad block to 56 bytes */
|
||||||
|
memset((uint8*) &data + count, 0, 56 - count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append length in bits and transform */
|
||||||
|
data[14] = highBitcount;
|
||||||
|
data[15] = lowBitcount;
|
||||||
|
|
||||||
|
sha1_transform();
|
||||||
|
|
||||||
|
uint8 *hash=(uint8 *)result;
|
||||||
|
for (count = 0; count < DIGEST_SIZE; count++)
|
||||||
|
hash[count] = (uint8) ((digest[count>>2]) >> (8*(3-(count & 0x3)))) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hash *CreateSHA1LEHash(){return(new SHA1LE);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
198
src/hash/sha256.cpp
Normal file
198
src/hash/sha256.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||||
|
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||||
|
|
||||||
|
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||||
|
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||||
|
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||||
|
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||||
|
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||||
|
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||||
|
|
||||||
|
/**************************** VARIABLES *****************************/
|
||||||
|
constexpr uint32 k[64] =
|
||||||
|
{
|
||||||
|
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||||
|
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||||
|
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||||
|
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||||
|
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||||
|
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||||
|
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||||
|
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||||
|
};
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
class SHA256:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 state[8];
|
||||||
|
uint8 data[64]; // SHA data buffer
|
||||||
|
uint64 bitlen;
|
||||||
|
uint32 datalen;
|
||||||
|
|
||||||
|
uint32 m[64];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void sha256_transform()
|
||||||
|
{
|
||||||
|
uint32 a, b, c, d, e, f, g, h, i, j, t1, t2;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||||
|
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||||
|
|
||||||
|
for ( ; i < 64; ++i)
|
||||||
|
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||||
|
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
e = state[4];
|
||||||
|
f = state[5];
|
||||||
|
g = state[6];
|
||||||
|
h = state[7];
|
||||||
|
|
||||||
|
for (i = 0; i < 64; ++i) {
|
||||||
|
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||||
|
t2 = EP0(a) + MAJ(a,b,c);
|
||||||
|
h = g;
|
||||||
|
g = f;
|
||||||
|
f = e;
|
||||||
|
e = d + t1;
|
||||||
|
d = c;
|
||||||
|
c = b;
|
||||||
|
b = a;
|
||||||
|
a = t1 + t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
state[4] += e;
|
||||||
|
state[5] += f;
|
||||||
|
state[6] += g;
|
||||||
|
state[7] += h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="SHA256";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("SHA256");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
state[0] = 0x6a09e667;
|
||||||
|
state[1] = 0xbb67ae85;
|
||||||
|
state[2] = 0x3c6ef372;
|
||||||
|
state[3] = 0xa54ff53a;
|
||||||
|
state[4] = 0x510e527f;
|
||||||
|
state[5] = 0x9b05688c;
|
||||||
|
state[6] = 0x1f83d9ab;
|
||||||
|
state[7] = 0x5be0cd19;
|
||||||
|
|
||||||
|
bitlen=0;
|
||||||
|
datalen=0;
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint count)override
|
||||||
|
{
|
||||||
|
const uint8 *u8input=(const uint8 *)input;
|
||||||
|
uint32 size;
|
||||||
|
|
||||||
|
while(count>0)
|
||||||
|
{
|
||||||
|
size=BLOCK_SIZE-datalen;
|
||||||
|
|
||||||
|
if(size>count)
|
||||||
|
size=count;
|
||||||
|
|
||||||
|
memcpy(data+datalen,u8input,size);
|
||||||
|
datalen+=size;
|
||||||
|
count-=size;
|
||||||
|
u8input+=size;
|
||||||
|
|
||||||
|
if (datalen == BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
sha256_transform();
|
||||||
|
bitlen += 512;
|
||||||
|
datalen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *result)override
|
||||||
|
{
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
i = datalen;
|
||||||
|
|
||||||
|
// Pad whatever data is left in the buffer.
|
||||||
|
if (datalen < 56)
|
||||||
|
{
|
||||||
|
data[i++] = 0x80;
|
||||||
|
|
||||||
|
memset(data+i,0,56-i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data[i++] = 0x80;
|
||||||
|
|
||||||
|
memset(data+i,0,64-i);
|
||||||
|
|
||||||
|
sha256_transform();
|
||||||
|
memset(data, 0, 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append to the padding the total message's length in bits and transform.
|
||||||
|
bitlen += datalen * 8;
|
||||||
|
data[63] = bitlen;
|
||||||
|
data[62] = bitlen >> 8;
|
||||||
|
data[61] = bitlen >> 16;
|
||||||
|
data[60] = bitlen >> 24;
|
||||||
|
data[59] = bitlen >> 32;
|
||||||
|
data[58] = bitlen >> 40;
|
||||||
|
data[57] = bitlen >> 48;
|
||||||
|
data[56] = bitlen >> 56;
|
||||||
|
sha256_transform();
|
||||||
|
|
||||||
|
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||||
|
// reverse all the bytes when copying the final state to the output hash.
|
||||||
|
|
||||||
|
uint8 *hash=(uint8 *)result;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
hash[i] = (state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 4] = (state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 8] = (state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 12] = (state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 16] = (state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 20] = (state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 24] = (state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
hash[i + 28] = (state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};//class SHA256
|
||||||
|
|
||||||
|
Hash *CreateSHA256Hash(){return(new SHA256);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
||||||
|
|
244
src/hash/sha512.cpp
Normal file
244
src/hash/sha512.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
#include<hgl/util/hash/Hash.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
#define SHA2_SHFR(x, n) (x >> n)
|
||||||
|
#define SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
|
||||||
|
#define SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
|
||||||
|
#define SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
|
||||||
|
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
|
||||||
|
#define SHA512_F1(x) (SHA2_ROTR(x, 28) ^ SHA2_ROTR(x, 34) ^ SHA2_ROTR(x, 39))
|
||||||
|
#define SHA512_F2(x) (SHA2_ROTR(x, 14) ^ SHA2_ROTR(x, 18) ^ SHA2_ROTR(x, 41))
|
||||||
|
#define SHA512_F3(x) (SHA2_ROTR(x, 1) ^ SHA2_ROTR(x, 8) ^ SHA2_SHFR(x, 7))
|
||||||
|
#define SHA512_F4(x) (SHA2_ROTR(x, 19) ^ SHA2_ROTR(x, 61) ^ SHA2_SHFR(x, 6))
|
||||||
|
|
||||||
|
#define SHA2_UNPACK32(x, str) \
|
||||||
|
{ \
|
||||||
|
*((str) + 3) = (uint8) ((x) ); \
|
||||||
|
*((str) + 2) = (uint8) ((x) >> 8); \
|
||||||
|
*((str) + 1) = (uint8) ((x) >> 16); \
|
||||||
|
*((str) + 0) = (uint8) ((x) >> 24); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHA2_UNPACK64(x, str) \
|
||||||
|
{ \
|
||||||
|
*((str) + 7) = (uint8) ((x) ); \
|
||||||
|
*((str) + 6) = (uint8) ((x) >> 8); \
|
||||||
|
*((str) + 5) = (uint8) ((x) >> 16); \
|
||||||
|
*((str) + 4) = (uint8) ((x) >> 24); \
|
||||||
|
*((str) + 3) = (uint8) ((x) >> 32); \
|
||||||
|
*((str) + 2) = (uint8) ((x) >> 40); \
|
||||||
|
*((str) + 1) = (uint8) ((x) >> 48); \
|
||||||
|
*((str) + 0) = (uint8) ((x) >> 56); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHA2_PACK64(str, x) \
|
||||||
|
{ \
|
||||||
|
*(x) = ((uint64) *((str) + 7) ) \
|
||||||
|
| ((uint64) *((str) + 6) << 8) \
|
||||||
|
| ((uint64) *((str) + 5) << 16) \
|
||||||
|
| ((uint64) *((str) + 4) << 24) \
|
||||||
|
| ((uint64) *((str) + 3) << 32) \
|
||||||
|
| ((uint64) *((str) + 2) << 40) \
|
||||||
|
| ((uint64) *((str) + 1) << 48) \
|
||||||
|
| ((uint64) *((str) + 0) << 56); \
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint SHA384_512_BLOCK_SIZE = (1024/8);
|
||||||
|
|
||||||
|
constexpr uint64 K[80] =
|
||||||
|
{
|
||||||
|
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||||
|
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||||
|
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||||
|
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||||
|
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||||
|
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||||
|
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||||
|
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||||
|
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||||
|
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||||
|
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||||
|
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||||
|
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||||
|
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||||
|
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||||
|
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||||
|
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||||
|
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||||
|
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||||
|
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||||
|
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||||
|
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||||
|
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||||
|
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||||
|
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||||
|
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||||
|
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||||
|
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||||
|
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||||
|
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||||
|
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||||
|
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||||
|
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||||
|
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||||
|
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||||
|
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||||
|
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||||
|
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||||
|
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||||
|
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||||
|
};
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
class SHA512:public Hash
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK_SIZE = 64,
|
||||||
|
DIGEST_SIZE = 64
|
||||||
|
};
|
||||||
|
|
||||||
|
uint m_tot_len;
|
||||||
|
uint m_len;
|
||||||
|
uint8 m_block[2 * SHA384_512_BLOCK_SIZE];
|
||||||
|
uint64 m_h[8];
|
||||||
|
|
||||||
|
uint64 w[80];
|
||||||
|
uint64 wv[8];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void transform(const unsigned char *message, unsigned int block_nb)
|
||||||
|
{
|
||||||
|
uint64 t1, t2;
|
||||||
|
const unsigned char *sub_block;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < (int) block_nb; i++)
|
||||||
|
{
|
||||||
|
sub_block = message + (i << 7);
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
SHA2_PACK64(&sub_block[j << 3], &w[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 16; j < 80; j++)
|
||||||
|
{
|
||||||
|
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
wv[j] = m_h[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 80; j++)
|
||||||
|
{
|
||||||
|
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6]) + K[j] + w[j];
|
||||||
|
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||||
|
|
||||||
|
wv[7] = wv[6];
|
||||||
|
wv[6] = wv[5];
|
||||||
|
wv[5] = wv[4];
|
||||||
|
wv[4] = wv[3] + t1;
|
||||||
|
wv[3] = wv[2];
|
||||||
|
wv[2] = wv[1];
|
||||||
|
wv[1] = wv[0];
|
||||||
|
wv[0] = t1 + t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
m_h[j] += wv[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void GetName(UTF8String &str)const override{str="SHA512";}
|
||||||
|
void GetName(UTF16String &str)const override{str=U16_TEXT("SHA512");}
|
||||||
|
|
||||||
|
const int GetHashBytes()const override{return DIGEST_SIZE;}
|
||||||
|
|
||||||
|
void Init()override
|
||||||
|
{
|
||||||
|
m_h[0] = 0x6a09e667f3bcc908ULL;
|
||||||
|
m_h[1] = 0xbb67ae8584caa73bULL;
|
||||||
|
m_h[2] = 0x3c6ef372fe94f82bULL;
|
||||||
|
m_h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||||
|
m_h[4] = 0x510e527fade682d1ULL;
|
||||||
|
m_h[5] = 0x9b05688c2b3e6c1fULL;
|
||||||
|
m_h[6] = 0x1f83d9abfb41bd6bULL;
|
||||||
|
m_h[7] = 0x5be0cd19137e2179ULL;
|
||||||
|
m_len = 0;
|
||||||
|
m_tot_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(const void *input,uint len)override
|
||||||
|
{
|
||||||
|
uint8 *message=(uint8 *)input;
|
||||||
|
|
||||||
|
uint block_nb;
|
||||||
|
uint new_len, rem_len, tmp_len;
|
||||||
|
const uint8 *shifted_message;
|
||||||
|
|
||||||
|
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
|
||||||
|
rem_len = len < tmp_len ? len : tmp_len;
|
||||||
|
|
||||||
|
memcpy(&m_block[m_len], message, rem_len);
|
||||||
|
|
||||||
|
if (m_len + len < SHA384_512_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
m_len += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_len = len - rem_len;
|
||||||
|
block_nb = new_len / SHA384_512_BLOCK_SIZE;
|
||||||
|
shifted_message = message + rem_len;
|
||||||
|
transform(m_block, 1);
|
||||||
|
transform(shifted_message, block_nb);
|
||||||
|
rem_len = new_len % SHA384_512_BLOCK_SIZE;
|
||||||
|
|
||||||
|
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
|
||||||
|
|
||||||
|
m_len = rem_len;
|
||||||
|
m_tot_len += (block_nb + 1) << 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Final(void *result)override
|
||||||
|
{
|
||||||
|
uint block_nb;
|
||||||
|
uint pm_len;
|
||||||
|
uint len_b;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
|
||||||
|
< (m_len % SHA384_512_BLOCK_SIZE));
|
||||||
|
|
||||||
|
len_b = (m_tot_len + m_len) << 3;
|
||||||
|
pm_len = block_nb << 7;
|
||||||
|
memset(m_block + m_len, 0, pm_len - m_len);
|
||||||
|
m_block[m_len] = 0x80;
|
||||||
|
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
|
||||||
|
transform(m_block, block_nb);
|
||||||
|
|
||||||
|
uint8 *digest=(uint8 *)result;
|
||||||
|
|
||||||
|
for (i = 0 ; i < 8; i++) {
|
||||||
|
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};//class SHA512
|
||||||
|
|
||||||
|
Hash *CreateSHA512Hash(){return(new SHA512);}
|
||||||
|
}//namespace util
|
||||||
|
}//namespace hgl
|
Loading…
x
Reference in New Issue
Block a user