diff options
| author | Stefan Boberg <[email protected]> | 2023-05-02 10:01:47 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-02 10:01:47 +0200 |
| commit | 075d17f8ada47e990fe94606c3d21df409223465 (patch) | |
| tree | e50549b766a2f3c354798a54ff73404217b4c9af /zencore/sha1.cpp | |
| parent | fix: bundle shouldn't append content zip to zen (diff) | |
| download | zen-075d17f8ada47e990fe94606c3d21df409223465.tar.xz zen-075d17f8ada47e990fe94606c3d21df409223465.zip | |
moved source directories into `/src` (#264)
* moved source directories into `/src`
* updated bundle.lua for new `src` path
* moved some docs, icon
* removed old test trees
Diffstat (limited to 'zencore/sha1.cpp')
| -rw-r--r-- | zencore/sha1.cpp | 443 |
1 files changed, 0 insertions, 443 deletions
diff --git a/zencore/sha1.cpp b/zencore/sha1.cpp deleted file mode 100644 index 3ee74d7d8..000000000 --- a/zencore/sha1.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// ////////////////////////////////////////////////////////// -// sha1.cpp -// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. -// see http://create.stephan-brumme.com/disclaimer.html -// - -#include <zencore/sha1.h> -#include <zencore/string.h> -#include <zencore/testing.h> -#include <zencore/zencore.h> - -#include <string.h> - -// big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN -#if ZEN_PLATFORM_LINUX -# include <endian.h> -#endif - -namespace zen { - -////////////////////////////////////////////////////////////////////////// - -SHA1 SHA1::Zero; // Initialized to all zeroes - -////////////////////////////////////////////////////////////////////////// - -SHA1Stream::SHA1Stream() -{ - Reset(); -} - -void -SHA1Stream::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); - } -} // namespace - -/// process 64 bytes -void -SHA1Stream::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 -SHA1Stream& -SHA1Stream::Append(const void* data, size_t byteCount) -{ - const uint8_t* current = (const uint8_t*)data; - - if (m_BufferSize > 0) - { - while (byteCount > 0 && m_BufferSize < BlockSize) - { - m_Buffer[m_BufferSize++] = *current++; - byteCount--; - } - } - - // full buffer - if (m_BufferSize == BlockSize) - { - ProcessBlock((void*)m_Buffer); - m_NumBytes += BlockSize; - m_BufferSize = 0; - } - - // no more data ? - if (byteCount == 0) - return *this; - - // process full blocks - while (byteCount >= BlockSize) - { - ProcessBlock(current); - current += BlockSize; - m_NumBytes += BlockSize; - byteCount -= BlockSize; - } - - // keep remaining bytes in buffer - while (byteCount > 0) - { - m_Buffer[m_BufferSize++] = *current++; - byteCount--; - } - - return *this; -} - -/// process final block, less than 64 bytes -void -SHA1Stream::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++ = (unsigned char)((msgBits >> 56) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 48) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 40) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 32) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 24) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 16) & 0xFF); - *addLength++ = (unsigned char)((msgBits >> 8) & 0xFF); - *addLength = (unsigned char)(msgBits & 0xFF); - - // process blocks - ProcessBlock(m_Buffer); - // flowed over into a second block ? - if (paddedLength > BlockSize) - ProcessBlock(extra); -} - -/// return latest hash as bytes -SHA1 -SHA1Stream::GetHash() -{ - SHA1 sha1; - // 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(); - - unsigned char* current = sha1.Hash; - for (int i = 0; i < HashValues; i++) - { - *current++ = (m_Hash[i] >> 24) & 0xFF; - *current++ = (m_Hash[i] >> 16) & 0xFF; - *current++ = (m_Hash[i] >> 8) & 0xFF; - *current++ = m_Hash[i] & 0xFF; - - // restore old hash - m_Hash[i] = oldHash[i]; - } - - return sha1; -} - -/// compute SHA1 of a memory block -SHA1 -SHA1Stream::Compute(const void* data, size_t byteCount) -{ - Reset(); - Append(data, byteCount); - return GetHash(); -} - -SHA1 -SHA1::HashMemory(const void* data, size_t byteCount) -{ - return SHA1Stream().Append(data, byteCount).GetHash(); -} - -SHA1 -SHA1::FromHexString(const char* string) -{ - SHA1 sha1; - - ParseHexBytes(string, 40, sha1.Hash); - - return sha1; -} - -const char* -SHA1::ToHexString(char* outString /* 40 characters + NUL terminator */) const -{ - ToHexBytes(Hash, sizeof(SHA1), outString); - outString[2 * sizeof(SHA1)] = '\0'; - - return outString; -} - -StringBuilderBase& -SHA1::ToHexString(StringBuilderBase& outBuilder) const -{ - char str[41]; - ToHexString(str); - - outBuilder.AppendRange(str, &str[40]); - - return outBuilder; -} - -////////////////////////////////////////////////////////////////////////// -// -// Testing related code follows... -// - -#if ZEN_WITH_TESTS - -void -sha1_forcelink() -{ -} - -// doctest::String -// toString(const SHA1& value) -// { -// char sha1text[2 * sizeof(SHA1) + 1]; -// value.ToHexString(sha1text); - -// return sha1text; -// } - -TEST_CASE("SHA1") -{ - uint8_t sha1_empty[20] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, - 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}; - SHA1 sha1z; - memcpy(sha1z.Hash, sha1_empty, sizeof sha1z.Hash); - - SUBCASE("Empty string") - { - SHA1 sha1 = SHA1::HashMemory(nullptr, 0); - - CHECK(sha1 == sha1z); - } - - SUBCASE("Empty stream") - { - SHA1Stream sha1s; - sha1s.Append(nullptr, 0); - sha1s.Append(nullptr, 0); - sha1s.Append(nullptr, 0); - CHECK(sha1s.GetHash() == sha1z); - } - - SUBCASE("SHA1 from string") - { - const SHA1 sha1empty = SHA1::FromHexString("da39a3ee5e6b4b0d3255bfef95601890afd80709"); - - CHECK(sha1z == sha1empty); - } - - SUBCASE("SHA1 to string") - { - char sha1str[41]; - sha1z.ToHexString(sha1str); - - CHECK(StringEquals(sha1str, "da39a3ee5e6b4b0d3255bfef95601890afd80709")); - } - - SUBCASE("Hash ABC") - { - const SHA1 sha1abc = SHA1::FromHexString("3c01bdbb26f358bab27f267924aa2c9a03fcfdb8"); - - SHA1Stream sha1s; - - sha1s.Append("A", 1); - sha1s.Append("B", 1); - sha1s.Append("C", 1); - CHECK(sha1s.GetHash() == sha1abc); - - sha1s.Reset(); - sha1s.Append("AB", 2); - sha1s.Append("C", 1); - CHECK(sha1s.GetHash() == sha1abc); - - sha1s.Reset(); - sha1s.Append("ABC", 3); - CHECK(sha1s.GetHash() == sha1abc); - - sha1s.Reset(); - sha1s.Append("A", 1); - sha1s.Append("BC", 2); - CHECK(sha1s.GetHash() == sha1abc); - } -} - -#endif - -} // namespace zen |