Overhaul of DN
This commit is contained in:
+2688
-3825
File diff suppressed because it is too large
Load Diff
+725
-254
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,33 +0,0 @@
|
||||
#if DN_WITH_NET_CURL
|
||||
#define DN_NO_WINDOWS_H_REPLACEMENT_HEADER
|
||||
#endif
|
||||
|
||||
#define DN_ARENA_TEMP_MEM_UAF_GUARD 1
|
||||
#define DN_ARENA_TEMP_MEM_UAF_TRACE_ON_BY_DEFAULT 0
|
||||
#define DN_WITH_OS 1
|
||||
#define DN_WITH_NET 1
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
#define DN_WITH_NET_EMSCRIPTEN 1
|
||||
#endif
|
||||
#include "../dn.h"
|
||||
|
||||
#if DN_WITH_NET_CURL
|
||||
#define CURL_STATICLIB
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
#include "../dn.cpp"
|
||||
|
||||
#define DN_UT_IMPLEMENTATION
|
||||
#include "../Standalone/dn_utest.h"
|
||||
#include "../Extra/dn_tests.cpp"
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
|
||||
int main(int, char**)
|
||||
{
|
||||
DN_Core dn = {};
|
||||
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS, DN_TCInitArgsDefault());
|
||||
DN_TST_RunSuite(DN_TSTPrint_Yes);
|
||||
return 0;
|
||||
}
|
||||
DN_MSVC_WARNING_POP
|
||||
@@ -1281,7 +1281,7 @@ static void *DN_OS_ThreadFunc_(void *user_context)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context)
|
||||
DN_API bool DN_OS_ThreadInitLane(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_OSThreadInitArgs init_args, void *user_context)
|
||||
{
|
||||
bool result = false;
|
||||
if (!thread)
|
||||
@@ -1291,7 +1291,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
|
||||
thread->user_context = user_context;
|
||||
thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
thread->lane = *lane;
|
||||
thread->tc_init_args = tc_init_args;
|
||||
thread->tc_init_args = init_args.tc_args;
|
||||
|
||||
// TODO(doyle): Check if semaphore is valid
|
||||
// NOTE: pthread_t is essentially the thread ID. In Windows, the handle and
|
||||
@@ -1307,6 +1307,9 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
|
||||
|
||||
pthread_attr_t attribs = {};
|
||||
pthread_attr_init(&attribs);
|
||||
if (init_args.stack_size)
|
||||
pthread_attr_setstacksize(&attribs, init_args.stack_size);
|
||||
|
||||
result = pthread_create(&p_thread, &attribs, DN_OS_ThreadFunc_, thread) == 0;
|
||||
pthread_attr_destroy(&attribs);
|
||||
|
||||
@@ -1415,21 +1418,21 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus()
|
||||
DN_Memcpy(result.name, str8.data, result.name_size);
|
||||
} else if (DN_Str8StartsWith(line, PID, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, PID.count, line.count));
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(str8, 0);
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(str8);
|
||||
result.pid = to_u64.value;
|
||||
DN_Assert(to_u64.success);
|
||||
} else if (DN_Str8StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, VM_SIZE.count, line.count));
|
||||
DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB")));
|
||||
DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs;
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0);
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size);
|
||||
result.vm_size = DN_Kilobytes(to_u64.value);
|
||||
DN_Assert(to_u64.success);
|
||||
} else if (DN_Str8StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Subset(line, VM_PEAK.count, line.count));
|
||||
DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB")));
|
||||
DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs;
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0);
|
||||
DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size);
|
||||
result.vm_peak = DN_Kilobytes(to_u64.value);
|
||||
DN_Assert(to_u64.success);
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,8 +1,7 @@
|
||||
#define DN_OS_W32_CPP
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#define DN_H_WITH_CORE 1
|
||||
#define DN_H_WITH_OS 1
|
||||
#define DN_WITH_OS 1
|
||||
#include "../dn.h"
|
||||
#include "dn_os_w32.h"
|
||||
#endif
|
||||
@@ -99,13 +98,15 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
|
||||
|
||||
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Core *dn = DN_Get();
|
||||
DN_AssertRaw(dn->init_flags & DN_InitFlags_OS && "DN must be initialised with the OS flag");
|
||||
DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0;
|
||||
DN_Assert(size <= DN_Cast(DWORD)(-1));
|
||||
void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size);
|
||||
|
||||
DN_Core *dn = DN_Get();
|
||||
if (dn) {
|
||||
DN_AtomicAddU64(&dn->os.mem_allocs_total, 1);
|
||||
DN_AtomicAddU64(&dn->os.mem_allocs_frame, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -637,10 +638,10 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
if (it->handle) {
|
||||
wide_it.handle = it->handle;
|
||||
} else {
|
||||
bool needs_asterisks = DN_Str8EndsWith(path, DN_Str8Lit("\\")) ||
|
||||
DN_Str8EndsWith(path, DN_Str8Lit("/"));
|
||||
bool has_glob = DN_Str8EndsWith(path, DN_Str8Lit("\\*")) ||
|
||||
DN_Str8EndsWith(path, DN_Str8Lit("/*"));
|
||||
bool needs_asterisks = DN_Str8EndsWithSensitive(path, DN_Str8Lit("\\")) ||
|
||||
DN_Str8EndsWithSensitive(path, DN_Str8Lit("/"));
|
||||
bool has_glob = DN_Str8EndsWithSensitive(path, DN_Str8Lit("\\*")) ||
|
||||
DN_Str8EndsWithSensitive(path, DN_Str8Lit("/*"));
|
||||
|
||||
DN_Str8 adjusted_path = path;
|
||||
if (!has_glob) {
|
||||
@@ -1227,14 +1228,13 @@ DN_API void DN_OS_ConditionVariableBroadcast(DN_OSConditionVariable *cv)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_OSThread
|
||||
static DWORD __stdcall DN_OS_ThreadFunc_(void *user_context)
|
||||
{
|
||||
DN_OS_ThreadExecute_(user_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context)
|
||||
DN_API bool DN_OS_ThreadInitLane(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_OSThreadInitArgs init_args, void *user_context)
|
||||
{
|
||||
bool result = false;
|
||||
if (!thread)
|
||||
@@ -1243,7 +1243,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
|
||||
thread->func = func;
|
||||
thread->user_context = user_context;
|
||||
thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
thread->tc_init_args = tc_init_args;
|
||||
thread->tc_init_args = init_args.tc_args;
|
||||
if (lane) {
|
||||
thread->is_lane_set = true;
|
||||
thread->lane = *lane;
|
||||
@@ -1253,7 +1253,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
|
||||
DWORD thread_id = 0;
|
||||
SECURITY_ATTRIBUTES security_attribs = {};
|
||||
thread->handle = CreateThread(&security_attribs,
|
||||
0 /*stack_size*/,
|
||||
init_args.stack_size,
|
||||
DN_OS_ThreadFunc_,
|
||||
thread,
|
||||
0 /*creation_flags*/,
|
||||
@@ -1522,10 +1522,10 @@ DN_API DN_Str8 DN_OS_W32Str16ToStr8FromHeap(DN_Str16 src)
|
||||
if (required_size <= 0)
|
||||
return result;
|
||||
|
||||
// NOTE: Str8 allocate ensures there's one extra byte for
|
||||
// null-termination already so no-need to +1 the required size
|
||||
DN_Str8 buffer = DN_Str8FromHeap(required_size, DN_ZMem_No);
|
||||
if (buffer.count == 0)
|
||||
DN_Str8 buffer = {};
|
||||
buffer.data = DN_Cast(char *) DN_OS_MemAlloc(required_size + 1, DN_ZMem_No);
|
||||
buffer.count = required_size;
|
||||
if (!buffer.data)
|
||||
return result;
|
||||
|
||||
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.count, nullptr, nullptr);
|
||||
|
||||
@@ -861,7 +861,7 @@ DN_INIField *DN_INI_AppendKeyF(DN_INICore *ini, DN_INIArena *arena, DN_INISectio
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(DN_INI_WITH_UNIT_TESTS)
|
||||
#if defined(DN_INI_WITH_TESTS)
|
||||
void DN_INI_UnitTests()
|
||||
{
|
||||
// NOTE: Section and comments
|
||||
@@ -1141,4 +1141,4 @@ void DN_INI_UnitTests()
|
||||
DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->next->key, DN_INIStr8Lit("bar")));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // #if defined(DN_INI_WITH_TESTS)
|
||||
|
||||
+20
-19
@@ -2,15 +2,16 @@
|
||||
#define DN_INI_H
|
||||
|
||||
// NOTE: DN INI Configuration
|
||||
|
||||
// Getting Started
|
||||
// This is a single header and implementation file library that implements .ini file handling.
|
||||
// It supports the following .ini features:
|
||||
//
|
||||
// - Plain sections: [sections]
|
||||
// - Arbitrarily nested sections delimited by '.': [sections.a] [sections.a.b] [sections.a.b....]
|
||||
// - Repeated section names (the last section takes precedence)
|
||||
// - Comments marked by #: [section] # Comment
|
||||
// - Multi-line values for keys:
|
||||
// Plain sections: [sections]
|
||||
// Arbitrarily nested sections delimited by '.': [sections.a] [sections.a.b] [sections.a.b....]
|
||||
// Repeated section names (the last section takes precedence)
|
||||
// Comments marked by #: [section] # Comment
|
||||
// Multi-line values for keys:
|
||||
// [my_section]
|
||||
// the_key = the_value \
|
||||
// another line for the key \
|
||||
@@ -20,10 +21,10 @@
|
||||
// Include both .h and .c in your translation unit or compile the .c separately and link against
|
||||
// it to get started. The goals of the library are as follows:
|
||||
//
|
||||
// - Zero allocations to parse, accepts a NULL buffer to determine the amount of bytes required
|
||||
// Zero allocations to parse, accepts a NULL buffer to determine the amount of bytes required
|
||||
// to parse the .ini buffer
|
||||
// - Compile in C99 and compatible with C++
|
||||
//
|
||||
// Compile in C99 and compatible with C++
|
||||
|
||||
// Example
|
||||
/*
|
||||
#include <stdio.h>
|
||||
@@ -94,21 +95,21 @@
|
||||
}
|
||||
*/
|
||||
|
||||
#include <stdint.h> // size_t
|
||||
#include <stdint.h> // size_t
|
||||
|
||||
#if !defined(DN_INI_Assert)
|
||||
#if !defined(DN_INI_Assert)
|
||||
#include <assert.h>
|
||||
#define DN_INI_Assert(expr) assert(expr)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(DN_INI_VSNPrintF)
|
||||
#if !defined(DN_INI_VSNPrintF)
|
||||
#include <stdio.h>
|
||||
#define DN_INI_VSNPrintF(buffer, size, fmt, args) vsnprintf(buffer, size, fmt, args)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(DN_INI_Memset) || !defined(DN_INI_Memcmp) || !defined(DN_INI_Memcpy)
|
||||
#if !defined(DN_INI_Memset) || !defined(DN_INI_Memcmp) || !defined(DN_INI_Memcpy)
|
||||
#include <string.h>
|
||||
#if !defined(DN_INI_Memset)
|
||||
#define DN_INI_Memset(ptr, val, size) memset(ptr, val, size)
|
||||
@@ -121,7 +122,7 @@
|
||||
#if !defined(DN_INI_Memcpy)
|
||||
#define DN_INI_Memcpy(dest, src, size) memcpy(dest, src, size)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum DN_INITokenType {
|
||||
DN_INITokenType_Nil,
|
||||
@@ -278,7 +279,7 @@ DN_INIField * DN_INI_AppendKeyCStr8 (DN_INICore *ini, DN
|
||||
DN_INIField * DN_INI_AppendKeyF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...);
|
||||
void DN_INI_AppendField (DN_INISection *section, DN_INIField *field);
|
||||
|
||||
#if defined(DN_INI_WITH_UNIT_TESTS)
|
||||
void DN_INI_UnitTests ();
|
||||
#if defined(DN_INI_WITH_TESTS)
|
||||
void DN_INI_TestSuite ();
|
||||
#endif
|
||||
#endif // !defined(DN_INI_H)
|
||||
#endif // #if !defined(DN_INI_H)
|
||||
|
||||
+443
-120
@@ -2,18 +2,22 @@
|
||||
#define DN_SHA3_H
|
||||
|
||||
// NOTE: DN_Sha3 -- FIPS202 SHA3 + non-finalized SHA3 (aka. Keccak) hashing algorithms
|
||||
//
|
||||
|
||||
// Overview
|
||||
// Single header file implementation of the Keccak hashing algorithms from the Keccak and SHA3
|
||||
// families (including the FIPS202 published algorithms and the non-finalized ones, i.e. the ones
|
||||
// used in Ethereum and Monero which adopted SHA3 before it was finalized. The only difference
|
||||
// between the 2 is a different delimited suffix).
|
||||
//
|
||||
|
||||
// Configuration
|
||||
// Define this in one and only one C++ file to enable the implementation code of the header file.
|
||||
//
|
||||
// #define DN_SHA3_IMPLEMENTATION
|
||||
//
|
||||
// Define this to enable unit tests in the implementation, it requires dn.h to be visible in the
|
||||
//
|
||||
// #define DN_SHA3_WITH_TESTS
|
||||
|
||||
// License
|
||||
// MIT License
|
||||
//
|
||||
@@ -35,26 +39,26 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include <stdint.h>
|
||||
#if !defined(DN_SHA3Memcpy)
|
||||
#if !defined(DN_SHA3_Memcpy)
|
||||
#include <string.h>
|
||||
#define DN_SHA3Memcpy(dest, src, count) memcpy(dest, src, count)
|
||||
#define DN_SHA3_Memcpy(dest, src, count) memcpy(dest, src, count)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_SHA3Memcmp)
|
||||
#if !defined(DN_SHA3_Memcmp)
|
||||
#include <string.h>
|
||||
#define DN_SHA3Memcmp(dest, src, count) memcmp(dest, src, count)
|
||||
#define DN_SHA3_Memcmp(dest, src, count) memcmp(dest, src, count)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_SHA3Memset)
|
||||
#if !defined(DN_SHA3_Memset)
|
||||
#include <string.h>
|
||||
#define DN_SHA3Memset(dest, byte, count) memset(dest, byte, count)
|
||||
#define DN_SHA3_Memset(dest, byte, count) memset(dest, byte, count)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_SHA3Assert)
|
||||
#if !defined(DN_SHA3_Assert)
|
||||
#if defined(NDEBUG)
|
||||
#define DN_SHA3Assert(expr)
|
||||
#define DN_SHA3_Assert(expr)
|
||||
#else
|
||||
#define DN_SHA3Assert(expr) \
|
||||
#define DN_SHA3_Assert(expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
(*(volatile int *)0) = 0; \
|
||||
@@ -81,47 +85,52 @@ typedef struct DN_SHA3State {
|
||||
char delimited_suffix; // The delimited suffix of the current hash
|
||||
} DN_SHA3State;
|
||||
|
||||
enum DN_SHA3Family
|
||||
enum DN_SHA3Type
|
||||
{
|
||||
DN_SHA3Family_SHA3, // FIPS 202 SHA3 (delimited suffix is 0x6)
|
||||
DN_SHA3Family_Keccak, // Non-finalized SHA3 (only difference is delimited suffix of 0x1 instead of 0x6)
|
||||
DN_SHA3Type_SHA3, // FIPS 202 SHA3 (delimited suffix is 0x6)
|
||||
DN_SHA3Type_Keccak, // Non-finalized SHA3 (only difference is delimited suffix of 0x1 instead of 0x6)
|
||||
};
|
||||
|
||||
// hash_size_bits: Number of bits to hash to. Available sizes are 224, 256, 384 and 512.
|
||||
DN_SHA3State DN_SHA3FamilyInit (DN_SHA3Family type, size_t hash_size_bits);
|
||||
DN_SHA3State DN_SHA3FamilyInitSHA3 (size_t hash_size_bits);
|
||||
DN_SHA3State DN_SHA3FamilyInitKeccak(size_t hash_size_bits);
|
||||
void DN_SHA3FamilyUpdate (DN_SHA3State *sha3, void const *data, size_t data_size);
|
||||
void DN_SHA3FamilyFinish (DN_SHA3State *sha3, void *dest, size_t dest_size);
|
||||
void DN_SHA3FamilyHash (DN_SHA3Family type, size_t hash_size_bits, void const *src, size_t src_size, void *dest, int dest_size);
|
||||
DN_SHA3State DN_SHA3_Init (DN_SHA3Type type, size_t hash_size_bits);
|
||||
DN_SHA3State DN_SHA3_InitSHA3 (size_t hash_size_bits);
|
||||
DN_SHA3State DN_SHA3_InitKeccak (size_t hash_size_bits);
|
||||
void DN_SHA3_Update (DN_SHA3State *sha3, void const *data, size_t data_size);
|
||||
void DN_SHA3_Finish (DN_SHA3State *sha3, void *dest, size_t dest_size);
|
||||
void DN_SHA3_Hash (DN_SHA3Type type, size_t hash_size_bits, void const *src, size_t src_size, void *dest, int dest_size);
|
||||
|
||||
void DN_SHA3Hash224bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x28 DN_SHA3Hash224b (void const *src, size_t src_size);
|
||||
void DN_SHA3Hash256bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x32 DN_SHA3Hash256b (void const *src, size_t src_size);
|
||||
void DN_SHA3Hash384bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x48 DN_SHA3Hash384b (void const *src, size_t src_size);
|
||||
void DN_SHA3Hash512bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x64 DN_SHA3Hash512b (void const *src, size_t src_size);
|
||||
void DN_SHA3_Hash224bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x28 DN_SHA3_Hash224b (void const *src, size_t src_size);
|
||||
void DN_SHA3_Hash256bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x32 DN_SHA3_Hash256b (void const *src, size_t src_size);
|
||||
void DN_SHA3_Hash384bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x48 DN_SHA3_Hash384b (void const *src, size_t src_size);
|
||||
void DN_SHA3_Hash512bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x64 DN_SHA3_Hash512b (void const *src, size_t src_size);
|
||||
|
||||
void DN_KeccakHash224bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x28 DN_KeccakHash224b (void const *src, size_t src_size);
|
||||
void DN_KeccakHash256bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x32 DN_KeccakHash256b (void const *src, size_t src_size);
|
||||
void DN_KeccakHash384bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x48 DN_KeccakHash384b (void const *src, size_t src_size);
|
||||
void DN_KeccakHash512bPtr (void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x64 DN_KeccakHash512b (void const *src, size_t src_size);
|
||||
void DN_SHA3_HashKeccak224bPtr(void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x28 DN_SHA3_HashKeccak224b (void const *src, size_t src_size);
|
||||
void DN_SHA3_HashKeccak256bPtr(void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x32 DN_SHA3_HashKeccak256b (void const *src, size_t src_size);
|
||||
void DN_SHA3_HashKeccak384bPtr(void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x48 DN_SHA3_HashKeccak384b (void const *src, size_t src_size);
|
||||
void DN_SHA3_HashKeccak512bPtr(void const *src, size_t src_size, void *dest, size_t dest_size);
|
||||
DN_SHA3U8x64 DN_SHA3_HashKeccak512b (void const *src, size_t src_size);
|
||||
|
||||
void DN_SHA3HexFromBytes (void const *src, uint64_t src_size, char *dest, uint64_t dest_size);
|
||||
DN_SHA3Str8x56 DN_SHA3HexFromU8x28 (DN_SHA3U8x28 const *bytes);
|
||||
DN_SHA3Str8x64 DN_SHA3HexFromU8x32 (DN_SHA3U8x32 const *bytes);
|
||||
DN_SHA3Str8x96 DN_SHA3HexFromU8x48 (DN_SHA3U8x48 const *bytes);
|
||||
DN_SHA3Str8x128 DN_SHA3HexFromU8x64 (DN_SHA3U8x64 const *bytes);
|
||||
bool DN_SHA3U8x28Eq (DN_SHA3U8x28 const *a, DN_SHA3U8x28 const *b);
|
||||
bool DN_SHA3U8x32Eq (DN_SHA3U8x32 const *a, DN_SHA3U8x32 const *b);
|
||||
bool DN_SHA3U8x48Eq (DN_SHA3U8x48 const *a, DN_SHA3U8x48 const *b);
|
||||
bool DN_SHA3U8x64Eq (DN_SHA3U8x64 const *a, DN_SHA3U8x64 const *b);
|
||||
void DN_SHA3_HexFromBytes (void const *src, uint64_t src_size, char *dest, uint64_t dest_size);
|
||||
DN_SHA3Str8x56 DN_SHA3_HexFromU8x28 (DN_SHA3U8x28 const *bytes);
|
||||
DN_SHA3Str8x64 DN_SHA3_HexFromU8x32 (DN_SHA3U8x32 const *bytes);
|
||||
DN_SHA3Str8x96 DN_SHA3_HexFromU8x48 (DN_SHA3U8x48 const *bytes);
|
||||
DN_SHA3Str8x128 DN_SHA3_HexFromU8x64 (DN_SHA3U8x64 const *bytes);
|
||||
bool DN_SHA3_U8x28Eq (DN_SHA3U8x28 const *a, DN_SHA3U8x28 const *b);
|
||||
bool DN_SHA3_U8x32Eq (DN_SHA3U8x32 const *a, DN_SHA3U8x32 const *b);
|
||||
bool DN_SHA3_U8x48Eq (DN_SHA3U8x48 const *a, DN_SHA3U8x48 const *b);
|
||||
bool DN_SHA3_U8x64Eq (DN_SHA3U8x64 const *a, DN_SHA3U8x64 const *b);
|
||||
|
||||
#if defined(DN_SHA3_WITH_TESTS)
|
||||
DN_TestCore DN_SHA3_TestSuite(DN_Arena *arena);
|
||||
void DN_SHA3_TestSuiteThenOutput(DN_Str8FromTestCoreFlags flags);
|
||||
#endif
|
||||
#endif // DN_SHA3_H
|
||||
|
||||
#if defined(DN_SHA3_IMPLEMENTATION)
|
||||
@@ -143,7 +152,7 @@ uint64_t const DN_SHA3_ROTATIONS[][5] =
|
||||
};
|
||||
|
||||
#define DN_SHA3_ROL64(val, rotate) (((val) << (rotate)) | (((val) >> (64 - (rotate)))))
|
||||
static void DN_SHA3FamilyPermute_(void *state)
|
||||
static void DN_SHA3_Permute_(void *state)
|
||||
{
|
||||
uint64_t *lanes_u64 = (uint64_t *)state;
|
||||
for (int round_index = 0; round_index < 24; round_index++) {
|
||||
@@ -206,9 +215,9 @@ static void DN_SHA3FamilyPermute_(void *state)
|
||||
}
|
||||
}
|
||||
|
||||
DN_SHA3State DN_SHA3FamilyInit(DN_SHA3Family type, size_t hash_size_bits)
|
||||
DN_SHA3State DN_SHA3_Init(DN_SHA3Type type, size_t hash_size_bits)
|
||||
{
|
||||
DN_SHA3Assert(hash_size_bits == 224 ||
|
||||
DN_SHA3_Assert(hash_size_bits == 224 ||
|
||||
hash_size_bits == 256 ||
|
||||
hash_size_bits == 384 ||
|
||||
hash_size_bits == 512);
|
||||
@@ -224,24 +233,24 @@ DN_SHA3State DN_SHA3FamilyInit(DN_SHA3Family type, size_t hash_size_bits)
|
||||
#endif
|
||||
result.hash_size_bits = hash_size_bits;
|
||||
result.absorb_size = bitrate / 8;
|
||||
result.delimited_suffix = type == DN_SHA3Family_SHA3 ? SHA3_DELIMITED_SUFFIX : KECCAK_DELIMITED_SUFFIX;
|
||||
DN_SHA3Assert(bitrate + (hash_size_bits * 2) /*capacity*/ == 1600);
|
||||
result.delimited_suffix = type == DN_SHA3Type_SHA3 ? SHA3_DELIMITED_SUFFIX : KECCAK_DELIMITED_SUFFIX;
|
||||
DN_SHA3_Assert(bitrate + (hash_size_bits * 2) /*capacity*/ == 1600);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_SHA3State DN_SHA3FamilyInitSHA3(size_t hash_size_bits)
|
||||
DN_SHA3State DN_SHA3_InitSHA3(size_t hash_size_bits)
|
||||
{
|
||||
DN_SHA3State result = DN_SHA3FamilyInit(DN_SHA3Family_SHA3, hash_size_bits);
|
||||
DN_SHA3State result = DN_SHA3_Init(DN_SHA3Type_SHA3, hash_size_bits);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_SHA3State DN_SHA3FamilyInitKeccak(size_t hash_size_bits)
|
||||
DN_SHA3State DN_SHA3_InitKeccak(size_t hash_size_bits)
|
||||
{
|
||||
DN_SHA3State result = DN_SHA3FamilyInit(DN_SHA3Family_Keccak, hash_size_bits);
|
||||
DN_SHA3State result = DN_SHA3_Init(DN_SHA3Type_Keccak, hash_size_bits);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3FamilyUpdate(DN_SHA3State *sha3, void const *data, size_t data_size)
|
||||
void DN_SHA3_Update(DN_SHA3State *sha3, void const *data, size_t data_size)
|
||||
{
|
||||
uint8_t *state = sha3->state;
|
||||
uint8_t const *ptr = (uint8_t *)data;
|
||||
@@ -258,21 +267,21 @@ void DN_SHA3FamilyUpdate(DN_SHA3State *sha3, void const *data, size_t data_size)
|
||||
ptr_size -= bytes_to_absorb;
|
||||
|
||||
if (sha3->state_size >= sha3->absorb_size) {
|
||||
DN_SHA3Assert(sha3->state_size == sha3->absorb_size);
|
||||
DN_SHA3FamilyPermute_(state);
|
||||
DN_SHA3_Assert(sha3->state_size == sha3->absorb_size);
|
||||
DN_SHA3_Permute_(state);
|
||||
sha3->state_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DN_SHA3FamilyFinish(DN_SHA3State *sha3, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Finish(DN_SHA3State *sha3, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3Assert(dest_size >= (size_t)(sha3->hash_size_bits / 8));
|
||||
DN_SHA3_Assert(dest_size >= (size_t)(sha3->hash_size_bits / 8));
|
||||
|
||||
// Sponge Finalization Step: Final padding bit
|
||||
size_t const INDEX_OF_0X80_BYTE = sha3->absorb_size - 1;
|
||||
size_t const delimited_suffix_index = sha3->state_size;
|
||||
DN_SHA3Assert(delimited_suffix_index < sha3->absorb_size);
|
||||
DN_SHA3_Assert(delimited_suffix_index < sha3->absorb_size);
|
||||
|
||||
uint8_t *state = sha3->state;
|
||||
state[delimited_suffix_index] ^= sha3->delimited_suffix;
|
||||
@@ -287,7 +296,7 @@ void DN_SHA3FamilyFinish(DN_SHA3State *sha3, void *dest, size_t dest_size)
|
||||
// this from the implementation here.
|
||||
|
||||
state[INDEX_OF_0X80_BYTE] ^= 0x80;
|
||||
DN_SHA3FamilyPermute_(state);
|
||||
DN_SHA3_Permute_(state);
|
||||
|
||||
// Squeeze Step: Squeeze bytes from the state into our hash
|
||||
uint8_t *dest_u8 = (uint8_t *)dest;
|
||||
@@ -295,8 +304,8 @@ void DN_SHA3FamilyFinish(DN_SHA3State *sha3, void *dest, size_t dest_size)
|
||||
size_t squeeze_index = 0;
|
||||
for (; squeeze_index < squeeze_count; squeeze_index++) {
|
||||
if (squeeze_index)
|
||||
DN_SHA3FamilyPermute_(state);
|
||||
DN_SHA3Memcpy(dest_u8, state, sha3->absorb_size);
|
||||
DN_SHA3_Permute_(state);
|
||||
DN_SHA3_Memcpy(dest_u8, state, sha3->absorb_size);
|
||||
dest_u8 += sha3->absorb_size;
|
||||
}
|
||||
|
||||
@@ -304,119 +313,119 @@ void DN_SHA3FamilyFinish(DN_SHA3State *sha3, void *dest, size_t dest_size)
|
||||
size_t const remainder = dest_size % sha3->absorb_size;
|
||||
if (remainder) {
|
||||
if (squeeze_index)
|
||||
DN_SHA3FamilyPermute_(state);
|
||||
DN_SHA3Memcpy(dest_u8, state, remainder);
|
||||
DN_SHA3_Permute_(state);
|
||||
DN_SHA3_Memcpy(dest_u8, state, remainder);
|
||||
}
|
||||
}
|
||||
|
||||
void DN_SHA3FamilyHash(DN_SHA3Family type, size_t hash_size_bits, void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Hash(DN_SHA3Type type, size_t hash_size_bits, void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3State state = DN_SHA3FamilyInit(type, hash_size_bits);
|
||||
DN_SHA3FamilyUpdate(&state, src, src_size);
|
||||
DN_SHA3FamilyFinish(&state, dest, dest_size);
|
||||
DN_SHA3State state = DN_SHA3_Init(type, hash_size_bits);
|
||||
DN_SHA3_Update(&state, src, src_size);
|
||||
DN_SHA3_Finish(&state, dest, dest_size);
|
||||
}
|
||||
|
||||
void DN_SHA3Hash224bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Hash224bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_SHA3, /*hash_size_bits=*/ 224, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_SHA3, /*hash_size_bits=*/ 224, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x28 DN_SHA3Hash224b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x28 DN_SHA3_Hash224b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x28 result = {};
|
||||
DN_SHA3Hash224bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_Hash224bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3Hash256bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Hash256bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_SHA3, /*hash_size_bits=*/ 256, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_SHA3, /*hash_size_bits=*/ 256, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x32 DN_SHA3Hash256b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x32 DN_SHA3_Hash256b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x32 result = {};
|
||||
DN_SHA3Hash256bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_Hash256bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3Hash384bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Hash384bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_SHA3, /*hash_size_bits=*/ 384, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_SHA3, /*hash_size_bits=*/ 384, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x48 DN_SHA3Hash384b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x48 DN_SHA3_Hash384b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x48 result = {};
|
||||
DN_SHA3Hash384bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_Hash384bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3Hash512bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_Hash512bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_SHA3, /*hash_size_bits=*/ 512, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_SHA3, /*hash_size_bits=*/ 512, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x64 DN_SHA3Hash512b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x64 DN_SHA3_Hash512b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x64 result = {};
|
||||
DN_SHA3Hash512bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_Hash512bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_KeccakHash224bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_HashKeccak224bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_Keccak, /*hash_size_bits=*/ 224, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_Keccak, /*hash_size_bits=*/ 224, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x28 DN_KeccakHash224b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x28 DN_SHA3_HashKeccak224b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x28 result = {};
|
||||
DN_KeccakHash224bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_HashKeccak224bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_KeccakHash256bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_HashKeccak256bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_Keccak, /*hash_size_bits=*/ 256, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_Keccak, /*hash_size_bits=*/ 256, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x32 DN_KeccakHash256b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x32 DN_SHA3_HashKeccak256b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x32 result = {};
|
||||
DN_KeccakHash256bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_HashKeccak256bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_KeccakHash384bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_HashKeccak384bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_Keccak, /*hash_size_bits=*/ 384, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_Keccak, /*hash_size_bits=*/ 384, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x48 DN_KeccakHash384b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x48 DN_SHA3_HashKeccak384b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x48 result = {};
|
||||
DN_KeccakHash384bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_HashKeccak384bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_KeccakHash512bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
void DN_SHA3_HashKeccak512bPtr(void const *src, size_t src_size, void *dest, size_t dest_size)
|
||||
{
|
||||
DN_SHA3FamilyHash(DN_SHA3Family_Keccak, /*hash_size_bits=*/ 512, src, src_size, dest, dest_size);
|
||||
DN_SHA3_Hash(DN_SHA3Type_Keccak, /*hash_size_bits=*/ 512, src, src_size, dest, dest_size);
|
||||
}
|
||||
|
||||
DN_SHA3U8x64 DN_KeccakHash512b(void const *src, size_t src_size)
|
||||
DN_SHA3U8x64 DN_SHA3_HashKeccak512b(void const *src, size_t src_size)
|
||||
{
|
||||
DN_SHA3U8x64 result = {};
|
||||
DN_KeccakHash512bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
DN_SHA3_HashKeccak512bPtr(src, src_size, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3HexFromBytes(void const *src, size_t src_size, char *dest, size_t dest_size)
|
||||
void DN_SHA3_HexFromBytes(void const *src, size_t src_size, char *dest, size_t dest_size)
|
||||
{
|
||||
(void)src_size;
|
||||
(void)dest_size;
|
||||
DN_SHA3Assert(dest_size >= src_size * 2);
|
||||
DN_SHA3_Assert(dest_size >= src_size * 2);
|
||||
|
||||
unsigned char *src_u8 = (unsigned char *)src;
|
||||
for (size_t src_index = 0, dest_index = 0; src_index < src_size;
|
||||
@@ -429,59 +438,373 @@ void DN_SHA3HexFromBytes(void const *src, size_t src_size, char *dest, size_t de
|
||||
}
|
||||
}
|
||||
|
||||
DN_SHA3Str8x56 DN_SHA3HexFromU8x28(DN_SHA3U8x28 const *bytes)
|
||||
DN_SHA3Str8x56 DN_SHA3_HexFromU8x28(DN_SHA3U8x28 const *bytes)
|
||||
{
|
||||
DN_SHA3Str8x56 result;
|
||||
DN_SHA3HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
DN_SHA3_HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
result.data[sizeof(result.data) - 1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_SHA3Str8x64 DN_SHA3HexFromU8x32(DN_SHA3U8x32 const *bytes)
|
||||
DN_SHA3Str8x64 DN_SHA3_HexFromU8x32(DN_SHA3U8x32 const *bytes)
|
||||
{
|
||||
DN_SHA3Str8x64 result;
|
||||
DN_SHA3HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
DN_SHA3_HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
result.data[sizeof(result.data) - 1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_SHA3Str8x96 DN_SHA3HexFromU8x48(DN_SHA3U8x48 const *bytes)
|
||||
DN_SHA3Str8x96 DN_SHA3_HexFromU8x48(DN_SHA3U8x48 const *bytes)
|
||||
{
|
||||
DN_SHA3Str8x96 result;
|
||||
DN_SHA3HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
DN_SHA3_HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
result.data[sizeof(result.data) - 1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_SHA3Str8x128 DN_SHA3HexFromU8x64(DN_SHA3U8x64 const *bytes)
|
||||
DN_SHA3Str8x128 DN_SHA3_HexFromU8x64(DN_SHA3U8x64 const *bytes)
|
||||
{
|
||||
DN_SHA3Str8x128 result;
|
||||
DN_SHA3HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
DN_SHA3_HexFromBytes(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
||||
result.data[sizeof(result.data) - 1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DN_SHA3U8x32Eq(DN_SHA3U8x28 const *a, DN_SHA3U8x28 const *b)
|
||||
bool DN_SHA3_U8x32Eq(DN_SHA3U8x28 const *a, DN_SHA3U8x28 const *b)
|
||||
{
|
||||
int result = DN_SHA3Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
int result = DN_SHA3_Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DN_SHA3U8x32Eq(DN_SHA3U8x32 const *a, DN_SHA3U8x32 const *b)
|
||||
bool DN_SHA3_U8x32Eq(DN_SHA3U8x32 const *a, DN_SHA3U8x32 const *b)
|
||||
{
|
||||
int result = DN_SHA3Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
int result = DN_SHA3_Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DN_SHA3U8x48Eq(DN_SHA3U8x48 const *a, DN_SHA3U8x48 const *b)
|
||||
bool DN_SHA3_U8x48Eq(DN_SHA3U8x48 const *a, DN_SHA3U8x48 const *b)
|
||||
{
|
||||
int result = DN_SHA3Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
int result = DN_SHA3_Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DN_SHA3U8x64Eq(DN_SHA3U8x64 const *a, DN_SHA3U8x64 const *b)
|
||||
bool DN_SHA3_U8x64Eq(DN_SHA3U8x64 const *a, DN_SHA3U8x64 const *b)
|
||||
{
|
||||
int result = DN_SHA3Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
int result = DN_SHA3_Memcmp(a->data, b->data, sizeof(*a)) == 0;
|
||||
return result;
|
||||
}
|
||||
#endif // DN_SHA3_IMPLEMENTATION
|
||||
|
||||
#if defined(DN_SHA3_WITH_TESTS)
|
||||
#if !defined(DN_H)
|
||||
#error dn.h must be included to enable tests for dn_sha3.h
|
||||
#endif
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wunused-parameter)
|
||||
DN_GCC_WARNING_DISABLE(-Wsign-compare)
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4244)
|
||||
DN_MSVC_WARNING_DISABLE(4100)
|
||||
DN_MSVC_WARNING_DISABLE(6385)
|
||||
// NOTE: Keccak Reference Implementation
|
||||
// A very compact Keccak implementation taken from the reference implementation
|
||||
// repository
|
||||
// https://github.com/XKCP/XKCP/blob/master/Standalone/CompactFIPS202/C/Keccak-more-compact.c
|
||||
#define FOR(i, n) for (i = 0; i < n; ++i)
|
||||
void DN_SHA3RefImplKeccak_(int r, int c, const uint8_t *in, uint64_t inLen, uint8_t sfx, uint8_t *out, uint64_t outLen);
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHAKE128_(const uint8_t *in, uint64_t inLen, uint8_t *out, uint64_t outLen)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(1344, 256, in, inLen, 0x1F, out, outLen);
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHAKE256_(const uint8_t *in, uint64_t inLen, uint8_t *out, uint64_t outLen)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(1088, 512, in, inLen, 0x1F, out, outLen);
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHA3_224_(const uint8_t *in, uint64_t inLen, uint8_t *out)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(1152, 448, in, inLen, 0x06, out, 28);
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHA3_256_(const uint8_t *in, uint64_t inLen, uint8_t *out)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(1088, 512, in, inLen, 0x06, out, 32);
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHA3_384_(const uint8_t *in, uint64_t inLen, uint8_t *out)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(832, 768, in, inLen, 0x06, out, 48);
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplFIPS202_SHA3_512_(const uint8_t *in, uint64_t inLen, uint8_t *out)
|
||||
{
|
||||
DN_SHA3RefImplKeccak_(576, 1024, in, inLen, 0x06, out, 64);
|
||||
}
|
||||
|
||||
int DN_SHA3RefImplLFSR86540_(uint8_t *R)
|
||||
{
|
||||
(*R) = ((*R) << 1) ^ (((*R) & 0x80) ? 0x71 : 0);
|
||||
return ((*R) & 2) >> 1;
|
||||
}
|
||||
|
||||
#define ROL(a, o) ((((uint64_t)a) << o) ^ (((uint64_t)a) >> (64 - o)))
|
||||
|
||||
static uint64_t DN_SHA3RefImplload64_(const uint8_t *x)
|
||||
{
|
||||
int i;
|
||||
uint64_t u = 0;
|
||||
FOR(i, 8)
|
||||
{
|
||||
u <<= 8;
|
||||
u |= x[7 - i];
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
static void DN_SHA3RefImplstore64_(uint8_t *x, uint64_t u)
|
||||
{
|
||||
int i;
|
||||
FOR(i, 8)
|
||||
{
|
||||
x[i] = u;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void DN_SHA3RefImplxor64_(uint8_t *x, uint64_t u)
|
||||
{
|
||||
int i;
|
||||
FOR(i, 8)
|
||||
{
|
||||
x[i] ^= u;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
#define rL(x, y) DN_SHA3RefImplload64_((uint8_t *)s + 8 * (x + 5 * y))
|
||||
#define wL(x, y, l) DN_SHA3RefImplstore64_((uint8_t *)s + 8 * (x + 5 * y), l)
|
||||
#define XL(x, y, l) DN_SHA3RefImplxor64_((uint8_t *)s + 8 * (x + 5 * y), l)
|
||||
|
||||
void DN_SHA3RefImplKeccak_F1600(void *s)
|
||||
{
|
||||
int r, x, y, i, j, Y;
|
||||
uint8_t R = 0x01;
|
||||
uint64_t C[5], D;
|
||||
for (i = 0; i < 24; i++) {
|
||||
/*??*/ FOR(x, 5) C[x] = rL(x, 0) ^ rL(x, 1) ^ rL(x, 2) ^ rL(x, 3) ^ rL(x, 4);
|
||||
FOR(x, 5)
|
||||
{
|
||||
D = C[(x + 4) % 5] ^ ROL(C[(x + 1) % 5], 1);
|
||||
FOR(y, 5)
|
||||
XL(x, y, D);
|
||||
}
|
||||
/*????*/ x = 1;
|
||||
y = r = 0;
|
||||
D = rL(x, y);
|
||||
FOR(j, 24)
|
||||
{
|
||||
r += j + 1;
|
||||
Y = (2 * x + 3 * y) % 5;
|
||||
x = y;
|
||||
y = Y;
|
||||
C[0] = rL(x, y);
|
||||
wL(x, y, ROL(D, r % 64));
|
||||
D = C[0];
|
||||
}
|
||||
/*??*/ FOR(y, 5)
|
||||
{
|
||||
FOR(x, 5)
|
||||
C[x] = rL(x, y);
|
||||
FOR(x, 5)
|
||||
wL(x, y, C[x] ^ ((~C[(x + 1) % 5]) & C[(x + 2) % 5]));
|
||||
}
|
||||
/*??*/ FOR(j, 7) if (DN_SHA3RefImplLFSR86540_(&R)) XL(0, 0, (uint64_t)1 << ((1 << j) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
void DN_SHA3RefImplKeccak_(int r, int c, const uint8_t *in, uint64_t inLen, uint8_t sfx, uint8_t *out, uint64_t outLen)
|
||||
{
|
||||
/*initialize*/ uint8_t s[200];
|
||||
int R = r / 8;
|
||||
int i, b = 0;
|
||||
FOR(i, 200)
|
||||
s[i] = 0;
|
||||
/*absorb*/ while (inLen > 0) {
|
||||
b = (inLen < R) ? inLen : R;
|
||||
FOR(i, b)
|
||||
s[i] ^= in[i];
|
||||
in += b;
|
||||
inLen -= b;
|
||||
if (b == R) {
|
||||
DN_SHA3RefImplKeccak_F1600(s);
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
/*pad*/ s[b] ^= sfx;
|
||||
if ((sfx & 0x80) && (b == (R - 1)))
|
||||
DN_SHA3RefImplKeccak_F1600(s);
|
||||
s[R - 1] ^= 0x80;
|
||||
DN_SHA3RefImplKeccak_F1600(s);
|
||||
/*squeeze*/ while (outLen > 0) {
|
||||
b = (outLen < R) ? outLen : R;
|
||||
FOR(i, b)
|
||||
out[i] = s[i];
|
||||
out += b;
|
||||
outLen -= b;
|
||||
if (outLen > 0)
|
||||
DN_SHA3RefImplKeccak_F1600(s);
|
||||
}
|
||||
}
|
||||
|
||||
#undef XL
|
||||
#undef wL
|
||||
#undef rL
|
||||
#undef ROL
|
||||
#undef FOR
|
||||
DN_MSVC_WARNING_POP
|
||||
DN_GCC_WARNING_POP
|
||||
|
||||
enum DN_SHA3TestHash
|
||||
{
|
||||
DN_SHA3TestHash_224,
|
||||
DN_SHA3TestHash_256,
|
||||
DN_SHA3TestHash_384,
|
||||
DN_SHA3TestHash_512,
|
||||
DN_SHA3TestHash_Keccak224,
|
||||
DN_SHA3TestHash_Keccak256,
|
||||
DN_SHA3TestHash_Keccak384,
|
||||
DN_SHA3TestHash_Keccak512,
|
||||
DN_SHA3TestHash_Count,
|
||||
};
|
||||
|
||||
static void DN_SHA3TestHashDispatch_(DN_TestCore *test, DN_SHA3TestHash hash_type, DN_Str8 input)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&test->arena, 1);
|
||||
DN_Str8 input_hex = DN_HexFromPtrBytesArena(input.data, input.count, &scratch.arena, DN_TrimLeadingZero_No);
|
||||
switch (hash_type) {
|
||||
case DN_SHA3TestHash_Count: DN_AssertInvalidCodePath; break;
|
||||
case DN_SHA3TestHash_224: {
|
||||
DN_SHA3U8x28 hash = DN_SHA3_Hash224b(input.data, input.count);
|
||||
DN_SHA3U8x28 expect;
|
||||
DN_SHA3RefImplFIPS202_SHA3_224_(DN_Cast(uint8_t *) input.data, input.count, (uint8_t *)expect.data);
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_256: {
|
||||
DN_SHA3U8x32 hash = DN_SHA3_Hash256b(input.data, input.count);
|
||||
DN_SHA3U8x32 expect;
|
||||
DN_SHA3RefImplFIPS202_SHA3_256_(DN_Cast(uint8_t *) input.data, input.count, (uint8_t *)expect.data);
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_384: {
|
||||
DN_SHA3U8x48 hash = DN_SHA3_Hash384b(input.data, input.count);
|
||||
DN_SHA3U8x48 expect;
|
||||
DN_SHA3RefImplFIPS202_SHA3_384_(DN_Cast(uint8_t *) input.data, input.count, (uint8_t *)expect.data);
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_512: {
|
||||
DN_SHA3U8x64 hash = DN_SHA3_Hash512b(input.data, input.count);
|
||||
DN_SHA3U8x64 expect;
|
||||
DN_SHA3RefImplFIPS202_SHA3_512_(DN_Cast(uint8_t *) input.data, input.count, (uint8_t *)expect.data);
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_Keccak224: {
|
||||
DN_SHA3U8x28 hash = DN_SHA3_HashKeccak224b(input.data, input.count);
|
||||
DN_SHA3U8x28 expect;
|
||||
DN_SHA3RefImplKeccak_(1152, 448, DN_Cast(uint8_t *) input.data, input.count, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_Keccak256: {
|
||||
DN_SHA3U8x32 hash = DN_SHA3_HashKeccak256b(input.data, input.count);
|
||||
DN_SHA3U8x32 expect;
|
||||
DN_SHA3RefImplKeccak_(1088, 512, DN_Cast(uint8_t *) input.data, input.count, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_Keccak384: {
|
||||
DN_SHA3U8x48 hash = DN_SHA3_HashKeccak384b(input.data, input.count);
|
||||
DN_SHA3U8x48 expect;
|
||||
DN_SHA3RefImplKeccak_(832, 768, DN_Cast(uint8_t *) input.data, input.count, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
|
||||
case DN_SHA3TestHash_Keccak512: {
|
||||
DN_SHA3U8x64 hash = DN_SHA3_HashKeccak512b(input.data, input.count);
|
||||
DN_SHA3U8x64 expect;
|
||||
DN_SHA3RefImplKeccak_(576, 1024, DN_Cast(uint8_t *) input.data, input.count, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_TestVerifyBytesEqF(test, DN_Str8FromLitArray(hash.data), DN_Str8FromLitArray(expect.data), "Input: %.*s", DN_Str8PrintFmt(input_hex));
|
||||
} break;
|
||||
}
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
DN_TestCore DN_SHA3_TestSuite(DN_Arena *arena)
|
||||
{
|
||||
DN_TestCore result = DN_TestInit(arena);
|
||||
for (DN_TestGroupScopeF(&result, "SHA3")) {
|
||||
for (DN_ForIndexU(hash_type, DN_SHA3TestHash_Count)) {
|
||||
// NOTE: Get a name for the hash type
|
||||
DN_Str8 hash_name = {};
|
||||
switch (hash_type) {
|
||||
case DN_SHA3TestHash_224: hash_name = DN_Str8Lit("SHA3-224"); break;
|
||||
case DN_SHA3TestHash_256: hash_name = DN_Str8Lit("SHA3-256"); break;
|
||||
case DN_SHA3TestHash_384: hash_name = DN_Str8Lit("SHA3-384"); break;
|
||||
case DN_SHA3TestHash_512: hash_name = DN_Str8Lit("SHA3-512"); break;
|
||||
case DN_SHA3TestHash_Keccak224: hash_name = DN_Str8Lit("Keccak-224"); break;
|
||||
case DN_SHA3TestHash_Keccak256: hash_name = DN_Str8Lit("Keccak-256"); break;
|
||||
case DN_SHA3TestHash_Keccak384: hash_name = DN_Str8Lit("Keccak-384"); break;
|
||||
case DN_SHA3TestHash_Keccak512: hash_name = DN_Str8Lit("Keccak-512"); break;
|
||||
case DN_SHA3TestHash_Count: DN_AssertInvalidCodePath; break;
|
||||
}
|
||||
|
||||
// NOTE: Test SHA3 against some fixed inputs
|
||||
{
|
||||
DN_Str8 const INPUTS[] = {
|
||||
DN_Str8Lit("abc"),
|
||||
DN_Str8Lit(""),
|
||||
DN_Str8Lit("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
|
||||
DN_Str8Lit("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
|
||||
};
|
||||
|
||||
for (DN_ForItCArray(it, DN_Str8 const, INPUTS)) {
|
||||
for (DN_TestScopeF(&result, "[%.*s] %.*s", DN_Str8PrintFmt(hash_name), DN_Str8PrintFmt(*it.data)))
|
||||
DN_SHA3TestHashDispatch_(&result, DN_Cast(DN_SHA3TestHash)hash_type, *it.data);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Test SHA3 against some deterministic inputs generated from a PRNG
|
||||
for (DN_TestScopeF(&result, "[%.*s] Deterministic random inputs", DN_Str8PrintFmt(hash_name))) {
|
||||
DN_PCG32 rng = DN_PCG32Init(0xd48e'be21'2af8'733d);
|
||||
for (DN_USize index = 0; index < 128; index++) {
|
||||
// NOTE: Create a 4kb buffer with the deterministic contents
|
||||
char src[4096] = {};
|
||||
DN_U32 src_size = DN_PCG32Range(&rng, 0, sizeof(src));
|
||||
for (DN_USize src_index = 0; src_index < src_size; src_index++)
|
||||
src[src_index] = DN_Cast(char) DN_PCG32Range(&rng, 0, 255);
|
||||
|
||||
// NOTE: Do the hashing
|
||||
DN_Str8 input = DN_Str8FromPtr(src, src_size);
|
||||
DN_SHA3TestHashDispatch_(&result, DN_Cast(DN_SHA3TestHash)hash_type, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_SHA3_TestSuiteThenOutput(DN_Str8FromTestCoreFlags flags)
|
||||
{
|
||||
DN_Arena arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_Kilobytes(64), DN_MemFlags_Nil, DN_OS_HeapInitDefault());
|
||||
DN_TestCore test = DN_SHA3_TestSuite(&arena);
|
||||
DN_Str8 output = DN_Str8FromTestCore(&test, &arena, flags);
|
||||
printf("%.*s", DN_Str8PrintFmt(output));
|
||||
DN_ArenaDeinit(&arena);
|
||||
}
|
||||
#endif // #if defined(DN_SHA3_WITH_TESTS)
|
||||
#endif // #if defined(DN_SHA3_IMPLEMENTATION)
|
||||
|
||||
@@ -1,333 +0,0 @@
|
||||
#if !defined(DN_UT_H)
|
||||
#define DN_UT_H
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$\ $$\ $$$$$$$$\ $$$$$$$$\ $$$$$$\ $$$$$$$$\
|
||||
// $$ | $$ |\__$$ __|$$ _____|$$ __$$\\__$$ __|
|
||||
// $$ | $$ | $$ | $$ | $$ / \__| $$ |
|
||||
// $$ | $$ | $$ | $$$$$\ \$$$$$$\ $$ |
|
||||
// $$ | $$ | $$ | $$ __| \____$$\ $$ |
|
||||
// $$ | $$ | $$ | $$ | $$\ $$ | $$ |
|
||||
// \$$$$$$ | $$ | $$$$$$$$\ \$$$$$$ | $$ |
|
||||
// \______/ \__| \________| \______/ \__|
|
||||
//
|
||||
// dn_utest.h -- Extremely minimal unit testing framework
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A super minimal testing framework, most of the logic here is the pretty
|
||||
// printing of test results.
|
||||
//
|
||||
// NOTE: Configuration /////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// #define DN_UT_IMPLEMENTATION
|
||||
// Define this in one and only one C++ file to enable the implementation
|
||||
// code of the header file. This will also automatically enable the JSMN
|
||||
// implementation.
|
||||
//
|
||||
// #define DN_UT_RESULT_LPAD
|
||||
// Define this to a number to specify how much to pad the output of the test
|
||||
// result line before the test result is printed.
|
||||
//
|
||||
// #define DN_UT_RESULT_PAD_CHAR
|
||||
// Define this to a character to specify the default character to use for
|
||||
// padding. By default this is '.'
|
||||
//
|
||||
// #define DN_UT_SPACING
|
||||
// Define this to a number to specify the number of spaces between the group
|
||||
// declaration and the test output in the group.
|
||||
//
|
||||
// #define DN_UT_BAD_COLOR
|
||||
// Define this to a terminal color code to specify what color errors will be
|
||||
// presented as.
|
||||
//
|
||||
// #define DN_UT_GOOD_COLOR
|
||||
// Define this to a terminal color code to specify what color sucess will be
|
||||
// presented as.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: Macros ////////////////////////////////////////////////////////////////////////////////////
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(DN_UT_RESULT_LPAD)
|
||||
#define DN_UT_RESULT_LPAD 90
|
||||
#endif
|
||||
|
||||
#if !defined(DN_UT_RESULT_PAD_CHAR)
|
||||
#define DN_UT_RESULT_PAD_CHAR '.'
|
||||
#endif
|
||||
|
||||
#if !defined(DN_UT_SPACING)
|
||||
#define DN_UT_SPACING 2
|
||||
#endif
|
||||
|
||||
#if !defined(DN_UT_BAD_COLOR)
|
||||
#define DN_UT_BAD_COLOR "\x1b[31m"
|
||||
#endif
|
||||
|
||||
#if !defined(DN_UT_GOOD_COLOR)
|
||||
#define DN_UT_GOOD_COLOR "\x1b[32m"
|
||||
#endif
|
||||
|
||||
#define DN_UT_COLOR_RESET "\x1b[0m"
|
||||
|
||||
#define DN_UT_Test(test, fmt, ...) \
|
||||
int dummy_ = (DN_UT_BeginF((test), fmt, ##__VA_ARGS__), 0); \
|
||||
(void)dummy_, (test)->state == DN_UTState_TestBegun; \
|
||||
DN_UT_End(test)
|
||||
|
||||
#define DN_UT_AssertF(test, expr, fmt, ...) \
|
||||
DN_UT_AssertAtF((test), __FILE__, __LINE__, (expr), fmt, ##__VA_ARGS__)
|
||||
|
||||
#define DN_UT_Assert(test, expr) \
|
||||
DN_UT_AssertAt((test), __FILE__, __LINE__, (expr))
|
||||
|
||||
// TODO: Fix the logs. They print before the tests, we should accumulate logs
|
||||
// per test, then, dump them on test on. But to do this nicely without crappy
|
||||
// mem management we need to implement an arena.
|
||||
#define DN_UT_Log(test, fmt, ...) \
|
||||
DN_UT_LogF(test, "%*s" fmt "\n", DN_UT_SPACING * 2, "", ##__VA_ARGS__)
|
||||
|
||||
#define DN_UT_AssertAtF(test, file, line, expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
(test)->state = DN_UTState_TestFailed; \
|
||||
DN_UT_LogInsideTestF(test, \
|
||||
"%*sAssertion File: %s:%d\n" \
|
||||
"%*sExpression: [" #expr \
|
||||
"]\n" \
|
||||
"%*sReason: " fmt "\n", \
|
||||
DN_UT_SPACING * 2, \
|
||||
"", \
|
||||
file, \
|
||||
line, \
|
||||
DN_UT_SPACING * 2, \
|
||||
"", \
|
||||
DN_UT_SPACING * 2, \
|
||||
"", \
|
||||
##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DN_UT_AssertAt(test, file, line, expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
(test)->state = DN_UTState_TestFailed; \
|
||||
DN_UT_LogInsideTestF(test, \
|
||||
"%*sAssertion File: %s:%d\n" \
|
||||
"%*sExpression: [" #expr "]\n", \
|
||||
DN_UT_SPACING * 2, \
|
||||
"", \
|
||||
file, \
|
||||
line, \
|
||||
DN_UT_SPACING * 2, \
|
||||
""); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// NOTE: Header ////////////////////////////////////////////////////////////////////////////////////
|
||||
typedef enum DN_UTState
|
||||
{
|
||||
DN_UTState_Nil,
|
||||
DN_UTState_TestBegun,
|
||||
DN_UTState_TestFailed,
|
||||
} DN_UTState;
|
||||
|
||||
typedef struct DN_UTStr8Link
|
||||
{
|
||||
char *data;
|
||||
size_t size;
|
||||
DN_UTStr8Link *next;
|
||||
DN_UTStr8Link *prev;
|
||||
} DN_UTStr8Link;
|
||||
|
||||
typedef struct DN_UTCore
|
||||
{
|
||||
int num_tests_in_group;
|
||||
int num_tests_ok_in_group;
|
||||
DN_UTState state;
|
||||
char name[256];
|
||||
size_t name_size;
|
||||
DN_UTStr8Link *curr_test_messages;
|
||||
DN_UTStr8Link *output;
|
||||
} DN_UTCore;
|
||||
|
||||
DN_UTCore DN_UT_Init();
|
||||
void DN_UT_Deinit(DN_UTCore *ut);
|
||||
|
||||
void DN_UT_BeginFV(DN_UTCore *test, char const *fmt, va_list args);
|
||||
void DN_UT_BeginF(DN_UTCore *test, char const *fmt, ...);
|
||||
void DN_UT_End(DN_UTCore *test);
|
||||
|
||||
void DN_UT_LogF(DN_UTCore *test, char const *fmt, ...);
|
||||
void DN_UT_LogInsideTestF(DN_UTCore *test, char const *fmt, ...);
|
||||
|
||||
bool DN_UT_AllTestsPassed(DN_UTCore const *test);
|
||||
void DN_UT_PrintTests(DN_UTCore const *test);
|
||||
#endif // DN_UT_H
|
||||
|
||||
// NOTE: Implementation ////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(DN_UT_IMPLEMENTATION)
|
||||
DN_UTCore DN_UT_Init()
|
||||
{
|
||||
DN_UTCore result = {};
|
||||
result.output = (DN_UTStr8Link *)calloc(1, sizeof(*result.output));
|
||||
result.curr_test_messages = (DN_UTStr8Link *)calloc(1, sizeof(*result.curr_test_messages));
|
||||
assert(result.output);
|
||||
assert(result.curr_test_messages);
|
||||
result.output->next = result.output->prev = result.output;
|
||||
result.curr_test_messages->next = result.curr_test_messages->prev = result.curr_test_messages;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_UT_Deinit(DN_UTCore *ut)
|
||||
{
|
||||
for (DN_UTStr8Link *it = ut->output->next; it != ut->output; it = ut->output->next) {
|
||||
it->next->prev = it->prev;
|
||||
it->prev->next = it->next;
|
||||
free(it);
|
||||
}
|
||||
free(ut->output);
|
||||
|
||||
for (DN_UTStr8Link *it = ut->curr_test_messages->next; it != ut->curr_test_messages; it = ut->curr_test_messages->next) {
|
||||
it->next->prev = it->prev;
|
||||
it->prev->next = it->next;
|
||||
free(it);
|
||||
}
|
||||
free(ut->curr_test_messages);
|
||||
}
|
||||
|
||||
void DN_UT_BeginFV(DN_UTCore *ut, char const *fmt, va_list args)
|
||||
{
|
||||
assert(ut->output && ut->curr_test_messages && "Test must be initialised by calling DN_UT_Init()");
|
||||
assert(ut->state == DN_UTState_Nil &&
|
||||
"Nesting a unit ut within another unit test is not allowed, ensure"
|
||||
"the first test has finished by calling DN_UT_End");
|
||||
|
||||
ut->num_tests_in_group++;
|
||||
ut->state = DN_UTState_TestBegun;
|
||||
ut->name_size = 0;
|
||||
{
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
ut->name_size = vsnprintf(NULL, 0, fmt, args_copy);
|
||||
va_end(args_copy);
|
||||
}
|
||||
|
||||
assert(ut->name_size < sizeof(ut->name));
|
||||
vsnprintf(ut->name, sizeof(ut->name), fmt, args);
|
||||
}
|
||||
|
||||
void DN_UT_BeginF(DN_UTCore *ut, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_UT_BeginFV(ut, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static DN_UTStr8Link *DN_UT_AllocStr8LinkFV(char const *fmt, va_list args)
|
||||
{
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
size_t size = vsnprintf(nullptr, 0, fmt, args_copy) + 1;
|
||||
va_end(args_copy);
|
||||
|
||||
DN_UTStr8Link *result = (DN_UTStr8Link *)malloc(sizeof(*result) + size);
|
||||
if (result) {
|
||||
result->data = (char *)result + sizeof(*result);
|
||||
result->size = vsnprintf(result->data, size, fmt, args);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_UT_End(DN_UTCore *ut)
|
||||
{
|
||||
assert(ut->state != DN_UTState_Nil && "Test was marked as ended but a ut was never commenced using DN_UT_Begin");
|
||||
size_t pad_size = DN_UT_RESULT_LPAD - (DN_UT_SPACING + ut->name_size);
|
||||
if (pad_size < 0)
|
||||
pad_size = 0;
|
||||
|
||||
char pad_buffer[DN_UT_RESULT_LPAD] = {};
|
||||
memset(pad_buffer, DN_UT_RESULT_PAD_CHAR, pad_size);
|
||||
|
||||
DN_UT_LogF(ut, "%*s%.*s%.*s", DN_UT_SPACING, "", (int)ut->name_size, ut->name, (int)pad_size, pad_buffer);
|
||||
if (ut->state == DN_UTState_TestFailed) {
|
||||
DN_UT_LogF(ut, DN_UT_BAD_COLOR " FAILED");
|
||||
} else {
|
||||
DN_UT_LogF(ut, DN_UT_GOOD_COLOR " OK");
|
||||
ut->num_tests_ok_in_group++;
|
||||
}
|
||||
DN_UT_LogF(ut, DN_UT_COLOR_RESET "\n");
|
||||
ut->state = DN_UTState_Nil;
|
||||
|
||||
// NOTE: Append any test messages (like assertions) into the main output buffer
|
||||
for (DN_UTStr8Link *it = ut->curr_test_messages->next; it != ut->curr_test_messages; it = ut->curr_test_messages->next) {
|
||||
// NOTE: Detach
|
||||
it->next->prev = it->prev;
|
||||
it->prev->next = it->next;
|
||||
|
||||
// NOTE: Attach
|
||||
it->next = ut->output;
|
||||
it->prev = ut->output->prev;
|
||||
it->next->prev = it;
|
||||
it->prev->next = it;
|
||||
}
|
||||
}
|
||||
|
||||
void DN_UT_LogF(DN_UTCore *ut, char const *fmt, ...)
|
||||
{
|
||||
assert(ut->output && ut->curr_test_messages && "UT was not initialised by calling UT_Init yet");
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_UTStr8Link *result = DN_UT_AllocStr8LinkFV(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
result->next = ut->output;
|
||||
result->prev = ut->output->prev;
|
||||
result->next->prev = result;
|
||||
result->prev->next = result;
|
||||
}
|
||||
|
||||
void DN_UT_LogInsideTestF(DN_UTCore *ut, char const *fmt, ...)
|
||||
{
|
||||
assert(ut->state >= DN_UTState_TestBegun && "");
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_UTStr8Link *result = DN_UT_AllocStr8LinkFV(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
result->next = ut->curr_test_messages;
|
||||
result->prev = ut->curr_test_messages->prev;
|
||||
result->next->prev = result;
|
||||
result->prev->next = result;
|
||||
}
|
||||
|
||||
bool DN_UT_AllTestsPassed(DN_UTCore const *ut)
|
||||
{
|
||||
bool result = ut->num_tests_ok_in_group == ut->num_tests_in_group;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_UT_PrintTests(DN_UTCore const *ut)
|
||||
{
|
||||
for (DN_UTStr8Link *it = ut->output->next; it != ut->output; it = it->next)
|
||||
fprintf(stdout, "%.*s", (int)it->size, it->data);
|
||||
|
||||
bool all_clear = DN_UT_AllTestsPassed(ut);
|
||||
fprintf(stdout,
|
||||
"%s\n %02d/%02d tests passed -- %s\n\n" DN_UT_COLOR_RESET,
|
||||
all_clear ? DN_UT_GOOD_COLOR : DN_UT_BAD_COLOR,
|
||||
ut->num_tests_ok_in_group,
|
||||
ut->num_tests_in_group,
|
||||
all_clear ? "OK" : "FAILED");
|
||||
}
|
||||
#endif // DN_UT_IMPLEMENTATION
|
||||
+2663
-670
File diff suppressed because it is too large
Load Diff
+724
-253
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
#if DN_WITH_NET_CURL
|
||||
#define DN_NO_WINDOWS_H_REPLACEMENT_HEADER
|
||||
#endif
|
||||
|
||||
#define DN_PARANOIA_LEVEL 1
|
||||
#define DN_WITH_OS 1
|
||||
#define DN_WITH_NET 1
|
||||
#define DN_WITH_TESTS 1
|
||||
#include "dn.h"
|
||||
|
||||
#if DN_WITH_NET_CURL
|
||||
#define CURL_STATICLIB
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
#define DN_WITH_NET_EMSCRIPTEN 1
|
||||
#endif
|
||||
#include "dn.cpp"
|
||||
|
||||
#define DN_SHA3_WITH_TESTS
|
||||
#define DN_SHA3_IMPLEMENTATION
|
||||
#include "Standalone/dn_sha3.h"
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
|
||||
int main(int, char**)
|
||||
{
|
||||
DN_Core dn = {};
|
||||
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS, DN_TCInitArgsDefault());
|
||||
|
||||
DN_Arena* arena = DN_TCMainArena();
|
||||
DN_TestCore dn_test = DN_TestSuite(arena);
|
||||
DN_TestCore sha3_test = DN_SHA3_TestSuite(arena);
|
||||
DN_Str8 dn_str8 = DN_Str8FromTestCore(&dn_test, arena, DN_Str8FromTestCoreFlags_Colour);
|
||||
DN_Str8 sha3_str8 = DN_Str8FromTestCore(&sha3_test, arena, DN_Str8FromTestCoreFlags_Colour);
|
||||
DN_OS_PrintOutF("%.*s\n%.*s", DN_Str8PrintFmt(dn_str8), DN_Str8PrintFmt(sha3_str8));
|
||||
return 0;
|
||||
}
|
||||
DN_MSVC_WARNING_POP
|
||||
@@ -34,17 +34,17 @@ pushd %build_dir%
|
||||
:: GR- Disable C RTTI
|
||||
:: Oi Use CPU Intrinsics
|
||||
:: Z7 Combine multi-debug files to one debug file
|
||||
set flags=%flags% -D DN_UNIT_TESTS_WITH_KECCAK %script_dir%\Source\Extra\dn_tests_main.cpp
|
||||
set flags=%flags% %script_dir%\Source\dn_tests.cpp
|
||||
set msvc_driver_flags=-EHa -GR- -Od -Oi -Z7 -wd4201 -W4 -nologo %flags% -fsanitize=address
|
||||
|
||||
where /q emcc && (
|
||||
echo [BUILD] Emscripten emcc detected, compiling ...
|
||||
call emcc -g -msimd128 -msse2 %flags% -o %build_dir%\dn_unit_tests_emcc.js -s FETCH=1 -pthread -s ASYNCIFY=1 -lwebsocket -Wall || echo EMCC build failed&& exit /b 1
|
||||
call emcc -g -msimd128 -msse2 %flags% -o %build_dir%\dn_tests_emcc.js -s FETCH=1 -pthread -s ASYNCIFY=1 -lwebsocket -Wall || echo EMCC build failed&& exit /b 1
|
||||
)
|
||||
|
||||
where /q cl && (
|
||||
echo [BUILD] MSVC cl detected, compiling ...
|
||||
set msvc_cmd=cl -MTd %msvc_driver_flags% -analyze -Fe:dn_unit_tests_msvc -Fo:dn_unit_tests_msvc
|
||||
set msvc_cmd=cl -MTd %msvc_driver_flags% -analyze -Fe:dn_tests_msvc -Fo:dn_tests_msvc
|
||||
if exist %build_dir%/Curl/Install/lib/libcurl-d.lib (
|
||||
set msvc_cmd=!msvc_cmd! -D DN_WITH_NET_CURL=1 -I %build_dir%/Curl/Install/include %build_dir%/Curl/Install/lib/libcurl-d.lib crypt32.lib ws2_32.lib advapi32.lib wldap32.lib iphlpapi.lib secur32.lib
|
||||
)
|
||||
@@ -63,7 +63,7 @@ pushd %build_dir%
|
||||
|
||||
where /q clang-cl && (
|
||||
echo [BUILD] LLVM clang-cl detected, compiling ...
|
||||
set clang_cmd=clang-cl -MT %msvc_driver_flags% -fsanitize=undefined -Fe:dn_unit_tests_clang -link
|
||||
set clang_cmd=clang-cl -MT %msvc_driver_flags% -fsanitize=undefined -Fe:dn_tests_clang -link
|
||||
powershell -Command "$time = Measure-Command { !clang_cmd! | Out-Default }; Write-Host '[BUILD] clang-cl:'$time.TotalSeconds's'; exit $LASTEXITCODE" || echo CLANG build failed&& exit /b 1
|
||||
)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
||||
line = DN_Str8FromFmtArena(&scratch.arena, "%S// DN: Single header generator commented out => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer));
|
||||
DN_Str8 rel_include_path = DN_Str8TrimWhitespaceAround(find.after_match_to_end_of_buffer);
|
||||
DN_Str8 root_dir = DN_Str8FileDirectoryFromPath(cpp_path);
|
||||
extra_include_path = DN_OS_PathF(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffix(rel_include_path, DN_Str8Lit("\"")));
|
||||
extra_include_path = DN_OS_PathF(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffixSensitive(rel_include_path, DN_Str8Lit("\"")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user