mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 14:25:38 +03:00
Merge pull request #206 from ClaudiuHKS/master
Add new hashers and new natives
This commit is contained in:
commit
af6c6850ec
@ -268,6 +268,7 @@ class AMXXConfig(object):
|
||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'sdk')]
|
||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'amtl')]
|
||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'memtools')]
|
||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'hashing')]
|
||||
return
|
||||
|
||||
#
|
||||
|
@ -69,7 +69,6 @@ binary.sources = [
|
||||
'fakemeta.cpp',
|
||||
'amxxfile.cpp',
|
||||
'CLang.cpp',
|
||||
'md5.cpp',
|
||||
'emsg.cpp',
|
||||
'CForward.cpp',
|
||||
'CPlugin.cpp',
|
||||
@ -100,6 +99,13 @@ binary.sources = [
|
||||
'cvars.cpp',
|
||||
'../public/memtools/CDetour/detours.cpp',
|
||||
'../public/memtools/CDetour/asm/asm.c',
|
||||
'../public/hashing/hashing.cpp',
|
||||
'../public/hashing/hashers/crc32.cpp',
|
||||
'../public/hashing/hashers/md5.cpp',
|
||||
'../public/hashing/hashers/sha1.cpp',
|
||||
'../public/hashing/hashers/sha256.cpp',
|
||||
'../public/hashing/hashers/sha3.cpp',
|
||||
'../public/hashing/hashers/keccak.cpp'
|
||||
]
|
||||
|
||||
if builder.target_platform == 'windows':
|
||||
|
@ -318,8 +318,8 @@ void reparse_color(String* def)
|
||||
// -- BAILOPAN
|
||||
int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
{
|
||||
FILE *fp = fopen(file, "rt");
|
||||
if (!fp)
|
||||
const char* md5buffer = hashFile(file, Hash_Md5);
|
||||
if (!md5buffer)
|
||||
{
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
for (iter = FileList.begin(); iter != FileList.end(); ++iter)
|
||||
@ -335,11 +335,6 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
md5.update(fp); // closes for us
|
||||
md5.finalize();
|
||||
char md5buffer[33];
|
||||
md5.hex_digest(md5buffer);
|
||||
bool foundFlag = false;
|
||||
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
@ -366,7 +361,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
FileList.push_back(p);
|
||||
}
|
||||
|
||||
fp = fopen(file, "rt");
|
||||
FILE* fp = fopen(file, "rt");
|
||||
if (!fp)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Failed to re-open dictionary file: %s", file);
|
||||
|
@ -17,13 +17,17 @@ PROJECT = amxmodx
|
||||
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
||||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
amxxfile.cpp CLang.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
||||
nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
|
||||
trie_natives.cpp CDataPack.cpp datapacks.cpp stackstructs.cpp \
|
||||
CTextParsers.cpp textparse.cpp CvarManager.cpp cvars.cpp \
|
||||
../public/memtools/CDetour/detours.cpp ../public/memtools/CDetour/asm/asm.c
|
||||
../public/memtools/CDetour/detours.cpp ../public/memtools/CDetour/asm/asm.c \
|
||||
../public/hashing/hashing.cpp ../public/hashing/hashers/crc32.cpp \
|
||||
../public/hashing/hashers/md5.cpp ../public/hashing/hashers/sha1.cpp \
|
||||
../public/hashing/hashers/sha256.cpp ../public/hashing/hashers/sha3.cpp \
|
||||
../public/hashing/hashers/keccak.cpp
|
||||
|
||||
##############################################
|
||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||
@ -38,8 +42,8 @@ CPP_OSX = clang
|
||||
|
||||
LINK = -Lzlib
|
||||
|
||||
INCLUDE = -I. -I../public/amtl -I$(HLSDK) -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared \
|
||||
-I$(HLSDK)/public -I$(MM_ROOT)
|
||||
INCLUDE = -I. -I../public/amtl -I../public/hashing -I$(HLSDK) -I$(HLSDK)/common -I$(HLSDK)/dlls \
|
||||
-I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/public -I$(MM_ROOT)
|
||||
|
||||
################################################
|
||||
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
|
||||
|
@ -1440,41 +1440,64 @@ static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_md5(AMX *amx, cell *params)
|
||||
{
|
||||
int len = 0;
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
char buffer[33];
|
||||
const char *hash = hashString((const char *)str, len, Hash_Md5);
|
||||
|
||||
MD5 md5;
|
||||
md5.update((unsigned char *)str, len);
|
||||
md5.finalize();
|
||||
md5.hex_digest(buffer);
|
||||
|
||||
return set_amxstring(amx, params[2], buffer, 32);
|
||||
return set_amxstring(amx, params[2], hash, 32);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params)
|
||||
{
|
||||
int len = 0;
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
char buffer[33];
|
||||
char file[255];
|
||||
|
||||
build_pathname_r(file, sizeof(file)-1, "%s", str);
|
||||
|
||||
FILE *fp = fopen(file, "rb");
|
||||
|
||||
if (!fp)
|
||||
const char *hash = hashFile((const char *)file, Hash_Md5);
|
||||
if (!hash)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Cant open file \"%s\"", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
md5.update(fp); //closes for you
|
||||
md5.finalize();
|
||||
md5.hex_digest(buffer);
|
||||
return set_amxstring(amx, params[2], hash, 32);
|
||||
}
|
||||
|
||||
return set_amxstring(amx, params[2], buffer, 32);
|
||||
static cell AMX_NATIVE_CALL amx_hash_string(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
HashType type = (HashType)params[2];
|
||||
|
||||
const char *hash = hashString((const char *)str, len, type);
|
||||
if (!hash)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Cant hash string \"%s\"", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return set_amxstring(amx, params[3], hash, params[4]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_hash_file(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
char file[255];
|
||||
build_pathname_r(file, sizeof(file)-1, "%s", str);
|
||||
|
||||
HashType type = (HashType)params[2];
|
||||
|
||||
const char *hash = hashFile((const char *)file, type);
|
||||
if (!hash)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Cant open file \"%s\"", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return set_amxstring(amx, params[3], hash, params[4]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_pluginsnum(AMX *amx, cell *params)
|
||||
@ -4535,6 +4558,8 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
||||
{"log_to_file", log_to_file},
|
||||
{"md5", amx_md5},
|
||||
{"md5_file", amx_md5_file},
|
||||
{"hash_string", amx_hash_string},
|
||||
{"hash_file", amx_hash_file},
|
||||
{"module_exists", module_exists},
|
||||
{"mkdir", amx_mkdir},
|
||||
{"next_hudchannel", next_hudchannel},
|
||||
|
@ -29,7 +29,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
#include "hashing.h"
|
||||
#include "CVector.h"
|
||||
#include "CList.h"
|
||||
#include "CQueue.h"
|
||||
|
474
amxmodx/md5.cpp
474
amxmodx/md5.cpp
@ -1,474 +0,0 @@
|
||||
// MD5.CC - source code for the C++/object oriented translation and
|
||||
// modification of MD5.
|
||||
|
||||
// Translation and modification (c) 1995 by Mordechai T. Abzug
|
||||
|
||||
// This translation/ modification is provided "as is," without express or
|
||||
// implied warranty of any kind.
|
||||
|
||||
// The translator/ modifier does not claim (1) that MD5 will do what you think
|
||||
// it does; (2) that this translation/ modification is accurate; or (3) that
|
||||
// this software is "merchantible." (Language for this disclaimer partially
|
||||
// copied from the disclaimer below).
|
||||
|
||||
/* based on:
|
||||
|
||||
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
MDDRIVER.C - test driver for MD2, MD4 and MD5
|
||||
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
// MD5 simple initialization method
|
||||
|
||||
MD5::MD5(){
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MD5 block update operation. Continues an MD5 message-digest
|
||||
// operation, processing another message block, and updating the
|
||||
// context.
|
||||
|
||||
void MD5::update (uint1 *input, uint4 input_length) {
|
||||
|
||||
uint4 input_index, buffer_index;
|
||||
uint4 buffer_space; // how much space is left in buffer
|
||||
|
||||
if (finalized){ // so we can't update!
|
||||
/*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
|
||||
|
||||
// Update number of bits
|
||||
if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
|
||||
count[1]++;
|
||||
|
||||
count[1] += ((uint4)input_length >> 29);
|
||||
|
||||
|
||||
buffer_space = 64 - buffer_index; // how much space is left in buffer
|
||||
|
||||
// Transform as many times as possible.
|
||||
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
|
||||
// fill the rest of the buffer and transform
|
||||
memcpy (buffer + buffer_index, input, buffer_space);
|
||||
transform (buffer);
|
||||
|
||||
// now, transform each 64-byte piece of the input, bypassing the buffer
|
||||
for (input_index = buffer_space; input_index + 63 < input_length;
|
||||
input_index += 64)
|
||||
transform (input+input_index);
|
||||
|
||||
buffer_index = 0; // so we can buffer remaining
|
||||
}
|
||||
else
|
||||
input_index=0; // so we can buffer the whole input
|
||||
|
||||
|
||||
// and here we do the buffering:
|
||||
memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MD5 update for files.
|
||||
// Like above, except that it works on files (and uses above as a primitive.)
|
||||
|
||||
void MD5::update(FILE *file){
|
||||
|
||||
unsigned char buffer[1024];
|
||||
int len;
|
||||
|
||||
while ((len=fread(buffer, 1, 1024, file)))
|
||||
update(buffer, len);
|
||||
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
// the message digest and zeroizing the context.
|
||||
|
||||
|
||||
void MD5::finalize (){
|
||||
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
static uint1 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
|
||||
};
|
||||
|
||||
if (finalized){
|
||||
/* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/
|
||||
return;
|
||||
}
|
||||
|
||||
// Save number of bits
|
||||
encode (bits, count, 8);
|
||||
|
||||
// Pad out to 56 mod 64.
|
||||
index = (uint4) ((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
|
||||
encode (digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information
|
||||
memset (buffer, 0, sizeof(*buffer));
|
||||
|
||||
finalized=1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
MD5::MD5(FILE *file){
|
||||
|
||||
init(); // must be called be all constructors
|
||||
update(file);
|
||||
finalize ();
|
||||
}
|
||||
|
||||
unsigned char *MD5::raw_digest(){
|
||||
|
||||
uint1 *s = new uint1[16];
|
||||
|
||||
if (!finalized){
|
||||
/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return ( (unsigned char*) "");
|
||||
}
|
||||
|
||||
memcpy(s, digest, 16);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *MD5::hex_digest(){
|
||||
|
||||
int i;
|
||||
char *s= new char[33];
|
||||
|
||||
if (!finalized){
|
||||
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(s+i*2, "%02x", digest[i]);
|
||||
|
||||
s[32]='\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
const char *MD5::hex_digest(char buffer[33]){
|
||||
|
||||
int i;
|
||||
|
||||
if (!finalized)
|
||||
{
|
||||
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(buffer+i*2, "%02x", digest[i]);
|
||||
|
||||
buffer[32]='\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// PRIVATE METHODS:
|
||||
|
||||
|
||||
|
||||
void MD5::init(){
|
||||
finalized=0; // we just started!
|
||||
|
||||
// Nothing counted, so count=0
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// Load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Constants for MD5Transform routine.
|
||||
// Although we could use C++ style constants, defines are actually better,
|
||||
// since they let us easily evade scope clashes.
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
|
||||
// MD5 basic transformation. Transforms state based on block.
|
||||
void MD5::transform (uint1 block[64]){
|
||||
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
decode (x, block, 64);
|
||||
|
||||
assert(!finalized); // not just a user error, since the method is private
|
||||
|
||||
/* 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 ( (uint1 *) x, 0, sizeof(x));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
|
||||
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (uint1) (input[i] & 0xff);
|
||||
output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::decode (uint4 *output, uint1 *input, uint4 len){
|
||||
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
|
||||
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Note: Replace "for loop" with standard memcpy if possible.
|
||||
void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output[i] = input[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Note: Replace "for loop" with standard memset if possible.
|
||||
void MD5::memset (uint1 *output, uint1 value, uint4 len){
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output[i] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ROTATE_LEFT rotates x left n bits.
|
||||
|
||||
inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
|
||||
return (x << n) | (x >> (32-n)) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
|
||||
inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
|
||||
|
||||
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += F(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += G(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += H(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += I(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
105
amxmodx/md5.h
105
amxmodx/md5.h
@ -1,105 +0,0 @@
|
||||
// MD5.CC - source code for the C++/object oriented translation and
|
||||
// modification of MD5.
|
||||
|
||||
// Translation and modification (c) 1995 by Mordechai T. Abzug
|
||||
|
||||
// This translation/ modification is provided "as is," without express or
|
||||
// implied warranty of any kind.
|
||||
|
||||
// The translator/ modifier does not claim (1) that MD5 will do what you think
|
||||
// it does; (2) that this translation/ modification is accurate; or (3) that
|
||||
// this software is "merchantible." (Language for this disclaimer partially
|
||||
// copied from the disclaimer below).
|
||||
|
||||
/* based on:
|
||||
|
||||
MD5.H - header file for MD5C.C
|
||||
MDDRIVER.C - test driver for MD2, MD4 and MD5
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
//#include <fstream.h>
|
||||
//#include <iostream.h>
|
||||
|
||||
class MD5 {
|
||||
|
||||
public:
|
||||
// methods for controlled operation:
|
||||
MD5 (); // simple initializer
|
||||
void update (unsigned char *input, unsigned int input_length);
|
||||
void update (FILE *file);
|
||||
void finalize ();
|
||||
|
||||
// constructors for special circumstances. All these constructors finalize
|
||||
// the MD5 context.
|
||||
MD5 (unsigned char *string); // digest string, finalize
|
||||
MD5 (FILE *file); // digest file, close, finalize
|
||||
|
||||
// methods to acquire finalized result
|
||||
unsigned char *raw_digest (); // digest as a 16-byte binary array
|
||||
const char *hex_digest (); // digest as a 33-byte ascii-hex string
|
||||
const char *hex_digest (char buffer[33]); //same as above, passing buffer
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// first, some types:
|
||||
typedef unsigned int uint4; // assumes integer is 4 words long
|
||||
typedef unsigned short int uint2; // assumes short integer is 2 words long
|
||||
typedef unsigned char uint1; // assumes char is 1 word long
|
||||
|
||||
// next, the private data:
|
||||
uint4 state[4];
|
||||
uint4 count[2]; // number of *bits*, mod 2^64
|
||||
uint1 buffer[64]; // input buffer
|
||||
uint1 digest[16];
|
||||
uint1 finalized;
|
||||
|
||||
// last, the private methods, mostly static:
|
||||
void init (); // called by all constructors
|
||||
void transform (uint1 *buffer); // does the real update work. Note
|
||||
// that length is implied to be 64.
|
||||
|
||||
static void encode (uint1 *dest, uint4 *src, uint4 length);
|
||||
static void decode (uint4 *dest, uint1 *src, uint4 length);
|
||||
static void memcpy (uint1 *dest, uint1 *src, uint4 length);
|
||||
static void memset (uint1 *start, uint1 val, uint4 length);
|
||||
|
||||
static inline uint4 rotate_left (uint4 x, uint4 n);
|
||||
static inline uint4 F (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I (uint4 x, uint4 y, uint4 z);
|
||||
static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
|
||||
};
|
@ -149,7 +149,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\hashing;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<StringPooling>true</StringPooling>
|
||||
@ -294,6 +294,13 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\public\memtools\CDetour\asm\asm.c" />
|
||||
<ClCompile Include="..\..\public\memtools\CDetour\detours.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashing.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\crc32.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\md5.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha1.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha256.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha3.cpp" />
|
||||
<ClCompile Include="..\..\public\hashing\hashers\keccak.cpp" />
|
||||
<ClCompile Include="..\amx.cpp" />
|
||||
<ClCompile Include="..\amxcore.cpp" />
|
||||
<ClCompile Include="..\amxdbg.cpp" />
|
||||
@ -333,7 +340,6 @@
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libraries.cpp" />
|
||||
<ClCompile Include="..\md5.cpp" />
|
||||
<ClCompile Include="..\messages.cpp" />
|
||||
<ClCompile Include="..\meta_api.cpp" />
|
||||
<ClCompile Include="..\modules.cpp" />
|
||||
@ -367,6 +373,13 @@
|
||||
<ClInclude Include="..\..\public\memtools\CDetour\asm\asm.h" />
|
||||
<ClInclude Include="..\..\public\memtools\CDetour\detourhelpers.h" />
|
||||
<ClInclude Include="..\..\public\memtools\CDetour\detours.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashing.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\crc32.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\md5.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha1.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha256.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha3.h" />
|
||||
<ClInclude Include="..\..\public\hashing\hashers\keccak.h" />
|
||||
<ClInclude Include="..\amx.h" />
|
||||
<ClInclude Include="..\amxdbg.h" />
|
||||
<ClInclude Include="..\amxmodx.h" />
|
||||
@ -398,7 +411,6 @@
|
||||
<ClInclude Include="..\fakemeta.h" />
|
||||
<ClInclude Include="..\format.h" />
|
||||
<ClInclude Include="..\libraries.h" />
|
||||
<ClInclude Include="..\md5.h" />
|
||||
<ClInclude Include="..\messages.h" />
|
||||
<ClInclude Include="..\modules.h" />
|
||||
<ClInclude Include="..\natives.h" />
|
||||
|
@ -34,6 +34,12 @@
|
||||
<Filter Include="Memtools\CDetour\asm">
|
||||
<UniqueIdentifier>{64a22cd4-3715-45de-8af2-e54017733be6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Hashing">
|
||||
<UniqueIdentifier>{c9218ea1-c21e-4b90-b7a2-cb665d905a3f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Hashing\Hashers">
|
||||
<UniqueIdentifier>{v3248ea1-a53v-5ax5-b2d1-f3gh53d2fg43}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\amx.cpp">
|
||||
@ -120,9 +126,6 @@
|
||||
<ClCompile Include="..\libraries.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\md5.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\messages.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -204,6 +207,27 @@
|
||||
<ClCompile Include="..\cvars.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashing.cpp">
|
||||
<Filter>Hashing</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\crc32.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\md5.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha1.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha256.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\sha3.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\public\hashing\hashers\keccak.cpp">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\amx.h">
|
||||
@ -290,9 +314,6 @@
|
||||
<ClInclude Include="..\libraries.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\md5.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\messages.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -362,6 +383,27 @@
|
||||
<ClInclude Include="..\CvarManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashing.h">
|
||||
<Filter>Hashing</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\crc32.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\md5.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha1.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha256.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\sha3.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\public\hashing\hashers\keccak.h">
|
||||
<Filter>Hashing\Hashers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\version.rc">
|
||||
|
@ -450,3 +450,25 @@ enum AdminProp
|
||||
AdminProp_Access,
|
||||
AdminProp_Flags
|
||||
};
|
||||
|
||||
/**
|
||||
* HashType constants
|
||||
* To be used on hash_file() and hash_string()
|
||||
*/
|
||||
enum HashType
|
||||
{
|
||||
Hash_Crc32 = 0, // Provides CRC32 hashing
|
||||
Hash_Md5, // Provides MD5 hashing
|
||||
Hash_Sha1, // Provides SHA1 hashing
|
||||
Hash_Sha256, // Provides SHA256 hashing
|
||||
|
||||
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
||||
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
||||
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
||||
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
||||
|
||||
Hash_Keccak_224, // Provides Keccak 224 bit hashing
|
||||
Hash_Keccak_256, // Provides Keccak 256 bit hashing
|
||||
Hash_Keccak_384, // Provides Keccak 384 bit hashing
|
||||
Hash_Keccak_512 // Provides Keccak 512 bit hashing
|
||||
};
|
||||
|
@ -2310,6 +2310,7 @@ native force_unmodified(force_type, const mins[3], const maxs[3], const filename
|
||||
*
|
||||
* @return Number of cells written to the buffer (always 32)
|
||||
*/
|
||||
#pragma deprecated Use hash_string() function. Also, see Hash_* constants.
|
||||
native md5(const szString[], md5buffer[34]);
|
||||
|
||||
/**
|
||||
@ -2321,8 +2322,34 @@ native md5(const szString[], md5buffer[34]);
|
||||
* @return Number of cells written to the buffer (always 32)
|
||||
* @error If the file can not be opened, and error is thrown.
|
||||
*/
|
||||
#pragma deprecated Use hash_file() function. Also, see Hash_* constants.
|
||||
native md5_file(const file[], md5buffer[34]);
|
||||
|
||||
/**
|
||||
* Generate a hash value (message digest)
|
||||
*
|
||||
* @param string String to be hashed.
|
||||
* @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file.
|
||||
* @param output Output string to store hash in.
|
||||
* @param outputSize The maximum size of the output string to store hash in.
|
||||
*
|
||||
* @return Number of written bytes.
|
||||
*/
|
||||
native hash_string(const string[], const HashType:type, output[], const outputSize);
|
||||
|
||||
/**
|
||||
* Generate a hash value using the contents of a given file
|
||||
*
|
||||
* @param fileName Path of file to be hashed.
|
||||
* @param type Type of selected hashing algorithm. See Hash_* constants in amxconst.inc file.
|
||||
* @param output Output string to store hash in.
|
||||
* @param outputSize The maximum size of the output string to store hash in.
|
||||
*
|
||||
* @return Number of written bytes.
|
||||
* @error If the file couldn't be opened, an error is thrown.
|
||||
*/
|
||||
native hash_file(const fileName[], const HashType:type, output[], const outputSize);
|
||||
|
||||
/**
|
||||
* Returns the internal flags set on the plugin's state.
|
||||
*
|
||||
@ -3076,6 +3103,5 @@ native admins_flush();
|
||||
*/
|
||||
native bool:has_map_ent_class(const classname[]);
|
||||
|
||||
|
||||
// Always keep this at the bottom of this file
|
||||
#include <message_stocks>
|
||||
|
79
plugins/testsuite/hashing_test.sma
Normal file
79
plugins/testsuite/hashing_test.sma
Normal file
@ -0,0 +1,79 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet:
|
||||
//
|
||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||
// Copyright (C) The AMX Mod X Development Team.
|
||||
//
|
||||
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://alliedmods.net/amxmodx-license
|
||||
|
||||
#include <amxmodx>
|
||||
|
||||
new const g_hashTypes[HashType][] =
|
||||
{
|
||||
"CRC32",
|
||||
"MD5",
|
||||
"SHA1",
|
||||
"SHA256",
|
||||
"SHA3 224",
|
||||
"SHA3 256",
|
||||
"SHA3 384",
|
||||
"SHA3 512",
|
||||
"Keccak 224",
|
||||
"Keccak 256",
|
||||
"Keccak 384",
|
||||
"Keccak 512"
|
||||
};
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_plugin("Hashing Test", "1.0", "Hattrick (Claudiu HKS)");
|
||||
register_srvcmd("hash_string", "cmdHashString");
|
||||
register_srvcmd("hash_file", "cmdHashFile");
|
||||
}
|
||||
|
||||
public cmdHashString()
|
||||
{
|
||||
if (read_argc() < 2)
|
||||
{
|
||||
server_print("Specify string to be hashed.");
|
||||
return PLUGIN_HANDLED;
|
||||
}
|
||||
|
||||
new String[256], Output[256], HashType:Type;
|
||||
read_argv(1, String, charsmax(String));
|
||||
|
||||
log_amx("Hashing string %s...", String);
|
||||
log_amx("-----------------------------------");
|
||||
|
||||
for (Type = Hash_Crc32; Type < any:sizeof g_hashTypes; Type++)
|
||||
{
|
||||
hash_string(String, Type, Output, charsmax(Output));
|
||||
log_amx("%s : %s", g_hashTypes[Type], Output);
|
||||
}
|
||||
|
||||
return PLUGIN_HANDLED;
|
||||
}
|
||||
|
||||
public cmdHashFile()
|
||||
{
|
||||
if (read_argc() < 2)
|
||||
{
|
||||
server_print("Specify file to be hashed.");
|
||||
return PLUGIN_HANDLED;
|
||||
}
|
||||
|
||||
new File[256], Output[256], HashType:Type;
|
||||
read_argv(1, File, charsmax(File));
|
||||
|
||||
log_amx("Hashing file %s...", File);
|
||||
log_amx("-----------------------------------");
|
||||
|
||||
for (Type = Hash_Crc32; Type < any:sizeof g_hashTypes; Type++)
|
||||
{
|
||||
hash_file(File, Type, Output, charsmax(Output));
|
||||
log_amx("%s : %s", g_hashTypes[Type], Output);
|
||||
}
|
||||
|
||||
return PLUGIN_HANDLED;
|
||||
}
|
417
public/hashing/hashers/crc32.cpp
Normal file
417
public/hashing/hashers/crc32.cpp
Normal file
@ -0,0 +1,417 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// crc32.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "crc32.h"
|
||||
|
||||
|
||||
/// same as reset()
|
||||
CRC32::CRC32()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/// restart
|
||||
void CRC32::reset()
|
||||
{
|
||||
m_hash = 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
/// look-up table
|
||||
static const uint32_t crc32Lookup[8][256] =
|
||||
{
|
||||
// generated by:
|
||||
//for (uint32_t i = 0; i <= 0xFF; i++)
|
||||
//{
|
||||
// uint32_t crc = i;
|
||||
// for (unsigned int j = 0; j < 8; j++)
|
||||
// crc = (crc >> 1) ^ ((crc & 1) * Polynomial);
|
||||
// crc32Lookup[0][i] = crc;
|
||||
//}
|
||||
// slicing-by-8 algorithm (from Intel):
|
||||
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
// http://sourceforge.net/projects/slicing-by-8/
|
||||
//for (unsigned int i = 0; i <= 0xFF; i++)
|
||||
//{
|
||||
// crc32Lookup[1][i] = (crc32Lookup[0][i] >> 8) ^ crc32Lookup[0][crc32Lookup[0][i] & 0xFF];
|
||||
// crc32Lookup[2][i] = (crc32Lookup[1][i] >> 8) ^ crc32Lookup[0][crc32Lookup[1][i] & 0xFF];
|
||||
// crc32Lookup[3][i] = (crc32Lookup[2][i] >> 8) ^ crc32Lookup[0][crc32Lookup[2][i] & 0xFF];
|
||||
|
||||
// crc32Lookup[4][i] = (crc32Lookup[3][i] >> 8) ^ crc32Lookup[0][crc32Lookup[3][i] & 0xFF];
|
||||
// crc32Lookup[5][i] = (crc32Lookup[4][i] >> 8) ^ crc32Lookup[0][crc32Lookup[4][i] & 0xFF];
|
||||
// crc32Lookup[6][i] = (crc32Lookup[5][i] >> 8) ^ crc32Lookup[0][crc32Lookup[5][i] & 0xFF];
|
||||
// crc32Lookup[7][i] = (crc32Lookup[6][i] >> 8) ^ crc32Lookup[0][crc32Lookup[6][i] & 0xFF];
|
||||
//}
|
||||
{ 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 },
|
||||
|
||||
{ 0x00000000,0x191B3141,0x32366282,0x2B2D53C3,0x646CC504,0x7D77F445,0x565AA786,0x4F4196C7,
|
||||
0xC8D98A08,0xD1C2BB49,0xFAEFE88A,0xE3F4D9CB,0xACB54F0C,0xB5AE7E4D,0x9E832D8E,0x87981CCF,
|
||||
0x4AC21251,0x53D92310,0x78F470D3,0x61EF4192,0x2EAED755,0x37B5E614,0x1C98B5D7,0x05838496,
|
||||
0x821B9859,0x9B00A918,0xB02DFADB,0xA936CB9A,0xE6775D5D,0xFF6C6C1C,0xD4413FDF,0xCD5A0E9E,
|
||||
0x958424A2,0x8C9F15E3,0xA7B24620,0xBEA97761,0xF1E8E1A6,0xE8F3D0E7,0xC3DE8324,0xDAC5B265,
|
||||
0x5D5DAEAA,0x44469FEB,0x6F6BCC28,0x7670FD69,0x39316BAE,0x202A5AEF,0x0B07092C,0x121C386D,
|
||||
0xDF4636F3,0xC65D07B2,0xED705471,0xF46B6530,0xBB2AF3F7,0xA231C2B6,0x891C9175,0x9007A034,
|
||||
0x179FBCFB,0x0E848DBA,0x25A9DE79,0x3CB2EF38,0x73F379FF,0x6AE848BE,0x41C51B7D,0x58DE2A3C,
|
||||
0xF0794F05,0xE9627E44,0xC24F2D87,0xDB541CC6,0x94158A01,0x8D0EBB40,0xA623E883,0xBF38D9C2,
|
||||
0x38A0C50D,0x21BBF44C,0x0A96A78F,0x138D96CE,0x5CCC0009,0x45D73148,0x6EFA628B,0x77E153CA,
|
||||
0xBABB5D54,0xA3A06C15,0x888D3FD6,0x91960E97,0xDED79850,0xC7CCA911,0xECE1FAD2,0xF5FACB93,
|
||||
0x7262D75C,0x6B79E61D,0x4054B5DE,0x594F849F,0x160E1258,0x0F152319,0x243870DA,0x3D23419B,
|
||||
0x65FD6BA7,0x7CE65AE6,0x57CB0925,0x4ED03864,0x0191AEA3,0x188A9FE2,0x33A7CC21,0x2ABCFD60,
|
||||
0xAD24E1AF,0xB43FD0EE,0x9F12832D,0x8609B26C,0xC94824AB,0xD05315EA,0xFB7E4629,0xE2657768,
|
||||
0x2F3F79F6,0x362448B7,0x1D091B74,0x04122A35,0x4B53BCF2,0x52488DB3,0x7965DE70,0x607EEF31,
|
||||
0xE7E6F3FE,0xFEFDC2BF,0xD5D0917C,0xCCCBA03D,0x838A36FA,0x9A9107BB,0xB1BC5478,0xA8A76539,
|
||||
0x3B83984B,0x2298A90A,0x09B5FAC9,0x10AECB88,0x5FEF5D4F,0x46F46C0E,0x6DD93FCD,0x74C20E8C,
|
||||
0xF35A1243,0xEA412302,0xC16C70C1,0xD8774180,0x9736D747,0x8E2DE606,0xA500B5C5,0xBC1B8484,
|
||||
0x71418A1A,0x685ABB5B,0x4377E898,0x5A6CD9D9,0x152D4F1E,0x0C367E5F,0x271B2D9C,0x3E001CDD,
|
||||
0xB9980012,0xA0833153,0x8BAE6290,0x92B553D1,0xDDF4C516,0xC4EFF457,0xEFC2A794,0xF6D996D5,
|
||||
0xAE07BCE9,0xB71C8DA8,0x9C31DE6B,0x852AEF2A,0xCA6B79ED,0xD37048AC,0xF85D1B6F,0xE1462A2E,
|
||||
0x66DE36E1,0x7FC507A0,0x54E85463,0x4DF36522,0x02B2F3E5,0x1BA9C2A4,0x30849167,0x299FA026,
|
||||
0xE4C5AEB8,0xFDDE9FF9,0xD6F3CC3A,0xCFE8FD7B,0x80A96BBC,0x99B25AFD,0xB29F093E,0xAB84387F,
|
||||
0x2C1C24B0,0x350715F1,0x1E2A4632,0x07317773,0x4870E1B4,0x516BD0F5,0x7A468336,0x635DB277,
|
||||
0xCBFAD74E,0xD2E1E60F,0xF9CCB5CC,0xE0D7848D,0xAF96124A,0xB68D230B,0x9DA070C8,0x84BB4189,
|
||||
0x03235D46,0x1A386C07,0x31153FC4,0x280E0E85,0x674F9842,0x7E54A903,0x5579FAC0,0x4C62CB81,
|
||||
0x8138C51F,0x9823F45E,0xB30EA79D,0xAA1596DC,0xE554001B,0xFC4F315A,0xD7626299,0xCE7953D8,
|
||||
0x49E14F17,0x50FA7E56,0x7BD72D95,0x62CC1CD4,0x2D8D8A13,0x3496BB52,0x1FBBE891,0x06A0D9D0,
|
||||
0x5E7EF3EC,0x4765C2AD,0x6C48916E,0x7553A02F,0x3A1236E8,0x230907A9,0x0824546A,0x113F652B,
|
||||
0x96A779E4,0x8FBC48A5,0xA4911B66,0xBD8A2A27,0xF2CBBCE0,0xEBD08DA1,0xC0FDDE62,0xD9E6EF23,
|
||||
0x14BCE1BD,0x0DA7D0FC,0x268A833F,0x3F91B27E,0x70D024B9,0x69CB15F8,0x42E6463B,0x5BFD777A,
|
||||
0xDC656BB5,0xC57E5AF4,0xEE530937,0xF7483876,0xB809AEB1,0xA1129FF0,0x8A3FCC33,0x9324FD72 },
|
||||
|
||||
{ 0x00000000,0x01C26A37,0x0384D46E,0x0246BE59,0x0709A8DC,0x06CBC2EB,0x048D7CB2,0x054F1685,
|
||||
0x0E1351B8,0x0FD13B8F,0x0D9785D6,0x0C55EFE1,0x091AF964,0x08D89353,0x0A9E2D0A,0x0B5C473D,
|
||||
0x1C26A370,0x1DE4C947,0x1FA2771E,0x1E601D29,0x1B2F0BAC,0x1AED619B,0x18ABDFC2,0x1969B5F5,
|
||||
0x1235F2C8,0x13F798FF,0x11B126A6,0x10734C91,0x153C5A14,0x14FE3023,0x16B88E7A,0x177AE44D,
|
||||
0x384D46E0,0x398F2CD7,0x3BC9928E,0x3A0BF8B9,0x3F44EE3C,0x3E86840B,0x3CC03A52,0x3D025065,
|
||||
0x365E1758,0x379C7D6F,0x35DAC336,0x3418A901,0x3157BF84,0x3095D5B3,0x32D36BEA,0x331101DD,
|
||||
0x246BE590,0x25A98FA7,0x27EF31FE,0x262D5BC9,0x23624D4C,0x22A0277B,0x20E69922,0x2124F315,
|
||||
0x2A78B428,0x2BBADE1F,0x29FC6046,0x283E0A71,0x2D711CF4,0x2CB376C3,0x2EF5C89A,0x2F37A2AD,
|
||||
0x709A8DC0,0x7158E7F7,0x731E59AE,0x72DC3399,0x7793251C,0x76514F2B,0x7417F172,0x75D59B45,
|
||||
0x7E89DC78,0x7F4BB64F,0x7D0D0816,0x7CCF6221,0x798074A4,0x78421E93,0x7A04A0CA,0x7BC6CAFD,
|
||||
0x6CBC2EB0,0x6D7E4487,0x6F38FADE,0x6EFA90E9,0x6BB5866C,0x6A77EC5B,0x68315202,0x69F33835,
|
||||
0x62AF7F08,0x636D153F,0x612BAB66,0x60E9C151,0x65A6D7D4,0x6464BDE3,0x662203BA,0x67E0698D,
|
||||
0x48D7CB20,0x4915A117,0x4B531F4E,0x4A917579,0x4FDE63FC,0x4E1C09CB,0x4C5AB792,0x4D98DDA5,
|
||||
0x46C49A98,0x4706F0AF,0x45404EF6,0x448224C1,0x41CD3244,0x400F5873,0x4249E62A,0x438B8C1D,
|
||||
0x54F16850,0x55330267,0x5775BC3E,0x56B7D609,0x53F8C08C,0x523AAABB,0x507C14E2,0x51BE7ED5,
|
||||
0x5AE239E8,0x5B2053DF,0x5966ED86,0x58A487B1,0x5DEB9134,0x5C29FB03,0x5E6F455A,0x5FAD2F6D,
|
||||
0xE1351B80,0xE0F771B7,0xE2B1CFEE,0xE373A5D9,0xE63CB35C,0xE7FED96B,0xE5B86732,0xE47A0D05,
|
||||
0xEF264A38,0xEEE4200F,0xECA29E56,0xED60F461,0xE82FE2E4,0xE9ED88D3,0xEBAB368A,0xEA695CBD,
|
||||
0xFD13B8F0,0xFCD1D2C7,0xFE976C9E,0xFF5506A9,0xFA1A102C,0xFBD87A1B,0xF99EC442,0xF85CAE75,
|
||||
0xF300E948,0xF2C2837F,0xF0843D26,0xF1465711,0xF4094194,0xF5CB2BA3,0xF78D95FA,0xF64FFFCD,
|
||||
0xD9785D60,0xD8BA3757,0xDAFC890E,0xDB3EE339,0xDE71F5BC,0xDFB39F8B,0xDDF521D2,0xDC374BE5,
|
||||
0xD76B0CD8,0xD6A966EF,0xD4EFD8B6,0xD52DB281,0xD062A404,0xD1A0CE33,0xD3E6706A,0xD2241A5D,
|
||||
0xC55EFE10,0xC49C9427,0xC6DA2A7E,0xC7184049,0xC25756CC,0xC3953CFB,0xC1D382A2,0xC011E895,
|
||||
0xCB4DAFA8,0xCA8FC59F,0xC8C97BC6,0xC90B11F1,0xCC440774,0xCD866D43,0xCFC0D31A,0xCE02B92D,
|
||||
0x91AF9640,0x906DFC77,0x922B422E,0x93E92819,0x96A63E9C,0x976454AB,0x9522EAF2,0x94E080C5,
|
||||
0x9FBCC7F8,0x9E7EADCF,0x9C381396,0x9DFA79A1,0x98B56F24,0x99770513,0x9B31BB4A,0x9AF3D17D,
|
||||
0x8D893530,0x8C4B5F07,0x8E0DE15E,0x8FCF8B69,0x8A809DEC,0x8B42F7DB,0x89044982,0x88C623B5,
|
||||
0x839A6488,0x82580EBF,0x801EB0E6,0x81DCDAD1,0x8493CC54,0x8551A663,0x8717183A,0x86D5720D,
|
||||
0xA9E2D0A0,0xA820BA97,0xAA6604CE,0xABA46EF9,0xAEEB787C,0xAF29124B,0xAD6FAC12,0xACADC625,
|
||||
0xA7F18118,0xA633EB2F,0xA4755576,0xA5B73F41,0xA0F829C4,0xA13A43F3,0xA37CFDAA,0xA2BE979D,
|
||||
0xB5C473D0,0xB40619E7,0xB640A7BE,0xB782CD89,0xB2CDDB0C,0xB30FB13B,0xB1490F62,0xB08B6555,
|
||||
0xBBD72268,0xBA15485F,0xB853F606,0xB9919C31,0xBCDE8AB4,0xBD1CE083,0xBF5A5EDA,0xBE9834ED },
|
||||
|
||||
{ 0x00000000,0xB8BC6765,0xAA09C88B,0x12B5AFEE,0x8F629757,0x37DEF032,0x256B5FDC,0x9DD738B9,
|
||||
0xC5B428EF,0x7D084F8A,0x6FBDE064,0xD7018701,0x4AD6BFB8,0xF26AD8DD,0xE0DF7733,0x58631056,
|
||||
0x5019579F,0xE8A530FA,0xFA109F14,0x42ACF871,0xDF7BC0C8,0x67C7A7AD,0x75720843,0xCDCE6F26,
|
||||
0x95AD7F70,0x2D111815,0x3FA4B7FB,0x8718D09E,0x1ACFE827,0xA2738F42,0xB0C620AC,0x087A47C9,
|
||||
0xA032AF3E,0x188EC85B,0x0A3B67B5,0xB28700D0,0x2F503869,0x97EC5F0C,0x8559F0E2,0x3DE59787,
|
||||
0x658687D1,0xDD3AE0B4,0xCF8F4F5A,0x7733283F,0xEAE41086,0x525877E3,0x40EDD80D,0xF851BF68,
|
||||
0xF02BF8A1,0x48979FC4,0x5A22302A,0xE29E574F,0x7F496FF6,0xC7F50893,0xD540A77D,0x6DFCC018,
|
||||
0x359FD04E,0x8D23B72B,0x9F9618C5,0x272A7FA0,0xBAFD4719,0x0241207C,0x10F48F92,0xA848E8F7,
|
||||
0x9B14583D,0x23A83F58,0x311D90B6,0x89A1F7D3,0x1476CF6A,0xACCAA80F,0xBE7F07E1,0x06C36084,
|
||||
0x5EA070D2,0xE61C17B7,0xF4A9B859,0x4C15DF3C,0xD1C2E785,0x697E80E0,0x7BCB2F0E,0xC377486B,
|
||||
0xCB0D0FA2,0x73B168C7,0x6104C729,0xD9B8A04C,0x446F98F5,0xFCD3FF90,0xEE66507E,0x56DA371B,
|
||||
0x0EB9274D,0xB6054028,0xA4B0EFC6,0x1C0C88A3,0x81DBB01A,0x3967D77F,0x2BD27891,0x936E1FF4,
|
||||
0x3B26F703,0x839A9066,0x912F3F88,0x299358ED,0xB4446054,0x0CF80731,0x1E4DA8DF,0xA6F1CFBA,
|
||||
0xFE92DFEC,0x462EB889,0x549B1767,0xEC277002,0x71F048BB,0xC94C2FDE,0xDBF98030,0x6345E755,
|
||||
0x6B3FA09C,0xD383C7F9,0xC1366817,0x798A0F72,0xE45D37CB,0x5CE150AE,0x4E54FF40,0xF6E89825,
|
||||
0xAE8B8873,0x1637EF16,0x048240F8,0xBC3E279D,0x21E91F24,0x99557841,0x8BE0D7AF,0x335CB0CA,
|
||||
0xED59B63B,0x55E5D15E,0x47507EB0,0xFFEC19D5,0x623B216C,0xDA874609,0xC832E9E7,0x708E8E82,
|
||||
0x28ED9ED4,0x9051F9B1,0x82E4565F,0x3A58313A,0xA78F0983,0x1F336EE6,0x0D86C108,0xB53AA66D,
|
||||
0xBD40E1A4,0x05FC86C1,0x1749292F,0xAFF54E4A,0x322276F3,0x8A9E1196,0x982BBE78,0x2097D91D,
|
||||
0x78F4C94B,0xC048AE2E,0xD2FD01C0,0x6A4166A5,0xF7965E1C,0x4F2A3979,0x5D9F9697,0xE523F1F2,
|
||||
0x4D6B1905,0xF5D77E60,0xE762D18E,0x5FDEB6EB,0xC2098E52,0x7AB5E937,0x680046D9,0xD0BC21BC,
|
||||
0x88DF31EA,0x3063568F,0x22D6F961,0x9A6A9E04,0x07BDA6BD,0xBF01C1D8,0xADB46E36,0x15080953,
|
||||
0x1D724E9A,0xA5CE29FF,0xB77B8611,0x0FC7E174,0x9210D9CD,0x2AACBEA8,0x38191146,0x80A57623,
|
||||
0xD8C66675,0x607A0110,0x72CFAEFE,0xCA73C99B,0x57A4F122,0xEF189647,0xFDAD39A9,0x45115ECC,
|
||||
0x764DEE06,0xCEF18963,0xDC44268D,0x64F841E8,0xF92F7951,0x41931E34,0x5326B1DA,0xEB9AD6BF,
|
||||
0xB3F9C6E9,0x0B45A18C,0x19F00E62,0xA14C6907,0x3C9B51BE,0x842736DB,0x96929935,0x2E2EFE50,
|
||||
0x2654B999,0x9EE8DEFC,0x8C5D7112,0x34E11677,0xA9362ECE,0x118A49AB,0x033FE645,0xBB838120,
|
||||
0xE3E09176,0x5B5CF613,0x49E959FD,0xF1553E98,0x6C820621,0xD43E6144,0xC68BCEAA,0x7E37A9CF,
|
||||
0xD67F4138,0x6EC3265D,0x7C7689B3,0xC4CAEED6,0x591DD66F,0xE1A1B10A,0xF3141EE4,0x4BA87981,
|
||||
0x13CB69D7,0xAB770EB2,0xB9C2A15C,0x017EC639,0x9CA9FE80,0x241599E5,0x36A0360B,0x8E1C516E,
|
||||
0x866616A7,0x3EDA71C2,0x2C6FDE2C,0x94D3B949,0x090481F0,0xB1B8E695,0xA30D497B,0x1BB12E1E,
|
||||
0x43D23E48,0xFB6E592D,0xE9DBF6C3,0x516791A6,0xCCB0A91F,0x740CCE7A,0x66B96194,0xDE0506F1 },
|
||||
|
||||
{ 0x00000000,0x3D6029B0,0x7AC05360,0x47A07AD0,0xF580A6C0,0xC8E08F70,0x8F40F5A0,0xB220DC10,
|
||||
0x30704BC1,0x0D106271,0x4AB018A1,0x77D03111,0xC5F0ED01,0xF890C4B1,0xBF30BE61,0x825097D1,
|
||||
0x60E09782,0x5D80BE32,0x1A20C4E2,0x2740ED52,0x95603142,0xA80018F2,0xEFA06222,0xD2C04B92,
|
||||
0x5090DC43,0x6DF0F5F3,0x2A508F23,0x1730A693,0xA5107A83,0x98705333,0xDFD029E3,0xE2B00053,
|
||||
0xC1C12F04,0xFCA106B4,0xBB017C64,0x866155D4,0x344189C4,0x0921A074,0x4E81DAA4,0x73E1F314,
|
||||
0xF1B164C5,0xCCD14D75,0x8B7137A5,0xB6111E15,0x0431C205,0x3951EBB5,0x7EF19165,0x4391B8D5,
|
||||
0xA121B886,0x9C419136,0xDBE1EBE6,0xE681C256,0x54A11E46,0x69C137F6,0x2E614D26,0x13016496,
|
||||
0x9151F347,0xAC31DAF7,0xEB91A027,0xD6F18997,0x64D15587,0x59B17C37,0x1E1106E7,0x23712F57,
|
||||
0x58F35849,0x659371F9,0x22330B29,0x1F532299,0xAD73FE89,0x9013D739,0xD7B3ADE9,0xEAD38459,
|
||||
0x68831388,0x55E33A38,0x124340E8,0x2F236958,0x9D03B548,0xA0639CF8,0xE7C3E628,0xDAA3CF98,
|
||||
0x3813CFCB,0x0573E67B,0x42D39CAB,0x7FB3B51B,0xCD93690B,0xF0F340BB,0xB7533A6B,0x8A3313DB,
|
||||
0x0863840A,0x3503ADBA,0x72A3D76A,0x4FC3FEDA,0xFDE322CA,0xC0830B7A,0x872371AA,0xBA43581A,
|
||||
0x9932774D,0xA4525EFD,0xE3F2242D,0xDE920D9D,0x6CB2D18D,0x51D2F83D,0x167282ED,0x2B12AB5D,
|
||||
0xA9423C8C,0x9422153C,0xD3826FEC,0xEEE2465C,0x5CC29A4C,0x61A2B3FC,0x2602C92C,0x1B62E09C,
|
||||
0xF9D2E0CF,0xC4B2C97F,0x8312B3AF,0xBE729A1F,0x0C52460F,0x31326FBF,0x7692156F,0x4BF23CDF,
|
||||
0xC9A2AB0E,0xF4C282BE,0xB362F86E,0x8E02D1DE,0x3C220DCE,0x0142247E,0x46E25EAE,0x7B82771E,
|
||||
0xB1E6B092,0x8C869922,0xCB26E3F2,0xF646CA42,0x44661652,0x79063FE2,0x3EA64532,0x03C66C82,
|
||||
0x8196FB53,0xBCF6D2E3,0xFB56A833,0xC6368183,0x74165D93,0x49767423,0x0ED60EF3,0x33B62743,
|
||||
0xD1062710,0xEC660EA0,0xABC67470,0x96A65DC0,0x248681D0,0x19E6A860,0x5E46D2B0,0x6326FB00,
|
||||
0xE1766CD1,0xDC164561,0x9BB63FB1,0xA6D61601,0x14F6CA11,0x2996E3A1,0x6E369971,0x5356B0C1,
|
||||
0x70279F96,0x4D47B626,0x0AE7CCF6,0x3787E546,0x85A73956,0xB8C710E6,0xFF676A36,0xC2074386,
|
||||
0x4057D457,0x7D37FDE7,0x3A978737,0x07F7AE87,0xB5D77297,0x88B75B27,0xCF1721F7,0xF2770847,
|
||||
0x10C70814,0x2DA721A4,0x6A075B74,0x576772C4,0xE547AED4,0xD8278764,0x9F87FDB4,0xA2E7D404,
|
||||
0x20B743D5,0x1DD76A65,0x5A7710B5,0x67173905,0xD537E515,0xE857CCA5,0xAFF7B675,0x92979FC5,
|
||||
0xE915E8DB,0xD475C16B,0x93D5BBBB,0xAEB5920B,0x1C954E1B,0x21F567AB,0x66551D7B,0x5B3534CB,
|
||||
0xD965A31A,0xE4058AAA,0xA3A5F07A,0x9EC5D9CA,0x2CE505DA,0x11852C6A,0x562556BA,0x6B457F0A,
|
||||
0x89F57F59,0xB49556E9,0xF3352C39,0xCE550589,0x7C75D999,0x4115F029,0x06B58AF9,0x3BD5A349,
|
||||
0xB9853498,0x84E51D28,0xC34567F8,0xFE254E48,0x4C059258,0x7165BBE8,0x36C5C138,0x0BA5E888,
|
||||
0x28D4C7DF,0x15B4EE6F,0x521494BF,0x6F74BD0F,0xDD54611F,0xE03448AF,0xA794327F,0x9AF41BCF,
|
||||
0x18A48C1E,0x25C4A5AE,0x6264DF7E,0x5F04F6CE,0xED242ADE,0xD044036E,0x97E479BE,0xAA84500E,
|
||||
0x4834505D,0x755479ED,0x32F4033D,0x0F942A8D,0xBDB4F69D,0x80D4DF2D,0xC774A5FD,0xFA148C4D,
|
||||
0x78441B9C,0x4524322C,0x028448FC,0x3FE4614C,0x8DC4BD5C,0xB0A494EC,0xF704EE3C,0xCA64C78C },
|
||||
|
||||
{ 0x00000000,0xCB5CD3A5,0x4DC8A10B,0x869472AE,0x9B914216,0x50CD91B3,0xD659E31D,0x1D0530B8,
|
||||
0xEC53826D,0x270F51C8,0xA19B2366,0x6AC7F0C3,0x77C2C07B,0xBC9E13DE,0x3A0A6170,0xF156B2D5,
|
||||
0x03D6029B,0xC88AD13E,0x4E1EA390,0x85427035,0x9847408D,0x531B9328,0xD58FE186,0x1ED33223,
|
||||
0xEF8580F6,0x24D95353,0xA24D21FD,0x6911F258,0x7414C2E0,0xBF481145,0x39DC63EB,0xF280B04E,
|
||||
0x07AC0536,0xCCF0D693,0x4A64A43D,0x81387798,0x9C3D4720,0x57619485,0xD1F5E62B,0x1AA9358E,
|
||||
0xEBFF875B,0x20A354FE,0xA6372650,0x6D6BF5F5,0x706EC54D,0xBB3216E8,0x3DA66446,0xF6FAB7E3,
|
||||
0x047A07AD,0xCF26D408,0x49B2A6A6,0x82EE7503,0x9FEB45BB,0x54B7961E,0xD223E4B0,0x197F3715,
|
||||
0xE82985C0,0x23755665,0xA5E124CB,0x6EBDF76E,0x73B8C7D6,0xB8E41473,0x3E7066DD,0xF52CB578,
|
||||
0x0F580A6C,0xC404D9C9,0x4290AB67,0x89CC78C2,0x94C9487A,0x5F959BDF,0xD901E971,0x125D3AD4,
|
||||
0xE30B8801,0x28575BA4,0xAEC3290A,0x659FFAAF,0x789ACA17,0xB3C619B2,0x35526B1C,0xFE0EB8B9,
|
||||
0x0C8E08F7,0xC7D2DB52,0x4146A9FC,0x8A1A7A59,0x971F4AE1,0x5C439944,0xDAD7EBEA,0x118B384F,
|
||||
0xE0DD8A9A,0x2B81593F,0xAD152B91,0x6649F834,0x7B4CC88C,0xB0101B29,0x36846987,0xFDD8BA22,
|
||||
0x08F40F5A,0xC3A8DCFF,0x453CAE51,0x8E607DF4,0x93654D4C,0x58399EE9,0xDEADEC47,0x15F13FE2,
|
||||
0xE4A78D37,0x2FFB5E92,0xA96F2C3C,0x6233FF99,0x7F36CF21,0xB46A1C84,0x32FE6E2A,0xF9A2BD8F,
|
||||
0x0B220DC1,0xC07EDE64,0x46EAACCA,0x8DB67F6F,0x90B34FD7,0x5BEF9C72,0xDD7BEEDC,0x16273D79,
|
||||
0xE7718FAC,0x2C2D5C09,0xAAB92EA7,0x61E5FD02,0x7CE0CDBA,0xB7BC1E1F,0x31286CB1,0xFA74BF14,
|
||||
0x1EB014D8,0xD5ECC77D,0x5378B5D3,0x98246676,0x852156CE,0x4E7D856B,0xC8E9F7C5,0x03B52460,
|
||||
0xF2E396B5,0x39BF4510,0xBF2B37BE,0x7477E41B,0x6972D4A3,0xA22E0706,0x24BA75A8,0xEFE6A60D,
|
||||
0x1D661643,0xD63AC5E6,0x50AEB748,0x9BF264ED,0x86F75455,0x4DAB87F0,0xCB3FF55E,0x006326FB,
|
||||
0xF135942E,0x3A69478B,0xBCFD3525,0x77A1E680,0x6AA4D638,0xA1F8059D,0x276C7733,0xEC30A496,
|
||||
0x191C11EE,0xD240C24B,0x54D4B0E5,0x9F886340,0x828D53F8,0x49D1805D,0xCF45F2F3,0x04192156,
|
||||
0xF54F9383,0x3E134026,0xB8873288,0x73DBE12D,0x6EDED195,0xA5820230,0x2316709E,0xE84AA33B,
|
||||
0x1ACA1375,0xD196C0D0,0x5702B27E,0x9C5E61DB,0x815B5163,0x4A0782C6,0xCC93F068,0x07CF23CD,
|
||||
0xF6999118,0x3DC542BD,0xBB513013,0x700DE3B6,0x6D08D30E,0xA65400AB,0x20C07205,0xEB9CA1A0,
|
||||
0x11E81EB4,0xDAB4CD11,0x5C20BFBF,0x977C6C1A,0x8A795CA2,0x41258F07,0xC7B1FDA9,0x0CED2E0C,
|
||||
0xFDBB9CD9,0x36E74F7C,0xB0733DD2,0x7B2FEE77,0x662ADECF,0xAD760D6A,0x2BE27FC4,0xE0BEAC61,
|
||||
0x123E1C2F,0xD962CF8A,0x5FF6BD24,0x94AA6E81,0x89AF5E39,0x42F38D9C,0xC467FF32,0x0F3B2C97,
|
||||
0xFE6D9E42,0x35314DE7,0xB3A53F49,0x78F9ECEC,0x65FCDC54,0xAEA00FF1,0x28347D5F,0xE368AEFA,
|
||||
0x16441B82,0xDD18C827,0x5B8CBA89,0x90D0692C,0x8DD55994,0x46898A31,0xC01DF89F,0x0B412B3A,
|
||||
0xFA1799EF,0x314B4A4A,0xB7DF38E4,0x7C83EB41,0x6186DBF9,0xAADA085C,0x2C4E7AF2,0xE712A957,
|
||||
0x15921919,0xDECECABC,0x585AB812,0x93066BB7,0x8E035B0F,0x455F88AA,0xC3CBFA04,0x089729A1,
|
||||
0xF9C19B74,0x329D48D1,0xB4093A7F,0x7F55E9DA,0x6250D962,0xA90C0AC7,0x2F987869,0xE4C4ABCC },
|
||||
|
||||
{ 0x00000000,0xA6770BB4,0x979F1129,0x31E81A9D,0xF44F2413,0x52382FA7,0x63D0353A,0xC5A73E8E,
|
||||
0x33EF4E67,0x959845D3,0xA4705F4E,0x020754FA,0xC7A06A74,0x61D761C0,0x503F7B5D,0xF64870E9,
|
||||
0x67DE9CCE,0xC1A9977A,0xF0418DE7,0x56368653,0x9391B8DD,0x35E6B369,0x040EA9F4,0xA279A240,
|
||||
0x5431D2A9,0xF246D91D,0xC3AEC380,0x65D9C834,0xA07EF6BA,0x0609FD0E,0x37E1E793,0x9196EC27,
|
||||
0xCFBD399C,0x69CA3228,0x582228B5,0xFE552301,0x3BF21D8F,0x9D85163B,0xAC6D0CA6,0x0A1A0712,
|
||||
0xFC5277FB,0x5A257C4F,0x6BCD66D2,0xCDBA6D66,0x081D53E8,0xAE6A585C,0x9F8242C1,0x39F54975,
|
||||
0xA863A552,0x0E14AEE6,0x3FFCB47B,0x998BBFCF,0x5C2C8141,0xFA5B8AF5,0xCBB39068,0x6DC49BDC,
|
||||
0x9B8CEB35,0x3DFBE081,0x0C13FA1C,0xAA64F1A8,0x6FC3CF26,0xC9B4C492,0xF85CDE0F,0x5E2BD5BB,
|
||||
0x440B7579,0xE27C7ECD,0xD3946450,0x75E36FE4,0xB044516A,0x16335ADE,0x27DB4043,0x81AC4BF7,
|
||||
0x77E43B1E,0xD19330AA,0xE07B2A37,0x460C2183,0x83AB1F0D,0x25DC14B9,0x14340E24,0xB2430590,
|
||||
0x23D5E9B7,0x85A2E203,0xB44AF89E,0x123DF32A,0xD79ACDA4,0x71EDC610,0x4005DC8D,0xE672D739,
|
||||
0x103AA7D0,0xB64DAC64,0x87A5B6F9,0x21D2BD4D,0xE47583C3,0x42028877,0x73EA92EA,0xD59D995E,
|
||||
0x8BB64CE5,0x2DC14751,0x1C295DCC,0xBA5E5678,0x7FF968F6,0xD98E6342,0xE86679DF,0x4E11726B,
|
||||
0xB8590282,0x1E2E0936,0x2FC613AB,0x89B1181F,0x4C162691,0xEA612D25,0xDB8937B8,0x7DFE3C0C,
|
||||
0xEC68D02B,0x4A1FDB9F,0x7BF7C102,0xDD80CAB6,0x1827F438,0xBE50FF8C,0x8FB8E511,0x29CFEEA5,
|
||||
0xDF879E4C,0x79F095F8,0x48188F65,0xEE6F84D1,0x2BC8BA5F,0x8DBFB1EB,0xBC57AB76,0x1A20A0C2,
|
||||
0x8816EAF2,0x2E61E146,0x1F89FBDB,0xB9FEF06F,0x7C59CEE1,0xDA2EC555,0xEBC6DFC8,0x4DB1D47C,
|
||||
0xBBF9A495,0x1D8EAF21,0x2C66B5BC,0x8A11BE08,0x4FB68086,0xE9C18B32,0xD82991AF,0x7E5E9A1B,
|
||||
0xEFC8763C,0x49BF7D88,0x78576715,0xDE206CA1,0x1B87522F,0xBDF0599B,0x8C184306,0x2A6F48B2,
|
||||
0xDC27385B,0x7A5033EF,0x4BB82972,0xEDCF22C6,0x28681C48,0x8E1F17FC,0xBFF70D61,0x198006D5,
|
||||
0x47ABD36E,0xE1DCD8DA,0xD034C247,0x7643C9F3,0xB3E4F77D,0x1593FCC9,0x247BE654,0x820CEDE0,
|
||||
0x74449D09,0xD23396BD,0xE3DB8C20,0x45AC8794,0x800BB91A,0x267CB2AE,0x1794A833,0xB1E3A387,
|
||||
0x20754FA0,0x86024414,0xB7EA5E89,0x119D553D,0xD43A6BB3,0x724D6007,0x43A57A9A,0xE5D2712E,
|
||||
0x139A01C7,0xB5ED0A73,0x840510EE,0x22721B5A,0xE7D525D4,0x41A22E60,0x704A34FD,0xD63D3F49,
|
||||
0xCC1D9F8B,0x6A6A943F,0x5B828EA2,0xFDF58516,0x3852BB98,0x9E25B02C,0xAFCDAAB1,0x09BAA105,
|
||||
0xFFF2D1EC,0x5985DA58,0x686DC0C5,0xCE1ACB71,0x0BBDF5FF,0xADCAFE4B,0x9C22E4D6,0x3A55EF62,
|
||||
0xABC30345,0x0DB408F1,0x3C5C126C,0x9A2B19D8,0x5F8C2756,0xF9FB2CE2,0xC813367F,0x6E643DCB,
|
||||
0x982C4D22,0x3E5B4696,0x0FB35C0B,0xA9C457BF,0x6C636931,0xCA146285,0xFBFC7818,0x5D8B73AC,
|
||||
0x03A0A617,0xA5D7ADA3,0x943FB73E,0x3248BC8A,0xF7EF8204,0x519889B0,0x6070932D,0xC6079899,
|
||||
0x304FE870,0x9638E3C4,0xA7D0F959,0x01A7F2ED,0xC400CC63,0x6277C7D7,0x539FDD4A,0xF5E8D6FE,
|
||||
0x647E3AD9,0xC209316D,0xF3E12BF0,0x55962044,0x90311ECA,0x3646157E,0x07AE0FE3,0xA1D90457,
|
||||
0x579174BE,0xF1E67F0A,0xC00E6597,0x66796E23,0xA3DE50AD,0x05A95B19,0x34414184,0x92364A30 },
|
||||
|
||||
{ 0x00000000,0xCCAA009E,0x4225077D,0x8E8F07E3,0x844A0EFA,0x48E00E64,0xC66F0987,0x0AC50919,
|
||||
0xD3E51BB5,0x1F4F1B2B,0x91C01CC8,0x5D6A1C56,0x57AF154F,0x9B0515D1,0x158A1232,0xD92012AC,
|
||||
0x7CBB312B,0xB01131B5,0x3E9E3656,0xF23436C8,0xF8F13FD1,0x345B3F4F,0xBAD438AC,0x767E3832,
|
||||
0xAF5E2A9E,0x63F42A00,0xED7B2DE3,0x21D12D7D,0x2B142464,0xE7BE24FA,0x69312319,0xA59B2387,
|
||||
0xF9766256,0x35DC62C8,0xBB53652B,0x77F965B5,0x7D3C6CAC,0xB1966C32,0x3F196BD1,0xF3B36B4F,
|
||||
0x2A9379E3,0xE639797D,0x68B67E9E,0xA41C7E00,0xAED97719,0x62737787,0xECFC7064,0x205670FA,
|
||||
0x85CD537D,0x496753E3,0xC7E85400,0x0B42549E,0x01875D87,0xCD2D5D19,0x43A25AFA,0x8F085A64,
|
||||
0x562848C8,0x9A824856,0x140D4FB5,0xD8A74F2B,0xD2624632,0x1EC846AC,0x9047414F,0x5CED41D1,
|
||||
0x299DC2ED,0xE537C273,0x6BB8C590,0xA712C50E,0xADD7CC17,0x617DCC89,0xEFF2CB6A,0x2358CBF4,
|
||||
0xFA78D958,0x36D2D9C6,0xB85DDE25,0x74F7DEBB,0x7E32D7A2,0xB298D73C,0x3C17D0DF,0xF0BDD041,
|
||||
0x5526F3C6,0x998CF358,0x1703F4BB,0xDBA9F425,0xD16CFD3C,0x1DC6FDA2,0x9349FA41,0x5FE3FADF,
|
||||
0x86C3E873,0x4A69E8ED,0xC4E6EF0E,0x084CEF90,0x0289E689,0xCE23E617,0x40ACE1F4,0x8C06E16A,
|
||||
0xD0EBA0BB,0x1C41A025,0x92CEA7C6,0x5E64A758,0x54A1AE41,0x980BAEDF,0x1684A93C,0xDA2EA9A2,
|
||||
0x030EBB0E,0xCFA4BB90,0x412BBC73,0x8D81BCED,0x8744B5F4,0x4BEEB56A,0xC561B289,0x09CBB217,
|
||||
0xAC509190,0x60FA910E,0xEE7596ED,0x22DF9673,0x281A9F6A,0xE4B09FF4,0x6A3F9817,0xA6959889,
|
||||
0x7FB58A25,0xB31F8ABB,0x3D908D58,0xF13A8DC6,0xFBFF84DF,0x37558441,0xB9DA83A2,0x7570833C,
|
||||
0x533B85DA,0x9F918544,0x111E82A7,0xDDB48239,0xD7718B20,0x1BDB8BBE,0x95548C5D,0x59FE8CC3,
|
||||
0x80DE9E6F,0x4C749EF1,0xC2FB9912,0x0E51998C,0x04949095,0xC83E900B,0x46B197E8,0x8A1B9776,
|
||||
0x2F80B4F1,0xE32AB46F,0x6DA5B38C,0xA10FB312,0xABCABA0B,0x6760BA95,0xE9EFBD76,0x2545BDE8,
|
||||
0xFC65AF44,0x30CFAFDA,0xBE40A839,0x72EAA8A7,0x782FA1BE,0xB485A120,0x3A0AA6C3,0xF6A0A65D,
|
||||
0xAA4DE78C,0x66E7E712,0xE868E0F1,0x24C2E06F,0x2E07E976,0xE2ADE9E8,0x6C22EE0B,0xA088EE95,
|
||||
0x79A8FC39,0xB502FCA7,0x3B8DFB44,0xF727FBDA,0xFDE2F2C3,0x3148F25D,0xBFC7F5BE,0x736DF520,
|
||||
0xD6F6D6A7,0x1A5CD639,0x94D3D1DA,0x5879D144,0x52BCD85D,0x9E16D8C3,0x1099DF20,0xDC33DFBE,
|
||||
0x0513CD12,0xC9B9CD8C,0x4736CA6F,0x8B9CCAF1,0x8159C3E8,0x4DF3C376,0xC37CC495,0x0FD6C40B,
|
||||
0x7AA64737,0xB60C47A9,0x3883404A,0xF42940D4,0xFEEC49CD,0x32464953,0xBCC94EB0,0x70634E2E,
|
||||
0xA9435C82,0x65E95C1C,0xEB665BFF,0x27CC5B61,0x2D095278,0xE1A352E6,0x6F2C5505,0xA386559B,
|
||||
0x061D761C,0xCAB77682,0x44387161,0x889271FF,0x825778E6,0x4EFD7878,0xC0727F9B,0x0CD87F05,
|
||||
0xD5F86DA9,0x19526D37,0x97DD6AD4,0x5B776A4A,0x51B26353,0x9D1863CD,0x1397642E,0xDF3D64B0,
|
||||
0x83D02561,0x4F7A25FF,0xC1F5221C,0x0D5F2282,0x079A2B9B,0xCB302B05,0x45BF2CE6,0x89152C78,
|
||||
0x50353ED4,0x9C9F3E4A,0x121039A9,0xDEBA3937,0xD47F302E,0x18D530B0,0x965A3753,0x5AF037CD,
|
||||
0xFF6B144A,0x33C114D4,0xBD4E1337,0x71E413A9,0x7B211AB0,0xB78B1A2E,0x39041DCD,0xF5AE1D53,
|
||||
0x2C8E0FFF,0xE0240F61,0x6EAB0882,0xA201081C,0xA8C40105,0x646E019B,0xEAE10678,0x264B06E6 }
|
||||
};
|
||||
|
||||
inline uint32_t swap(uint32_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap32(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ulong(x);
|
||||
#endif
|
||||
|
||||
return (x >> 24) |
|
||||
((x >> 8) & 0x0000FF00) |
|
||||
((x << 8) & 0x00FF0000) |
|
||||
(x << 24);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void CRC32::add(const void* data, size_t numBytes)
|
||||
{
|
||||
uint32_t* current = (uint32_t*) data;
|
||||
uint32_t crc = ~m_hash;
|
||||
|
||||
// process eight bytes at once
|
||||
while (numBytes >= 8)
|
||||
{
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
uint32_t one = *current++ ^ swap(crc);
|
||||
uint32_t two = *current++;
|
||||
crc = crc32Lookup[7][ one>>24 ] ^
|
||||
crc32Lookup[6][(one>>16) & 0xFF] ^
|
||||
crc32Lookup[5][(one>> 8) & 0xFF] ^
|
||||
crc32Lookup[4][ one & 0xFF] ^
|
||||
crc32Lookup[3][ two>>24 ] ^
|
||||
crc32Lookup[2][(two>>16) & 0xFF] ^
|
||||
crc32Lookup[1][(two>> 8) & 0xFF] ^
|
||||
crc32Lookup[0][ two & 0xFF];
|
||||
#else
|
||||
uint32_t one = *current++ ^ crc;
|
||||
uint32_t two = *current++;
|
||||
crc = crc32Lookup[7][ one & 0xFF] ^
|
||||
crc32Lookup[6][(one>> 8) & 0xFF] ^
|
||||
crc32Lookup[5][(one>>16) & 0xFF] ^
|
||||
crc32Lookup[4][ one>>24 ] ^
|
||||
crc32Lookup[3][ two & 0xFF] ^
|
||||
crc32Lookup[2][(two>> 8) & 0xFF] ^
|
||||
crc32Lookup[1][(two>>16) & 0xFF] ^
|
||||
crc32Lookup[0][ two>>24 ];
|
||||
#endif
|
||||
numBytes -= 8;
|
||||
}
|
||||
|
||||
unsigned char* currentChar = (unsigned char*) current;
|
||||
// remaining 1 to 7 bytes (standard CRC table-based algorithm)
|
||||
while (numBytes--)
|
||||
crc = (crc >> 8) ^ crc32Lookup[0][(crc & 0xFF) ^ *currentChar++];
|
||||
|
||||
m_hash = ~crc;
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* CRC32::getHash()
|
||||
{
|
||||
// convert hash to string
|
||||
static const char dec2hex[16+1] = "0123456789abcdef";
|
||||
|
||||
static char hashBuffer[8+1];
|
||||
|
||||
hashBuffer[0] = dec2hex[ m_hash >> 28 ];
|
||||
hashBuffer[1] = dec2hex[(m_hash >> 24) & 15];
|
||||
hashBuffer[2] = dec2hex[(m_hash >> 20) & 15];
|
||||
hashBuffer[3] = dec2hex[(m_hash >> 16) & 15];
|
||||
hashBuffer[4] = dec2hex[(m_hash >> 12) & 15];
|
||||
hashBuffer[5] = dec2hex[(m_hash >> 8) & 15];
|
||||
hashBuffer[6] = dec2hex[(m_hash >> 4) & 15];
|
||||
hashBuffer[7] = dec2hex[ m_hash & 15];
|
||||
|
||||
// zero-terminated string
|
||||
hashBuffer[8] = 0;
|
||||
|
||||
// convert to std::string
|
||||
return (const char *)hashBuffer;
|
||||
}
|
||||
|
||||
|
||||
/// compute CRC32 of a memory block
|
||||
const char* CRC32::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute CRC32 of a string, excluding final zero
|
||||
const char* CRC32::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
47
public/hashing/hashers/crc32.h
Normal file
47
public/hashing/hashers/crc32.h
Normal file
@ -0,0 +1,47 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// crc32.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute CRC32 hash, based on Intel's Slicing-by-8 algorithm
|
||||
/** Usage:
|
||||
CRC32 crc32;
|
||||
std::string myHash = crc32("Hello World"); // std::string
|
||||
std::string myHash2 = crc32("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
CRC32 crc32;
|
||||
while (more data available)
|
||||
crc32.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = crc32.getHash();
|
||||
*/
|
||||
class CRC32 //: public Hash
|
||||
{
|
||||
public:
|
||||
/// same as reset()
|
||||
CRC32();
|
||||
|
||||
/// compute CRC32 of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute CRC32 of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// hash
|
||||
uint32_t m_hash;
|
||||
};
|
280
public/hashing/hashers/keccak.cpp
Normal file
280
public/hashing/hashers/keccak.cpp
Normal file
@ -0,0 +1,280 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// keccak.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "keccak.h"
|
||||
|
||||
|
||||
/// same as reset()
|
||||
Keccak::Keccak(Bits bits)
|
||||
: m_blockSize(200 - 2 * (bits / 8)),
|
||||
m_bits(bits)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/// same as reset()
|
||||
void Keccak::changeBits(Bits bits)
|
||||
{
|
||||
m_blockSize = (200 - 2 * (bits / 8));
|
||||
m_bits = bits;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
/// restart
|
||||
void Keccak::reset()
|
||||
{
|
||||
for (size_t i = 0; i < StateSize; i++)
|
||||
m_hash[i] = 0;
|
||||
|
||||
m_numBytes = 0;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
|
||||
/// constants and local helper functions
|
||||
namespace
|
||||
{
|
||||
const unsigned int KeccakRounds = 24;
|
||||
const uint64_t XorMasks[KeccakRounds] =
|
||||
{
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
|
||||
0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
|
||||
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
|
||||
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
|
||||
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
|
||||
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
|
||||
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
|
||||
};
|
||||
|
||||
/// rotate left and wrap around to the right
|
||||
inline uint64_t rotateLeft(uint64_t x, uint8_t numBits)
|
||||
{
|
||||
return (x << numBits) | (x >> (64 - numBits));
|
||||
}
|
||||
|
||||
/// convert litte vs big endian
|
||||
inline uint64_t swap(uint64_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap64(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_uint64(x);
|
||||
#endif
|
||||
|
||||
return (x >> 56) |
|
||||
((x >> 40) & 0x000000000000FF00ULL) |
|
||||
((x >> 24) & 0x0000000000FF0000ULL) |
|
||||
((x >> 8) & 0x00000000FF000000ULL) |
|
||||
((x << 8) & 0x000000FF00000000ULL) |
|
||||
((x << 24) & 0x0000FF0000000000ULL) |
|
||||
((x << 40) & 0x00FF000000000000ULL) |
|
||||
(x << 56);
|
||||
}
|
||||
|
||||
|
||||
/// return x % 5 for 0 <= x <= 9
|
||||
unsigned int mod5(unsigned int x)
|
||||
{
|
||||
if (x < 5)
|
||||
return x;
|
||||
|
||||
return x - 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process a full block
|
||||
void Keccak::processBlock(const void* data)
|
||||
{
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
#define LITTLEENDIAN(x) swap(x)
|
||||
#else
|
||||
#define LITTLEENDIAN(x) (x)
|
||||
#endif
|
||||
|
||||
const uint64_t* data64 = (const uint64_t*) data;
|
||||
// mix data into state
|
||||
for (unsigned int i = 0; i < m_blockSize / 8; i++)
|
||||
m_hash[i] ^= LITTLEENDIAN(data64[i]);
|
||||
|
||||
// re-compute state
|
||||
for (unsigned int round = 0; round < KeccakRounds; round++)
|
||||
{
|
||||
// Theta
|
||||
uint64_t coefficients[5];
|
||||
for (unsigned int i = 0; i < 5; i++)
|
||||
coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20];
|
||||
|
||||
for (unsigned int i = 0; i < 5; i++)
|
||||
{
|
||||
uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1);
|
||||
m_hash[i ] ^= one;
|
||||
m_hash[i + 5] ^= one;
|
||||
m_hash[i + 10] ^= one;
|
||||
m_hash[i + 15] ^= one;
|
||||
m_hash[i + 20] ^= one;
|
||||
}
|
||||
|
||||
// temporary
|
||||
uint64_t one;
|
||||
|
||||
// Rho Pi
|
||||
uint64_t last = m_hash[1];
|
||||
one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one;
|
||||
one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one;
|
||||
one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one;
|
||||
one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one;
|
||||
one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one;
|
||||
one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one;
|
||||
one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one;
|
||||
one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one;
|
||||
one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one;
|
||||
one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one;
|
||||
one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one;
|
||||
one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one;
|
||||
one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one;
|
||||
one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one;
|
||||
one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one;
|
||||
one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one;
|
||||
one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one;
|
||||
one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one;
|
||||
one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one;
|
||||
one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one;
|
||||
one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one;
|
||||
one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one;
|
||||
one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one;
|
||||
m_hash[ 1] = rotateLeft(last, 44);
|
||||
|
||||
// Chi
|
||||
for (unsigned int j = 0; j < 25; j += 5)
|
||||
{
|
||||
// temporaries
|
||||
uint64_t one = m_hash[j];
|
||||
uint64_t two = m_hash[j + 1];
|
||||
|
||||
m_hash[j] ^= m_hash[j + 2] & ~two;
|
||||
m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2];
|
||||
m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3];
|
||||
m_hash[j + 3] ^= one & ~m_hash[j + 4];
|
||||
m_hash[j + 4] ^= two & ~one;
|
||||
}
|
||||
|
||||
// Iota
|
||||
m_hash[0] ^= XorMasks[round];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void Keccak::add(const void* data, size_t numBytes)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*) data;
|
||||
|
||||
if (m_bufferSize > 0)
|
||||
{
|
||||
while (numBytes > 0 && m_bufferSize < m_blockSize)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
// full buffer
|
||||
if (m_bufferSize == m_blockSize)
|
||||
{
|
||||
processBlock((void*)m_buffer);
|
||||
m_numBytes += m_blockSize;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
// no more data ?
|
||||
if (numBytes == 0)
|
||||
return;
|
||||
|
||||
// process full blocks
|
||||
while (numBytes >= m_blockSize)
|
||||
{
|
||||
processBlock(current);
|
||||
current += m_blockSize;
|
||||
m_numBytes += m_blockSize;
|
||||
numBytes -= m_blockSize;
|
||||
}
|
||||
|
||||
// keep remaining bytes in buffer
|
||||
while (numBytes > 0)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process everything left in the internal buffer
|
||||
void Keccak::processBuffer()
|
||||
{
|
||||
unsigned int blockSize = 200 - 2 * (m_bits / 8);
|
||||
|
||||
// add padding
|
||||
size_t offset = m_bufferSize;
|
||||
// add a "1" byte
|
||||
m_buffer[offset++] = 1;
|
||||
// fill with zeros
|
||||
while (offset < blockSize - 1)
|
||||
m_buffer[offset++] = 0;
|
||||
|
||||
// and add a single set bit
|
||||
m_buffer[blockSize - 1] = 0x80;
|
||||
|
||||
processBlock(m_buffer);
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* Keccak::getHash()
|
||||
{
|
||||
// process remaining bytes
|
||||
processBuffer();
|
||||
|
||||
// convert hash to string
|
||||
static const char dec2hex[16 + 1] = "0123456789abcdef";
|
||||
|
||||
// number of significant elements in hash (uint64_t)
|
||||
unsigned int hashLength = m_bits / 64;
|
||||
|
||||
static char result[128+1];
|
||||
size_t written = 0;
|
||||
for (unsigned int i = 0; i < hashLength; i++)
|
||||
for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes
|
||||
{
|
||||
// convert a byte to hex
|
||||
unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j));
|
||||
result[written++] = dec2hex[oneByte >> 4];
|
||||
result[written++] = dec2hex[oneByte & 15];
|
||||
}
|
||||
result[written] = 0;
|
||||
return (const char *)result;
|
||||
}
|
||||
|
||||
|
||||
/// compute Keccak hash of a memory block
|
||||
const char* Keccak::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute Keccak hash of a string, excluding final zero
|
||||
const char* Keccak::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
72
public/hashing/hashers/keccak.h
Normal file
72
public/hashing/hashers/keccak.h
Normal file
@ -0,0 +1,72 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// keccak.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute Keccak hash (designated SHA3)
|
||||
/** Usage:
|
||||
Keccak keccak;
|
||||
std::string myHash = keccak("Hello World"); // std::string
|
||||
std::string myHash2 = keccak("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
Keccak keccak;
|
||||
while (more data available)
|
||||
keccak.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = keccak.getHash();
|
||||
*/
|
||||
class Keccak //: public Hash
|
||||
{
|
||||
public:
|
||||
/// algorithm variants
|
||||
enum Bits { Keccak224 = 224, Keccak256 = 256, Keccak384 = 384, Keccak512 = 512 };
|
||||
|
||||
/// same as reset()
|
||||
explicit Keccak(Bits bits = Keccak256);
|
||||
|
||||
/// compute hash of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute hash of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// same as reset()
|
||||
void changeBits(Bits bits);
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// process a full block
|
||||
void processBlock(const void* data);
|
||||
/// process everything left in the internal buffer
|
||||
void processBuffer();
|
||||
|
||||
/// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224)
|
||||
enum { StateSize = 1600 / (8 * 8),
|
||||
MaxBlockSize = 200 - 2 * (224 / 8) };
|
||||
|
||||
/// hash
|
||||
uint64_t m_hash[StateSize];
|
||||
/// size of processed data in bytes
|
||||
uint64_t m_numBytes;
|
||||
/// block size (less or equal to MaxBlockSize)
|
||||
size_t m_blockSize;
|
||||
/// valid bytes in m_buffer
|
||||
size_t m_bufferSize;
|
||||
/// bytes not processed yet
|
||||
uint8_t m_buffer[MaxBlockSize];
|
||||
/// variant
|
||||
Bits m_bits;
|
||||
};
|
398
public/hashing/hashers/md5.cpp
Normal file
398
public/hashing/hashers/md5.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// md5.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/// same as reset()
|
||||
MD5::MD5()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/// restart
|
||||
void MD5::reset()
|
||||
{
|
||||
m_numBytes = 0;
|
||||
m_bufferSize = 0;
|
||||
|
||||
// according to RFC 1321
|
||||
m_hash[0] = 0x67452301;
|
||||
m_hash[1] = 0xefcdab89;
|
||||
m_hash[2] = 0x98badcfe;
|
||||
m_hash[3] = 0x10325476;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// mix functions for processBlock()
|
||||
inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d);
|
||||
}
|
||||
|
||||
inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return c ^ (d & (b ^ c)); // original: f = (b & d) | (c & (~d));
|
||||
}
|
||||
|
||||
inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return b ^ c ^ d;
|
||||
}
|
||||
|
||||
inline uint32_t f4(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return c ^ (b | ~d);
|
||||
}
|
||||
|
||||
inline uint32_t rotate(uint32_t a, uint32_t c)
|
||||
{
|
||||
return (a << c) | (a >> (32 - c));
|
||||
}
|
||||
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
inline uint32_t swap(uint32_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap32(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ulong(x);
|
||||
#endif
|
||||
|
||||
return (x >> 24) |
|
||||
((x >> 8) & 0x0000FF00) |
|
||||
((x << 8) & 0x00FF0000) |
|
||||
(x << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// process 64 bytes
|
||||
void MD5::processBlock(const void* data)
|
||||
{
|
||||
// get last hash
|
||||
uint32_t a = m_hash[0];
|
||||
uint32_t b = m_hash[1];
|
||||
uint32_t c = m_hash[2];
|
||||
uint32_t d = m_hash[3];
|
||||
|
||||
// data represented as 16x 32-bit words
|
||||
const uint32_t* words = (uint32_t*) data;
|
||||
|
||||
// computations are little endian, swap data if necessary
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
#define LITTLEENDIAN(x) swap(x)
|
||||
#else
|
||||
#define LITTLEENDIAN(x) (x)
|
||||
#endif
|
||||
|
||||
// first round
|
||||
uint32_t word0 = LITTLEENDIAN(words[ 0]);
|
||||
a = rotate(a + f1(b,c,d) + word0 + 0xd76aa478, 7) + b;
|
||||
uint32_t word1 = LITTLEENDIAN(words[ 1]);
|
||||
d = rotate(d + f1(a,b,c) + word1 + 0xe8c7b756, 12) + a;
|
||||
uint32_t word2 = LITTLEENDIAN(words[ 2]);
|
||||
c = rotate(c + f1(d,a,b) + word2 + 0x242070db, 17) + d;
|
||||
uint32_t word3 = LITTLEENDIAN(words[ 3]);
|
||||
b = rotate(b + f1(c,d,a) + word3 + 0xc1bdceee, 22) + c;
|
||||
|
||||
uint32_t word4 = LITTLEENDIAN(words[ 4]);
|
||||
a = rotate(a + f1(b,c,d) + word4 + 0xf57c0faf, 7) + b;
|
||||
uint32_t word5 = LITTLEENDIAN(words[ 5]);
|
||||
d = rotate(d + f1(a,b,c) + word5 + 0x4787c62a, 12) + a;
|
||||
uint32_t word6 = LITTLEENDIAN(words[ 6]);
|
||||
c = rotate(c + f1(d,a,b) + word6 + 0xa8304613, 17) + d;
|
||||
uint32_t word7 = LITTLEENDIAN(words[ 7]);
|
||||
b = rotate(b + f1(c,d,a) + word7 + 0xfd469501, 22) + c;
|
||||
|
||||
uint32_t word8 = LITTLEENDIAN(words[ 8]);
|
||||
a = rotate(a + f1(b,c,d) + word8 + 0x698098d8, 7) + b;
|
||||
uint32_t word9 = LITTLEENDIAN(words[ 9]);
|
||||
d = rotate(d + f1(a,b,c) + word9 + 0x8b44f7af, 12) + a;
|
||||
uint32_t word10 = LITTLEENDIAN(words[10]);
|
||||
c = rotate(c + f1(d,a,b) + word10 + 0xffff5bb1, 17) + d;
|
||||
uint32_t word11 = LITTLEENDIAN(words[11]);
|
||||
b = rotate(b + f1(c,d,a) + word11 + 0x895cd7be, 22) + c;
|
||||
|
||||
uint32_t word12 = LITTLEENDIAN(words[12]);
|
||||
a = rotate(a + f1(b,c,d) + word12 + 0x6b901122, 7) + b;
|
||||
uint32_t word13 = LITTLEENDIAN(words[13]);
|
||||
d = rotate(d + f1(a,b,c) + word13 + 0xfd987193, 12) + a;
|
||||
uint32_t word14 = LITTLEENDIAN(words[14]);
|
||||
c = rotate(c + f1(d,a,b) + word14 + 0xa679438e, 17) + d;
|
||||
uint32_t word15 = LITTLEENDIAN(words[15]);
|
||||
b = rotate(b + f1(c,d,a) + word15 + 0x49b40821, 22) + c;
|
||||
|
||||
// second round
|
||||
a = rotate(a + f2(b,c,d) + word1 + 0xf61e2562, 5) + b;
|
||||
d = rotate(d + f2(a,b,c) + word6 + 0xc040b340, 9) + a;
|
||||
c = rotate(c + f2(d,a,b) + word11 + 0x265e5a51, 14) + d;
|
||||
b = rotate(b + f2(c,d,a) + word0 + 0xe9b6c7aa, 20) + c;
|
||||
|
||||
a = rotate(a + f2(b,c,d) + word5 + 0xd62f105d, 5) + b;
|
||||
d = rotate(d + f2(a,b,c) + word10 + 0x02441453, 9) + a;
|
||||
c = rotate(c + f2(d,a,b) + word15 + 0xd8a1e681, 14) + d;
|
||||
b = rotate(b + f2(c,d,a) + word4 + 0xe7d3fbc8, 20) + c;
|
||||
|
||||
a = rotate(a + f2(b,c,d) + word9 + 0x21e1cde6, 5) + b;
|
||||
d = rotate(d + f2(a,b,c) + word14 + 0xc33707d6, 9) + a;
|
||||
c = rotate(c + f2(d,a,b) + word3 + 0xf4d50d87, 14) + d;
|
||||
b = rotate(b + f2(c,d,a) + word8 + 0x455a14ed, 20) + c;
|
||||
|
||||
a = rotate(a + f2(b,c,d) + word13 + 0xa9e3e905, 5) + b;
|
||||
d = rotate(d + f2(a,b,c) + word2 + 0xfcefa3f8, 9) + a;
|
||||
c = rotate(c + f2(d,a,b) + word7 + 0x676f02d9, 14) + d;
|
||||
b = rotate(b + f2(c,d,a) + word12 + 0x8d2a4c8a, 20) + c;
|
||||
|
||||
// third round
|
||||
a = rotate(a + f3(b,c,d) + word5 + 0xfffa3942, 4) + b;
|
||||
d = rotate(d + f3(a,b,c) + word8 + 0x8771f681, 11) + a;
|
||||
c = rotate(c + f3(d,a,b) + word11 + 0x6d9d6122, 16) + d;
|
||||
b = rotate(b + f3(c,d,a) + word14 + 0xfde5380c, 23) + c;
|
||||
|
||||
a = rotate(a + f3(b,c,d) + word1 + 0xa4beea44, 4) + b;
|
||||
d = rotate(d + f3(a,b,c) + word4 + 0x4bdecfa9, 11) + a;
|
||||
c = rotate(c + f3(d,a,b) + word7 + 0xf6bb4b60, 16) + d;
|
||||
b = rotate(b + f3(c,d,a) + word10 + 0xbebfbc70, 23) + c;
|
||||
|
||||
a = rotate(a + f3(b,c,d) + word13 + 0x289b7ec6, 4) + b;
|
||||
d = rotate(d + f3(a,b,c) + word0 + 0xeaa127fa, 11) + a;
|
||||
c = rotate(c + f3(d,a,b) + word3 + 0xd4ef3085, 16) + d;
|
||||
b = rotate(b + f3(c,d,a) + word6 + 0x04881d05, 23) + c;
|
||||
|
||||
a = rotate(a + f3(b,c,d) + word9 + 0xd9d4d039, 4) + b;
|
||||
d = rotate(d + f3(a,b,c) + word12 + 0xe6db99e5, 11) + a;
|
||||
c = rotate(c + f3(d,a,b) + word15 + 0x1fa27cf8, 16) + d;
|
||||
b = rotate(b + f3(c,d,a) + word2 + 0xc4ac5665, 23) + c;
|
||||
|
||||
// fourth round
|
||||
a = rotate(a + f4(b,c,d) + word0 + 0xf4292244, 6) + b;
|
||||
d = rotate(d + f4(a,b,c) + word7 + 0x432aff97, 10) + a;
|
||||
c = rotate(c + f4(d,a,b) + word14 + 0xab9423a7, 15) + d;
|
||||
b = rotate(b + f4(c,d,a) + word5 + 0xfc93a039, 21) + c;
|
||||
|
||||
a = rotate(a + f4(b,c,d) + word12 + 0x655b59c3, 6) + b;
|
||||
d = rotate(d + f4(a,b,c) + word3 + 0x8f0ccc92, 10) + a;
|
||||
c = rotate(c + f4(d,a,b) + word10 + 0xffeff47d, 15) + d;
|
||||
b = rotate(b + f4(c,d,a) + word1 + 0x85845dd1, 21) + c;
|
||||
|
||||
a = rotate(a + f4(b,c,d) + word8 + 0x6fa87e4f, 6) + b;
|
||||
d = rotate(d + f4(a,b,c) + word15 + 0xfe2ce6e0, 10) + a;
|
||||
c = rotate(c + f4(d,a,b) + word6 + 0xa3014314, 15) + d;
|
||||
b = rotate(b + f4(c,d,a) + word13 + 0x4e0811a1, 21) + c;
|
||||
|
||||
a = rotate(a + f4(b,c,d) + word4 + 0xf7537e82, 6) + b;
|
||||
d = rotate(d + f4(a,b,c) + word11 + 0xbd3af235, 10) + a;
|
||||
c = rotate(c + f4(d,a,b) + word2 + 0x2ad7d2bb, 15) + d;
|
||||
b = rotate(b + f4(c,d,a) + word9 + 0xeb86d391, 21) + c;
|
||||
|
||||
// update hash
|
||||
m_hash[0] += a;
|
||||
m_hash[1] += b;
|
||||
m_hash[2] += c;
|
||||
m_hash[3] += d;
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void MD5::add(const void* data, size_t numBytes)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*) data;
|
||||
|
||||
if (m_bufferSize > 0)
|
||||
{
|
||||
while (numBytes > 0 && m_bufferSize < BlockSize)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
// full buffer
|
||||
if (m_bufferSize == BlockSize)
|
||||
{
|
||||
processBlock(m_buffer);
|
||||
m_numBytes += BlockSize;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
// no more data ?
|
||||
if (numBytes == 0)
|
||||
return;
|
||||
|
||||
// process full blocks
|
||||
while (numBytes >= BlockSize)
|
||||
{
|
||||
processBlock(current);
|
||||
current += BlockSize;
|
||||
m_numBytes += BlockSize;
|
||||
numBytes -= BlockSize;
|
||||
}
|
||||
|
||||
// keep remaining bytes in buffer
|
||||
while (numBytes > 0)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process final block, less than 64 bytes
|
||||
void MD5::processBuffer()
|
||||
{
|
||||
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
|
||||
|
||||
// - append "1" bit to message
|
||||
// - append "0" bits until message length in bit mod 512 is 448
|
||||
// - append length as 64 bit integer
|
||||
|
||||
// number of bits
|
||||
size_t paddedLength = m_bufferSize * 8;
|
||||
|
||||
// plus one bit set to 1 (always appended)
|
||||
paddedLength++;
|
||||
|
||||
// number of bits must be (numBits % 512) = 448
|
||||
size_t lower11Bits = paddedLength & 511;
|
||||
if (lower11Bits <= 448)
|
||||
paddedLength += 448 - lower11Bits;
|
||||
else
|
||||
paddedLength += 512 + 448 - lower11Bits;
|
||||
// convert from bits to bytes
|
||||
paddedLength /= 8;
|
||||
|
||||
// only needed if additional data flows over into a second block
|
||||
unsigned char extra[BlockSize];
|
||||
|
||||
// append a "1" bit, 128 => binary 10000000
|
||||
if (m_bufferSize < BlockSize)
|
||||
m_buffer[m_bufferSize] = 128;
|
||||
else
|
||||
extra[0] = 128;
|
||||
|
||||
size_t i;
|
||||
for (i = m_bufferSize + 1; i < BlockSize; i++)
|
||||
m_buffer[i] = 0;
|
||||
for (; i < paddedLength; i++)
|
||||
extra[i - BlockSize] = 0;
|
||||
|
||||
// add message length in bits as 64 bit number
|
||||
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
|
||||
// find right position
|
||||
unsigned char* addLength;
|
||||
if (paddedLength < BlockSize)
|
||||
addLength = m_buffer + paddedLength;
|
||||
else
|
||||
addLength = extra + paddedLength - BlockSize;
|
||||
|
||||
// must be little endian
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF; msgBits >>= 8;
|
||||
*addLength++ = msgBits & 0xFF;
|
||||
|
||||
// process blocks
|
||||
processBlock(m_buffer);
|
||||
// flowed over into a second block ?
|
||||
if (paddedLength > BlockSize)
|
||||
processBlock(extra);
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* MD5::getHash()
|
||||
{
|
||||
// convert hash to string
|
||||
static const char dec2hex[16+1] = "0123456789abcdef";
|
||||
|
||||
// save old hash if buffer is partially filled
|
||||
uint32_t oldHash[4];
|
||||
oldHash[0] = m_hash[0];
|
||||
oldHash[1] = m_hash[1];
|
||||
oldHash[2] = m_hash[2];
|
||||
oldHash[3] = m_hash[3];
|
||||
|
||||
// process remaining bytes
|
||||
processBuffer();
|
||||
|
||||
// create hash string
|
||||
static char hashBuffer[4*8+1];
|
||||
|
||||
hashBuffer[ 0] = dec2hex[(m_hash[0] >> 4) & 15];
|
||||
hashBuffer[ 1] = dec2hex[ m_hash[0] & 15];
|
||||
hashBuffer[ 2] = dec2hex[(m_hash[0] >> 12) & 15];
|
||||
hashBuffer[ 3] = dec2hex[(m_hash[0] >> 8) & 15];
|
||||
hashBuffer[ 4] = dec2hex[(m_hash[0] >> 20) & 15];
|
||||
hashBuffer[ 5] = dec2hex[(m_hash[0] >> 16) & 15];
|
||||
hashBuffer[ 6] = dec2hex[ m_hash[0] >> 28 ];
|
||||
hashBuffer[ 7] = dec2hex[(m_hash[0] >> 24) & 15];
|
||||
|
||||
hashBuffer[ 8] = dec2hex[(m_hash[1] >> 4) & 15];
|
||||
hashBuffer[ 9] = dec2hex[ m_hash[1] & 15];
|
||||
hashBuffer[10] = dec2hex[(m_hash[1] >> 12) & 15];
|
||||
hashBuffer[11] = dec2hex[(m_hash[1] >> 8) & 15];
|
||||
hashBuffer[12] = dec2hex[(m_hash[1] >> 20) & 15];
|
||||
hashBuffer[13] = dec2hex[(m_hash[1] >> 16) & 15];
|
||||
hashBuffer[14] = dec2hex[ m_hash[1] >> 28 ];
|
||||
hashBuffer[15] = dec2hex[(m_hash[1] >> 24) & 15];
|
||||
|
||||
hashBuffer[16] = dec2hex[(m_hash[2] >> 4) & 15];
|
||||
hashBuffer[17] = dec2hex[ m_hash[2] & 15];
|
||||
hashBuffer[18] = dec2hex[(m_hash[2] >> 12) & 15];
|
||||
hashBuffer[19] = dec2hex[(m_hash[2] >> 8) & 15];
|
||||
hashBuffer[20] = dec2hex[(m_hash[2] >> 20) & 15];
|
||||
hashBuffer[21] = dec2hex[(m_hash[2] >> 16) & 15];
|
||||
hashBuffer[22] = dec2hex[ m_hash[2] >> 28 ];
|
||||
hashBuffer[23] = dec2hex[(m_hash[2] >> 24) & 15];
|
||||
|
||||
hashBuffer[24] = dec2hex[(m_hash[3] >> 4) & 15];
|
||||
hashBuffer[25] = dec2hex[ m_hash[3] & 15];
|
||||
hashBuffer[26] = dec2hex[(m_hash[3] >> 12) & 15];
|
||||
hashBuffer[27] = dec2hex[(m_hash[3] >> 8) & 15];
|
||||
hashBuffer[28] = dec2hex[(m_hash[3] >> 20) & 15];
|
||||
hashBuffer[29] = dec2hex[(m_hash[3] >> 16) & 15];
|
||||
hashBuffer[30] = dec2hex[ m_hash[3] >> 28 ];
|
||||
hashBuffer[31] = dec2hex[(m_hash[3] >> 24) & 15];
|
||||
|
||||
// zero-terminated string
|
||||
hashBuffer[32] = 0;
|
||||
|
||||
// restore old hash
|
||||
m_hash[0] = oldHash[0];
|
||||
m_hash[1] = oldHash[1];
|
||||
m_hash[2] = oldHash[2];
|
||||
m_hash[3] = oldHash[3];
|
||||
|
||||
// convert to std::string
|
||||
return (const char*)hashBuffer;
|
||||
}
|
||||
|
||||
|
||||
/// compute MD5 of a memory block
|
||||
const char* MD5::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute MD5 of a string, excluding final zero
|
||||
const char* MD5::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
61
public/hashing/hashers/md5.h
Normal file
61
public/hashing/hashers/md5.h
Normal file
@ -0,0 +1,61 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// md5.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute MD5 hash
|
||||
/** Usage:
|
||||
MD5 md5;
|
||||
std::string myHash = md5("Hello World"); // std::string
|
||||
std::string myHash2 = md5("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
MD5 md5;
|
||||
while (more data available)
|
||||
md5.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = md5.getHash();
|
||||
*/
|
||||
class MD5 //: public Hash
|
||||
{
|
||||
public:
|
||||
/// same as reset()
|
||||
MD5();
|
||||
|
||||
/// compute MD5 of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute MD5 of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// process 64 bytes
|
||||
void processBlock(const void* data);
|
||||
/// process everything left in the internal buffer
|
||||
void processBuffer();
|
||||
|
||||
/// split into 64 byte blocks (=> 512 bits)
|
||||
enum { BlockSize = 512 / 8 };
|
||||
|
||||
/// size of processed data in bytes
|
||||
uint64_t m_numBytes;
|
||||
/// valid bytes in m_buffer
|
||||
size_t m_bufferSize;
|
||||
/// bytes not processed yet
|
||||
uint8_t m_buffer[BlockSize];
|
||||
/// hash, stored as integers
|
||||
uint32_t m_hash[4];
|
||||
};
|
313
public/hashing/hashers/sha1.cpp
Normal file
313
public/hashing/hashers/sha1.cpp
Normal file
@ -0,0 +1,313 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha1.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
/// same as reset()
|
||||
SHA1::SHA1()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/// restart
|
||||
void SHA1::reset()
|
||||
{
|
||||
m_numBytes = 0;
|
||||
m_bufferSize = 0;
|
||||
|
||||
// according to RFC 1321
|
||||
m_hash[0] = 0x67452301;
|
||||
m_hash[1] = 0xefcdab89;
|
||||
m_hash[2] = 0x98badcfe;
|
||||
m_hash[3] = 0x10325476;
|
||||
m_hash[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// mix functions for processBlock()
|
||||
inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d);
|
||||
}
|
||||
|
||||
inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return b ^ c ^ d;
|
||||
}
|
||||
|
||||
inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
return (b & c) | (b & d) | (c & d);
|
||||
}
|
||||
|
||||
inline uint32_t rotate(uint32_t a, uint32_t c)
|
||||
{
|
||||
return (a << c) | (a >> (32 - c));
|
||||
}
|
||||
|
||||
inline uint32_t swap(uint32_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap32(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ulong(x);
|
||||
#endif
|
||||
|
||||
return (x >> 24) |
|
||||
((x >> 8) & 0x0000FF00) |
|
||||
((x << 8) & 0x00FF0000) |
|
||||
(x << 24);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process 64 bytes
|
||||
void SHA1::processBlock(const void* data)
|
||||
{
|
||||
// get last hash
|
||||
uint32_t a = m_hash[0];
|
||||
uint32_t b = m_hash[1];
|
||||
uint32_t c = m_hash[2];
|
||||
uint32_t d = m_hash[3];
|
||||
uint32_t e = m_hash[4];
|
||||
|
||||
// data represented as 16x 32-bit words
|
||||
const uint32_t* input = (uint32_t*) data;
|
||||
// convert to big endian
|
||||
uint32_t words[80];
|
||||
for (int i = 0; i < 16; i++)
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
words[i] = input[i];
|
||||
#else
|
||||
words[i] = swap(input[i]);
|
||||
#endif
|
||||
|
||||
// extend to 80 words
|
||||
for (int i = 16; i < 80; i++)
|
||||
words[i] = rotate(words[i-3] ^ words[i-8] ^ words[i-14] ^ words[i-16], 1);
|
||||
|
||||
// first round
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int offset = 5*i;
|
||||
e += rotate(a,5) + f1(b,c,d) + words[offset ] + 0x5a827999; b = rotate(b,30);
|
||||
d += rotate(e,5) + f1(a,b,c) + words[offset+1] + 0x5a827999; a = rotate(a,30);
|
||||
c += rotate(d,5) + f1(e,a,b) + words[offset+2] + 0x5a827999; e = rotate(e,30);
|
||||
b += rotate(c,5) + f1(d,e,a) + words[offset+3] + 0x5a827999; d = rotate(d,30);
|
||||
a += rotate(b,5) + f1(c,d,e) + words[offset+4] + 0x5a827999; c = rotate(c,30);
|
||||
}
|
||||
|
||||
// second round
|
||||
for (int i = 4; i < 8; i++)
|
||||
{
|
||||
int offset = 5*i;
|
||||
e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0x6ed9eba1; b = rotate(b,30);
|
||||
d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0x6ed9eba1; a = rotate(a,30);
|
||||
c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0x6ed9eba1; e = rotate(e,30);
|
||||
b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0x6ed9eba1; d = rotate(d,30);
|
||||
a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0x6ed9eba1; c = rotate(c,30);
|
||||
}
|
||||
|
||||
// third round
|
||||
for (int i = 8; i < 12; i++)
|
||||
{
|
||||
int offset = 5*i;
|
||||
e += rotate(a,5) + f3(b,c,d) + words[offset ] + 0x8f1bbcdc; b = rotate(b,30);
|
||||
d += rotate(e,5) + f3(a,b,c) + words[offset+1] + 0x8f1bbcdc; a = rotate(a,30);
|
||||
c += rotate(d,5) + f3(e,a,b) + words[offset+2] + 0x8f1bbcdc; e = rotate(e,30);
|
||||
b += rotate(c,5) + f3(d,e,a) + words[offset+3] + 0x8f1bbcdc; d = rotate(d,30);
|
||||
a += rotate(b,5) + f3(c,d,e) + words[offset+4] + 0x8f1bbcdc; c = rotate(c,30);
|
||||
}
|
||||
|
||||
// fourth round
|
||||
for (int i = 12; i < 16; i++)
|
||||
{
|
||||
int offset = 5*i;
|
||||
e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0xca62c1d6; b = rotate(b,30);
|
||||
d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0xca62c1d6; a = rotate(a,30);
|
||||
c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0xca62c1d6; e = rotate(e,30);
|
||||
b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0xca62c1d6; d = rotate(d,30);
|
||||
a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0xca62c1d6; c = rotate(c,30);
|
||||
}
|
||||
|
||||
// update hash
|
||||
m_hash[0] += a;
|
||||
m_hash[1] += b;
|
||||
m_hash[2] += c;
|
||||
m_hash[3] += d;
|
||||
m_hash[4] += e;
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void SHA1::add(const void* data, size_t numBytes)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*) data;
|
||||
|
||||
if (m_bufferSize > 0)
|
||||
{
|
||||
while (numBytes > 0 && m_bufferSize < BlockSize)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
// full buffer
|
||||
if (m_bufferSize == BlockSize)
|
||||
{
|
||||
processBlock((void*)m_buffer);
|
||||
m_numBytes += BlockSize;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
// no more data ?
|
||||
if (numBytes == 0)
|
||||
return;
|
||||
|
||||
// process full blocks
|
||||
while (numBytes >= BlockSize)
|
||||
{
|
||||
processBlock(current);
|
||||
current += BlockSize;
|
||||
m_numBytes += BlockSize;
|
||||
numBytes -= BlockSize;
|
||||
}
|
||||
|
||||
// keep remaining bytes in buffer
|
||||
while (numBytes > 0)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process final block, less than 64 bytes
|
||||
void SHA1::processBuffer()
|
||||
{
|
||||
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
|
||||
|
||||
// - append "1" bit to message
|
||||
// - append "0" bits until message length in bit mod 512 is 448
|
||||
// - append length as 64 bit integer
|
||||
|
||||
// number of bits
|
||||
size_t paddedLength = m_bufferSize * 8;
|
||||
|
||||
// plus one bit set to 1 (always appended)
|
||||
paddedLength++;
|
||||
|
||||
// number of bits must be (numBits % 512) = 448
|
||||
size_t lower11Bits = paddedLength & 511;
|
||||
if (lower11Bits <= 448)
|
||||
paddedLength += 448 - lower11Bits;
|
||||
else
|
||||
paddedLength += 512 + 448 - lower11Bits;
|
||||
// convert from bits to bytes
|
||||
paddedLength /= 8;
|
||||
|
||||
// only needed if additional data flows over into a second block
|
||||
unsigned char extra[BlockSize];
|
||||
|
||||
// append a "1" bit, 128 => binary 10000000
|
||||
if (m_bufferSize < BlockSize)
|
||||
m_buffer[m_bufferSize] = 128;
|
||||
else
|
||||
extra[0] = 128;
|
||||
|
||||
size_t i;
|
||||
for (i = m_bufferSize + 1; i < BlockSize; i++)
|
||||
m_buffer[i] = 0;
|
||||
for (; i < paddedLength; i++)
|
||||
extra[i - BlockSize] = 0;
|
||||
|
||||
// add message length in bits as 64 bit number
|
||||
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
|
||||
// find right position
|
||||
unsigned char* addLength;
|
||||
if (paddedLength < BlockSize)
|
||||
addLength = m_buffer + paddedLength;
|
||||
else
|
||||
addLength = extra + paddedLength - BlockSize;
|
||||
|
||||
// must be big endian
|
||||
*addLength++ = (msgBits >> 56) & 0xFF;
|
||||
*addLength++ = (msgBits >> 48) & 0xFF;
|
||||
*addLength++ = (msgBits >> 40) & 0xFF;
|
||||
*addLength++ = (msgBits >> 32) & 0xFF;
|
||||
*addLength++ = (msgBits >> 24) & 0xFF;
|
||||
*addLength++ = (msgBits >> 16) & 0xFF;
|
||||
*addLength++ = (msgBits >> 8) & 0xFF;
|
||||
*addLength = msgBits & 0xFF;
|
||||
|
||||
// process blocks
|
||||
processBlock(m_buffer);
|
||||
// flowed over into a second block ?
|
||||
if (paddedLength > BlockSize)
|
||||
processBlock(extra);
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* SHA1::getHash()
|
||||
{
|
||||
// convert hash to string
|
||||
static const char dec2hex[16+1] = "0123456789abcdef";
|
||||
|
||||
// save old hash if buffer is partially filled
|
||||
uint32_t oldHash[HashValues];
|
||||
for (int i = 0; i < HashValues; i++)
|
||||
oldHash[i] = m_hash[i];
|
||||
|
||||
// process remaining bytes
|
||||
processBuffer();
|
||||
|
||||
// create hash string
|
||||
static char hashBuffer[HashValues*8+1];
|
||||
size_t offset = 0;
|
||||
for (int i = 0; i < HashValues; i++)
|
||||
{
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 28) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 24) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 20) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 16) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 12) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 8) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 4) & 15];
|
||||
hashBuffer[offset++] = dec2hex[ m_hash[i] & 15];
|
||||
|
||||
// restore old hash
|
||||
m_hash[i] = oldHash[i];
|
||||
}
|
||||
// zero-terminated string
|
||||
hashBuffer[offset] = 0;
|
||||
|
||||
// convert to std::string
|
||||
return (const char *)hashBuffer;
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA1 of a memory block
|
||||
const char* SHA1::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA1 of a string, excluding final zero
|
||||
const char* SHA1::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
61
public/hashing/hashers/sha1.h
Normal file
61
public/hashing/hashers/sha1.h
Normal file
@ -0,0 +1,61 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha1.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute SHA1 hash
|
||||
/** Usage:
|
||||
SHA1 sha1;
|
||||
std::string myHash = sha1("Hello World"); // std::string
|
||||
std::string myHash2 = sha1("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
SHA1 sha1;
|
||||
while (more data available)
|
||||
sha1.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = sha1.getHash();
|
||||
*/
|
||||
class SHA1 //: public Hash
|
||||
{
|
||||
public:
|
||||
/// same as reset()
|
||||
SHA1();
|
||||
|
||||
/// compute SHA1 of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute SHA1 of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// process 64 bytes
|
||||
void processBlock(const void* data);
|
||||
/// process everything left in the internal buffer
|
||||
void processBuffer();
|
||||
|
||||
/// split into 64 byte blocks (=> 512 bits)
|
||||
enum { BlockSize = 512 / 8, HashValues = 5 };
|
||||
|
||||
/// size of processed data in bytes
|
||||
uint64_t m_numBytes;
|
||||
/// valid bytes in m_buffer
|
||||
size_t m_bufferSize;
|
||||
/// bytes not processed yet
|
||||
uint8_t m_buffer[BlockSize];
|
||||
/// hash, stored as integers
|
||||
uint32_t m_hash[HashValues];
|
||||
};
|
399
public/hashing/hashers/sha256.cpp
Normal file
399
public/hashing/hashers/sha256.cpp
Normal file
@ -0,0 +1,399 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha256.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "sha256.h"
|
||||
|
||||
|
||||
/// same as reset()
|
||||
SHA256::SHA256()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/// restart
|
||||
void SHA256::reset()
|
||||
{
|
||||
m_numBytes = 0;
|
||||
m_bufferSize = 0;
|
||||
|
||||
// according to RFC 1321
|
||||
m_hash[0] = 0x6a09e667;
|
||||
m_hash[1] = 0xbb67ae85;
|
||||
m_hash[2] = 0x3c6ef372;
|
||||
m_hash[3] = 0xa54ff53a;
|
||||
m_hash[4] = 0x510e527f;
|
||||
m_hash[5] = 0x9b05688c;
|
||||
m_hash[6] = 0x1f83d9ab;
|
||||
m_hash[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
inline uint32_t rotate(uint32_t a, uint32_t c)
|
||||
{
|
||||
return (a >> c) | (a << (32 - c));
|
||||
}
|
||||
|
||||
inline uint32_t swap(uint32_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap32(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_ulong(x);
|
||||
#endif
|
||||
|
||||
return (x >> 24) |
|
||||
((x >> 8) & 0x0000FF00) |
|
||||
((x << 8) & 0x00FF0000) |
|
||||
(x << 24);
|
||||
}
|
||||
|
||||
// mix functions for processBlock()
|
||||
inline uint32_t f1(uint32_t e, uint32_t f, uint32_t g)
|
||||
{
|
||||
uint32_t term1 = rotate(e, 6) ^ rotate(e, 11) ^ rotate(e, 25);
|
||||
uint32_t term2 = (e & f) ^ (~e & g); //(g ^ (e & (f ^ g)))
|
||||
return term1 + term2;
|
||||
}
|
||||
|
||||
inline uint32_t f2(uint32_t a, uint32_t b, uint32_t c)
|
||||
{
|
||||
uint32_t term1 = rotate(a, 2) ^ rotate(a, 13) ^ rotate(a, 22);
|
||||
uint32_t term2 = ((a | b) & c) | (a & b); //(a & (b ^ c)) ^ (b & c);
|
||||
return term1 + term2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process 64 bytes
|
||||
void SHA256::processBlock(const void* data)
|
||||
{
|
||||
// get last hash
|
||||
uint32_t a = m_hash[0];
|
||||
uint32_t b = m_hash[1];
|
||||
uint32_t c = m_hash[2];
|
||||
uint32_t d = m_hash[3];
|
||||
uint32_t e = m_hash[4];
|
||||
uint32_t f = m_hash[5];
|
||||
uint32_t g = m_hash[6];
|
||||
uint32_t h = m_hash[7];
|
||||
|
||||
// data represented as 16x 32-bit words
|
||||
const uint32_t* input = (uint32_t*) data;
|
||||
// convert to big endian
|
||||
uint32_t words[64];
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
words[i] = input[i];
|
||||
#else
|
||||
words[i] = swap(input[i]);
|
||||
#endif
|
||||
|
||||
uint32_t x,y; // temporaries
|
||||
|
||||
// first round
|
||||
x = h + f1(e,f,g) + 0x428a2f98 + words[ 0]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0x71374491 + words[ 1]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0xb5c0fbcf + words[ 2]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0xe9b5dba5 + words[ 3]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x3956c25b + words[ 4]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0x59f111f1 + words[ 5]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x923f82a4 + words[ 6]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0xab1c5ed5 + words[ 7]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// secound round
|
||||
x = h + f1(e,f,g) + 0xd807aa98 + words[ 8]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0x12835b01 + words[ 9]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0x243185be + words[10]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0x550c7dc3 + words[11]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x72be5d74 + words[12]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0x80deb1fe + words[13]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x9bdc06a7 + words[14]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0xc19bf174 + words[15]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 24 words
|
||||
for (; i < 24; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// third round
|
||||
x = h + f1(e,f,g) + 0xe49b69c1 + words[16]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0xefbe4786 + words[17]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0x0fc19dc6 + words[18]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0x240ca1cc + words[19]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x2de92c6f + words[20]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0x4a7484aa + words[21]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x5cb0a9dc + words[22]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0x76f988da + words[23]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 32 words
|
||||
for (; i < 32; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// fourth round
|
||||
x = h + f1(e,f,g) + 0x983e5152 + words[24]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0xa831c66d + words[25]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0xb00327c8 + words[26]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0xbf597fc7 + words[27]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0xc6e00bf3 + words[28]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0xd5a79147 + words[29]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x06ca6351 + words[30]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0x14292967 + words[31]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 40 words
|
||||
for (; i < 40; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// fifth round
|
||||
x = h + f1(e,f,g) + 0x27b70a85 + words[32]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0x2e1b2138 + words[33]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0x4d2c6dfc + words[34]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0x53380d13 + words[35]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x650a7354 + words[36]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0x766a0abb + words[37]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x81c2c92e + words[38]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0x92722c85 + words[39]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 48 words
|
||||
for (; i < 48; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// sixth round
|
||||
x = h + f1(e,f,g) + 0xa2bfe8a1 + words[40]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0xa81a664b + words[41]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0xc24b8b70 + words[42]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0xc76c51a3 + words[43]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0xd192e819 + words[44]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0xd6990624 + words[45]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0xf40e3585 + words[46]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0x106aa070 + words[47]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 56 words
|
||||
for (; i < 56; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// seventh round
|
||||
x = h + f1(e,f,g) + 0x19a4c116 + words[48]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0x1e376c08 + words[49]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0x2748774c + words[50]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0x34b0bcb5 + words[51]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x391c0cb3 + words[52]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0x4ed8aa4a + words[53]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0x5b9cca4f + words[54]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0x682e6ff3 + words[55]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// extend to 64 words
|
||||
for (; i < 64; i++)
|
||||
words[i] = words[i-16] +
|
||||
(rotate(words[i-15], 7) ^ rotate(words[i-15], 18) ^ (words[i-15] >> 3)) +
|
||||
words[i-7] +
|
||||
(rotate(words[i- 2], 17) ^ rotate(words[i- 2], 19) ^ (words[i- 2] >> 10));
|
||||
|
||||
// eigth round
|
||||
x = h + f1(e,f,g) + 0x748f82ee + words[56]; y = f2(a,b,c); d += x; h = x + y;
|
||||
x = g + f1(d,e,f) + 0x78a5636f + words[57]; y = f2(h,a,b); c += x; g = x + y;
|
||||
x = f + f1(c,d,e) + 0x84c87814 + words[58]; y = f2(g,h,a); b += x; f = x + y;
|
||||
x = e + f1(b,c,d) + 0x8cc70208 + words[59]; y = f2(f,g,h); a += x; e = x + y;
|
||||
x = d + f1(a,b,c) + 0x90befffa + words[60]; y = f2(e,f,g); h += x; d = x + y;
|
||||
x = c + f1(h,a,b) + 0xa4506ceb + words[61]; y = f2(d,e,f); g += x; c = x + y;
|
||||
x = b + f1(g,h,a) + 0xbef9a3f7 + words[62]; y = f2(c,d,e); f += x; b = x + y;
|
||||
x = a + f1(f,g,h) + 0xc67178f2 + words[63]; y = f2(b,c,d); e += x; a = x + y;
|
||||
|
||||
// update hash
|
||||
m_hash[0] += a;
|
||||
m_hash[1] += b;
|
||||
m_hash[2] += c;
|
||||
m_hash[3] += d;
|
||||
m_hash[4] += e;
|
||||
m_hash[5] += f;
|
||||
m_hash[6] += g;
|
||||
m_hash[7] += h;
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void SHA256::add(const void* data, size_t numBytes)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*) data;
|
||||
|
||||
if (m_bufferSize > 0)
|
||||
{
|
||||
while (numBytes > 0 && m_bufferSize < BlockSize)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
// full buffer
|
||||
if (m_bufferSize == BlockSize)
|
||||
{
|
||||
processBlock(m_buffer);
|
||||
m_numBytes += BlockSize;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
// no more data ?
|
||||
if (numBytes == 0)
|
||||
return;
|
||||
|
||||
// process full blocks
|
||||
while (numBytes >= BlockSize)
|
||||
{
|
||||
processBlock(current);
|
||||
current += BlockSize;
|
||||
m_numBytes += BlockSize;
|
||||
numBytes -= BlockSize;
|
||||
}
|
||||
|
||||
// keep remaining bytes in buffer
|
||||
while (numBytes > 0)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process final block, less than 64 bytes
|
||||
void SHA256::processBuffer()
|
||||
{
|
||||
// the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte
|
||||
|
||||
// - append "1" bit to message
|
||||
// - append "0" bits until message length in bit mod 512 is 448
|
||||
// - append length as 64 bit integer
|
||||
|
||||
// number of bits
|
||||
size_t paddedLength = m_bufferSize * 8;
|
||||
|
||||
// plus one bit set to 1 (always appended)
|
||||
paddedLength++;
|
||||
|
||||
// number of bits must be (numBits % 512) = 448
|
||||
size_t lower11Bits = paddedLength & 511;
|
||||
if (lower11Bits <= 448)
|
||||
paddedLength += 448 - lower11Bits;
|
||||
else
|
||||
paddedLength += 512 + 448 - lower11Bits;
|
||||
// convert from bits to bytes
|
||||
paddedLength /= 8;
|
||||
|
||||
// only needed if additional data flows over into a second block
|
||||
unsigned char extra[BlockSize];
|
||||
|
||||
// append a "1" bit, 128 => binary 10000000
|
||||
if (m_bufferSize < BlockSize)
|
||||
m_buffer[m_bufferSize] = 128;
|
||||
else
|
||||
extra[0] = 128;
|
||||
|
||||
size_t i;
|
||||
for (i = m_bufferSize + 1; i < BlockSize; i++)
|
||||
m_buffer[i] = 0;
|
||||
for (; i < paddedLength; i++)
|
||||
extra[i - BlockSize] = 0;
|
||||
|
||||
// add message length in bits as 64 bit number
|
||||
uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
|
||||
// find right position
|
||||
unsigned char* addLength;
|
||||
if (paddedLength < BlockSize)
|
||||
addLength = m_buffer + paddedLength;
|
||||
else
|
||||
addLength = extra + paddedLength - BlockSize;
|
||||
|
||||
// must be big endian
|
||||
*addLength++ = (msgBits >> 56) & 0xFF;
|
||||
*addLength++ = (msgBits >> 48) & 0xFF;
|
||||
*addLength++ = (msgBits >> 40) & 0xFF;
|
||||
*addLength++ = (msgBits >> 32) & 0xFF;
|
||||
*addLength++ = (msgBits >> 24) & 0xFF;
|
||||
*addLength++ = (msgBits >> 16) & 0xFF;
|
||||
*addLength++ = (msgBits >> 8) & 0xFF;
|
||||
*addLength = msgBits & 0xFF;
|
||||
|
||||
// process blocks
|
||||
processBlock(m_buffer);
|
||||
// flowed over into a second block ?
|
||||
if (paddedLength > BlockSize)
|
||||
processBlock(extra);
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* SHA256::getHash()
|
||||
{
|
||||
// convert hash to string
|
||||
static const char dec2hex[16+1] = "0123456789abcdef";
|
||||
|
||||
// save old hash if buffer is partially filled
|
||||
uint32_t oldHash[HashValues];
|
||||
for (int i = 0; i < HashValues; i++)
|
||||
oldHash[i] = m_hash[i];
|
||||
|
||||
// process remaining bytes
|
||||
processBuffer();
|
||||
|
||||
// create hash string
|
||||
static char hashBuffer[HashValues*8+1];
|
||||
size_t offset = 0;
|
||||
for (int i = 0; i < HashValues; i++)
|
||||
{
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 28) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 24) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 20) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 16) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 12) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 8) & 15];
|
||||
hashBuffer[offset++] = dec2hex[(m_hash[i] >> 4) & 15];
|
||||
hashBuffer[offset++] = dec2hex[ m_hash[i] & 15];
|
||||
|
||||
// restore old hash
|
||||
m_hash[i] = oldHash[i];
|
||||
}
|
||||
// zero-terminated string
|
||||
hashBuffer[offset] = 0;
|
||||
|
||||
// convert to std::string
|
||||
return (const char *)hashBuffer;
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA256 of a memory block
|
||||
const char* SHA256::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA256 of a string, excluding final zero
|
||||
const char* SHA256::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
61
public/hashing/hashers/sha256.h
Normal file
61
public/hashing/hashers/sha256.h
Normal file
@ -0,0 +1,61 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha256.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute SHA256 hash
|
||||
/** Usage:
|
||||
SHA256 sha256;
|
||||
std::string myHash = sha256("Hello World"); // std::string
|
||||
std::string myHash2 = sha256("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
SHA256 sha256;
|
||||
while (more data available)
|
||||
sha256.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = sha256.getHash();
|
||||
*/
|
||||
class SHA256 //: public Hash
|
||||
{
|
||||
public:
|
||||
/// same as reset()
|
||||
SHA256();
|
||||
|
||||
/// compute SHA256 of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute SHA256 of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// process 64 bytes
|
||||
void processBlock(const void* data);
|
||||
/// process everything left in the internal buffer
|
||||
void processBuffer();
|
||||
|
||||
/// split into 64 byte blocks (=> 512 bits)
|
||||
enum { BlockSize = 512 / 8, HashValues = 8 };
|
||||
|
||||
/// size of processed data in bytes
|
||||
uint64_t m_numBytes;
|
||||
/// valid bytes in m_buffer
|
||||
size_t m_bufferSize;
|
||||
/// bytes not processed yet
|
||||
uint8_t m_buffer[BlockSize];
|
||||
/// hash, stored as integers
|
||||
uint32_t m_hash[8];
|
||||
};
|
281
public/hashing/hashers/sha3.cpp
Normal file
281
public/hashing/hashers/sha3.cpp
Normal file
@ -0,0 +1,281 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha3.cpp
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#include "sha3.h"
|
||||
|
||||
|
||||
/// same as reset()
|
||||
SHA3::SHA3(Bits bits)
|
||||
: m_blockSize(200 - 2 * (bits / 8)),
|
||||
m_bits(bits)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/// same as reset()
|
||||
void SHA3::changeBits(Bits bits)
|
||||
{
|
||||
m_blockSize = (200 - 2 * (bits / 8));
|
||||
m_bits = bits;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
/// restart
|
||||
void SHA3::reset()
|
||||
{
|
||||
for (size_t i = 0; i < StateSize; i++)
|
||||
m_hash[i] = 0;
|
||||
|
||||
m_numBytes = 0;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
|
||||
/// constants and local helper functions
|
||||
namespace
|
||||
{
|
||||
const unsigned int Rounds = 24;
|
||||
const uint64_t XorMasks[Rounds] =
|
||||
{
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
|
||||
0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
|
||||
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
|
||||
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
|
||||
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
|
||||
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
|
||||
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
|
||||
};
|
||||
|
||||
/// rotate left and wrap around to the right
|
||||
inline uint64_t rotateLeft(uint64_t x, uint8_t numBits)
|
||||
{
|
||||
return (x << numBits) | (x >> (64 - numBits));
|
||||
}
|
||||
|
||||
/// convert litte vs big endian
|
||||
inline uint64_t swap(uint64_t x)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_bswap64(x);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _byteswap_uint64(x);
|
||||
#endif
|
||||
|
||||
return (x >> 56) |
|
||||
((x >> 40) & 0x000000000000FF00ULL) |
|
||||
((x >> 24) & 0x0000000000FF0000ULL) |
|
||||
((x >> 8) & 0x00000000FF000000ULL) |
|
||||
((x << 8) & 0x000000FF00000000ULL) |
|
||||
((x << 24) & 0x0000FF0000000000ULL) |
|
||||
((x << 40) & 0x00FF000000000000ULL) |
|
||||
(x << 56);
|
||||
}
|
||||
|
||||
|
||||
/// return x % 5 for 0 <= x <= 9
|
||||
unsigned int mod5(unsigned int x)
|
||||
{
|
||||
if (x < 5)
|
||||
return x;
|
||||
|
||||
return x - 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process a full block
|
||||
void SHA3::processBlock(const void* data)
|
||||
{
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
#define LITTLEENDIAN(x) swap(x)
|
||||
#else
|
||||
#define LITTLEENDIAN(x) (x)
|
||||
#endif
|
||||
|
||||
const uint64_t* data64 = (const uint64_t*) data;
|
||||
// mix data into state
|
||||
for (unsigned int i = 0; i < m_blockSize / 8; i++)
|
||||
m_hash[i] ^= LITTLEENDIAN(data64[i]);
|
||||
|
||||
// re-compute state
|
||||
for (unsigned int round = 0; round < Rounds; round++)
|
||||
{
|
||||
// Theta
|
||||
uint64_t coefficients[5];
|
||||
for (unsigned int i = 0; i < 5; i++)
|
||||
coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20];
|
||||
|
||||
for (unsigned int i = 0; i < 5; i++)
|
||||
{
|
||||
uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1);
|
||||
m_hash[i ] ^= one;
|
||||
m_hash[i + 5] ^= one;
|
||||
m_hash[i + 10] ^= one;
|
||||
m_hash[i + 15] ^= one;
|
||||
m_hash[i + 20] ^= one;
|
||||
}
|
||||
|
||||
// temporary
|
||||
uint64_t one;
|
||||
|
||||
// Rho Pi
|
||||
uint64_t last = m_hash[1];
|
||||
one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one;
|
||||
one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one;
|
||||
one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one;
|
||||
one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one;
|
||||
one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one;
|
||||
one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one;
|
||||
one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one;
|
||||
one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one;
|
||||
one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one;
|
||||
one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one;
|
||||
one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one;
|
||||
one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one;
|
||||
one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one;
|
||||
one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one;
|
||||
one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one;
|
||||
one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one;
|
||||
one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one;
|
||||
one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one;
|
||||
one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one;
|
||||
one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one;
|
||||
one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one;
|
||||
one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one;
|
||||
one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one;
|
||||
m_hash[ 1] = rotateLeft(last, 44);
|
||||
|
||||
// Chi
|
||||
for (unsigned int j = 0; j < 25; j += 5)
|
||||
{
|
||||
// temporaries
|
||||
uint64_t one = m_hash[j];
|
||||
uint64_t two = m_hash[j + 1];
|
||||
|
||||
m_hash[j] ^= m_hash[j + 2] & ~two;
|
||||
m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2];
|
||||
m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3];
|
||||
m_hash[j + 3] ^= one & ~m_hash[j + 4];
|
||||
m_hash[j + 4] ^= two & ~one;
|
||||
}
|
||||
|
||||
// Iota
|
||||
m_hash[0] ^= XorMasks[round];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void SHA3::add(const void* data, size_t numBytes)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*) data;
|
||||
|
||||
if (m_bufferSize > 0)
|
||||
{
|
||||
while (numBytes > 0 && m_bufferSize < m_blockSize)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
// full buffer
|
||||
if (m_bufferSize == m_blockSize)
|
||||
{
|
||||
processBlock((void*)m_buffer);
|
||||
m_numBytes += m_blockSize;
|
||||
m_bufferSize = 0;
|
||||
}
|
||||
|
||||
// no more data ?
|
||||
if (numBytes == 0)
|
||||
return;
|
||||
|
||||
// process full blocks
|
||||
while (numBytes >= m_blockSize)
|
||||
{
|
||||
processBlock(current);
|
||||
current += m_blockSize;
|
||||
m_numBytes += m_blockSize;
|
||||
numBytes -= m_blockSize;
|
||||
}
|
||||
|
||||
// keep remaining bytes in buffer
|
||||
while (numBytes > 0)
|
||||
{
|
||||
m_buffer[m_bufferSize++] = *current++;
|
||||
numBytes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// process everything left in the internal buffer
|
||||
void SHA3::processBuffer()
|
||||
{
|
||||
unsigned int blockSize = 200 - 2 * (m_bits / 8);
|
||||
|
||||
// add padding
|
||||
size_t offset = m_bufferSize;
|
||||
// add a "1" byte
|
||||
m_buffer[offset++] = 0x06;
|
||||
// fill with zeros
|
||||
while (offset < blockSize - 1)
|
||||
m_buffer[offset++] = 0;
|
||||
|
||||
// and add a single set bit
|
||||
m_buffer[blockSize - 1] = 0x80;
|
||||
|
||||
processBlock(m_buffer);
|
||||
}
|
||||
|
||||
|
||||
/// return latest hash as 16 hex characters
|
||||
const char* SHA3::getHash()
|
||||
{
|
||||
// process remaining bytes
|
||||
processBuffer();
|
||||
|
||||
// convert hash to string
|
||||
static const char dec2hex[16 + 1] = "0123456789abcdef";
|
||||
|
||||
// number of significant elements in hash (uint64_t)
|
||||
unsigned int hashLength = m_bits / 64;
|
||||
|
||||
static char result[128+1];
|
||||
size_t written = 0;
|
||||
for (unsigned int i = 0; i < hashLength; i++)
|
||||
for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes
|
||||
{
|
||||
// convert a byte to hex
|
||||
unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j));
|
||||
result[written++]= dec2hex[oneByte >> 4];
|
||||
result[written++]= dec2hex[oneByte & 15];
|
||||
}
|
||||
result[written] = 0;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA3 of a memory block
|
||||
const char* SHA3::operator()(const void* data, size_t numBytes)
|
||||
{
|
||||
reset();
|
||||
add(data, numBytes);
|
||||
return getHash();
|
||||
}
|
||||
|
||||
|
||||
/// compute SHA3 of a string, excluding final zero
|
||||
const char* SHA3::operator()(const char* text, size_t size)
|
||||
{
|
||||
reset();
|
||||
add(text, size);
|
||||
return getHash();
|
||||
}
|
72
public/hashing/hashers/sha3.h
Normal file
72
public/hashing/hashers/sha3.h
Normal file
@ -0,0 +1,72 @@
|
||||
// //////////////////////////////////////////////////////////
|
||||
// sha3.h
|
||||
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
|
||||
// see http://create.stephan-brumme.com/disclaimer.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../hashing.h"
|
||||
|
||||
/// compute SHA3 hash
|
||||
/** Usage:
|
||||
SHA3 sha3;
|
||||
std::string myHash = sha3("Hello World"); // std::string
|
||||
std::string myHash2 = sha3("How are you", 11); // arbitrary data, 11 bytes
|
||||
|
||||
// or in a streaming fashion:
|
||||
|
||||
SHA3 sha3;
|
||||
while (more data available)
|
||||
sha3.add(pointer to fresh data, number of new bytes);
|
||||
std::string myHash3 = sha3.getHash();
|
||||
*/
|
||||
class SHA3 //: public Hash
|
||||
{
|
||||
public:
|
||||
/// algorithm variants
|
||||
enum Bits { Bits224 = 224, Bits256 = 256, Bits384 = 384, Bits512 = 512 };
|
||||
|
||||
/// same as reset()
|
||||
explicit SHA3(Bits bits = Bits256);
|
||||
|
||||
/// compute hash of a memory block
|
||||
const char* operator()(const void* data, size_t numBytes);
|
||||
/// compute hash of a string, excluding final zero
|
||||
const char* operator()(const char* text, size_t size);
|
||||
|
||||
/// add arbitrary number of bytes
|
||||
void add(const void* data, size_t numBytes);
|
||||
|
||||
/// return latest hash as hex characters
|
||||
const char* getHash();
|
||||
|
||||
/// same as reset()
|
||||
void changeBits(Bits bits);
|
||||
|
||||
/// restart
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/// process a full block
|
||||
void processBlock(const void* data);
|
||||
/// process everything left in the internal buffer
|
||||
void processBuffer();
|
||||
|
||||
/// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224)
|
||||
enum { StateSize = 1600 / (8 * 8),
|
||||
MaxBlockSize = 200 - 2 * (224 / 8) };
|
||||
|
||||
/// hash
|
||||
uint64_t m_hash[StateSize];
|
||||
/// size of processed data in bytes
|
||||
uint64_t m_numBytes;
|
||||
/// block size (less or equal to MaxBlockSize)
|
||||
size_t m_blockSize;
|
||||
/// valid bytes in m_buffer
|
||||
size_t m_bufferSize;
|
||||
/// bytes not processed yet
|
||||
uint8_t m_buffer[MaxBlockSize];
|
||||
/// variant
|
||||
Bits m_bits;
|
||||
};
|
170
public/hashing/hashing.cpp
Normal file
170
public/hashing/hashing.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet:
|
||||
//
|
||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||
// Copyright (C) The AMX Mod X Development Team.
|
||||
//
|
||||
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://alliedmods.net/amxmodx-license
|
||||
|
||||
#include "hashing.h"
|
||||
|
||||
|
||||
/**
|
||||
* Hashes a file content (bytes)
|
||||
* @note Returns NULL if "fileName" does not represent a file name
|
||||
* @note Returns NULL if file could not be opened
|
||||
* @note Returns NULL if invalid "Type" is specified
|
||||
*/
|
||||
const char* hashFile(const char* fileName, HashType Type)
|
||||
{
|
||||
/**
|
||||
* Sanity check of input parameters
|
||||
*/
|
||||
if (!fileName || fileName[0] == 0)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* Opens and checks file
|
||||
*/
|
||||
FILE* pFile = fopen(fileName, "rb");
|
||||
if (!pFile)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* Gets hashers ready.
|
||||
*/
|
||||
CRC32 Crc32;
|
||||
MD5 Md5;
|
||||
SHA1 Sha1;
|
||||
SHA256 Sha256;
|
||||
SHA3 Sha3;
|
||||
Keccak Kec;
|
||||
|
||||
/**
|
||||
* Changes bits if needed
|
||||
*/
|
||||
switch (Type)
|
||||
{
|
||||
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
||||
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
||||
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
||||
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
||||
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
||||
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves file's content and fills hashers in.
|
||||
*/
|
||||
char Bytes[8192];
|
||||
size_t Count;
|
||||
while ((Count = fread(Bytes, sizeof(char), sizeof Bytes, pFile)))
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case Hash_Crc32: Crc32.add(Bytes, Count); break;
|
||||
case Hash_Md5: Md5.add(Bytes, Count); break;
|
||||
case Hash_Sha1: Sha1.add(Bytes, Count); break;
|
||||
case Hash_Sha256: Sha256.add(Bytes, Count); break;
|
||||
case Hash_Sha3_224:
|
||||
case Hash_Sha3_256:
|
||||
case Hash_Sha3_384:
|
||||
case Hash_Sha3_512: Sha3.add(Bytes, Count); break;
|
||||
case Hash_Keccak_224:
|
||||
case Hash_Keccak_256:
|
||||
case Hash_Keccak_384:
|
||||
case Hash_Keccak_512: Kec.add(Bytes, Count); break;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes file
|
||||
*/
|
||||
fclose(pFile);
|
||||
|
||||
/**
|
||||
* Retrieves hash
|
||||
*/
|
||||
switch (Type)
|
||||
{
|
||||
case Hash_Crc32: return Crc32.getHash();
|
||||
case Hash_Md5: return Md5.getHash();
|
||||
case Hash_Sha1: return Sha1.getHash();
|
||||
case Hash_Sha256: return Sha256.getHash();
|
||||
case Hash_Sha3_224:
|
||||
case Hash_Sha3_256:
|
||||
case Hash_Sha3_384:
|
||||
case Hash_Sha3_512: return Sha3.getHash();
|
||||
case Hash_Keccak_224:
|
||||
case Hash_Keccak_256:
|
||||
case Hash_Keccak_384:
|
||||
case Hash_Keccak_512: return Kec.getHash();
|
||||
};
|
||||
|
||||
/**
|
||||
* Something went wrong
|
||||
*/
|
||||
return NULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hashes a string
|
||||
* @note Returns NULL if "String" does not represent a string
|
||||
* @note Returns NULL if invalid "Type" is specified
|
||||
*/
|
||||
const char* hashString(const char* String, size_t stringLen, HashType Type)
|
||||
{
|
||||
/**
|
||||
* Sanity check of input parameters
|
||||
*/
|
||||
if (!String)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* Gets hashers ready.
|
||||
*/
|
||||
CRC32 Crc32;
|
||||
MD5 Md5;
|
||||
SHA1 Sha1;
|
||||
SHA256 Sha256;
|
||||
SHA3 Sha3;
|
||||
Keccak Kec;
|
||||
|
||||
/**
|
||||
* Changes bits if needed
|
||||
*/
|
||||
switch (Type)
|
||||
{
|
||||
case Hash_Sha3_224: Sha3.changeBits(SHA3::Bits224); break;
|
||||
case Hash_Sha3_384: Sha3.changeBits(SHA3::Bits384); break;
|
||||
case Hash_Sha3_512: Sha3.changeBits(SHA3::Bits512); break;
|
||||
case Hash_Keccak_224: Kec.changeBits(Keccak::Keccak224); break;
|
||||
case Hash_Keccak_384: Kec.changeBits(Keccak::Keccak384); break;
|
||||
case Hash_Keccak_512: Kec.changeBits(Keccak::Keccak512); break;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fills hashers in, computes string hash and returns the hash
|
||||
*/
|
||||
switch (Type)
|
||||
{
|
||||
case Hash_Crc32: return Crc32(String, stringLen);
|
||||
case Hash_Md5: return Md5(String, stringLen);
|
||||
case Hash_Sha1: return Sha1(String, stringLen);
|
||||
case Hash_Sha256: return Sha256(String, stringLen);
|
||||
case Hash_Sha3_224:
|
||||
case Hash_Sha3_256:
|
||||
case Hash_Sha3_384:
|
||||
case Hash_Sha3_512: return Sha3(String, stringLen);
|
||||
case Hash_Keccak_224:
|
||||
case Hash_Keccak_256:
|
||||
case Hash_Keccak_384:
|
||||
case Hash_Keccak_512: return Kec(String, stringLen);
|
||||
};
|
||||
|
||||
/**
|
||||
* Something went wrong
|
||||
*/
|
||||
return NULL;
|
||||
};
|
86
public/hashing/hashing.h
Normal file
86
public/hashing/hashing.h
Normal file
@ -0,0 +1,86 @@
|
||||
// vim: set ts=4 sw=4 tw=99 noet:
|
||||
//
|
||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||
// Copyright (C) The AMX Mod X Development Team.
|
||||
//
|
||||
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://alliedmods.net/amxmodx-license
|
||||
|
||||
#if !defined __HASHING_H__
|
||||
#define __HASHING_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/endian.h>
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#define __BIG_ENDIAN BIG_ENDIAN
|
||||
#elif defined(LINUX) || defined(EMSCRIPTEN)
|
||||
#include <endian.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/types.h>
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
#endif
|
||||
|
||||
#if !defined(BIG_ENDIAN)
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
|
||||
#if !defined(LITTLE_ENDIAN)
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets hashers included.
|
||||
*/
|
||||
#include "hashers/crc32.h"
|
||||
#include "hashers/md5.h"
|
||||
#include "hashers/sha1.h"
|
||||
#include "hashers/sha256.h"
|
||||
#include "hashers/sha3.h"
|
||||
#include "hashers/keccak.h"
|
||||
|
||||
/**
|
||||
* HashType constants.
|
||||
* To be used on hashFile() and hashString()
|
||||
*/
|
||||
enum HashType
|
||||
{
|
||||
Hash_Crc32 = 0, // Provides CRC32 hashing
|
||||
Hash_Md5, // Provides MD5 hashing
|
||||
Hash_Sha1, // Provides SHA1 hashing
|
||||
Hash_Sha256, // Provides SHA256 hashing
|
||||
|
||||
Hash_Sha3_224, // Provides SHA3 224 bit hashing
|
||||
Hash_Sha3_256, // Provides SHA3 256 bit hashing
|
||||
Hash_Sha3_384, // Provides SHA3 384 bit hashing
|
||||
Hash_Sha3_512, // Provides SHA3 512 bit hashing
|
||||
|
||||
Hash_Keccak_224, // Provides KECCAK 224 bit hashing
|
||||
Hash_Keccak_256, // Provides KECCAK 256 bit hashing
|
||||
Hash_Keccak_384, // Provides KECCAK 384 bit hashing
|
||||
Hash_Keccak_512, // Provides KECCAK 512 bit hashing
|
||||
};
|
||||
|
||||
/**
|
||||
* Hashes a file content (bytes)
|
||||
* @note Returns NULL if "fileName" does not represent a file name
|
||||
* @note Returns NULL if file could not be opened
|
||||
* @note Returns NULL if invalid "Type" is specified
|
||||
*/
|
||||
const char* hashFile(const char* fileName, HashType Type);
|
||||
|
||||
/**
|
||||
* Hashes a string
|
||||
* @note Returns NULL if "String" does not represent a string
|
||||
* @note Returns NULL if the string has no bytes to hash
|
||||
* @note Returns NULL if invalid "Type" is specified
|
||||
*/
|
||||
const char* hashString(const char* String, size_t stringLen, HashType Type);
|
||||
|
||||
#endif // __HASHING_H__
|
@ -90,3 +90,27 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
--------------------------------------------------------------
|
||||
Portable C++ Hashing Library, as used in AMX Mod X Core module
|
||||
--------------------------------------------------------------
|
||||
Copyright (c) 2014 Stephan Brumme
|
||||
|
||||
All source code published on http://create.stephan-brumme.com
|
||||
and its sub-pages is licensed similar to the zlib license:
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the author be held liable for any damages arising from
|
||||
the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
* The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software.
|
||||
* If you use this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
* Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
|
@ -222,6 +222,7 @@ scripting_files = [
|
||||
'testsuite/fmttest.sma',
|
||||
'testsuite/fwdtest1.sma',
|
||||
'testsuite/fwdtest2.sma',
|
||||
'testsuite/hashing_test.sma',
|
||||
'testsuite/logtest.sma',
|
||||
'testsuite/menutest.sma',
|
||||
'testsuite/native_test.sma',
|
||||
|
Loading…
Reference in New Issue
Block a user