Implemented SHA1

This commit is contained in:
Gabriel Tofvesson 2018-03-06 04:13:31 +01:00
parent caf800c4cd
commit 4da1b8723c
4 changed files with 151 additions and 0 deletions

107
SHA1/SHA1.cpp Normal file
View File

@ -0,0 +1,107 @@
#define SHA1_API
#include "SHA1.h"
#include <string>
namespace CryptoCPP {
namespace SHA1 {
SHA1_API char * digest(char * data, size_t data_size)
{
// Initialize buffers
unsigned int h0 = 0x67452301;
unsigned int h1 = 0xEFCDAB89;
unsigned int h2 = 0x98BADCFE;
unsigned int h3 = 0x10325476;
unsigned int h4 = 0xC3D2E1F0;
// Pad message
size_t ml = data_size + 1;
size_t full_size = ml + ((960 - (ml * 8 % 512)) % 512) / 8 + 8;
char * msg = new char[full_size];
memcpy(msg, data, data_size);
memset(msg + data_size, 0, full_size - data_size);
msg[data_size] = 0x80;
size_t len = data_size * 8;
for (int i = 0; i < 8; ++i) msg[full_size - 1 - i] = (len >> (i * 8)) & 255;
unsigned int chunks = full_size / 64;
// Perform hashing for each 512-bit block
for (size_t i = 0; i<chunks; ++i)
{
// Split block into words
unsigned int * w = new unsigned int[80];
for (unsigned int j = 0; j<16; ++j)
w[j] |= ((msg[i * 64 + j * 4] << 24) | (msg[i * 64 + j * 4 + 1] << 16) | (msg[i * 64 + j * 4 + 2] << 8) | (msg[i * 64 + j * 4 + 3] << 0));
// Expand words
for (size_t j = 16; j<80; ++j)
w[j] = rot(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
// Initialize chunk-hash
unsigned int
a = h0,
b = h1,
c = h2,
d = h3,
e = h4;
// Do hash rounds
for (size_t t = 0; t<80; ++t)
{
unsigned int tmp = rot(a, 5) + func(t, b, c, d) + e + K(t) + w[t];
e = d;
d = c;
c = rot(b, 30);
b = a;
a = tmp;
}
h0 += a;
h1 += b;
h2 += c;
h3 += d;
h4 += e;
delete[] w;
}
delete[] msg;
char * result = new char[20];
write_reverse_endian(result, h0, 0);
write_reverse_endian(result, h1, 4);
write_reverse_endian(result, h2, 8);
write_reverse_endian(result, h3, 12);
write_reverse_endian(result, h4, 16);
return result;
}
SHA1_API unsigned int func(unsigned int t, unsigned int b, unsigned int c, unsigned int d)
{
return
t < 20 ? (b & c) | ((~b) & d) :
t < 40 ? b ^ c ^ d :
t < 60 ? (b & c) | (b & d) | (c & d) :
/*t<80*/ b ^ c ^ d;
}
SHA1_API unsigned int K(unsigned int t)
{
return
t < 20 ? 0x5A827999 :
t < 40 ? 0x6ED9EBA1 :
t < 60 ? 0x8F1BBCDC :
/*t<80*/ 0xCA62C1D6;
}
SHA1_API unsigned int rot(unsigned int value, size_t by)
{
return (value << by) | (value >> (32 - by));
}
SHA1_API void write_reverse_endian(char* to, unsigned int value, size_t offset)
{
for (size_t t = 0; t < 4; ++t) to[offset + 4 - t] = (value >> (t * 8)) & 255;
}
}
}

30
SHA1/SHA1.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#if defined(__MINGW32__) || defined(_WIN32)
#if defined(SHA1_API)
#undef SHA1_API
#define SHA1_API __declspec(dllexport)
#else
#define SHA1_API __declspec(dllimport)
#endif
#endif
#ifndef SHA1_API
#if __GNUC__ >= 4
#define SHA1_API __attribute__ ((visibility ("default")))
#else
#define SHA1_API
#endif
#endif
namespace CryptoCPP {
namespace SHA {
SHA1_API char * digest(char * data, size_t data_size);
SHA1_API unsigned int rot(unsigned int val, size_t by);
SHA1_API unsigned int func(unsigned int t, unsigned int b, unsigned int c, unsigned int d);
SHA1_API unsigned int K(unsigned int t);
SHA1_API void write_reverse_endian(char* to, unsigned int value, size_t offset);
}
}

View File

@ -116,6 +116,10 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="SHA1.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SHA1.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -14,4 +14,14 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SHA1.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SHA1.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>