diff options
| author | skallweitNV <64953474+skallweitNV@users.noreply.github.com> | 2022-12-02 16:34:53 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-02 16:34:53 +0100 |
| commit | e9b7c66a541636e72659fbfcc9a3f20a85f2bee8 (patch) | |
| tree | b65942799ff6267ebe29c8b64056819461621be7 | |
| parent | 92ae4949fe1af28ef31331fd4116c8111c057420 (diff) | |
Cleanup crypto utilities (#2549)
* Consolidate crypto functions into single module
* Migrate rest of code to new crypto module
* Fix name conflict
27 files changed, 1057 insertions, 922 deletions
diff --git a/build/visual-studio/core/core.vcxproj b/build/visual-studio/core/core.vcxproj index 47ca16cd5..e171a7d68 100644 --- a/build/visual-studio/core/core.vcxproj +++ b/build/visual-studio/core/core.vcxproj @@ -276,11 +276,10 @@ <ClInclude Include="..\..\..\source\core\slang-command-line.h" /> <ClInclude Include="..\..\..\source\core\slang-common.h" /> <ClInclude Include="..\..\..\source\core\slang-compression-system.h" /> + <ClInclude Include="..\..\..\source\core\slang-crypto.h" /> <ClInclude Include="..\..\..\source\core\slang-deflate-compression-system.h" /> <ClInclude Include="..\..\..\source\core\slang-destroyable.h" /> <ClInclude Include="..\..\..\source\core\slang-dictionary.h" /> - <ClInclude Include="..\..\..\source\core\slang-digest-builder.h" /> - <ClInclude Include="..\..\..\source\core\slang-digest-util.h" /> <ClInclude Include="..\..\..\source\core\slang-exception.h" /> <ClInclude Include="..\..\..\source\core\slang-file-system.h" /> <ClInclude Include="..\..\..\source\core\slang-free-list.h" /> @@ -295,7 +294,6 @@ <ClInclude Include="..\..\..\source\core\slang-list.h" /> <ClInclude Include="..\..\..\source\core\slang-lz4-compression-system.h" /> <ClInclude Include="..\..\..\source\core\slang-math.h" /> - <ClInclude Include="..\..\..\source\core\slang-md5.h" /> <ClInclude Include="..\..\..\source\core\slang-memory-arena.h" /> <ClInclude Include="..\..\..\source\core\slang-memory-file-system.h" /> <ClInclude Include="..\..\..\source\core\slang-offset-container.h" /> @@ -342,8 +340,8 @@ <ClCompile Include="..\..\..\source\core\slang-char-encode.cpp" /> <ClCompile Include="..\..\..\source\core\slang-char-util.cpp" /> <ClCompile Include="..\..\..\source\core\slang-command-line.cpp" /> + <ClCompile Include="..\..\..\source\core\slang-crypto.cpp" /> <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp" /> - <ClCompile Include="..\..\..\source\core\slang-digest-util.cpp" /> <ClCompile Include="..\..\..\source\core\slang-file-system.cpp" /> <ClCompile Include="..\..\..\source\core\slang-free-list.cpp" /> <ClCompile Include="..\..\..\source\core\slang-hex-dump-util.cpp" /> @@ -352,7 +350,6 @@ <ClCompile Include="..\..\..\source\core\slang-io.cpp" /> <ClCompile Include="..\..\..\source\core\slang-lazy-castable-list.cpp" /> <ClCompile Include="..\..\..\source\core\slang-lz4-compression-system.cpp" /> - <ClCompile Include="..\..\..\source\core\slang-md5.cpp" /> <ClCompile Include="..\..\..\source\core\slang-memory-arena.cpp" /> <ClCompile Include="..\..\..\source\core\slang-memory-file-system.cpp" /> <ClCompile Include="..\..\..\source\core\slang-offset-container.cpp" /> diff --git a/build/visual-studio/core/core.vcxproj.filters b/build/visual-studio/core/core.vcxproj.filters index 068023108..06d151349 100644 --- a/build/visual-studio/core/core.vcxproj.filters +++ b/build/visual-studio/core/core.vcxproj.filters @@ -60,6 +60,9 @@ <ClInclude Include="..\..\..\source\core\slang-compression-system.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\core\slang-crypto.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\..\..\source\core\slang-deflate-compression-system.h"> <Filter>Header Files</Filter> </ClInclude> @@ -69,12 +72,6 @@ <ClInclude Include="..\..\..\source\core\slang-dictionary.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-digest-builder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-digest-util.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\source\core\slang-exception.h"> <Filter>Header Files</Filter> </ClInclude> @@ -117,9 +114,6 @@ <ClInclude Include="..\..\..\source\core\slang-math.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-md5.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\source\core\slang-memory-arena.h"> <Filter>Header Files</Filter> </ClInclude> @@ -254,10 +248,10 @@ <ClCompile Include="..\..\..\source\core\slang-command-line.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp"> + <ClCompile Include="..\..\..\source\core\slang-crypto.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-digest-util.cpp"> + <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp"> <Filter>Source Files</Filter> </ClCompile> <ClCompile Include="..\..\..\source\core\slang-file-system.cpp"> @@ -284,9 +278,6 @@ <ClCompile Include="..\..\..\source\core\slang-lz4-compression-system.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-md5.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\..\source\core\slang-memory-arena.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj b/build/visual-studio/slang-rt/slang-rt.vcxproj index 13afadf6a..03d3852fd 100644 --- a/build/visual-studio/slang-rt/slang-rt.vcxproj +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj @@ -288,11 +288,10 @@ <ClInclude Include="..\..\..\source\core\slang-command-line.h" /> <ClInclude Include="..\..\..\source\core\slang-common.h" /> <ClInclude Include="..\..\..\source\core\slang-compression-system.h" /> + <ClInclude Include="..\..\..\source\core\slang-crypto.h" /> <ClInclude Include="..\..\..\source\core\slang-deflate-compression-system.h" /> <ClInclude Include="..\..\..\source\core\slang-destroyable.h" /> <ClInclude Include="..\..\..\source\core\slang-dictionary.h" /> - <ClInclude Include="..\..\..\source\core\slang-digest-builder.h" /> - <ClInclude Include="..\..\..\source\core\slang-digest-util.h" /> <ClInclude Include="..\..\..\source\core\slang-exception.h" /> <ClInclude Include="..\..\..\source\core\slang-file-system.h" /> <ClInclude Include="..\..\..\source\core\slang-free-list.h" /> @@ -307,7 +306,6 @@ <ClInclude Include="..\..\..\source\core\slang-list.h" /> <ClInclude Include="..\..\..\source\core\slang-lz4-compression-system.h" /> <ClInclude Include="..\..\..\source\core\slang-math.h" /> - <ClInclude Include="..\..\..\source\core\slang-md5.h" /> <ClInclude Include="..\..\..\source\core\slang-memory-arena.h" /> <ClInclude Include="..\..\..\source\core\slang-memory-file-system.h" /> <ClInclude Include="..\..\..\source\core\slang-offset-container.h" /> @@ -355,8 +353,8 @@ <ClCompile Include="..\..\..\source\core\slang-char-encode.cpp" /> <ClCompile Include="..\..\..\source\core\slang-char-util.cpp" /> <ClCompile Include="..\..\..\source\core\slang-command-line.cpp" /> + <ClCompile Include="..\..\..\source\core\slang-crypto.cpp" /> <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp" /> - <ClCompile Include="..\..\..\source\core\slang-digest-util.cpp" /> <ClCompile Include="..\..\..\source\core\slang-file-system.cpp" /> <ClCompile Include="..\..\..\source\core\slang-free-list.cpp" /> <ClCompile Include="..\..\..\source\core\slang-hex-dump-util.cpp" /> @@ -365,7 +363,6 @@ <ClCompile Include="..\..\..\source\core\slang-io.cpp" /> <ClCompile Include="..\..\..\source\core\slang-lazy-castable-list.cpp" /> <ClCompile Include="..\..\..\source\core\slang-lz4-compression-system.cpp" /> - <ClCompile Include="..\..\..\source\core\slang-md5.cpp" /> <ClCompile Include="..\..\..\source\core\slang-memory-arena.cpp" /> <ClCompile Include="..\..\..\source\core\slang-memory-file-system.cpp" /> <ClCompile Include="..\..\..\source\core\slang-offset-container.cpp" /> diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj.filters b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters index dd72f5178..df9f8c2ca 100644 --- a/build/visual-studio/slang-rt/slang-rt.vcxproj.filters +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters @@ -60,6 +60,9 @@ <ClInclude Include="..\..\..\source\core\slang-compression-system.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\core\slang-crypto.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\..\..\source\core\slang-deflate-compression-system.h"> <Filter>Header Files</Filter> </ClInclude> @@ -69,12 +72,6 @@ <ClInclude Include="..\..\..\source\core\slang-dictionary.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-digest-builder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-digest-util.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\source\core\slang-exception.h"> <Filter>Header Files</Filter> </ClInclude> @@ -117,9 +114,6 @@ <ClInclude Include="..\..\..\source\core\slang-math.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\core\slang-md5.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\source\core\slang-memory-arena.h"> <Filter>Header Files</Filter> </ClInclude> @@ -257,10 +251,10 @@ <ClCompile Include="..\..\..\source\core\slang-command-line.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp"> + <ClCompile Include="..\..\..\source\core\slang-crypto.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-digest-util.cpp"> + <ClCompile Include="..\..\..\source\core\slang-deflate-compression-system.cpp"> <Filter>Source Files</Filter> </ClCompile> <ClCompile Include="..\..\..\source\core\slang-file-system.cpp"> @@ -287,9 +281,6 @@ <ClCompile Include="..\..\..\source\core\slang-lz4-compression-system.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\source\core\slang-md5.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\..\source\core\slang-memory-arena.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj b/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj index 539187f3e..deab210ee 100644 --- a/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj +++ b/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj @@ -285,8 +285,7 @@ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-com-host-callable.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-command-line-args.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-compression.cpp" />
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-digest-builder.cpp" />
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-digest-utils.cpp" />
+ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-crypto.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-file-system.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-find-type-by-name.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-free-list.cpp" />
@@ -294,7 +293,6 @@ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-json-native.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-json.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-lock-file.cpp" />
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-md5.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-memory-arena.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-offset-container.cpp" />
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-path.cpp" />
diff --git a/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj.filters b/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj.filters index 93d7e7325..a33dc44cc 100644 --- a/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj.filters +++ b/build/visual-studio/slang-unit-test-tool/slang-unit-test-tool.vcxproj.filters @@ -29,10 +29,7 @@ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-compression.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-digest-builder.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-digest-utils.cpp">
+ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-crypto.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-file-system.cpp">
@@ -56,9 +53,6 @@ <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-lock-file.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-md5.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\tools\slang-unit-test\unit-test-memory-arena.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -4138,31 +4138,6 @@ namespace slang None, UnsizedArray, StructuredBuffer, ConstantBuffer, ParameterBlock }; - // A struct storing a single hash represented as a four element uint32_t array. - // This is intended to be used with the current MD5 hashing implementation. - struct Digest - { - uint32_t values[4] = { 0 }; - - bool operator==(const Digest& rhs) - { - return values[0] == rhs.values[0] - && values[1] == rhs.values[1] - && values[2] == rhs.values[2] - && values[3] == rhs.values[3]; - } - - bool operator!=(const Digest& rhs) - { - return !(*this == rhs); - } - - uint32_t getHashCode() - { - return values[0]; - } - }; - /** A session provides a scope for code that is loaded. A session can be used to load modules of Slang source code, @@ -4464,7 +4439,7 @@ namespace slang virtual SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - Digest* outHash) = 0; + IBlob** outHash) = 0; /** Compute the hash code of this component type's contents as indicated by the file dependencies. This hash is ideal when we need to confirm whether shader code changes have occurred. For example, @@ -4477,7 +4452,7 @@ namespace slang type that should ever be hashing its contents is Module as it represents all the code in a given translation unit. */ - virtual SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(Digest* outHash) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(IBlob** outHash) = 0; /** Specialize the component by binding its specialization parameters to concrete arguments. diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp index 26245df9c..80b1f7a21 100644 --- a/source/compiler-core/slang-dxc-compiler.cpp +++ b/source/compiler-core/slang-dxc-compiler.cpp @@ -14,8 +14,6 @@ #include "../core/slang-semantic-version.h" #include "../core/slang-char-util.h" -#include "../core/slang-digest-builder.h" - #include "slang-include-system.h" #include "slang-source-loc.h" diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp index 6e11d9814..0673540dc 100644 --- a/source/compiler-core/slang-glslang-compiler.cpp +++ b/source/compiler-core/slang-glslang-compiler.cpp @@ -14,8 +14,6 @@ #include "../core/slang-semantic-version.h" #include "../core/slang-char-util.h" -#include "../core/slang-digest-builder.h" - #include "slang-artifact-associated-impl.h" #include "slang-artifact-desc-util.h" diff --git a/source/core/slang-crypto.cpp b/source/core/slang-crypto.cpp new file mode 100644 index 000000000..ece7b01e9 --- /dev/null +++ b/source/core/slang-crypto.cpp @@ -0,0 +1,603 @@ +/* + * MD5 implementation is based on: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * Original file header is at the bottom of this file. + * + * SHA1 implementation is based on: + * https://github.com/983/SHA1 + * Original LICENSE is at the bottom of this file. + */ + +#include "slang-crypto.h" +#include "../core/slang-char-util.h" + +namespace Slang +{ + +// DigestUtil + +/*static*/ String DigestUtil::digestToString(const void* digest, SlangInt digestSize) +{ + SLANG_ASSERT(digest && digestSize >= 0); + + static const char* hex = "0123456789abcdef"; + + String str; + const uint8_t* data = reinterpret_cast<const uint8_t*>(digest); + for (SlangInt i = 0; i < digestSize; ++i) + { + str.append(hex[data[i] >> 4]); + str.append(hex[data[i] & 0xf]); + } + return str; +} + +/*static*/ bool DigestUtil::stringToDigest(const char* str, SlangInt strLength, void *digest, SlangInt digestSize) +{ + SLANG_ASSERT(str && strLength >= 0 && digest && digestSize >= 0); + + if (strLength != digestSize * 2) + { + ::memset(digest, 0, digestSize); + return false; + } + + uint8_t* data = reinterpret_cast<uint8_t*>(digest); + for (SlangInt i = 0; i < digestSize; ++i) + { + int upper = CharUtil::getHexDigitValue(str[i * 2]); + int lower = CharUtil::getHexDigitValue(str[i * 2 + 1]); + if (upper == -1 || lower == -1) + { + ::memset(digest, 0, digestSize); + return false; + } + data[i] = uint8_t(lower | upper << 4);; + } + + return true; +} + +// MD5 + +MD5::MD5() +{ + init(); +} + +void MD5::init() +{ + m_lo = 0; + m_hi = 0; + m_a = 0x67452301; + m_b = 0xefcdab89; + m_c = 0x98badcfe; + m_d = 0x10325476; +} + +void MD5::update(const void* data, SlangInt size) +{ + uint32_t saved_lo; + SlangInt used, available; + + saved_lo = m_lo; + if ((m_lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + m_hi++; + m_hi += (uint32_t)size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + available = 64 - used; + + if (size < available) { + ::memcpy(&m_buffer[used], data, size); + return; + } + + ::memcpy(&m_buffer[used], data, available); + data = reinterpret_cast<const uint8_t*>(data) + available; + size -= available; + processBlock(m_buffer, 64); + } + + if (size >= 64) { + data = processBlock(data, size & ~(SlangInt)0x3f); + size &= 0x3f; + } + + ::memcpy(m_buffer, data, size); +} + +MD5::Digest MD5::finalize() +{ + uint32_t used, available; + + used = m_lo & 0x3f; + + m_buffer[used++] = 0x80; + + available = 64 - used; + + if (available < 8) { + ::memset(&m_buffer[used], 0, available); + processBlock(m_buffer, 64); + used = 0; + available = 64; + } + + ::memset(&m_buffer[used], 0, available - 8); + + m_lo <<= 3; + + m_buffer[56] = uint8_t(m_lo); + m_buffer[57] = uint8_t(m_lo >> 8); + m_buffer[58] = uint8_t(m_lo >> 16); + m_buffer[59] = uint8_t(m_lo >> 24); + m_buffer[60] = uint8_t(m_hi); + m_buffer[61] = uint8_t(m_hi >> 8); + m_buffer[62] = uint8_t(m_hi >> 16); + m_buffer[63] = uint8_t(m_hi >> 24); + + processBlock(m_buffer, 64); + + Digest digest; + digest.data[0] = m_a; + digest.data[1] = m_b; + digest.data[2] = m_c; + digest.data[3] = m_d; + + return digest; +} + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them in a + * properly aligned word in host byte order. + */ +#define SET(n) \ + (m_block[(n)] = \ + (uint32_t)ptr[(n) * 4] | \ + ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ + ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ + ((uint32_t)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (m_block[(n)]) + +const void* MD5::processBlock(const void* data, SlangInt size) +{ + const unsigned char* ptr; + ptr = (const unsigned char*)data; + + uint32_t a = m_a; + uint32_t b = m_b; + uint32_t c = m_c; + uint32_t d = m_d; + + do + { + uint32_t saved_a = a; + uint32_t saved_b = b; + uint32_t saved_c = c; + uint32_t saved_d = d; + + /* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + + /* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + + /* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) + + /* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } + while (size -= 64); + + m_a = a; + m_b = b; + m_c = c; + m_d = d; + + return ptr; +} + +#undef F +#undef G +#undef H +#undef H2 +#undef I +#undef STEP +#undef SET +#undef GET + +/*static*/ MD5::Digest MD5::compute(const void* data, SlangInt size) +{ + MD5 md5; + md5.update(data, size); + return md5.finalize(); +} + +// SHA1 + +SHA1::SHA1() +{ + init(); +} + +void SHA1::init() +{ + m_index = 0; + m_bits = 0; + m_state[0] = 0x67452301; + m_state[1] = 0xefcdab89; + m_state[2] = 0x98badcfe; + m_state[3] = 0x10325476; + m_state[4] = 0xc3d2e1f0; +} + +void SHA1::update(const void* data, SlangInt len) +{ + if (!data || len <= 0) + { + return; + } + + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data); + + // Fill up buffer if not full. + while (len > 0 && m_index != 0) + { + addByte(*ptr++); + m_bits += 8; + len--; + } + + // Process full blocks. + while (len >= sizeof(m_buf)) + { + processBlock(ptr); + ptr += sizeof(m_buf); + len -= sizeof(m_buf); + m_bits += sizeof(m_buf) * 8; + } + + // Process remaining bytes. + while (len > 0) + { + addByte(*ptr++); + m_bits += 8; + len--; + } +} + +SHA1::Digest SHA1::finalize() +{ + // Finalize with 0x80, some zero padding and the length in bits. + addByte(0x80); + while (m_index % 64 != 56) + { + addByte(0); + } + for (int i = 7; i >= 0; --i) + { + addByte(uint8_t(m_bits >> i * 8)); + } + + Digest digest; + uint8_t* data = reinterpret_cast<uint8_t*>(digest.data); + for (int i = 0; i < 5; i++) + { + for (int j = 3; j >= 0; j--) + { + data[i * 4 + j] = (m_state[i] >> ((3 - j) * 8)) & 0xff; + } + } + + return digest; +} + +void SHA1::addByte(uint8_t byte) +{ + m_buf[m_index++] = byte; + + if (m_index >= sizeof(m_buf)) + { + m_index = 0; + processBlock(m_buf); + } +} + +void SHA1::processBlock(const uint8_t* ptr) +{ + auto rol32 = [](uint32_t x, uint32_t n) + { + return (x << n) | (x >> (32 - n)); + }; + + auto makeWord = [](const uint8_t* p) + { + return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; + }; + + const uint32_t c0 = 0x5a827999; + const uint32_t c1 = 0x6ed9eba1; + const uint32_t c2 = 0x8f1bbcdc; + const uint32_t c3 = 0xca62c1d6; + + uint32_t a = m_state[0]; + uint32_t b = m_state[1]; + uint32_t c = m_state[2]; + uint32_t d = m_state[3]; + uint32_t e = m_state[4]; + + uint32_t w[16]; + + for (size_t i = 0; i < 16; i++) + { + w[i] = makeWord(ptr + i * 4); + } + +#define SHA1_LOAD(i) w[i&15] = rol32(w[(i + 13) & 15] ^ w[(i + 8) & 15] ^ w[(i + 2) & 15] ^ w[i & 15], 1); +#define SHA1_ROUND_0(v,u,x,y,z,i) z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); u = rol32(u, 30); +#define SHA1_ROUND_1(v,u,x,y,z,i) SHA1_LOAD(i) z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); u = rol32(u, 30); +#define SHA1_ROUND_2(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c1 + rol32(v, 5); u = rol32(u, 30); +#define SHA1_ROUND_3(v,u,x,y,z,i) SHA1_LOAD(i) z += (((u | x) & y) | (u & x)) + w[i & 15] + c2 + rol32(v, 5); u = rol32(u, 30); +#define SHA1_ROUND_4(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c3 + rol32(v, 5); u = rol32(u, 30); + + SHA1_ROUND_0(a, b, c, d, e, 0); + SHA1_ROUND_0(e, a, b, c, d, 1); + SHA1_ROUND_0(d, e, a, b, c, 2); + SHA1_ROUND_0(c, d, e, a, b, 3); + SHA1_ROUND_0(b, c, d, e, a, 4); + SHA1_ROUND_0(a, b, c, d, e, 5); + SHA1_ROUND_0(e, a, b, c, d, 6); + SHA1_ROUND_0(d, e, a, b, c, 7); + SHA1_ROUND_0(c, d, e, a, b, 8); + SHA1_ROUND_0(b, c, d, e, a, 9); + SHA1_ROUND_0(a, b, c, d, e, 10); + SHA1_ROUND_0(e, a, b, c, d, 11); + SHA1_ROUND_0(d, e, a, b, c, 12); + SHA1_ROUND_0(c, d, e, a, b, 13); + SHA1_ROUND_0(b, c, d, e, a, 14); + SHA1_ROUND_0(a, b, c, d, e, 15); + SHA1_ROUND_1(e, a, b, c, d, 16); + SHA1_ROUND_1(d, e, a, b, c, 17); + SHA1_ROUND_1(c, d, e, a, b, 18); + SHA1_ROUND_1(b, c, d, e, a, 19); + SHA1_ROUND_2(a, b, c, d, e, 20); + SHA1_ROUND_2(e, a, b, c, d, 21); + SHA1_ROUND_2(d, e, a, b, c, 22); + SHA1_ROUND_2(c, d, e, a, b, 23); + SHA1_ROUND_2(b, c, d, e, a, 24); + SHA1_ROUND_2(a, b, c, d, e, 25); + SHA1_ROUND_2(e, a, b, c, d, 26); + SHA1_ROUND_2(d, e, a, b, c, 27); + SHA1_ROUND_2(c, d, e, a, b, 28); + SHA1_ROUND_2(b, c, d, e, a, 29); + SHA1_ROUND_2(a, b, c, d, e, 30); + SHA1_ROUND_2(e, a, b, c, d, 31); + SHA1_ROUND_2(d, e, a, b, c, 32); + SHA1_ROUND_2(c, d, e, a, b, 33); + SHA1_ROUND_2(b, c, d, e, a, 34); + SHA1_ROUND_2(a, b, c, d, e, 35); + SHA1_ROUND_2(e, a, b, c, d, 36); + SHA1_ROUND_2(d, e, a, b, c, 37); + SHA1_ROUND_2(c, d, e, a, b, 38); + SHA1_ROUND_2(b, c, d, e, a, 39); + SHA1_ROUND_3(a, b, c, d, e, 40); + SHA1_ROUND_3(e, a, b, c, d, 41); + SHA1_ROUND_3(d, e, a, b, c, 42); + SHA1_ROUND_3(c, d, e, a, b, 43); + SHA1_ROUND_3(b, c, d, e, a, 44); + SHA1_ROUND_3(a, b, c, d, e, 45); + SHA1_ROUND_3(e, a, b, c, d, 46); + SHA1_ROUND_3(d, e, a, b, c, 47); + SHA1_ROUND_3(c, d, e, a, b, 48); + SHA1_ROUND_3(b, c, d, e, a, 49); + SHA1_ROUND_3(a, b, c, d, e, 50); + SHA1_ROUND_3(e, a, b, c, d, 51); + SHA1_ROUND_3(d, e, a, b, c, 52); + SHA1_ROUND_3(c, d, e, a, b, 53); + SHA1_ROUND_3(b, c, d, e, a, 54); + SHA1_ROUND_3(a, b, c, d, e, 55); + SHA1_ROUND_3(e, a, b, c, d, 56); + SHA1_ROUND_3(d, e, a, b, c, 57); + SHA1_ROUND_3(c, d, e, a, b, 58); + SHA1_ROUND_3(b, c, d, e, a, 59); + SHA1_ROUND_4(a, b, c, d, e, 60); + SHA1_ROUND_4(e, a, b, c, d, 61); + SHA1_ROUND_4(d, e, a, b, c, 62); + SHA1_ROUND_4(c, d, e, a, b, 63); + SHA1_ROUND_4(b, c, d, e, a, 64); + SHA1_ROUND_4(a, b, c, d, e, 65); + SHA1_ROUND_4(e, a, b, c, d, 66); + SHA1_ROUND_4(d, e, a, b, c, 67); + SHA1_ROUND_4(c, d, e, a, b, 68); + SHA1_ROUND_4(b, c, d, e, a, 69); + SHA1_ROUND_4(a, b, c, d, e, 70); + SHA1_ROUND_4(e, a, b, c, d, 71); + SHA1_ROUND_4(d, e, a, b, c, 72); + SHA1_ROUND_4(c, d, e, a, b, 73); + SHA1_ROUND_4(b, c, d, e, a, 74); + SHA1_ROUND_4(a, b, c, d, e, 75); + SHA1_ROUND_4(e, a, b, c, d, 76); + SHA1_ROUND_4(d, e, a, b, c, 77); + SHA1_ROUND_4(c, d, e, a, b, 78); + SHA1_ROUND_4(b, c, d, e, a, 79); + +#undef SHA1_LOAD +#undef SHA1_ROUND_0 +#undef SHA1_ROUND_1 +#undef SHA1_ROUND_2 +#undef SHA1_ROUND_3 +#undef SHA1_ROUND_4 + + m_state[0] += a; + m_state[1] += b; + m_state[2] += c; + m_state[3] += d; + m_state[4] += e; +} + +/* static */SHA1::Digest SHA1::compute(const void* data, SlangInt size) +{ + SHA1 sha1; + sha1.update(data, size); + return sha1.finalize(); +} + +} + + +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. + */ + +/* + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to <http://unlicense.org> + */ diff --git a/source/core/slang-crypto.h b/source/core/slang-crypto.h new file mode 100644 index 000000000..0df02201c --- /dev/null +++ b/source/core/slang-crypto.h @@ -0,0 +1,184 @@ +#pragma once +#include "../../slang.h" +#include "../core/slang-string.h" +#include "../core/slang-blob.h" +#include "../core/slang-list.h" + +namespace Slang +{ + struct DigestUtil + { + /// Convert a binary digest to a string (lower-case hexadecimal). + /// Returned string is double the length of the digest. + static String digestToString(const void* digest, SlangInt digestSize); + + /// Convert a string to a binary digest. + /// Expects a string of double the length of the digest size in hexadecimal format. + /// Sets the digest to all zeros if the string is invalid. + /// Returns true if string was converted successfully. + static bool stringToDigest(const char* str, SlangInt strLength, void *digest, SlangInt digestSize); + }; + + /// Represents a hash digest. Only sizes of multiple of 4 are supported. + template<SlangInt N> + class HashDigest + { + public: + static_assert(N % 4 == 0, "size must be multiple of 4"); + uint32_t data[N / 4] = { 0 }; + + HashDigest() = default; + + HashDigest(const char* str) + { + DigestUtil::stringToDigest(str, ::strlen(str), data, N); + } + + HashDigest(const String& str) + { + DigestUtil::stringToDigest(str.getBuffer(), str.getLength(), data, N); + } + + HashDigest(const UnownedStringSlice& str) + { + DigestUtil::stringToDigest(str.begin(), str.getLength(), data, N); + } + + HashDigest(ISlangBlob* blob) + { + if (blob->getBufferSize() == N) + { + ::memcpy(data, blob->getBufferPointer(), N); + } + } + + String toString() const + { + return DigestUtil::digestToString(data, N); + } + + ComPtr<ISlangBlob> toBlob() const + { + return RawBlob::create(data, sizeof(data)); + } + + bool operator==(const HashDigest& other) const + { + return ::memcmp(data, other.data, sizeof(data)) == 0; + } + + bool operator!=(const HashDigest& other) const + { + return !(*this == other); + } + + uint32_t getHashCode() const + { + return data[0]; + } + }; + + /// MD5 hash generator implementing https://www.ietf.org/rfc/rfc1321.txt + class MD5 + { + public: + using Digest = HashDigest<16>; + + MD5(); + + void init(); + void update(const void* data, SlangInt size); + Digest finalize(); + + static Digest compute(const void* data, SlangInt size); + + private: + const void* processBlock(const void* data, SlangInt size); + + uint32_t m_lo, m_hi; + uint32_t m_a, m_b, m_c, m_d; + uint32_t m_block[16]; + uint8_t m_buffer[64]; + }; + + /// SHA1 hash generator implementing https://www.ietf.org/rfc/rfc3174.txt + class SHA1 + { + public: + using Digest = HashDigest<20>; + + SHA1(); + + void init(); + void update(const void* data, SlangInt size); + Digest finalize(); + + static Digest compute(const void* data, SlangInt size); + + private: + void addByte(uint8_t x); + void processBlock(const uint8_t* ptr); + + uint32_t m_index; + uint64_t m_bits; + uint32_t m_state[5]; + uint8_t m_buf[64]; + }; + + // Helper class for building hashes. + template<typename Hash> + struct DigestBuilder + { + public: + void append(const void* data, SlangInt size) + { + m_hash.update(data, size); + } + + template<typename T, typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, int>::type = 0> + void append(const T value) + { + append(&value, sizeof(T)); + } + + void append(const String& str) + { + append(str.getBuffer(), str.getLength()); + } + + void append(const StringSlice& str) + { + append(str.begin(), str.getLength()); + } + + void append(const UnownedStringSlice& str) + { + append(str.begin(), str.getLength()); + } + + void append(ISlangBlob* blob) + { + append(blob->getBufferPointer(), blob->getBufferSize()); + } + + template<SlangInt N> + void append(const HashDigest<N>& digest) + { + append(digest.data, sizeof(digest.data)); + } + + template<typename T, typename std::enable_if<std::is_pod<T>::value, int>::type = 0> + void append(const List<T>& list) + { + append(list.getBuffer(), list.getCount() * sizeof(T)); + } + + typename Hash::Digest finalize() + { + return m_hash.finalize(); + } + + private: + Hash m_hash; + }; +} diff --git a/source/core/slang-digest-builder.h b/source/core/slang-digest-builder.h deleted file mode 100644 index c613b2239..000000000 --- a/source/core/slang-digest-builder.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once -#include "slang-md5.h" -#include "../../slang.h" -#include "../core/slang-string.h" -#include "../core/slang-list.h" - -namespace Slang -{ - using slang::Digest; - - // Wrapper struct that holds objects necessary for hashing. - struct DigestBuilder - { - public: - DigestBuilder() - { - hashGen.init(&context); - } - - template<typename T, typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, int>::type = 0> - DigestBuilder& operator<<(const T value) - { - append(value); - return *this; - } - - DigestBuilder& operator<<(const String& str) - { - append(str); - return *this; - } - - DigestBuilder& operator<<(const StringSlice& str) - { - append(str); - return *this; - } - - DigestBuilder& operator<<(const UnownedStringSlice& str) - { - append(str); - return *this; - } - - DigestBuilder& operator<<(ISlangBlob* blob) - { - append(blob); - return *this; - } - - DigestBuilder& operator<<(const slang::Digest& digest) - { - append(digest); - return *this; - } - - template<typename T, typename std::enable_if<std::is_pod<T>::value, int>::type = 0> - DigestBuilder& operator<<(const List<T>& list) - { - append(list); - return *this; - } - - void append(const void* data, SlangInt size) - { - hashGen.update(&context, data, size); - } - - template<typename T, typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, int>::type = 0> - void append(const T value) - { - append(&value, sizeof(T)); - } - - void append(const String& str) - { - append(str.getBuffer(), str.getLength()); - } - - void append(const StringSlice& str) - { - append(str.begin(), str.getLength()); - } - - void append(const UnownedStringSlice& str) - { - append(str.begin(), str.getLength()); - } - - void append(ISlangBlob* blob) - { - append(blob->getBufferPointer(), blob->getBufferSize()); - } - - void append(const slang::Digest& digest) - { - append(&digest, sizeof(digest)); - } - - template<typename T, typename std::enable_if<std::is_pod<T>::value, int>::type = 0> - void append(const List<T>& list) - { - append(list.getBuffer(), list.getCount() * sizeof(T)); - } - - Digest finalize() - { - Digest hash; - hashGen.finalize(&context, &hash); - return hash; - } - - private: - MD5HashGen hashGen; - MD5Context context; - }; -} diff --git a/source/core/slang-digest-util.cpp b/source/core/slang-digest-util.cpp deleted file mode 100644 index 8252dce65..000000000 --- a/source/core/slang-digest-util.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// string-digest-util.cpp -#include "slang-digest-util.h" - -#include "../core/slang-basic.h" -#include "../core/slang-digest-builder.h" -#include "../core/slang-md5.h" -#include "../core/slang-char-util.h" - -namespace Slang -{ - -/*static*/ Digest DigestUtil::computeDigestForStringSlice(UnownedStringSlice text) -{ - DigestBuilder builder; - builder.append(text); - return builder.finalize(); -} - -/*static*/ Digest DigestUtil::combine(const Digest& digestA, const Digest& digestB) -{ - DigestBuilder builder; - builder.append(digestA); - builder.append(digestB); - return builder.finalize(); -} - -/*static*/ String DigestUtil::toString(const Digest& digest) -{ - StringBuilder hashString; - - uint8_t* uint8Hash = (uint8_t*)digest.values; - - for (Index i = 0; i < 16; ++i) - { - auto hashSegmentString = String(uint8Hash[i], 16); - - if (hashSegmentString.getLength() == 1) - { - hashString.append("0"); - } - hashString.append(hashSegmentString.getBuffer()); - } - - return hashString; -} - -/*static*/ Digest DigestUtil::fromString(UnownedStringSlice hashString) -{ - uint8_t uint8Hash[16]; - - // When the hash is converted to a String, ReverseInternalAscii is called - // at the very end. Since there is no way to get a char* for hashString to pass - // to ReverseInternalAscii to flip the string back, we instead loop starting from - // the end and work backwards towards the beginning. - for (Index i = 0; i < 16; i++) - { - uint8Hash[i] = (uint8_t)CharUtil::getHexDigitValue(hashString[i * 2]) * 16 - + (uint8_t)CharUtil::getHexDigitValue(hashString[i * 2 + 1]); - } - - Digest digest; - memcpy(digest.values, uint8Hash, 16); - return digest; -} - -} diff --git a/source/core/slang-digest-util.h b/source/core/slang-digest-util.h deleted file mode 100644 index 1e272fd5e..000000000 --- a/source/core/slang-digest-util.h +++ /dev/null @@ -1,43 +0,0 @@ -// slang-digest-utils.h - Utility functions specifically designed to be used with slang::Digest -#pragma once -#include "../../slang.h" -#include "slang-string.h" - -namespace Slang -{ - using slang::Digest; - - struct DigestUtil - { - // Compute the digest for an UnownedStringSlice - static Digest computeDigestForStringSlice(UnownedStringSlice text); - - // Combines the two provided digests. - static Digest combine(const Digest& digestA, const Digest& digestB); - - // Returns the hash stored in digest as a String. - static String toString(const Digest& digest); - - // Returns the hash represented by hashString as a Digest. - static Digest fromString(UnownedStringSlice hashString); - }; - - inline StringBuilder& operator<<(StringBuilder& sb, const Digest& d) - { - // Must cast to uint8_t* first in order to correctly account for - // endianness. - uint8_t* uint8Hash = (uint8_t*)d.values; - - for (Index i = 0; i < 16; ++i) - { - int hashSegment = uint8Hash[i]; - // Check if we need to append a leading zero. - if (hashSegment < 16) - { - sb << "0"; - } - sb.append(hashSegment, 16); - } - return sb; - } -} diff --git a/source/core/slang-md5.cpp b/source/core/slang-md5.cpp deleted file mode 100644 index 049ebae95..000000000 --- a/source/core/slang-md5.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#ifndef HAVE_OPENSSL - -#include <string.h> - -#include "slang-md5.h" - -namespace Slang -{ - /* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, just like in Colin Plumb's - * implementation. - */ - #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) - #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) - #define H(x, y, z) (((x) ^ (y)) ^ (z)) - #define H2(x, y, z) ((x) ^ ((y) ^ (z))) - #define I(x, y, z) ((y) ^ ((x) | ~(z))) - - /* - * The MD5 transformation for all four rounds. - */ - #define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - - /* - * SET reads 4 input bytes in little-endian byte order and stores them in a - * properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned memory - * accesses is just an optimization. Nothing will break if it fails to detect - * a suitable architecture. - * - * Unfortunately, this optimization may be a C strict aliasing rules violation - * if the caller's data buffer has effective type that cannot be aliased by - * MD5_u32plus. In practice, this problem may occur if these MD5 routines are - * inlined into a calling function, or with future and dangerously advanced - * link-time optimizations. For the time being, keeping these MD5 routines in - * their own translation unit avoids the problem. - */ - #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) - #define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) - #define GET(n) \ - SET(n) - #else - #define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) - #define GET(n) \ - (ctx->block[(n)]) - #endif - - /* - * This processes one or more 64-byte data blocks, but does NOT update the bit - * counters. There are no alignment requirements. - */ - /*static*/const void* MD5HashGen::body(MD5Context* ctx, const void* data, SlangInt size) - { - const unsigned char* ptr; - MD5_u32plus a, b, c, d; - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (const unsigned char*)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - - /* Round 1 */ - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - - /* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - - /* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) - - /* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while (size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; - } - - void MD5HashGen::init(MD5Context* ctx) - { - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; - } - - void MD5HashGen::update(MD5Context* ctx, const void* data, SlangInt size) - { - MD5_u32plus saved_lo; - SlangInt used, available; - - saved_lo = ctx->lo; - if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += (MD5_u32plus)size >> 29; - - used = saved_lo & 0x3f; - - if (used) { - available = 64 - used; - - if (size < available) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, available); - data = (const unsigned char*)data + available; - size -= available; - body(ctx, ctx->buffer, 64); - } - - if (size >= 64) { - data = body(ctx, data, size & ~(SlangInt)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); - } - - #define OUTUINT(dst, src) \ - (dst)[0] = (uint32_t)src; \ - - #define OUTCHAR(dst, src) \ - (dst)[0] = (unsigned char)(src); \ - (dst)[1] = (unsigned char)((src) >> 8); \ - (dst)[2] = (unsigned char)((src) >> 16); \ - (dst)[3] = (unsigned char)((src) >> 24); - - void MD5HashGen::finalize(MD5Context* ctx, slang::Digest* result) - { - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if (available < 8) { - memset(&ctx->buffer[used], 0, available); - body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - OUTCHAR(&ctx->buffer[56], ctx->lo) - OUTCHAR(&ctx->buffer[60], ctx->hi) - - body(ctx, ctx->buffer, 64); - - OUTUINT(&result->values[0], ctx->a) - OUTUINT(&result->values[1], ctx->b) - OUTUINT(&result->values[2], ctx->c) - OUTUINT(&result->values[3], ctx->d) - - memset(ctx, 0, sizeof(*ctx)); - } -} - -#endif diff --git a/source/core/slang-md5.h b/source/core/slang-md5.h deleted file mode 100644 index d40102b69..000000000 --- a/source/core/slang-md5.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * See md5.c for more information. - */ - -#ifdef HAVE_OPENSSL -#include <openssl/md5.h> -#elif !defined(_MD5_H) -#define _MD5_H - -#pragma once -#include "../../slang.h" -#include "../core/slang-string.h" -#include "../core/slang-list.h" - -namespace Slang -{ - /* Any 32-bit or wider unsigned integer data type will do */ - typedef uint32_t MD5_u32plus; - - struct MD5Context - { - MD5_u32plus lo, hi; - MD5_u32plus a, b, c, d; - unsigned char buffer[64]; - MD5_u32plus block[16]; - }; - - class MD5HashGen - { - public: - void init(MD5Context* ctx); - - void update(MD5Context* ctx, const void* data, SlangInt size); - - void finalize(MD5Context* ctx, slang::Digest* result); - - private: - static const void* body(MD5Context* ctx, const void* data, SlangInt size); - }; -} - -#endif diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index a5e2003c2..ce0ae4085 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -224,7 +224,7 @@ namespace Slang } void EntryPoint::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { // CompositeComponentType will have already hashed the relevant entry point's name @@ -302,7 +302,7 @@ namespace Slang } void TypeConformance::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { SLANG_UNUSED(entryPointIndex); diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 07e611355..692fefbe2 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -3,7 +3,7 @@ #include "../core/slang-basic.h" #include "../core/slang-shared-library.h" -#include "../core/slang-digest-builder.h" +#include "../core/slang-crypto.h" #include "../compiler-core/slang-downstream-compiler.h" #include "../compiler-core/slang-downstream-compiler-util.h" @@ -297,8 +297,8 @@ namespace Slang SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - slang::Digest* outHash) SLANG_OVERRIDE; - SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::Digest* outHash) SLANG_OVERRIDE; + slang::IBlob** outHash) SLANG_OVERRIDE; + SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE; /// Get the linkage (aka "session" in the public API) for this component type. Linkage* getLinkage() { return m_linkage; } @@ -310,13 +310,13 @@ namespace Slang /// Update the hash builder with the dependencies for this component type. virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) = 0; /// Update the hash builder with the source contents for this component type. /// Module should be the only derived ComponentType class which has a meaningful /// implementation; all others should do nothing. - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) = 0; + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) = 0; /// Get the number of entry points linked into this component type. virtual Index getEntryPointCount() = 0; @@ -516,10 +516,10 @@ namespace Slang List<RefPtr<ComponentType>> const& childComponents); virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override; + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override; List<RefPtr<ComponentType>> const& getChildComponents() { return m_childComponents; }; Index getChildComponentCount() { return m_childComponents.getCount(); } @@ -598,10 +598,10 @@ namespace Slang DiagnosticSink* sink); virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override { SLANG_UNUSED(hashBuilder); } @@ -791,10 +791,10 @@ namespace Slang SLANG_OVERRIDE; virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override { SLANG_UNUSED(hashBuilder); } @@ -894,21 +894,21 @@ namespace Slang SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - slang::Digest* outHash) SLANG_OVERRIDE + slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash); } - SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::Digest* outHash) SLANG_OVERRIDE + SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeContentsBasedHash(outHash); } virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override { SLANG_UNUSED(hashBuilder); } @@ -1121,21 +1121,21 @@ namespace Slang SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - slang::Digest* outHash) SLANG_OVERRIDE + slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash); } - SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::Digest* outHash) SLANG_OVERRIDE + SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeContentsBasedHash(outHash); } virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override { SLANG_UNUSED(hashBuilder); } @@ -1317,21 +1317,21 @@ namespace Slang SLANG_NO_THROW void SLANG_MCALL computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - slang::Digest* outHash) SLANG_OVERRIDE + slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeDependencyBasedHash(entryPointIndex, targetIndex, outHash); } - SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::Digest* outHash) SLANG_OVERRIDE + SLANG_NO_THROW void SLANG_MCALL computeContentsBasedHash(slang::IBlob** outHash) SLANG_OVERRIDE { return Super::computeContentsBasedHash(outHash); } virtual void updateDependencyBasedHash( - DigestBuilder& hashBuilder, + DigestBuilder<MD5>& hashBuilder, SlangInt entryPointIndex) override; - virtual void updateContentsBasedHash(DigestBuilder& hashBuilder) override; + virtual void updateContentsBasedHash(DigestBuilder<MD5>& hashBuilder) override; /// Create a module (initially empty). Module(Linkage* linkage, ASTBuilder* astBuilder = nullptr); @@ -1475,8 +1475,8 @@ namespace Slang StringSlicePool m_mangledExportPool; List<NodeBase*> m_mangledExportSymbols; - slang::Digest lastModifiedDigest; - slang::Digest contentsDigest; + MD5::Digest lastModifiedDigest; + MD5::Digest contentsDigest; }; typedef Module LoadedModule; @@ -1772,7 +1772,7 @@ namespace Slang // defines, the compiler version, and other compiler options. This is then merged with the hash // produced for the program to produce a key that can be used with the shader cache. void updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt targetIndex); void addTarget( diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index f16f1b186..3b2175fad 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -44,9 +44,6 @@ #include "slang-check-impl.h" -#include "../core/slang-md5.h" -#include "../core/slang-digest-util.h" - #include "../../slang-tag-version.h" #include <sys/stat.h> @@ -1324,7 +1321,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createCompileRequest( } void Linkage::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt targetIndex) { // Add the Slang compiler version to the hash @@ -1693,9 +1690,8 @@ void TranslationUnitRequest::_addSourceFile(SourceFile* sourceFile) // fake path in the list of file path dependencies. This is needed to account // for non-file-based dependencies later when shader files are being hashed for // the shader cache. - - slang::Digest sourceHash = DigestUtil::computeDigestForStringSlice(sourceFile->getContent()); - getModule()->addFilePathDependency(DigestUtil::toString(sourceHash)); + auto sourceHash = MD5::compute(sourceFile->getContent().begin(), sourceFile->getContent().getLength()); + getModule()->addFilePathDependency(sourceHash.toString()); } } @@ -3252,7 +3248,7 @@ ISlangUnknown* Module::getInterface(const Guid& guid) } void Module::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { // CompositeComponentType will have already hashed this Module's file @@ -3261,11 +3257,11 @@ void Module::updateDependencyBasedHash( SLANG_UNUSED(entryPointIndex); } -void Module::updateContentsBasedHash(DigestBuilder& builder) +void Module::updateContentsBasedHash(DigestBuilder<MD5>& builder) { auto filePathDependencies = getFilePathDependencies(); - DigestBuilder lastModifiedBuilder; + DigestBuilder<MD5> lastModifiedBuilder; auto statFailed = false; for (auto file : filePathDependencies) { @@ -3279,12 +3275,12 @@ void Module::updateContentsBasedHash(DigestBuilder& builder) lastModifiedBuilder.append(fileStatus.st_mtime); } - slang::Digest temp = lastModifiedBuilder.finalize(); + MD5::Digest temp = lastModifiedBuilder.finalize(); if (statFailed || temp != lastModifiedDigest) { // Either a stat() call failed, or changes were made to at least one of the file dependencies, // so we will need to re-generate the contents digest and save the new digest. - DigestBuilder contentsBuilder; + DigestBuilder<MD5> contentsBuilder; for (auto file : filePathDependencies) { List<uint8_t> fileContents; @@ -3292,7 +3288,7 @@ void Module::updateContentsBasedHash(DigestBuilder& builder) { // Failure to read the file means this is a digest for the contents of a source // file which does not live on disk. - contentsBuilder.append(DigestUtil::fromString(file.getUnownedSlice())); + contentsBuilder.append(file); } else { @@ -3512,9 +3508,9 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode( SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash( SlangInt entryPointIndex, SlangInt targetIndex, - slang::Digest* outHash) + slang::IBlob** outHash) { - DigestBuilder builder; + DigestBuilder<MD5> builder; // A note on enums that may be hashed in as part of the following two function calls: // @@ -3542,14 +3538,16 @@ SLANG_NO_THROW void SLANG_MCALL ComponentType::computeDependencyBasedHash( auto entryPointNameOverride = getEntryPointNameOverride(entryPointIndex); builder.append(entryPointNameOverride); - *outHash = builder.finalize(); + auto hash = builder.finalize().toBlob(); + *outHash = hash.detach(); } -SLANG_NO_THROW void SLANG_MCALL ComponentType::computeContentsBasedHash(slang::Digest* outHash) +SLANG_NO_THROW void SLANG_MCALL ComponentType::computeContentsBasedHash(slang::IBlob** outHash) { - DigestBuilder builder; + DigestBuilder<MD5> builder; updateContentsBasedHash(builder); - *outHash = builder.finalize(); + auto hash = builder.finalize().toBlob(); + *outHash = hash.detach(); } SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable( @@ -3885,7 +3883,7 @@ CompositeComponentType::CompositeComponentType( } void CompositeComponentType::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { auto componentCount = getChildComponentCount(); @@ -3896,7 +3894,7 @@ void CompositeComponentType::updateDependencyBasedHash( } } -void CompositeComponentType::updateContentsBasedHash(DigestBuilder& builder) +void CompositeComponentType::updateContentsBasedHash(DigestBuilder<MD5>& builder) { auto componentCount = getChildComponentCount(); @@ -4386,7 +4384,7 @@ SpecializedComponentType::SpecializedComponentType( } void SpecializedComponentType::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { auto specializationArgCount = getSpecializationArgCount(); @@ -4397,7 +4395,6 @@ void SpecializedComponentType::updateDependencyBasedHash( builder.append(argString); } - slang::Digest baseHash; getBaseComponentType()->updateDependencyBasedHash(builder, entryPointIndex); } @@ -4446,7 +4443,7 @@ void RenamedEntryPointComponentType::acceptVisitor( } void RenamedEntryPointComponentType::updateDependencyBasedHash( - DigestBuilder& builder, + DigestBuilder<MD5>& builder, SlangInt entryPointIndex) { // CompositeComponentType will have already hashed the name override and file diff --git a/tools/gfx-unit-test/shader-cache-tests.cpp b/tools/gfx-unit-test/shader-cache-tests.cpp index c1d058d70..486b59cda 100644 --- a/tools/gfx-unit-test/shader-cache-tests.cpp +++ b/tools/gfx-unit-test/shader-cache-tests.cpp @@ -5,7 +5,6 @@ #include "tools/gfx-util/shader-cursor.h" #include "source/core/slang-basic.h" #include "source/core/slang-string-util.h" -#include "source/core/slang-digest-util.h" #include "source/core/slang-memory-file-system.h" #include "source/core/slang-file-system.h" diff --git a/tools/gfx/persistent-shader-cache.cpp b/tools/gfx/persistent-shader-cache.cpp index 54c46f9dc..7dc64632b 100644 --- a/tools/gfx/persistent-shader-cache.cpp +++ b/tools/gfx/persistent-shader-cache.cpp @@ -1,7 +1,6 @@ // slang-shader-cache-index.cpp #include "persistent-shader-cache.h" -#include "../../source/core/slang-digest-util.h" #include "../../source/core/slang-io.h" #include "../../source/core/slang-string-util.h" #include "../../source/core/slang-file-system.h" @@ -128,7 +127,7 @@ void PersistentShaderCache::loadCacheFromFile() } } -ShaderCacheEntry* PersistentShaderCache::findEntry(const slang::Digest& key, ISlangBlob** outCompiledCode) +ShaderCacheEntry* PersistentShaderCache::findEntry(const DigestType& key, ISlangBlob** outCompiledCode) { LinkedNode<Index>* entryIndexNode; if (!keyToEntry.TryGetValue(key, entryIndexNode)) @@ -140,7 +139,7 @@ ShaderCacheEntry* PersistentShaderCache::findEntry(const slang::Digest& key, ISl // If the key is found, load the stored contents from disk. We then move the corresponding // entry to the front of the linked list and update the cache file on disk - desc.shaderCacheFileSystem->loadFile(DigestUtil::toString(key).getBuffer(), outCompiledCode); + desc.shaderCacheFileSystem->loadFile(key.toString().getBuffer(), outCompiledCode); auto index = entryIndexNode->Value; entries[index].lastAccessedTime = (double)high_resolution_clock::now().time_since_epoch().count(); if (orderedEntries.FirstNode() != entryIndexNode) @@ -150,7 +149,7 @@ ShaderCacheEntry* PersistentShaderCache::findEntry(const slang::Digest& key, ISl if (mutableShaderCacheFileSystem && !isMemoryFileSystem) { auto offset = index * sizeof(ShaderCacheEntry); - indexStream.seek(SeekOrigin::Start, offset + 2 * sizeof(slang::Digest)); + indexStream.seek(SeekOrigin::Start, offset + 2 * sizeof(DigestType)); indexStream.write(&entries[index].lastAccessedTime, sizeof(double)); indexStream.flush(); } @@ -158,7 +157,7 @@ ShaderCacheEntry* PersistentShaderCache::findEntry(const slang::Digest& key, ISl return &entries[index]; } -void PersistentShaderCache::addEntry(const slang::Digest& dependencyDigest, const slang::Digest& contentsDigest, ISlangBlob* compiledCode) +void PersistentShaderCache::addEntry(const DigestType& dependencyDigest, const DigestType& contentsDigest, ISlangBlob* compiledCode) { if (!mutableShaderCacheFileSystem) { @@ -197,7 +196,7 @@ void PersistentShaderCache::addEntry(const slang::Digest& dependencyDigest, cons } keyToEntry.Add(dependencyDigest, entryNode); - mutableShaderCacheFileSystem->saveFileBlob(DigestUtil::toString(dependencyDigest).getBuffer(), compiledCode); + mutableShaderCacheFileSystem->saveFileBlob(dependencyDigest.toString().getBuffer(), compiledCode); if (!isMemoryFileSystem) { @@ -208,8 +207,8 @@ void PersistentShaderCache::addEntry(const slang::Digest& dependencyDigest, cons } void PersistentShaderCache::updateEntry( - const slang::Digest& dependencyDigest, - const slang::Digest& contentsDigest, + const DigestType& dependencyDigest, + const DigestType& contentsDigest, ISlangBlob* updatedCode) { if (!mutableShaderCacheFileSystem) @@ -224,13 +223,13 @@ void PersistentShaderCache::updateEntry( auto entryIndexNode = *keyToEntry.TryGetValue(dependencyDigest); auto index = entryIndexNode->Value; entries[index].contentsBasedDigest = contentsDigest; - mutableShaderCacheFileSystem->saveFileBlob(DigestUtil::toString(dependencyDigest).getBuffer(), updatedCode); + mutableShaderCacheFileSystem->saveFileBlob(dependencyDigest.toString().getBuffer(), updatedCode); if (!isMemoryFileSystem) { auto offset = index * sizeof(ShaderCacheEntry); - indexStream.seek(SeekOrigin::Start, offset + sizeof(slang::Digest)); - indexStream.write(&contentsDigest, sizeof(slang::Digest)); + indexStream.seek(SeekOrigin::Start, offset + sizeof(DigestType)); + indexStream.write(&contentsDigest, sizeof(DigestType)); indexStream.flush(); } } @@ -250,7 +249,7 @@ Index PersistentShaderCache::deleteLRUEntry() auto shaderKey = entries[index].dependencyBasedDigest; keyToEntry.Remove(shaderKey); - mutableShaderCacheFileSystem->remove(DigestUtil::toString(shaderKey).getBuffer()); + mutableShaderCacheFileSystem->remove(shaderKey.toString().getBuffer()); orderedEntries.Delete(lruEntry); return index; @@ -286,8 +285,8 @@ void PersistentShaderCache::loadCacheFromMemory() continue; ShaderCacheEntry entry; - entry.dependencyBasedDigest = DigestUtil::fromString(entryFields[0]); - entry.contentsBasedDigest = DigestUtil::fromString(entryFields[1]); + entry.dependencyBasedDigest = DigestType(entryFields[0]); + entry.contentsBasedDigest = DigestType(entryFields[1]); entry.lastAccessedTime = 0; auto entryNode = orderedEntries.AddLast(entries.getCount()); @@ -305,9 +304,9 @@ void PersistentShaderCache::saveCacheToMemory() for (auto& entryIndex : orderedEntries) { auto entry = entries[entryIndex]; - indexSb << entry.dependencyBasedDigest; + indexSb << entry.dependencyBasedDigest.toString(); indexSb << " "; - indexSb << entry.contentsBasedDigest; + indexSb << entry.contentsBasedDigest.toString(); indexSb << "\n"; } diff --git a/tools/gfx/persistent-shader-cache.h b/tools/gfx/persistent-shader-cache.h index 8e05eddf6..530d50a58 100644 --- a/tools/gfx/persistent-shader-cache.h +++ b/tools/gfx/persistent-shader-cache.h @@ -8,16 +8,19 @@ #include "../../source/core/slang-dictionary.h" #include "../../source/core/slang-linked-list.h" #include "../../source/core/slang-stream.h" +#include "../../source/core/slang-crypto.h" namespace gfx { using namespace Slang; +using DigestType = MD5::Digest; + struct ShaderCacheEntry { - slang::Digest dependencyBasedDigest; - slang::Digest contentsBasedDigest; + DigestType dependencyBasedDigest; + DigestType contentsBasedDigest; double lastAccessedTime; bool operator==(const ShaderCacheEntry& rhs) @@ -42,16 +45,16 @@ public: // Fetch the cache entry corresponding to the provided key. If found, move the entry to // the front of entries and return the entry and the corresponding compiled code in // outCompiledCode. Else, return nullptr. - ShaderCacheEntry* findEntry(const slang::Digest& key, ISlangBlob** outCompiledCode); + ShaderCacheEntry* findEntry(const DigestType& key, ISlangBlob** outCompiledCode); // Add an entry to the cache with the provided key and contents hashes. If // adding an entry causes the cache to exceed size limitations, this will also // delete the least recently used entry. - void addEntry(const slang::Digest& dependencyDigest, const slang::Digest& contentsDigest, ISlangBlob* compiledCode); + void addEntry(const DigestType& dependencyDigest, const DigestType& contentsDigest, ISlangBlob* compiledCode); // Update the contents hash for the specified entry in the cache and update the // corresponding file on disk. - void updateEntry(const slang::Digest& dependencyDigest, const slang::Digest& contentsDigest, ISlangBlob* updatedCode); + void updateEntry(const DigestType& dependencyDigest, const DigestType& contentsDigest, ISlangBlob* updatedCode); private: // Load a previous cache index saved to disk. If not found, create a new cache index @@ -82,7 +85,7 @@ private: // Dictionary mapping each shader's key to its corresponding node (entry) in the // linked list 'orderedEntries'. - Dictionary<slang::Digest, LinkedNode<Index>*> keyToEntry; + Dictionary<DigestType, LinkedNode<Index>*> keyToEntry; // Linked list containing the corresponding indices in 'entries' for entries in the // shader cache ordered from most to least recently used. diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 3dcdb324c..3397b325e 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -6,7 +6,6 @@ #include "../../source/core/slang-file-system.h" #include "../../slang.h" -#include "../../source/core/slang-digest-util.h" using namespace Slang; @@ -349,13 +348,15 @@ Result RendererBase::getEntryPointCodeFromShaderCache( ComPtr<slang::ISession> session; getSlangSession(session.writeRef()); - slang::Digest shaderKey; - program->computeDependencyBasedHash(entryPointIndex, targetIndex, &shaderKey); + ComPtr<ISlangBlob> shaderKeyBlob; + program->computeDependencyBasedHash(entryPointIndex, targetIndex, shaderKeyBlob.writeRef()); + DigestType shaderKey(shaderKeyBlob); // Produce a hash using the AST for this program - This is needed to check whether a cache entry is effectively dirty, // or to save along with the compiled code into an entry so the entry can be checked if fetched later on. - slang::Digest contentsHash; - program->computeContentsBasedHash(&contentsHash); + ComPtr<ISlangBlob> contentsHashBlob; + program->computeContentsBasedHash(contentsHashBlob.writeRef()); + DigestType contentsHash(contentsHashBlob); ComPtr<ISlangBlob> codeBlob; diff --git a/tools/slang-unit-test/unit-test-crypto.cpp b/tools/slang-unit-test/unit-test-crypto.cpp new file mode 100644 index 000000000..adb7b2218 --- /dev/null +++ b/tools/slang-unit-test/unit-test-crypto.cpp @@ -0,0 +1,173 @@ +// unit-test-sha1.cpp +#include "tools/unit-test/slang-unit-test.h" + +#include "../../source/core/slang-crypto.h" + +using namespace Slang; + +SLANG_UNIT_TEST(crypto) +{ + // HashDigest + { + using Digest = HashDigest<8>; + Digest empty; + SLANG_CHECK(empty.data[0] == 0 && empty.data[1] == 0); + SLANG_CHECK(empty.toString() == "0000000000000000"); + + Digest all = Digest("ffffffffffffffff"); + SLANG_CHECK(all.data[0] == 0xffffffff && all.data[1] == 0xffffffff); + SLANG_CHECK(all.toString() == "ffffffffffffffff"); + + SLANG_CHECK(empty == Digest("0000000000000000")); + SLANG_CHECK(all == Digest("ffffffffffffffff")); + SLANG_CHECK(empty != all); + + SLANG_CHECK(Digest("invalid") == empty); + SLANG_CHECK(Digest("X000000000000000") == empty); + SLANG_CHECK(Digest(" 000000000000000") == empty); + + SLANG_CHECK(Digest("0123456789abcdef").toString() == "0123456789abcdef"); + + Slang::ComPtr<ISlangBlob> blob = Digest("0123456789abcdef").toBlob(); + const uint8_t check[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; + SLANG_CHECK(blob->getBufferSize() == 8); + SLANG_CHECK(::memcmp(blob->getBufferPointer(), check, 8) == 0); + + SLANG_CHECK(Digest(blob) == Digest("0123456789abcdef")); + } + + // MD5 + + // Empty string + { + MD5 sha1; + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "d41d8cd98f00b204e9800998ecf8427e"); + } + + // One call to update() + { + MD5 sha1; + const String str("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + sha1.update(str.getBuffer(), str.getLength()); + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "818c6e601a24f72750da0f6c9b8ebe28"); + } + + // Two calls to update() + { + MD5 sha1; + const String str1("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + const String str2("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + sha1.update(str1.getBuffer(), str1.getLength()); + sha1.update(str2.getBuffer(), str2.getLength()); + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "87d3caecb0ab82faae84d60fde994aca"); + } + + // compute() + { + SLANG_CHECK(MD5::compute(nullptr, 0).toString() == "d41d8cd98f00b204e9800998ecf8427e"); + const String str("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + SLANG_CHECK(MD5::compute(str.getBuffer(), str.getLength()).toString() == "818c6e601a24f72750da0f6c9b8ebe28"); + } + + // SHA1 + + // Empty string + { + SHA1 sha1; + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); + } + + // One call to update() + { + SHA1 sha1; + const String str("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + sha1.update(str.getBuffer(), str.getLength()); + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "cca0871ecbe200379f0a1e4b46de177e2d62e655"); + } + + // Two calls to update() + { + SHA1 sha1; + const String str1("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + const String str2("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + sha1.update(str1.getBuffer(), str1.getLength()); + sha1.update(str2.getBuffer(), str2.getLength()); + auto digest = sha1.finalize(); + SLANG_CHECK(digest.toString() == "7a8213edf9976d2e693f27bbc7dc41546bcfcc97"); + } + + // compute() + { + SLANG_CHECK(SHA1::compute(nullptr, 0).toString() == "da39a3ee5e6b4b0d3255bfef95601890afd80709"); + const String str("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + SLANG_CHECK(SHA1::compute(str.getBuffer(), str.getLength()).toString() == "cca0871ecbe200379f0a1e4b46de177e2d62e655"); + } + + // DigestBuider + + // Raw numerical values, etc. + { + DigestBuilder<MD5> builder; + + int64_t valueA = -1; + uint64_t valueB = 1; + builder.append(valueA); + builder.append(valueB); + + auto digest = builder.finalize(); + SLANG_CHECK(digest.toString() == "5ba171e20898bdd205639013746f2679"); + } + + // List + { + DigestBuilder<MD5> builder; + + List<int64_t> listA; + listA.add(1); + listA.add(2); + listA.add(3); + listA.add(4); + builder.append(listA); + + auto digest = builder.finalize(); + SLANG_CHECK(digest.toString() == "9f66c130786a1a05e4731f71a3c5f172"); + } + + // UnownedStringSlice + { + DigestBuilder<MD5> builder; + + UnownedStringSlice stringSlice = UnownedStringSlice("String Slice Test"); + builder.append(stringSlice); + + auto digest = builder.finalize(); + SLANG_CHECK(digest.toString() == "5d6cc58e1824a4dfd0cf57395b603316"); + } + + // String + { + DigestBuilder<MD5> builder; + + String str = String("String Test"); + builder.append(str); + + auto digest = builder.finalize(); + SLANG_CHECK(digest.toString() == "df5a79cc2170c7401cf0a506ceb0ce24"); + } + + // Digest + { + DigestBuilder<MD5> builder; + + MD5::Digest hash; + builder.append(hash); + + auto digest = builder.finalize(); + SLANG_CHECK(digest.toString() == "4ae71336e44bf9bf79d2752e234818a5"); + } +} diff --git a/tools/slang-unit-test/unit-test-digest-builder.cpp b/tools/slang-unit-test/unit-test-digest-builder.cpp deleted file mode 100644 index b89b31a7b..000000000 --- a/tools/slang-unit-test/unit-test-digest-builder.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// unit-test-digest-utils.cpp - -#include "tools/unit-test/slang-unit-test.h" - -#include "../../source/core/slang-digest-builder.h" -#include "../../source/core/slang-digest-util.h" - -using namespace Slang; - -SLANG_UNIT_TEST(digestBuilder) -{ - // Raw numerical values, etc. - { - DigestBuilder builder; - - int64_t valueA = -1; - uint64_t valueB = 1; - builder.append(valueA); - builder.append(valueB); - - slang::Digest digest = builder.finalize(); - SLANG_CHECK(DigestUtil::toString(digest) == "5BA171E20898BDD205639013746F2679"); - } - - // List - { - DigestBuilder builder; - - List<int64_t> listA; - listA.add(1); - listA.add(2); - listA.add(3); - listA.add(4); - builder.append(listA); - - slang::Digest digest = builder.finalize(); - SLANG_CHECK(DigestUtil::toString(digest) == "9F66C130786A1A05E4731F71A3C5F172"); - } - - // UnownedStringSlice - { - DigestBuilder builder; - - UnownedStringSlice stringSlice = UnownedStringSlice("String Slice Test"); - builder.append(stringSlice); - - slang::Digest digest = builder.finalize(); - SLANG_CHECK(DigestUtil::toString(digest) == "5D6CC58E1824A4DFD0CF57395B603316"); - } - - // String - { - DigestBuilder builder; - - String str = String("String Test"); - builder.append(str); - - slang::Digest digest = builder.finalize(); - SLANG_CHECK(DigestUtil::toString(digest) == "DF5A79CC2170C7401CF0A506CEB0CE24"); - } - - // Digest - { - DigestBuilder builder; - - slang::Digest hash; - builder.append(hash); - - slang::Digest digest = builder.finalize(); - SLANG_CHECK(DigestUtil::toString(digest) == "4AE71336E44BF9BF79D2752E234818A5"); - } -} diff --git a/tools/slang-unit-test/unit-test-digest-utils.cpp b/tools/slang-unit-test/unit-test-digest-utils.cpp deleted file mode 100644 index a463fe07f..000000000 --- a/tools/slang-unit-test/unit-test-digest-utils.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// unit-test-digest-utils.cpp - -#include "tools/unit-test/slang-unit-test.h" - -#include "../../source/core/slang-digest-util.h" - -using namespace Slang; - -SLANG_UNIT_TEST(digestUtils) -{ - { - slang::Digest testA; - testA.values[0] = 1; - testA.values[1] = 2; - testA.values[2] = 3; - testA.values[3] = 4; - - String testAString = DigestUtil::toString(testA); - SLANG_CHECK(testAString.equals(String("01000000020000000300000004000000"))); - } - - { - slang::Digest testC; - testC.values[0] = 0x11111111; - testC.values[1] = 0x22222222; - testC.values[2] = 0x33333333; - testC.values[3] = 0x44444444; - - String testCString = DigestUtil::toString(testC); - SLANG_CHECK(testCString.equals(String("11111111222222223333333344444444"))); - } - - { - auto digestString = UnownedStringSlice("5D6CC58E1824A4DFD0CF57395B603316"); - slang::Digest digest = DigestUtil::fromString(digestString); - auto resultString = DigestUtil::toString(digest); - SLANG_CHECK(resultString == digestString); - } - - { - auto digestString = UnownedStringSlice("01000000020000000300000004000000"); - slang::Digest digest = DigestUtil::fromString(digestString); - auto resultString = DigestUtil::toString(digest); - SLANG_CHECK(resultString == digestString); - } - - { - slang::Digest testD; - testD.values[0] = 1; - testD.values[1] = 2; - testD.values[2] = 3; - testD.values[3] = 4; - - StringBuilder testDSb; - testDSb << testD; - SLANG_CHECK(testDSb.equals(String("01000000020000000300000004000000"))); - } -} diff --git a/tools/slang-unit-test/unit-test-md5.cpp b/tools/slang-unit-test/unit-test-md5.cpp deleted file mode 100644 index 1297d4f17..000000000 --- a/tools/slang-unit-test/unit-test-md5.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// unit-test-md5.cpp -#include "tools/unit-test/slang-unit-test.h" - -#include "../../source/core/slang-md5.h" -#include "../../source/core/slang-string.h" -#include "../../source/core/slang-digest-util.h" - -using namespace Slang; - -SLANG_UNIT_TEST(md5hash) -{ - // Empty string - { - MD5Context ctx; - MD5HashGen gen; - gen.init(&ctx); - slang::Digest digest; - gen.finalize(&ctx, &digest); - SLANG_CHECK(DigestUtil::toString(digest) == "D41D8CD98F00B204E9800998ECF8427E"); - } - - // One call to update() - { - MD5Context ctx; - MD5HashGen gen; - gen.init(&ctx); - const String str("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); - gen.update(&ctx, str.getBuffer(), str.getLength()); - slang::Digest digest; - gen.finalize(&ctx, &digest); - SLANG_CHECK(DigestUtil::toString(digest) == "818C6E601A24F72750DA0F6C9B8EBE28"); - } - - // Two calls to update() - { - MD5Context ctx; - MD5HashGen gen; - gen.init(&ctx); - const String str1("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); - const String str2("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); - gen.update(&ctx, str1.getBuffer(), str1.getLength()); - gen.update(&ctx, str2.getBuffer(), str2.getLength()); - slang::Digest digest; - gen.finalize(&ctx, &digest); - SLANG_CHECK(DigestUtil::toString(digest) == "87D3CAECB0AB82FAAE84D60FDE994ACA"); - } -} |
