Get latest DQN lib from side projects

This commit is contained in:
2025-02-14 00:27:42 +11:00
parent 6b403eae71
commit a844d2b992
45 changed files with 11343 additions and 10359 deletions
+124 -124
View File
@@ -10,257 +10,257 @@
// \$$$$$$ |$$ | $$ | $$ | $$$$$$\ $$$$$$$$\ $$$$$$$$\
// \______/ \__| \__| \__| \______|\________|\________|
//
// dqn_cpp_file.h -- Functions to emit C++ formatted code
// dn_cpp_file.h -- Functions to emit C++ formatted code
//
////////////////////////////////////////////////////////////////////////////////
*/
#if !defined(DQN_CPP_FILE_H)
#define DQN_CPP_FILE_H
#if !defined(DN_CPP_FILE_H)
#define DN_CPP_FILE_H
#include <stdio.h> /// printf, fputc
#include <stdarg.h> /// va_list...
#include <assert.h> /// assert
typedef struct Dqn_CppFile { ///< Maintains state for printing C++ style formatted files
typedef struct DN_CppFile { ///< Maintains state for printing C++ style formatted files
FILE *file; ///< (Write) File to print to
int indent; ///< Current indent level of the printer
int space_per_indent; ///< (Write) Number of spaces per indent
unsigned char if_chain[256]; ///
unsigned char if_chain_size; ///
} Dqn_CppFile;
} DN_CppFile;
#define Dqn_CppSpacePerIndent(cpp) ((cpp) && (cpp)->space_per_indent) ? ((cpp)->space_per_indent) : 4
#define DN_CppSpacePerIndent(cpp) ((cpp) && (cpp)->space_per_indent) ? ((cpp)->space_per_indent) : 4
/// Print the format string indented and terminate the string with a new-line.
void Dqn_CppLineV(Dqn_CppFile *cpp, char const *fmt, va_list args);
void Dqn_CppLine(Dqn_CppFile *cpp, char const *fmt, ...);
void DN_CppLineV(DN_CppFile *cpp, char const *fmt, va_list args);
void DN_CppLine(DN_CppFile *cpp, char const *fmt, ...);
/// Print the format string indented
void Dqn_CppPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args);
void Dqn_CppPrint(Dqn_CppFile *cpp, char const *fmt, ...);
void DN_CppPrintV(DN_CppFile *cpp, char const *fmt, va_list args);
void DN_CppPrint(DN_CppFile *cpp, char const *fmt, ...);
/// Print the format string
#define Dqn_CppAppend(cpp, fmt, ...) fprintf((cpp)->file, fmt, ##__VA_ARGS__)
#define Dqn_CppAppendV(cpp, fmt, args) vfprintf((cpp)->file, fmt, args)
#define DN_CppAppend(cpp, fmt, ...) fprintf((cpp)->file, fmt, ##__VA_ARGS__)
#define DN_CppAppendV(cpp, fmt, args) vfprintf((cpp)->file, fmt, args)
/// End the current line, useful after CppPrint and CppAppend
#define Dqn_CppNewLine(cpp) fputc('\n', (cpp)->file)
#define DN_CppNewLine(cpp) fputc('\n', (cpp)->file)
/// Manually modify the indent level
#define Dqn_CppIndent(cpp) (cpp)->indent++
#define Dqn_CppUnindent(cpp) (cpp)->indent--; assert((cpp)->indent >= 0)
#define DN_CppIndent(cpp) (cpp)->indent++
#define DN_CppUnindent(cpp) (cpp)->indent--; assert((cpp)->indent >= 0)
/// Block scope functions that execute a function on entry and exit of the
/// scope by exploiting the comma operator and a for loop.
///
/// @code
/// Dqn_CppEnumBlock(cpp, "abc") {
/// DN_CppEnumBlock(cpp, "abc") {
/// printf("Hello world!");
/// }
///
/// // Is equivalent to
///
/// Dqn_CppBeginBlock(cpp, "abc");
/// DN_CppBeginBlock(cpp, "abc");
/// printf("Hello world!");
/// Dqn_CppEndEnumBlock(cpp);
/// DN_CppEndEnumBlock(cpp);
/// @endcode
#define Dqn_CppEnumBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginEnumBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndEnumBlock(cpp), false))
#define DN_CppEnumBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginEnumBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndEnumBlock(cpp), false))
#define Dqn_CppForBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginForBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndForBlock(cpp), false))
#define DN_CppForBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginForBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndForBlock(cpp), false))
#define Dqn_CppWhileBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginWhileBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndWhileBlock(cpp), false))
#define DN_CppWhileBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginWhileBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndWhileBlock(cpp), false))
#define Dqn_CppIfOrElseIfBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginIfOrElseIfBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndIfOrElseIfBlock(cpp), false))
#define DN_CppIfOrElseIfBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginIfOrElseIfBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndIfOrElseIfBlock(cpp), false))
#define Dqn_CppElseBlock(cpp) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginElseBlock(cpp), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndElseBlock(cpp), false))
#define DN_CppElseBlock(cpp) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginElseBlock(cpp), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndElseBlock(cpp), false))
#define Dqn_CppFuncBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginFuncBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndFuncBlock(cpp), false))
#define DN_CppFuncBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginFuncBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndFuncBlock(cpp), false))
#define Dqn_CppStructBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginStructBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndStructBlock(cpp), false))
#define DN_CppStructBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginStructBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndStructBlock(cpp), false))
#define Dqn_CppSwitchBlock(cpp, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginSwitchBlock(cpp, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndSwitchBlock(cpp), false))
#define DN_CppSwitchBlock(cpp, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginSwitchBlock(cpp, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndSwitchBlock(cpp), false))
#define Dqn_CppBlock(cpp, ending, fmt, ...) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndBlock(cpp, ending), false))
#define DN_CppBlock(cpp, ending, fmt, ...) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
(DN_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndBlock(cpp, ending), false))
#define Dqn_CppIfChain(cpp) \
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppBeginIfChain(cpp), true); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndIfChain(cpp), false))
#define DN_CppIfChain(cpp) \
for (bool DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppBeginIfChain(cpp), true); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__); \
DN_CPP_TOKEN_PASTE_(once_, __LINE__) = (DN_CppEndIfChain(cpp), false))
/// Print the format string followed by a "{" and enter a new line whilst
/// increasing the indent level after the brace.
void Dqn_CppBeginBlock (Dqn_CppFile *cpp, bool append, char const *fmt, ...);
void Dqn_CppBeginBlockV(Dqn_CppFile *cpp, bool append, char const *fmt, va_list args);
void Dqn_CppEndBlock (Dqn_CppFile *cpp, char const *ending);
void DN_CppBeginBlock (DN_CppFile *cpp, bool append, char const *fmt, ...);
void DN_CppBeginBlockV(DN_CppFile *cpp, bool append, char const *fmt, va_list args);
void DN_CppEndBlock (DN_CppFile *cpp, char const *ending);
/// Begin/End a block, specifically for the following language constructs.
#define Dqn_CppBeginEnumBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, "enum " fmt, ##__VA_ARGS__)
#define Dqn_CppEndEnumBlock(cpp) Dqn_CppEndBlock(cpp, ";\n")
#define DN_CppBeginEnumBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, "enum " fmt, ##__VA_ARGS__)
#define DN_CppEndEnumBlock(cpp) DN_CppEndBlock(cpp, ";\n")
#define Dqn_CppBeginWhileBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, "while (" fmt ")", ##__VA_ARGS__)
#define Dqn_CppEndWhileBlock(cpp) Dqn_CppEndBlock(cpp, "\n")
#define DN_CppBeginWhileBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, "while (" fmt ")", ##__VA_ARGS__)
#define DN_CppEndWhileBlock(cpp) DN_CppEndBlock(cpp, "\n")
#define Dqn_CppBeginForBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, "for (" fmt ")", ##__VA_ARGS__)
#define Dqn_CppEndForBlock(cpp) Dqn_CppEndBlock(cpp, "\n")
#define DN_CppBeginForBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, "for (" fmt ")", ##__VA_ARGS__)
#define DN_CppEndForBlock(cpp) DN_CppEndBlock(cpp, "\n")
#define Dqn_CppBeginFuncBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__)
#define Dqn_CppEndFuncBlock(cpp) Dqn_CppEndBlock(cpp, "\n")
#define DN_CppBeginFuncBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__)
#define DN_CppEndFuncBlock(cpp) DN_CppEndBlock(cpp, "\n")
#define Dqn_CppBeginStructBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, "struct " fmt, ##__VA_ARGS__)
#define Dqn_CppEndStructBlock(cpp) Dqn_CppEndBlock(cpp, ";\n")
#define DN_CppBeginStructBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, "struct " fmt, ##__VA_ARGS__)
#define DN_CppEndStructBlock(cpp) DN_CppEndBlock(cpp, ";\n")
#define Dqn_CppBeginSwitchBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, "switch (" fmt ")", ##__VA_ARGS__)
#define Dqn_CppEndSwitchBlock(cpp) Dqn_CppEndBlock(cpp, "\n")
#define DN_CppBeginSwitchBlock(cpp, fmt, ...) DN_CppBeginBlock(cpp, false /*append*/, "switch (" fmt ")", ##__VA_ARGS__)
#define DN_CppEndSwitchBlock(cpp) DN_CppEndBlock(cpp, "\n")
void Dqn_CppBeginIfOrElseIfBlock (Dqn_CppFile *cpp, char const *fmt, ...);
#define Dqn_CppEndIfOrElseIfBlock(cpp) Dqn_CppEndBlock(cpp, "")
void DN_CppBeginIfOrElseIfBlock (DN_CppFile *cpp, char const *fmt, ...);
#define DN_CppEndIfOrElseIfBlock(cpp) DN_CppEndBlock(cpp, "")
void Dqn_CppBeginElseBlock (Dqn_CppFile *cpp);
void Dqn_CppEndElseBlock (Dqn_CppFile *cpp);
void DN_CppBeginElseBlock (DN_CppFile *cpp);
void DN_CppEndElseBlock (DN_CppFile *cpp);
#define DQN_CPP_TOKEN_PASTE2_(x, y) x ## y
#define DQN_CPP_TOKEN_PASTE_(x, y) DQN_CPP_TOKEN_PASTE2_(x, y)
#endif // DQN_CPP_FILE_H
#define DN_CPP_TOKEN_PASTE2_(x, y) x ## y
#define DN_CPP_TOKEN_PASTE_(x, y) DN_CPP_TOKEN_PASTE2_(x, y)
#endif // DN_CPP_FILE_H
#if defined(DQN_CPP_FILE_IMPLEMENTATION)
void Dqn_CppLineV(Dqn_CppFile *cpp, char const *fmt, va_list args)
#if defined(DN_CPP_FILE_IMPLEMENTATION)
void DN_CppLineV(DN_CppFile *cpp, char const *fmt, va_list args)
{
Dqn_CppPrintV(cpp, fmt, args);
Dqn_CppNewLine(cpp);
DN_CppPrintV(cpp, fmt, args);
DN_CppNewLine(cpp);
}
void Dqn_CppLine(Dqn_CppFile *cpp, char const *fmt, ...)
void DN_CppLine(DN_CppFile *cpp, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_CppLineV(cpp, fmt, args);
DN_CppLineV(cpp, fmt, args);
va_end(args);
}
void Dqn_CppPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args)
void DN_CppPrintV(DN_CppFile *cpp, char const *fmt, va_list args)
{
int space_per_indent = Dqn_CppSpacePerIndent(cpp);
int space_per_indent = DN_CppSpacePerIndent(cpp);
int spaces = fmt ? (cpp->indent * space_per_indent) : 0;
fprintf(cpp->file, "%*s", spaces, "");
vfprintf(cpp->file, fmt, args);
}
void Dqn_CppPrint(Dqn_CppFile *cpp, char const *fmt, ...)
void DN_CppPrint(DN_CppFile *cpp, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_CppPrintV(cpp, fmt, args);
DN_CppPrintV(cpp, fmt, args);
va_end(args);
}
void Dqn_CppBeginBlock(Dqn_CppFile *cpp, bool append, char const *fmt, ...)
void DN_CppBeginBlock(DN_CppFile *cpp, bool append, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_CppBeginBlockV(cpp, append, fmt, args);
DN_CppBeginBlockV(cpp, append, fmt, args);
va_end(args);
}
void Dqn_CppBeginBlockV(Dqn_CppFile *cpp, bool append, char const *fmt, va_list args)
void DN_CppBeginBlockV(DN_CppFile *cpp, bool append, char const *fmt, va_list args)
{
if (append)
Dqn_CppAppendV(cpp, fmt, args);
DN_CppAppendV(cpp, fmt, args);
else
Dqn_CppPrintV(cpp, fmt, args);
DN_CppPrintV(cpp, fmt, args);
bool empty_fmt = fmt == nullptr || strlen(fmt) == 0;
Dqn_CppAppend(cpp, "%s{\n", empty_fmt ? "" : " ");
Dqn_CppIndent(cpp);
DN_CppAppend(cpp, "%s{\n", empty_fmt ? "" : " ");
DN_CppIndent(cpp);
}
void Dqn_CppEndBlock(Dqn_CppFile *cpp, char const *ending)
void DN_CppEndBlock(DN_CppFile *cpp, char const *ending)
{
Dqn_CppUnindent(cpp);
Dqn_CppPrint(cpp, "}%s", ending);
DN_CppUnindent(cpp);
DN_CppPrint(cpp, "}%s", ending);
}
void Dqn_CppBeginIfOrElseIfBlock(Dqn_CppFile *cpp, char const *fmt, ...)
void DN_CppBeginIfOrElseIfBlock(DN_CppFile *cpp, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
assert(cpp->if_chain_size);
if (cpp->if_chain[cpp->if_chain_size - 1] == 0)
Dqn_CppPrint(cpp, "if");
DN_CppPrint(cpp, "if");
else
Dqn_CppAppend(cpp, " else if");
DN_CppAppend(cpp, " else if");
Dqn_CppAppend(cpp, " (");
Dqn_CppAppendV(cpp, fmt, args);
Dqn_CppAppend(cpp, ") {\n");
Dqn_CppIndent(cpp);
DN_CppAppend(cpp, " (");
DN_CppAppendV(cpp, fmt, args);
DN_CppAppend(cpp, ") {\n");
DN_CppIndent(cpp);
va_end(args);
cpp->if_chain[cpp->if_chain_size - 1]++;
}
void Dqn_CppBeginElseBlock(Dqn_CppFile *cpp)
void DN_CppBeginElseBlock(DN_CppFile *cpp)
{
assert(cpp->if_chain_size);
if (cpp->if_chain[cpp->if_chain_size - 1] >= 1)
Dqn_CppBeginBlock(cpp, true /*append*/, " else");
DN_CppBeginBlock(cpp, true /*append*/, " else");
}
void Dqn_CppEndElseBlock(Dqn_CppFile *cpp)
void DN_CppEndElseBlock(DN_CppFile *cpp)
{
if (cpp->if_chain[cpp->if_chain_size - 1] >= 1)
Dqn_CppEndBlock(cpp, "");
DN_CppEndBlock(cpp, "");
}
void Dqn_CppBeginIfChain(Dqn_CppFile *cpp)
void DN_CppBeginIfChain(DN_CppFile *cpp)
{
assert(cpp->if_chain_size < sizeof(cpp->if_chain)/sizeof(cpp->if_chain[0]));
cpp->if_chain_size++;
}
void Dqn_CppEndIfChain(Dqn_CppFile *cpp)
void DN_CppEndIfChain(DN_CppFile *cpp)
{
assert(cpp->if_chain_size);
if (cpp->if_chain[cpp->if_chain_size - 1] >= 1) {
Dqn_CppNewLine(cpp);
DN_CppNewLine(cpp);
}
cpp->if_chain[cpp->if_chain_size - 1] = 0;
cpp->if_chain_size--;
}
#endif // DQN_CPP_FILE_IMPLEMENTATION
#endif // DN_CPP_FILE_IMPLEMENTATION
+236 -236
View File
@@ -1,5 +1,5 @@
#if !defined(DQN_KECCAK_H)
#define DQN_KECCAK_H
#if !defined(DN_KECCAK_H)
#define DN_KECCAK_H
/*
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -13,7 +13,7 @@
// $$ | \$$\ $$$$$$$$\ \$$$$$$ |\$$$$$$ |$$ | $$ |$$ | \$$\
// \__| \__|\________| \______/ \______/ \__| \__|\__| \__|
//
// dqn_keccak.h -- FIPS202 SHA3 + non-finalized SHA3 (aka. Keccak) hashing algorithms
// dn_keccak.h -- FIPS202 SHA3 + non-finalized SHA3 (aka. Keccak) hashing algorithms
//
////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -65,31 +65,31 @@
// - Define this in one and only one C++ file to enable the implementation
// code of the header file.
//
// #define DQN_KECCAK_IMPLEMENTATION
// #define DN_KECCAK_IMPLEMENTATION
//
////////////////////////////////////////////////////////////////////////////////////////////////////
*/
#if !defined(DQN_KECCAK_MEMCPY)
#if !defined(DN_KECCAK_MEMCPY)
#include <string.h>
#define DQN_KECCAK_MEMCPY(dest, src, count) memcpy(dest, src, count)
#define DN_KECCAK_MEMCPY(dest, src, count) memcpy(dest, src, count)
#endif
#if !defined(DQN_KECCAK_MEMCMP)
#if !defined(DN_KECCAK_MEMCMP)
#include <string.h>
#define DQN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
#define DN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
#endif
#if !defined(DQN_KECCAK_MEMSET)
#if !defined(DN_KECCAK_MEMSET)
#include <string.h>
#define DQN_KECCAK_MEMSET(dest, byte, count) memset(dest, byte, count)
#define DN_KECCAK_MEMSET(dest, byte, count) memset(dest, byte, count)
#endif
#if !defined(DQN_KECCAK_ASSERT)
#if !defined(DN_KECCAK_ASSERT)
#if defined(NDEBUG)
#define DQN_KECCAK_ASSERT(expr)
#define DN_KECCAK_ASSERT(expr)
#else
#define DQN_KECCAK_ASSERT(expr) \
#define DN_KECCAK_ASSERT(expr) \
do \
{ \
if (!(expr)) \
@@ -102,43 +102,43 @@
// Use this macro in a printf-like function,
/*
Dqn_KeccakString64 string = {};
printf("%.*s\n", DQN_KECCAK_STRING64_FMT(string));
DN_KeccakString64 string = {};
printf("%.*s\n", DN_KECCAK_STRING64_FMT(string));
*/
#define DQN_KECCAK_STRING56_FMT(string) 56, string
#define DQN_KECCAK_STRING64_FMT(string) 64, string
#define DQN_KECCAK_STRING96_FMT(string) 96, string
#define DQN_KECCAK_STRING128_FMT(string) 128, string
#define DN_KECCAK_STRING56_FMT(string) 56, string
#define DN_KECCAK_STRING64_FMT(string) 64, string
#define DN_KECCAK_STRING96_FMT(string) 96, string
#define DN_KECCAK_STRING128_FMT(string) 128, string
typedef unsigned char Dqn_KeccakU8;
typedef unsigned short Dqn_KeccakU16;
typedef unsigned int Dqn_KeccakU32;
typedef unsigned int Dqn_KeccakUint;
typedef unsigned char DN_KeccakU8;
typedef unsigned short DN_KeccakU16;
typedef unsigned int DN_KeccakU32;
typedef unsigned int DN_KeccakUint;
#ifdef _MSC_VER
typedef unsigned __int64 Dqn_KeccakU64;
typedef unsigned __int64 DN_KeccakU64;
#else
typedef unsigned long long Dqn_KeccakU64;
typedef unsigned long long DN_KeccakU64;
#endif
typedef struct Dqn_KeccakBytes28 { char data[28]; } Dqn_KeccakBytes28; // 224 bit
typedef struct Dqn_KeccakBytes32 { char data[32]; } Dqn_KeccakBytes32; // 256 bit
typedef struct Dqn_KeccakBytes48 { char data[48]; } Dqn_KeccakBytes48; // 384 bit
typedef struct Dqn_KeccakBytes64 { char data[64]; } Dqn_KeccakBytes64; // 512 bit
typedef struct DN_KeccakBytes28 { char data[28]; } DN_KeccakBytes28; // 224 bit
typedef struct DN_KeccakBytes32 { char data[32]; } DN_KeccakBytes32; // 256 bit
typedef struct DN_KeccakBytes48 { char data[48]; } DN_KeccakBytes48; // 384 bit
typedef struct DN_KeccakBytes64 { char data[64]; } DN_KeccakBytes64; // 512 bit
typedef struct Dqn_KeccakString56 { char data[(sizeof(Dqn_KeccakBytes28) * 2) + 1]; } Dqn_KeccakString56;
typedef struct Dqn_KeccakString64 { char data[(sizeof(Dqn_KeccakBytes32) * 2) + 1]; } Dqn_KeccakString64;
typedef struct Dqn_KeccakString96 { char data[(sizeof(Dqn_KeccakBytes48) * 2) + 1]; } Dqn_KeccakString96;
typedef struct Dqn_KeccakString128 { char data[(sizeof(Dqn_KeccakBytes64) * 2) + 1]; } Dqn_KeccakString128;
typedef struct DN_KeccakString56 { char data[(sizeof(DN_KeccakBytes28) * 2) + 1]; } DN_KeccakString56;
typedef struct DN_KeccakString64 { char data[(sizeof(DN_KeccakBytes32) * 2) + 1]; } DN_KeccakString64;
typedef struct DN_KeccakString96 { char data[(sizeof(DN_KeccakBytes48) * 2) + 1]; } DN_KeccakString96;
typedef struct DN_KeccakString128 { char data[(sizeof(DN_KeccakBytes64) * 2) + 1]; } DN_KeccakString128;
#define DQN_KECCAK_LANE_SIZE_U64 5
typedef struct Dqn_KeccakState
#define DN_KECCAK_LANE_SIZE_U64 5
typedef struct DN_KeccakState
{
Dqn_KeccakU8 state[DQN_KECCAK_LANE_SIZE_U64 * DQN_KECCAK_LANE_SIZE_U64 * sizeof(Dqn_KeccakU64)];
DN_KeccakU8 state[DN_KECCAK_LANE_SIZE_U64 * DN_KECCAK_LANE_SIZE_U64 * sizeof(DN_KeccakU64)];
int state_size; // The number of bytes written to the state
int absorb_size; // The amount of bytes to absorb/sponge in/from the state
int hash_size_bits; // The size of the hash the context was initialised for in bits
char delimited_suffix; // The delimited suffix of the current hash
} Dqn_KeccakState;
} DN_KeccakState;
// NOTE: SHA3/Keccak Streaming API /////////////////////////////////////////////////////////////////
// Setup a hashing state for either
@@ -152,92 +152,92 @@ typedef struct Dqn_KeccakState
//
// sha3: If true, setup the state for FIPS 202 SHA3, otherwise the non-finalized version
// hash_size_bits: The number of bits to setup the context for, available sizes are 224, 256, 384 and 512.
Dqn_KeccakState Dqn_KeccakSHA3Init(bool sha3, int hash_size_bits);
DN_KeccakState DN_KeccakSHA3Init(bool sha3, int hash_size_bits);
// After initialising a 'Dqn_KeccakState' via 'Dqn_KeccakSHA3Init', iteratively
// update the hash with new data by calling 'Dqn_KeccakUpdate'. On completion,
// call 'Dqn_KeccakFinish' to generate the hash from the state. The 'dest_size'
// must be at-least the (bit-size / 8), i.e. for 'Dqn_Keccak512Init' it must be
// After initialising a 'DN_KeccakState' via 'DN_KeccakSHA3Init', iteratively
// update the hash with new data by calling 'DN_KeccakUpdate'. On completion,
// call 'DN_KeccakFinish' to generate the hash from the state. The 'dest_size'
// must be at-least the (bit-size / 8), i.e. for 'DN_Keccak512Init' it must be
// atleast (512 / 8) bytes, 64 bytes.
void Dqn_KeccakUpdate(Dqn_KeccakState *keccak, void const *data, Dqn_KeccakU64 data_size);
void Dqn_KeccakFinish(Dqn_KeccakState *keccak, void *dest, int dest_size);
void DN_KeccakUpdate(DN_KeccakState *keccak, void const *data, DN_KeccakU64 data_size);
void DN_KeccakFinish(DN_KeccakState *keccak, void *dest, int dest_size);
// NOTE: Simple API ////////////////////////////////////////////////////////////////////////////////
// Helper function that combines the Init, Update and Finish step in one shot,
// i.e. hashing a singlular contiguous buffer. Use the streaming API if data
// is split across different buffers.
void Dqn_KeccakSHA3Hash(bool sha3, int hash_size_bits, void const *src, Dqn_KeccakU64 src_size, void *dest, int dest_size);
void DN_KeccakSHA3Hash(bool sha3, int hash_size_bits, void const *src, DN_KeccakU64 src_size, void *dest, int dest_size);
#define Dqn_SHA3Hash(hash_size_bits, src, src_size, dest, dest_size) Dqn_KeccakSHA3Hash(true /*sha3*/, hash_size_bits, src, src_size, dest, dest_size)
#define Dqn_SHA3_224(src, src_size, dest, dest_size) Dqn_SHA3Hash(224, src, src_size, dest, dest_size)
#define Dqn_SHA3_256(src, src_size, dest, dest_size) Dqn_SHA3Hash(256, src, src_size, dest, dest_size)
#define Dqn_SHA3_384(src, src_size, dest, dest_size) Dqn_SHA3Hash(384, src, src_size, dest, dest_size)
#define Dqn_SHA3_512(src, src_size, dest, dest_size) Dqn_SHA3Hash(512, src, src_size, dest, dest_size)
#define DN_SHA3Hash(hash_size_bits, src, src_size, dest, dest_size) DN_KeccakSHA3Hash(true /*sha3*/, hash_size_bits, src, src_size, dest, dest_size)
#define DN_SHA3_224(src, src_size, dest, dest_size) DN_SHA3Hash(224, src, src_size, dest, dest_size)
#define DN_SHA3_256(src, src_size, dest, dest_size) DN_SHA3Hash(256, src, src_size, dest, dest_size)
#define DN_SHA3_384(src, src_size, dest, dest_size) DN_SHA3Hash(384, src, src_size, dest, dest_size)
#define DN_SHA3_512(src, src_size, dest, dest_size) DN_SHA3Hash(512, src, src_size, dest, dest_size)
#define Dqn_KeccakHash(hash_size_bits, src, src_size, dest, dest_size) Dqn_KeccakSHA3Hash(false /*sha3*/, hash_size_bits, src, src_size, dest, dest_size)
#define Dqn_Keccak224(src, src_size, dest, dest_size) Dqn_KeccakHash(224, src, src_size, dest, dest_size)
#define Dqn_Keccak256(src, src_size, dest, dest_size) Dqn_KeccakHash(256, src, src_size, dest, dest_size)
#define Dqn_Keccak384(src, src_size, dest, dest_size) Dqn_KeccakHash(384, src, src_size, dest, dest_size)
#define Dqn_Keccak512(src, src_size, dest, dest_size) Dqn_KeccakHash(512, src, src_size, dest, dest_size)
#define DN_KeccakHash(hash_size_bits, src, src_size, dest, dest_size) DN_KeccakSHA3Hash(false /*sha3*/, hash_size_bits, src, src_size, dest, dest_size)
#define DN_Keccak224(src, src_size, dest, dest_size) DN_KeccakHash(224, src, src_size, dest, dest_size)
#define DN_Keccak256(src, src_size, dest, dest_size) DN_KeccakHash(256, src, src_size, dest, dest_size)
#define DN_Keccak384(src, src_size, dest, dest_size) DN_KeccakHash(384, src, src_size, dest, dest_size)
#define DN_Keccak512(src, src_size, dest, dest_size) DN_KeccakHash(512, src, src_size, dest, dest_size)
// NOTE: SHA3 Helpers //////////////////////////////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_SHA3_224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes32 Dqn_SHA3_256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes48 Dqn_SHA3_384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes64 Dqn_SHA3_512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size);
DN_KeccakBytes28 DN_SHA3_224ToBytes28(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes32 DN_SHA3_256ToBytes32(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes48 DN_SHA3_384ToBytes48(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes64 DN_SHA3_512ToBytes64(void *bytes, DN_KeccakU64 bytes_size);
// NOTE: Keccak Helpers ////////////////////////////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_Keccak224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes32 Dqn_Keccak256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes48 Dqn_Keccak384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size);
Dqn_KeccakBytes64 Dqn_Keccak512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size);
DN_KeccakBytes28 DN_Keccak224ToBytes28(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes32 DN_Keccak256ToBytes32(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes48 DN_Keccak384ToBytes48(void *bytes, DN_KeccakU64 bytes_size);
DN_KeccakBytes64 DN_Keccak512ToBytes64(void *bytes, DN_KeccakU64 bytes_size);
#if defined(DQN_H)
// NOTE: SHA3 - Helpers for Dqn data structures ////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_SHA3_224StringToBytes28(Dqn_Str8 string);
Dqn_KeccakBytes32 Dqn_SHA3_256StringToBytes32(Dqn_Str8 string);
Dqn_KeccakBytes48 Dqn_SHA3_384StringToBytes48(Dqn_Str8 string);
Dqn_KeccakBytes64 Dqn_SHA3_512StringToBytes64(Dqn_Str8 string);
#if defined(DN_H)
// NOTE: SHA3 - Helpers for DN data structures ////////////////////////////////////////////////////
DN_KeccakBytes28 DN_SHA3_224StringToBytes28(DN_Str8 string);
DN_KeccakBytes32 DN_SHA3_256StringToBytes32(DN_Str8 string);
DN_KeccakBytes48 DN_SHA3_384StringToBytes48(DN_Str8 string);
DN_KeccakBytes64 DN_SHA3_512StringToBytes64(DN_Str8 string);
// NOTE: Keccak - Helpers for Dqn data structures //////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_Keccak224StringToBytes28(Dqn_Str8 string);
Dqn_KeccakBytes32 Dqn_Keccak256StringToBytes32(Dqn_Str8 string);
Dqn_KeccakBytes48 Dqn_Keccak384StringToBytes48(Dqn_Str8 string);
Dqn_KeccakBytes64 Dqn_Keccak512StringToBytes64(Dqn_Str8 string);
#endif // DQN_H
// NOTE: Keccak - Helpers for DN data structures //////////////////////////////////////////////////
DN_KeccakBytes28 DN_Keccak224StringToBytes28(DN_Str8 string);
DN_KeccakBytes32 DN_Keccak256StringToBytes32(DN_Str8 string);
DN_KeccakBytes48 DN_Keccak384StringToBytes48(DN_Str8 string);
DN_KeccakBytes64 DN_Keccak512StringToBytes64(DN_Str8 string);
#endif // DN_H
// NOTE: Helper functions //////////////////////////////////////////////////////////////////////////
// Convert a binary buffer into its hex representation into dest. The dest
// buffer must be large enough to contain the hex representation, i.e.
// atleast src_size * 2). This function does *not* null-terminate the buffer.
void Dqn_KeccakBytesToHex(void const *src, Dqn_KeccakU64 src_size, char *dest, Dqn_KeccakU64 dest_size);
void DN_KeccakBytesToHex(void const *src, DN_KeccakU64 src_size, char *dest, DN_KeccakU64 dest_size);
// Converts a fixed amount of bytes into a hexadecimal string. Helper functions
// that call into Dqn_KeccakBytesToHex.
// that call into DN_KeccakBytesToHex.
// return: The hexadecimal string of the bytes, null-terminated.
Dqn_KeccakString56 Dqn_KeccakBytes28ToHex(Dqn_KeccakBytes28 const *bytes);
Dqn_KeccakString64 Dqn_KeccakBytes32ToHex(Dqn_KeccakBytes32 const *bytes);
Dqn_KeccakString96 Dqn_KeccakBytes48ToHex(Dqn_KeccakBytes48 const *bytes);
Dqn_KeccakString128 Dqn_KeccakBytes64ToHex(Dqn_KeccakBytes64 const *bytes);
DN_KeccakString56 DN_KeccakBytes28ToHex(DN_KeccakBytes28 const *bytes);
DN_KeccakString64 DN_KeccakBytes32ToHex(DN_KeccakBytes32 const *bytes);
DN_KeccakString96 DN_KeccakBytes48ToHex(DN_KeccakBytes48 const *bytes);
DN_KeccakString128 DN_KeccakBytes64ToHex(DN_KeccakBytes64 const *bytes);
// Compares byte data structures for byte equality (via memcmp).
// return: 1 if the contents are equal otherwise 0.
int Dqn_KeccakBytes28Equals(Dqn_KeccakBytes28 const *a, Dqn_KeccakBytes28 const *b);
int Dqn_KeccakBytes32Equals(Dqn_KeccakBytes32 const *a, Dqn_KeccakBytes32 const *b);
int Dqn_KeccakBytes48Equals(Dqn_KeccakBytes48 const *a, Dqn_KeccakBytes48 const *b);
int Dqn_KeccakBytes64Equals(Dqn_KeccakBytes64 const *a, Dqn_KeccakBytes64 const *b);
int DN_KeccakBytes28Equals(DN_KeccakBytes28 const *a, DN_KeccakBytes28 const *b);
int DN_KeccakBytes32Equals(DN_KeccakBytes32 const *a, DN_KeccakBytes32 const *b);
int DN_KeccakBytes48Equals(DN_KeccakBytes48 const *a, DN_KeccakBytes48 const *b);
int DN_KeccakBytes64Equals(DN_KeccakBytes64 const *a, DN_KeccakBytes64 const *b);
#if defined(DQN_H) && defined(DQN_WITH_HEX)
// NOTE: Other helper functions for Dqn data structures ////////////////////////////////////////////
#if defined(DN_H) && defined(DN_WITH_HEX)
// NOTE: Other helper functions for DN data structures ////////////////////////////////////////////
// Converts a 64 character hex string into the 32 byte binary representation.
// Invalid hex characters in the string will be represented as 0.
// hex: Must be exactly a 64 character hex string.
Dqn_KeccakBytes32 Dqn_KeccakHex64StringToBytes(Dqn_Str8 hex);
#endif // DQN_H && DQN_WITH_HEX
#endif // DQN_KECCAK_H
DN_KeccakBytes32 DN_KeccakHex64StringToBytes(DN_Str8 hex);
#endif // DN_H && DN_WITH_HEX
#endif // DN_KECCAK_H
#if defined(DQN_KECCAK_IMPLEMENTATION)
Dqn_KeccakU64 const DQN_KECCAK_ROUNDS[] = {
#if defined(DN_KECCAK_IMPLEMENTATION)
DN_KeccakU64 const DN_KECCAK_ROUNDS[] = {
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000, 0x000000000000808B,
0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008A, 0x0000000000000088,
0x0000000080008009, 0x000000008000000A, 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
@@ -245,7 +245,7 @@ Dqn_KeccakU64 const DQN_KECCAK_ROUNDS[] = {
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
};
Dqn_KeccakU64 const DQN_KECCAK_ROTATIONS[][5] =
DN_KeccakU64 const DN_KECCAK_ROTATIONS[][5] =
{
{0, 36, 3, 41, 18},
{1, 44, 10, 45, 2},
@@ -254,21 +254,21 @@ Dqn_KeccakU64 const DQN_KECCAK_ROTATIONS[][5] =
{27, 20, 39, 8, 14},
};
#define DQN_KECCAK_ROL64(val, rotate) (((val) << (rotate)) | (((val) >> (64 - (rotate)))))
#define DN_KECCAK_ROL64(val, rotate) (((val) << (rotate)) | (((val) >> (64 - (rotate)))))
static void Dqn_Keccak__Permute(void *state)
static void DN_Keccak__Permute(void *state)
{
// TODO(dqn): Do some profiling on unrolling and can we SIMD some part of
// TODO(dn): Do some profiling on unrolling and can we SIMD some part of
// this? Unroll loop, look at data dependencies and investigate.
Dqn_KeccakU64 *lanes_u64 = (Dqn_KeccakU64 *)state;
DN_KeccakU64 *lanes_u64 = (DN_KeccakU64 *)state;
for (int round_index = 0; round_index < 24; round_index++)
{
#define LANE_INDEX(x, y) ((x) + ((y) * DQN_KECCAK_LANE_SIZE_U64))
// θ step //////////////////////////////////////////////////////////////////////////////////
#define LANE_INDEX(x, y) ((x) + ((y) * DN_KECCAK_LANE_SIZE_U64))
// ?? step //////////////////////////////////////////////////////////////////////////////////
#if 1
Dqn_KeccakU64 c[DQN_KECCAK_LANE_SIZE_U64];
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
DN_KeccakU64 c[DN_KECCAK_LANE_SIZE_U64];
for (int x = 0; x < DN_KECCAK_LANE_SIZE_U64; x++)
{
c[x] = lanes_u64[LANE_INDEX(x, 0)] ^
lanes_u64[LANE_INDEX(x, 1)] ^
@@ -277,87 +277,87 @@ static void Dqn_Keccak__Permute(void *state)
lanes_u64[LANE_INDEX(x, 4)];
}
Dqn_KeccakU64 d[DQN_KECCAK_LANE_SIZE_U64];
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
d[x] = c[(x + 4) % DQN_KECCAK_LANE_SIZE_U64] ^ DQN_KECCAK_ROL64(c[(x + 1) % DQN_KECCAK_LANE_SIZE_U64], 1);
DN_KeccakU64 d[DN_KECCAK_LANE_SIZE_U64];
for (int x = 0; x < DN_KECCAK_LANE_SIZE_U64; x++)
d[x] = c[(x + 4) % DN_KECCAK_LANE_SIZE_U64] ^ DN_KECCAK_ROL64(c[(x + 1) % DN_KECCAK_LANE_SIZE_U64], 1);
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
for (int y = 0; y < DN_KECCAK_LANE_SIZE_U64; y++)
for (int x = 0; x < DN_KECCAK_LANE_SIZE_U64; x++)
lanes_u64[LANE_INDEX(x, y)] ^= d[x];
#else
Dqn_KeccakU64 c[5], d[5];
DN_KeccakU64 c[5], d[5];
c[0] = lanes_u64[0 * 5 + 0] ^ lanes_u64[1 * 5 + 0] ^ lanes_u64[2 * 5 + 0] ^ lanes_u64[3 * 5 + 0] ^ lanes_u64[4 * 5 + 0];
c[1] = lanes_u64[0 * 5 + 1] ^ lanes_u64[1 * 5 + 1] ^ lanes_u64[2 * 5 + 1] ^ lanes_u64[3 * 5 + 1] ^ lanes_u64[4 * 5 + 1];
c[2] = lanes_u64[0 * 5 + 2] ^ lanes_u64[1 * 5 + 2] ^ lanes_u64[2 * 5 + 2] ^ lanes_u64[3 * 5 + 2] ^ lanes_u64[4 * 5 + 2];
c[3] = lanes_u64[0 * 5 + 3] ^ lanes_u64[1 * 5 + 3] ^ lanes_u64[2 * 5 + 3] ^ lanes_u64[3 * 5 + 3] ^ lanes_u64[4 * 5 + 3];
c[4] = lanes_u64[0 * 5 + 4] ^ lanes_u64[1 * 5 + 4] ^ lanes_u64[2 * 5 + 4] ^ lanes_u64[3 * 5 + 4] ^ lanes_u64[4 * 5 + 4];
d[0] = c[4] ^ DQN_KECCAK_ROL64(c[1], 1);
d[1] = c[0] ^ DQN_KECCAK_ROL64(c[2], 1);
d[2] = c[1] ^ DQN_KECCAK_ROL64(c[3], 1);
d[3] = c[2] ^ DQN_KECCAK_ROL64(c[4], 1);
d[4] = c[3] ^ DQN_KECCAK_ROL64(c[0], 1);
d[0] = c[4] ^ DN_KECCAK_ROL64(c[1], 1);
d[1] = c[0] ^ DN_KECCAK_ROL64(c[2], 1);
d[2] = c[1] ^ DN_KECCAK_ROL64(c[3], 1);
d[3] = c[2] ^ DN_KECCAK_ROL64(c[4], 1);
d[4] = c[3] ^ DN_KECCAK_ROL64(c[0], 1);
#endif
// ρ and π steps ///////////////////////////////////////////////////////////////////////////
Dqn_KeccakU64 b[DQN_KECCAK_LANE_SIZE_U64 * DQN_KECCAK_LANE_SIZE_U64];
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
// ?? and ?? steps ///////////////////////////////////////////////////////////////////////////
DN_KeccakU64 b[DN_KECCAK_LANE_SIZE_U64 * DN_KECCAK_LANE_SIZE_U64];
for (int y = 0; y < DN_KECCAK_LANE_SIZE_U64; y++)
{
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
for (int x = 0; x < DN_KECCAK_LANE_SIZE_U64; x++)
{
Dqn_KeccakU64 lane = lanes_u64[LANE_INDEX(x, y)];
Dqn_KeccakU64 rotate_count = DQN_KECCAK_ROTATIONS[x][y];
b[LANE_INDEX(y, (2 * x + 3 * y) % 5)] = DQN_KECCAK_ROL64(lane, rotate_count);
DN_KeccakU64 lane = lanes_u64[LANE_INDEX(x, y)];
DN_KeccakU64 rotate_count = DN_KECCAK_ROTATIONS[x][y];
b[LANE_INDEX(y, (2 * x + 3 * y) % 5)] = DN_KECCAK_ROL64(lane, rotate_count);
}
}
// χ step //////////////////////////////////////////////////////////////////////////////////
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
// ?? step //////////////////////////////////////////////////////////////////////////////////
for (int y = 0; y < DN_KECCAK_LANE_SIZE_U64; y++)
{
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
for (int x = 0; x < DN_KECCAK_LANE_SIZE_U64; x++)
{
Dqn_KeccakU64 rhs = ~b[LANE_INDEX((x + 1) % 5, y)] &
DN_KeccakU64 rhs = ~b[LANE_INDEX((x + 1) % 5, y)] &
b[LANE_INDEX((x + 2) % 5, y)];
lanes_u64[LANE_INDEX(x, y)] = b[LANE_INDEX(x, y)] ^ rhs;
}
}
// ι step //////////////////////////////////////////////////////////////////////////////////
lanes_u64[LANE_INDEX(0, 0)] ^= DQN_KECCAK_ROUNDS[round_index];
// ?? step //////////////////////////////////////////////////////////////////////////////////
lanes_u64[LANE_INDEX(0, 0)] ^= DN_KECCAK_ROUNDS[round_index];
#undef LANE_INDEX
#undef DQN_KECCAK_ROL64
#undef DN_KECCAK_ROL64
}
}
// NOTE: Streaming API /////////////////////////////////////////////////////////////////////////////
Dqn_KeccakState Dqn_KeccakSHA3Init(bool sha3, int hash_size_bits)
DN_KeccakState DN_KeccakSHA3Init(bool sha3, int hash_size_bits)
{
char const SHA3_DELIMITED_SUFFIX = 0x06;
char const KECCAK_DELIMITED_SUFFIX = 0x01;
int const bitrate = 1600 - (hash_size_bits * 2);
#if defined(__cplusplus)
Dqn_KeccakState result = {};
DN_KeccakState result = {};
#else
Dqn_KeccakState result = {0};
DN_KeccakState result = {0};
#endif
result.hash_size_bits = hash_size_bits;
result.absorb_size = bitrate / 8;
result.delimited_suffix = sha3 ? SHA3_DELIMITED_SUFFIX : KECCAK_DELIMITED_SUFFIX;
DQN_KECCAK_ASSERT(bitrate + (hash_size_bits * 2) /*capacity*/ == 1600);
DN_KECCAK_ASSERT(bitrate + (hash_size_bits * 2) /*capacity*/ == 1600);
return result;
}
void Dqn_KeccakUpdate(Dqn_KeccakState *keccak, void const *data, Dqn_KeccakU64 data_size)
void DN_KeccakUpdate(DN_KeccakState *keccak, void const *data, DN_KeccakU64 data_size)
{
Dqn_KeccakU8 *state = keccak->state;
Dqn_KeccakU8 const *ptr = (Dqn_KeccakU8 *)data;
Dqn_KeccakU64 ptr_size = data_size;
DN_KeccakU8 *state = keccak->state;
DN_KeccakU8 const *ptr = (DN_KeccakU8 *)data;
DN_KeccakU64 ptr_size = data_size;
while (ptr_size > 0)
{
Dqn_KeccakU64 space = keccak->absorb_size - keccak->state_size;
DN_KeccakU64 space = keccak->absorb_size - keccak->state_size;
int bytes_to_absorb = (int)(space < ptr_size ? space : ptr_size);
for (int index = 0; index < bytes_to_absorb; index++)
@@ -369,23 +369,23 @@ void Dqn_KeccakUpdate(Dqn_KeccakState *keccak, void const *data, Dqn_KeccakU64 d
if (keccak->state_size >= keccak->absorb_size)
{
DQN_KECCAK_ASSERT(keccak->state_size == keccak->absorb_size);
Dqn_Keccak__Permute(state);
DN_KECCAK_ASSERT(keccak->state_size == keccak->absorb_size);
DN_Keccak__Permute(state);
keccak->state_size = 0;
}
}
}
void Dqn_KeccakFinish(Dqn_KeccakState *keccak, void *dest, int dest_size)
void DN_KeccakFinish(DN_KeccakState *keccak, void *dest, int dest_size)
{
DQN_KECCAK_ASSERT(dest_size >= keccak->hash_size_bits / 8);
DN_KECCAK_ASSERT(dest_size >= keccak->hash_size_bits / 8);
// Sponge Finalization Step: Final padding bit /////////////////////////////////////////////////
int const INDEX_OF_0X80_BYTE = keccak->absorb_size - 1;
int const delimited_suffix_index = keccak->state_size;
DQN_KECCAK_ASSERT(delimited_suffix_index < keccak->absorb_size);
DN_KECCAK_ASSERT(delimited_suffix_index < keccak->absorb_size);
Dqn_KeccakU8 *state = keccak->state;
DN_KeccakU8 *state = keccak->state;
state[delimited_suffix_index] ^= keccak->delimited_suffix;
// NOTE: In the reference implementation, it checks that if the
@@ -398,16 +398,16 @@ void Dqn_KeccakFinish(Dqn_KeccakState *keccak, void *dest, int dest_size)
// this from the implementation here.
state[INDEX_OF_0X80_BYTE] ^= 0x80;
Dqn_Keccak__Permute(state);
DN_Keccak__Permute(state);
// Squeeze Step: Squeeze bytes from the state into our hash ////////////////////////////////////
Dqn_KeccakU8 *dest_u8 = (Dqn_KeccakU8 *)dest;
DN_KeccakU8 *dest_u8 = (DN_KeccakU8 *)dest;
int const squeeze_count = dest_size / keccak->absorb_size;
int squeeze_index = 0;
for (; squeeze_index < squeeze_count; squeeze_index++)
{
if (squeeze_index) Dqn_Keccak__Permute(state);
DQN_KECCAK_MEMCPY(dest_u8, state, keccak->absorb_size);
if (squeeze_index) DN_Keccak__Permute(state);
DN_KECCAK_MEMCPY(dest_u8, state, keccak->absorb_size);
dest_u8 += keccak->absorb_size;
}
@@ -415,147 +415,147 @@ void Dqn_KeccakFinish(Dqn_KeccakState *keccak, void *dest, int dest_size)
int const remainder = dest_size % keccak->absorb_size;
if (remainder)
{
if (squeeze_index) Dqn_Keccak__Permute(state);
DQN_KECCAK_MEMCPY(dest_u8, state, remainder);
if (squeeze_index) DN_Keccak__Permute(state);
DN_KECCAK_MEMCPY(dest_u8, state, remainder);
}
}
void Dqn_KeccakSHA3Hash(bool sha3, int hash_size_bits, void const *src, Dqn_KeccakU64 src_size, void *dest, int dest_size)
void DN_KeccakSHA3Hash(bool sha3, int hash_size_bits, void const *src, DN_KeccakU64 src_size, void *dest, int dest_size)
{
Dqn_KeccakState keccak = Dqn_KeccakSHA3Init(sha3, hash_size_bits);
Dqn_KeccakUpdate(&keccak, src, src_size);
Dqn_KeccakFinish(&keccak, dest, dest_size);
DN_KeccakState keccak = DN_KeccakSHA3Init(sha3, hash_size_bits);
DN_KeccakUpdate(&keccak, src, src_size);
DN_KeccakFinish(&keccak, dest, dest_size);
}
// NOTE: SHA3 Helpers //////////////////////////////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_SHA3_224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes28 DN_SHA3_224ToBytes28(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes28 result;
Dqn_SHA3_224(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes28 result;
DN_SHA3_224(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes32 Dqn_SHA3_256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes32 DN_SHA3_256ToBytes32(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes32 result;
Dqn_SHA3_256(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes32 result;
DN_SHA3_256(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes48 Dqn_SHA3_384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes48 DN_SHA3_384ToBytes48(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes48 result;
Dqn_SHA3_384(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes48 result;
DN_SHA3_384(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes64 Dqn_SHA3_512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes64 DN_SHA3_512ToBytes64(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes64 result;
Dqn_SHA3_512(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes64 result;
DN_SHA3_512(bytes, bytes_size, result.data, sizeof(result));
return result;
}
// NOTE: Keccak Helpers ////////////////////////////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_Keccak224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes28 DN_Keccak224ToBytes28(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes28 result;
Dqn_Keccak224(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes28 result;
DN_Keccak224(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes32 Dqn_Keccak256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes32 DN_Keccak256ToBytes32(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes32 result;
Dqn_Keccak256(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes32 result;
DN_Keccak256(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes48 Dqn_Keccak384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes48 DN_Keccak384ToBytes48(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes48 result;
Dqn_Keccak384(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes48 result;
DN_Keccak384(bytes, bytes_size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes64 Dqn_Keccak512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size)
DN_KeccakBytes64 DN_Keccak512ToBytes64(void *bytes, DN_KeccakU64 bytes_size)
{
Dqn_KeccakBytes64 result;
Dqn_Keccak512(bytes, bytes_size, result.data, sizeof(result));
DN_KeccakBytes64 result;
DN_Keccak512(bytes, bytes_size, result.data, sizeof(result));
return result;
}
#if defined(DQN_H)
// NOTE: SHA3 - Helpers for Dqn data structures ////////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_SHA3_224StringToBytes28(Dqn_Str8 string)
#if defined(DN_H)
// NOTE: SHA3 - Helpers for DN data structures ////////////////////////////////////////////////////
DN_KeccakBytes28 DN_SHA3_224StringToBytes28(DN_Str8 string)
{
Dqn_KeccakBytes28 result;
Dqn_SHA3_224(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes28 result;
DN_SHA3_224(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes32 Dqn_SHA3_256StringToBytes32(Dqn_Str8 string)
DN_KeccakBytes32 DN_SHA3_256StringToBytes32(DN_Str8 string)
{
Dqn_KeccakBytes32 result;
Dqn_SHA3_256(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes32 result;
DN_SHA3_256(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes48 Dqn_SHA3_384StringToBytes48(Dqn_Str8 string)
DN_KeccakBytes48 DN_SHA3_384StringToBytes48(DN_Str8 string)
{
Dqn_KeccakBytes48 result;
Dqn_SHA3_384(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes48 result;
DN_SHA3_384(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes64 Dqn_SHA3_512StringToBytes64(Dqn_Str8 string)
DN_KeccakBytes64 DN_SHA3_512StringToBytes64(DN_Str8 string)
{
Dqn_KeccakBytes64 result;
Dqn_SHA3_512(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes64 result;
DN_SHA3_512(string.data, string.size, result.data, sizeof(result));
return result;
}
#endif // DQN_H
#endif // DN_H
#if defined(DQN_H)
// NOTE: Keccak - Helpers for Dqn data structures //////////////////////////////////////////////////
Dqn_KeccakBytes28 Dqn_Keccak224StringToBytes28(Dqn_Str8 string)
#if defined(DN_H)
// NOTE: Keccak - Helpers for DN data structures //////////////////////////////////////////////////
DN_KeccakBytes28 DN_Keccak224StringToBytes28(DN_Str8 string)
{
Dqn_KeccakBytes28 result;
Dqn_Keccak224(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes28 result;
DN_Keccak224(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes32 Dqn_Keccak256StringToBytes32(Dqn_Str8 string)
DN_KeccakBytes32 DN_Keccak256StringToBytes32(DN_Str8 string)
{
Dqn_KeccakBytes32 result;
Dqn_Keccak256(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes32 result;
DN_Keccak256(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes48 Dqn_Keccak384StringToBytes48(Dqn_Str8 string)
DN_KeccakBytes48 DN_Keccak384StringToBytes48(DN_Str8 string)
{
Dqn_KeccakBytes48 result;
Dqn_Keccak384(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes48 result;
DN_Keccak384(string.data, string.size, result.data, sizeof(result));
return result;
}
Dqn_KeccakBytes64 Dqn_Keccak512StringToBytes64(Dqn_Str8 string)
DN_KeccakBytes64 DN_Keccak512StringToBytes64(DN_Str8 string)
{
Dqn_KeccakBytes64 result;
Dqn_Keccak512(string.data, string.size, result.data, sizeof(result));
DN_KeccakBytes64 result;
DN_Keccak512(string.data, string.size, result.data, sizeof(result));
return result;
}
#endif // DQN_H
#endif // DN_H
// NOTE: Helper functions //////////////////////////////////////////////////////////////////////////
void Dqn_KeccakBytesToHex(void const *src, Dqn_KeccakU64 src_size, char *dest, Dqn_KeccakU64 dest_size)
void DN_KeccakBytesToHex(void const *src, DN_KeccakU64 src_size, char *dest, DN_KeccakU64 dest_size)
{
(void)src_size; (void)dest_size;
DQN_KECCAK_ASSERT(dest_size >= src_size * 2);
DN_KECCAK_ASSERT(dest_size >= src_size * 2);
unsigned char *src_u8 = (unsigned char *)src;
for (Dqn_KeccakU64 src_index = 0, dest_index = 0;
for (DN_KeccakU64 src_index = 0, dest_index = 0;
src_index < src_size;
src_index += 1, dest_index += 2)
{
@@ -567,70 +567,70 @@ void Dqn_KeccakBytesToHex(void const *src, Dqn_KeccakU64 src_size, char *dest, D
}
}
Dqn_KeccakString56 Dqn_KeccakBytes28ToHex(Dqn_KeccakBytes28 const *bytes)
DN_KeccakString56 DN_KeccakBytes28ToHex(DN_KeccakBytes28 const *bytes)
{
Dqn_KeccakString56 result;
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
DN_KeccakString56 result;
DN_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
result.data[sizeof(result.data) - 1] = 0;
return result;
}
Dqn_KeccakString64 Dqn_KeccakBytes32ToHex(Dqn_KeccakBytes32 const *bytes)
DN_KeccakString64 DN_KeccakBytes32ToHex(DN_KeccakBytes32 const *bytes)
{
Dqn_KeccakString64 result;
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
DN_KeccakString64 result;
DN_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
result.data[sizeof(result.data) - 1] = 0;
return result;
}
Dqn_KeccakString96 Dqn_KeccakBytes48ToHex(Dqn_KeccakBytes48 const *bytes)
DN_KeccakString96 DN_KeccakBytes48ToHex(DN_KeccakBytes48 const *bytes)
{
Dqn_KeccakString96 result;
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
DN_KeccakString96 result;
DN_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
result.data[sizeof(result.data) - 1] = 0;
return result;
}
Dqn_KeccakString128 Dqn_KeccakBytes64ToHex(Dqn_KeccakBytes64 const *bytes)
DN_KeccakString128 DN_KeccakBytes64ToHex(DN_KeccakBytes64 const *bytes)
{
Dqn_KeccakString128 result;
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
DN_KeccakString128 result;
DN_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
result.data[sizeof(result.data) - 1] = 0;
return result;
}
int Dqn_KeccakBytes28Equals(Dqn_KeccakBytes28 const *a, Dqn_KeccakBytes28 const *b)
int DN_KeccakBytes28Equals(DN_KeccakBytes28 const *a, DN_KeccakBytes28 const *b)
{
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
int result = DN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
return result;
}
int Dqn_KeccakBytes32Equals(Dqn_KeccakBytes32 const *a, Dqn_KeccakBytes32 const *b)
int DN_KeccakBytes32Equals(DN_KeccakBytes32 const *a, DN_KeccakBytes32 const *b)
{
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
int result = DN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
return result;
}
int Dqn_KeccakBytes48Equals(Dqn_KeccakBytes48 const *a, Dqn_KeccakBytes48 const *b)
int DN_KeccakBytes48Equals(DN_KeccakBytes48 const *a, DN_KeccakBytes48 const *b)
{
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
int result = DN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
return result;
}
int Dqn_KeccakBytes64Equals(Dqn_KeccakBytes64 const *a, Dqn_KeccakBytes64 const *b)
int DN_KeccakBytes64Equals(DN_KeccakBytes64 const *a, DN_KeccakBytes64 const *b)
{
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
int result = DN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
return result;
}
#if defined(DQN_H) && defined(DQN_WITH_HEX)
// NOTE: Other helper functions for Dqn data structures ////////////////////////////////////////////
Dqn_KeccakBytes32 Dqn_KeccakHex64StringToBytes(Dqn_Str8 hex)
#if defined(DN_H) && defined(DN_WITH_HEX)
// NOTE: Other helper functions for DN data structures ////////////////////////////////////////////
DN_KeccakBytes32 DN_KeccakHex64StringToBytes(DN_Str8 hex)
{
DQN_KECCAK_ASSERT(hex.size == 64);
Dqn_KeccakBytes32 result;
Dqn_Hex_CString8ToByteBuffer(hex.data, hex.size, result.data, sizeof(result));
DN_KECCAK_ASSERT(hex.size == 64);
DN_KeccakBytes32 result;
DN_Hex_CString8ToByteBuffer(hex.data, hex.size, result.data, sizeof(result));
return result;
}
#endif // DQN_H && DQN_WITH_HEX
#endif // DQN_KECCAK_IMPLEMENTATION
#endif // DN_H && DN_WITH_HEX
#endif // DN_KECCAK_IMPLEMENTATION
+78 -78
View File
@@ -1,5 +1,5 @@
#if !defined(DQN_UTEST_H)
#define DQN_UTEST_H
#if !defined(DN_UTEST_H)
#define DN_UTEST_H
/*
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -13,7 +13,7 @@
// \$$$$$$ | $$ | $$$$$$$$\ \$$$$$$ | $$ |
// \______/ \__| \________| \______/ \__|
//
// dqn_utest.h -- Extremely minimal unit testing framework
// dn_utest.h -- Extremely minimal unit testing framework
//
////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -22,28 +22,28 @@
//
// NOTE: Configuration /////////////////////////////////////////////////////////////////////////////
//
// #define DQN_UTEST_IMPLEMENTATION
// #define DN_UTEST_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 DQN_UTEST_RESULT_LPAD
// #define DN_UTEST_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 DQN_UTEST_RESULT_PAD_CHAR
// #define DN_UTEST_RESULT_PAD_CHAR
// Define this to a character to specify the default character to use for
// padding. By default this is '.'
//
// #define DQN_UTEST_SPACING
// #define DN_UTEST_SPACING
// Define this to a number to specify the number of spaces between the group
// declaration and the test output in the group.
//
// #define DQN_UTEST_BAD_COLOR
// #define DN_UTEST_BAD_COLOR
// Define this to a terminal color code to specify what color errors will be
// presented as.
//
// #define DQN_UTEST_GOOD_COLOR
// #define DN_UTEST_GOOD_COLOR
// Define this to a terminal color code to specify what color sucess will be
// presented as.
//
@@ -56,114 +56,114 @@
#include <assert.h>
#include <string.h>
#if !defined(DQN_UTEST_RESULT_LPAD)
#define DQN_UTEST_RESULT_LPAD 90
#if !defined(DN_UTEST_RESULT_LPAD)
#define DN_UTEST_RESULT_LPAD 90
#endif
#if !defined(DQN_UTEST_RESULT_PAD_CHAR)
#define DQN_UTEST_RESULT_PAD_CHAR '.'
#if !defined(DN_UTEST_RESULT_PAD_CHAR)
#define DN_UTEST_RESULT_PAD_CHAR '.'
#endif
#if !defined(DQN_UTEST_SPACING)
#define DQN_UTEST_SPACING 2
#if !defined(DN_UTEST_SPACING)
#define DN_UTEST_SPACING 2
#endif
#if !defined(DQN_UTEST_BAD_COLOR)
#define DQN_UTEST_BAD_COLOR "\x1b[31m"
#if !defined(DN_UTEST_BAD_COLOR)
#define DN_UTEST_BAD_COLOR "\x1b[31m"
#endif
#if !defined(DQN_UTEST_GOOD_COLOR)
#define DQN_UTEST_GOOD_COLOR "\x1b[32m"
#if !defined(DN_UTEST_GOOD_COLOR)
#define DN_UTEST_GOOD_COLOR "\x1b[32m"
#endif
#define DQN_UTEST_COLOR_RESET "\x1b[0m"
#define DN_UTEST_COLOR_RESET "\x1b[0m"
#define DQN_UTEST_GROUP(test, fmt, ...) \
for (Dqn_UTest *test_var_ = (printf(fmt "\n", ## __VA_ARGS__), &test); \
#define DN_UTEST_GROUP(test, fmt, ...) \
for (DN_UTest *test_var_ = (printf(fmt "\n", ## __VA_ARGS__), &test); \
test_var_ != nullptr; \
Dqn_UTest_PrintStats(&test), test_var_ = nullptr)
DN_UTest_PrintStats(&test), test_var_ = nullptr)
#define DQN_UTEST_TEST(fmt, ...) \
for (int dummy_ = (Dqn_UTest_Begin(test_var_, fmt, ## __VA_ARGS__), 0); \
(void)dummy_, test_var_->state == Dqn_UTestState_TestBegun; \
Dqn_UTest_End(test_var_))
#define DN_UTEST_TEST(fmt, ...) \
for (int dummy_ = (DN_UTest_Begin(test_var_, fmt, ## __VA_ARGS__), 0); \
(void)dummy_, test_var_->state == DN_UTestState_TestBegun; \
DN_UTest_End(test_var_))
#define DQN_UTEST_ASSERTF(test, expr, fmt, ...) \
DQN_UTEST_ASSERTF_AT((test), __FILE__, __LINE__, (expr), fmt, ##__VA_ARGS__)
#define DN_UTEST_ASSERTF(test, expr, fmt, ...) \
DN_UTEST_ASSERTF_AT((test), __FILE__, __LINE__, (expr), fmt, ##__VA_ARGS__)
#define DQN_UTEST_ASSERT(test, expr) \
DQN_UTEST_ASSERT_AT((test), __FILE__, __LINE__, (expr))
#define DN_UTEST_ASSERT(test, expr) \
DN_UTEST_ASSERT_AT((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 DQN_UTEST_LOG(fmt, ...) \
fprintf(stdout, "%*s" fmt "\n", DQN_UTEST_SPACING * 2, "", ##__VA_ARGS__)
#define DN_UTEST_LOG(fmt, ...) \
fprintf(stdout, "%*s" fmt "\n", DN_UTEST_SPACING * 2, "", ##__VA_ARGS__)
#define DQN_UTEST_ASSERTF_AT(test, file, line, expr, fmt, ...) \
#define DN_UTEST_ASSERTF_AT(test, file, line, expr, fmt, ...) \
do { \
if (!(expr)) { \
(test)->state = Dqn_UTestState_TestFailed; \
(test)->state = DN_UTestState_TestFailed; \
fprintf(stderr, \
"%*sAssertion Triggered\n" \
"%*sFile: %s:%d\n" \
"%*sExpression: [" #expr "]\n" \
"%*sReason: " fmt "\n\n", \
DQN_UTEST_SPACING * 2, \
DN_UTEST_SPACING * 2, \
"", \
DQN_UTEST_SPACING * 3, \
DN_UTEST_SPACING * 3, \
"", \
file, \
line, \
DQN_UTEST_SPACING * 3, \
DN_UTEST_SPACING * 3, \
"", \
DQN_UTEST_SPACING * 3, \
DN_UTEST_SPACING * 3, \
"", \
##__VA_ARGS__); \
} \
} while (0)
#define DQN_UTEST_ASSERT_AT(test, file, line, expr) \
#define DN_UTEST_ASSERT_AT(test, file, line, expr) \
do { \
if (!(expr)) { \
(test)->state = Dqn_UTestState_TestFailed; \
(test)->state = DN_UTestState_TestFailed; \
fprintf(stderr, \
"%*sFile: %s:%d\n" \
"%*sExpression: [" #expr "]\n\n", \
DQN_UTEST_SPACING * 2, \
DN_UTEST_SPACING * 2, \
"", \
file, \
line, \
DQN_UTEST_SPACING * 2, \
DN_UTEST_SPACING * 2, \
""); \
} \
} while (0)
// NOTE: Header ////////////////////////////////////////////////////////////////////////////////////
typedef enum Dqn_UTestState {
Dqn_UTestState_Nil,
Dqn_UTestState_TestBegun,
Dqn_UTestState_TestFailed,
} Dqn_UTestState;
typedef enum DN_UTestState {
DN_UTestState_Nil,
DN_UTestState_TestBegun,
DN_UTestState_TestFailed,
} DN_UTestState;
typedef struct Dqn_UTest {
typedef struct DN_UTest {
int num_tests_in_group;
int num_tests_ok_in_group;
Dqn_UTestState state;
DN_UTestState state;
bool finished;
char name[256];
size_t name_size;
} Dqn_UTest;
} DN_UTest;
void Dqn_UTest_PrintStats(Dqn_UTest *test);
void Dqn_UTest_BeginV(Dqn_UTest *test, char const *fmt, va_list args);
void Dqn_UTest_Begin(Dqn_UTest *test, char const *fmt, ...);
void Dqn_UTest_End(Dqn_UTest *test);
#endif // DQN_UTEST_H
void DN_UTest_PrintStats(DN_UTest *test);
void DN_UTest_BeginV(DN_UTest *test, char const *fmt, va_list args);
void DN_UTest_Begin(DN_UTest *test, char const *fmt, ...);
void DN_UTest_End(DN_UTest *test);
#endif // DN_UTEST_H
// NOTE: Implementation ////////////////////////////////////////////////////////////////////////////
#if defined(DQN_UTEST_IMPLEMENTATION)
void Dqn_UTest_PrintStats(Dqn_UTest *test)
#if defined(DN_UTEST_IMPLEMENTATION)
void DN_UTest_PrintStats(DN_UTest *test)
{
if (test->finished)
return;
@@ -171,21 +171,21 @@ void Dqn_UTest_PrintStats(Dqn_UTest *test)
test->finished = true;
bool all_clear = test->num_tests_ok_in_group == test->num_tests_in_group;
fprintf(stdout,
"%s\n %02d/%02d tests passed -- %s\n\n" DQN_UTEST_COLOR_RESET,
all_clear ? DQN_UTEST_GOOD_COLOR : DQN_UTEST_BAD_COLOR,
"%s\n %02d/%02d tests passed -- %s\n\n" DN_UTEST_COLOR_RESET,
all_clear ? DN_UTEST_GOOD_COLOR : DN_UTEST_BAD_COLOR,
test->num_tests_ok_in_group,
test->num_tests_in_group,
all_clear ? "OK" : "FAILED");
}
void Dqn_UTest_BeginV(Dqn_UTest *test, char const *fmt, va_list args)
void DN_UTest_BeginV(DN_UTest *test, char const *fmt, va_list args)
{
assert(test->state == Dqn_UTestState_Nil &&
assert(test->state == DN_UTestState_Nil &&
"Nesting a unit test within another unit test is not allowed, ensure"
"the first test has finished by calling Dqn_UTest_End");
"the first test has finished by calling DN_UTest_End");
test->num_tests_in_group++;
test->state = Dqn_UTestState_TestBegun;
test->state = DN_UTestState_TestBegun;
test->name_size = 0;
{
@@ -199,32 +199,32 @@ void Dqn_UTest_BeginV(Dqn_UTest *test, char const *fmt, va_list args)
vsnprintf(test->name, sizeof(test->name), fmt, args);
}
void Dqn_UTest_Begin(Dqn_UTest *test, char const *fmt, ...)
void DN_UTest_Begin(DN_UTest *test, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_UTest_BeginV(test, fmt, args);
DN_UTest_BeginV(test, fmt, args);
va_end(args);
}
void Dqn_UTest_End(Dqn_UTest *test)
void DN_UTest_End(DN_UTest *test)
{
assert(test->state != Dqn_UTestState_Nil && "Test was marked as ended but a test was never commenced using Dqn_UTest_Begin");
size_t pad_size = DQN_UTEST_RESULT_LPAD - (DQN_UTEST_SPACING + test->name_size);
assert(test->state != DN_UTestState_Nil && "Test was marked as ended but a test was never commenced using DN_UTest_Begin");
size_t pad_size = DN_UTEST_RESULT_LPAD - (DN_UTEST_SPACING + test->name_size);
if (pad_size < 0)
pad_size = 0;
char pad_buffer[DQN_UTEST_RESULT_LPAD] = {};
memset(pad_buffer, DQN_UTEST_RESULT_PAD_CHAR, pad_size);
char pad_buffer[DN_UTEST_RESULT_LPAD] = {};
memset(pad_buffer, DN_UTEST_RESULT_PAD_CHAR, pad_size);
printf("%*s%.*s%.*s", DQN_UTEST_SPACING, "", (int)test->name_size, test->name, (int)pad_size, pad_buffer);
if (test->state == Dqn_UTestState_TestFailed) {
printf(DQN_UTEST_BAD_COLOR " FAILED");
printf("%*s%.*s%.*s", DN_UTEST_SPACING, "", (int)test->name_size, test->name, (int)pad_size, pad_buffer);
if (test->state == DN_UTestState_TestFailed) {
printf(DN_UTEST_BAD_COLOR " FAILED");
} else {
printf(DQN_UTEST_GOOD_COLOR " OK");
printf(DN_UTEST_GOOD_COLOR " OK");
test->num_tests_ok_in_group++;
}
printf(DQN_UTEST_COLOR_RESET "\n");
test->state = Dqn_UTestState_Nil;
printf(DN_UTEST_COLOR_RESET "\n");
test->state = DN_UTestState_Nil;
}
#endif // DQN_UTEST_IMPLEMENTATION
#endif // DN_UTEST_IMPLEMENTATION