2021-09-19 11:49:56 +00:00
|
|
|
|
#if !defined(DQN_KECCAK_H)
|
|
|
|
|
#define DQN_KECCAK_H
|
2024-02-25 13:15:09 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// $$\ $$\ $$$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\
|
|
|
|
|
// $$ | $$ |$$ _____|$$ __$$\ $$ __$$\ $$ __$$\ $$ | $$ |
|
|
|
|
|
// $$ |$$ / $$ | $$ / \__|$$ / \__|$$ / $$ |$$ |$$ /
|
|
|
|
|
// $$$$$ / $$$$$\ $$ | $$ | $$$$$$$$ |$$$$$ /
|
|
|
|
|
// $$ $$< $$ __| $$ | $$ | $$ __$$ |$$ $$<
|
|
|
|
|
// $$ |\$$\ $$ | $$ | $$\ $$ | $$\ $$ | $$ |$$ |\$$\
|
|
|
|
|
// $$ | \$$\ $$$$$$$$\ \$$$$$$ |\$$$$$$ |$$ | $$ |$$ | \$$\
|
|
|
|
|
// \__| \__|\________| \______/ \______/ \__| \__|\__| \__|
|
|
|
|
|
//
|
|
|
|
|
// dqn_keccak.h -- FIPS202 SHA3 + non-finalized SHA3 (aka. Keccak) hashing algorithms
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2021-09-19 11:49:56 +00:00
|
|
|
|
// 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).
|
|
|
|
|
//
|
2024-02-25 13:15:09 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// MIT License
|
|
|
|
|
//
|
2021-09-19 11:49:56 +00:00
|
|
|
|
// Copyright (c) 2021 github.com/doy-lee
|
|
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
//
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
|
//
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
// SOFTWARE.
|
|
|
|
|
//
|
2024-02-25 13:15:09 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// $$$$$$\ $$$$$$$\ $$$$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\
|
|
|
|
|
// $$ __$$\ $$ __$$\\__$$ __|\_$$ _|$$ __$$\ $$$\ $$ |$$ __$$\
|
|
|
|
|
// $$ / $$ |$$ | $$ | $$ | $$ | $$ / $$ |$$$$\ $$ |$$ / \__|
|
|
|
|
|
// $$ | $$ |$$$$$$$ | $$ | $$ | $$ | $$ |$$ $$\$$ |\$$$$$$\
|
|
|
|
|
// $$ | $$ |$$ ____/ $$ | $$ | $$ | $$ |$$ \$$$$ | \____$$\
|
|
|
|
|
// $$ | $$ |$$ | $$ | $$ | $$ | $$ |$$ |\$$$ |$$\ $$ |
|
|
|
|
|
// $$$$$$ |$$ | $$ | $$$$$$\ $$$$$$ |$$ | \$$ |\$$$$$$ |
|
|
|
|
|
// \______/ \__| \__| \______| \______/ \__| \__| \______/
|
|
|
|
|
//
|
|
|
|
|
// Options -- Compile time build customisation
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// - Define this in one and only one C++ file to enable the implementation
|
|
|
|
|
// code of the header file.
|
|
|
|
|
//
|
|
|
|
|
// #define DQN_KECCAK_IMPLEMENTATION
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if !defined(DQN_KECCAK_MEMCPY)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#include <string.h>
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#define DQN_KECCAK_MEMCPY(dest, src, count) memcpy(dest, src, count)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !defined(DQN_KECCAK_MEMCMP)
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#define DQN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if !defined(DQN_KECCAK_MEMSET)
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#define DQN_KECCAK_MEMSET(dest, byte, count) memset(dest, byte, count)
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#if !defined(DQN_KECCAK_ASSERT)
|
|
|
|
|
#if defined(NDEBUG)
|
|
|
|
|
#define DQN_KECCAK_ASSERT(expr)
|
|
|
|
|
#else
|
2023-07-04 14:04:53 +00:00
|
|
|
|
#define DQN_KECCAK_ASSERT(expr) \
|
2021-09-19 11:49:56 +00:00
|
|
|
|
do \
|
|
|
|
|
{ \
|
|
|
|
|
if (!(expr)) \
|
|
|
|
|
{ \
|
|
|
|
|
(*(volatile int *)0) = 0; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Use this macro in a printf-like function,
|
|
|
|
|
/*
|
|
|
|
|
Dqn_KeccakString64 string = {};
|
|
|
|
|
printf("%.*s\n", DQN_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
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
typedef unsigned char Dqn_KeccakU8;
|
|
|
|
|
typedef unsigned short Dqn_KeccakU16;
|
|
|
|
|
typedef unsigned int Dqn_KeccakU32;
|
|
|
|
|
typedef unsigned int Dqn_KeccakUint;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#ifdef _MSC_VER
|
2021-12-16 13:07:33 +00:00
|
|
|
|
typedef unsigned __int64 Dqn_KeccakU64;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#else
|
2021-12-16 13:07:33 +00:00
|
|
|
|
typedef unsigned long long Dqn_KeccakU64;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2022-08-06 06:43:20 +00:00
|
|
|
|
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;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#define DQN_KECCAK_LANE_SIZE_U64 5
|
|
|
|
|
typedef struct Dqn_KeccakState
|
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakU8 state[DQN_KECCAK_LANE_SIZE_U64 * DQN_KECCAK_LANE_SIZE_U64 * sizeof(Dqn_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;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: SHA3/Keccak Streaming API /////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
// Setup a hashing state for either
|
|
|
|
|
// - FIPS 202 SHA3
|
|
|
|
|
// - Non-finalized SHA3 (only difference is delimited suffix of 0x1 instead of 0x6 in SHA3)
|
|
|
|
|
// The non-finalized SHA3 version is the one adopted by many cryptocurrencies
|
|
|
|
|
// such as Ethereum and Monero as they adopted SHA3 before it was finalized.
|
|
|
|
|
//
|
|
|
|
|
// The state produced from this function is to be used alongside the
|
|
|
|
|
// 'KeccakUpdate' and 'KeccakFinish' functions.
|
|
|
|
|
//
|
|
|
|
|
// 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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
// 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
|
|
|
|
|
// 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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Simple API ////////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
// 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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#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 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)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: SHA3 Helpers //////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Keccak Helpers ////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if defined(DQN_H)
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
// 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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#endif // DQN_H
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Helper functions //////////////////////////////////////////////////////////////////////////
|
2021-09-19 11:49:56 +00:00
|
|
|
|
// Convert a binary buffer into its hex representation into dest. The dest
|
|
|
|
|
// buffer must be large enough to contain the hex representation, i.e.
|
2021-09-24 12:29:34 +00:00
|
|
|
|
// atleast src_size * 2). This function does *not* null-terminate the buffer.
|
2021-12-16 13:07:33 +00:00
|
|
|
|
void Dqn_KeccakBytesToHex(void const *src, Dqn_KeccakU64 src_size, char *dest, Dqn_KeccakU64 dest_size);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
|
|
|
|
// Converts a fixed amount of bytes into a hexadecimal string. Helper functions
|
2021-12-16 13:07:33 +00:00
|
|
|
|
// that call into Dqn_KeccakBytesToHex.
|
2021-09-19 11:49:56 +00:00
|
|
|
|
// return: The hexadecimal string of the bytes, null-terminated.
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
|
|
|
|
// Compares byte data structures for byte equality (via memcmp).
|
|
|
|
|
// return: 1 if the contents are equal otherwise 0.
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if defined(DQN_H) && defined(DQN_WITH_HEX)
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Other helper functions for Dqn data structures ////////////////////////////////////////////
|
2021-09-19 11:49:56 +00:00
|
|
|
|
// 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.
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes32 Dqn_KeccakHex64StringToBytes(Dqn_Str8 hex);
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#endif // DQN_H && DQN_WITH_HEX
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#endif // DQN_KECCAK_H
|
|
|
|
|
|
|
|
|
|
#if defined(DQN_KECCAK_IMPLEMENTATION)
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 const DQN_KECCAK_ROUNDS[] = {
|
2021-09-19 11:49:56 +00:00
|
|
|
|
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000, 0x000000000000808B,
|
|
|
|
|
0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008A, 0x0000000000000088,
|
|
|
|
|
0x0000000080008009, 0x000000008000000A, 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
|
|
|
|
|
0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
|
|
|
|
|
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 const DQN_KECCAK_ROTATIONS[][5] =
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
{0, 36, 3, 41, 18},
|
|
|
|
|
{1, 44, 10, 45, 2},
|
|
|
|
|
{62, 6, 43, 15, 61},
|
|
|
|
|
{28, 55, 25, 21, 56},
|
|
|
|
|
{27, 20, 39, 8, 14},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define DQN_KECCAK_ROL64(val, rotate) (((val) << (rotate)) | (((val) >> (64 - (rotate)))))
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
static void Dqn_Keccak__Permute(void *state)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
// TODO(dqn): Do some profiling on unrolling and can we SIMD some part of
|
|
|
|
|
// this? Unroll loop, look at data dependencies and investigate.
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 *lanes_u64 = (Dqn_KeccakU64 *)state;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
for (int round_index = 0; round_index < 24; round_index++)
|
|
|
|
|
{
|
|
|
|
|
#define LANE_INDEX(x, y) ((x) + ((y) * DQN_KECCAK_LANE_SIZE_U64))
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// θ step //////////////////////////////////////////////////////////////////////////////////
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#if 1
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 c[DQN_KECCAK_LANE_SIZE_U64];
|
2021-09-19 11:49:56 +00:00
|
|
|
|
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
|
|
|
|
|
{
|
|
|
|
|
c[x] = lanes_u64[LANE_INDEX(x, 0)] ^
|
|
|
|
|
lanes_u64[LANE_INDEX(x, 1)] ^
|
|
|
|
|
lanes_u64[LANE_INDEX(x, 2)] ^
|
|
|
|
|
lanes_u64[LANE_INDEX(x, 3)] ^
|
|
|
|
|
lanes_u64[LANE_INDEX(x, 4)];
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 d[DQN_KECCAK_LANE_SIZE_U64];
|
2021-09-19 11:49:56 +00:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
|
|
|
|
|
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
|
|
|
|
|
lanes_u64[LANE_INDEX(x, y)] ^= d[x];
|
|
|
|
|
#else
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 c[5], d[5];
|
2021-09-19 11:49:56 +00:00
|
|
|
|
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);
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// ρ and π steps ///////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 b[DQN_KECCAK_LANE_SIZE_U64 * DQN_KECCAK_LANE_SIZE_U64];
|
2021-09-19 11:49:56 +00:00
|
|
|
|
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
|
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 lane = lanes_u64[LANE_INDEX(x, y)];
|
|
|
|
|
Dqn_KeccakU64 rotate_count = DQN_KECCAK_ROTATIONS[x][y];
|
2021-09-19 11:49:56 +00:00
|
|
|
|
b[LANE_INDEX(y, (2 * x + 3 * y) % 5)] = DQN_KECCAK_ROL64(lane, rotate_count);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// χ step //////////////////////////////////////////////////////////////////////////////////
|
2021-09-19 11:49:56 +00:00
|
|
|
|
for (int y = 0; y < DQN_KECCAK_LANE_SIZE_U64; y++)
|
|
|
|
|
{
|
|
|
|
|
for (int x = 0; x < DQN_KECCAK_LANE_SIZE_U64; x++)
|
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU64 rhs = ~b[LANE_INDEX((x + 1) % 5, y)] &
|
2021-09-19 11:49:56 +00:00
|
|
|
|
b[LANE_INDEX((x + 2) % 5, y)];
|
|
|
|
|
|
|
|
|
|
lanes_u64[LANE_INDEX(x, y)] = b[LANE_INDEX(x, y)] ^ rhs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// ι step //////////////////////////////////////////////////////////////////////////////////
|
2021-09-19 11:49:56 +00:00
|
|
|
|
lanes_u64[LANE_INDEX(0, 0)] ^= DQN_KECCAK_ROUNDS[round_index];
|
|
|
|
|
#undef LANE_INDEX
|
|
|
|
|
#undef DQN_KECCAK_ROL64
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Streaming API /////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakState Dqn_KeccakSHA3Init(bool sha3, int hash_size_bits)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
char const SHA3_DELIMITED_SUFFIX = 0x06;
|
|
|
|
|
char const KECCAK_DELIMITED_SUFFIX = 0x01;
|
|
|
|
|
int const bitrate = 1600 - (hash_size_bits * 2);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2022-08-06 06:43:20 +00:00
|
|
|
|
#if defined(__cplusplus)
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakState result = {};
|
2022-08-06 06:43:20 +00:00
|
|
|
|
#else
|
|
|
|
|
Dqn_KeccakState result = {0};
|
|
|
|
|
#endif
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Dqn_KeccakUpdate(Dqn_KeccakState *keccak, void const *data, Dqn_KeccakU64 data_size)
|
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakU8 *state = keccak->state;
|
|
|
|
|
Dqn_KeccakU8 const *ptr = (Dqn_KeccakU8 *)data;
|
|
|
|
|
Dqn_KeccakU64 ptr_size = data_size;
|
|
|
|
|
while (ptr_size > 0)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_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++)
|
|
|
|
|
state[keccak->state_size + index] ^= ptr[index];
|
|
|
|
|
|
|
|
|
|
ptr += bytes_to_absorb;
|
|
|
|
|
keccak->state_size += bytes_to_absorb;
|
|
|
|
|
ptr_size -= bytes_to_absorb;
|
|
|
|
|
|
|
|
|
|
if (keccak->state_size >= keccak->absorb_size)
|
|
|
|
|
{
|
|
|
|
|
DQN_KECCAK_ASSERT(keccak->state_size == keccak->absorb_size);
|
|
|
|
|
Dqn_Keccak__Permute(state);
|
|
|
|
|
keccak->state_size = 0;
|
|
|
|
|
}
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
2021-12-16 13:07:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Dqn_KeccakFinish(Dqn_KeccakState *keccak, void *dest, int dest_size)
|
|
|
|
|
{
|
|
|
|
|
DQN_KECCAK_ASSERT(dest_size >= keccak->hash_size_bits / 8);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// Sponge Finalization Step: Final padding bit /////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
Dqn_KeccakU8 *state = keccak->state;
|
|
|
|
|
state[delimited_suffix_index] ^= keccak->delimited_suffix;
|
|
|
|
|
|
|
|
|
|
// NOTE: In the reference implementation, it checks that if the
|
|
|
|
|
// delimited suffix is set to the padding bit (0x80), then we need to
|
|
|
|
|
// permute twice. Once for the delimited suffix, and a second time for
|
|
|
|
|
// the "padding" permute.
|
|
|
|
|
//
|
|
|
|
|
// However all standard algorithms either specify a 0x01, or 0x06, 0x04
|
|
|
|
|
// delimited suffix and so forth- so this case is never hit. We can omit
|
|
|
|
|
// this from the implementation here.
|
|
|
|
|
|
|
|
|
|
state[INDEX_OF_0X80_BYTE] ^= 0x80;
|
|
|
|
|
Dqn_Keccak__Permute(state);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// Squeeze Step: Squeeze bytes from the state into our hash ////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakU8 *dest_u8 = (Dqn_KeccakU8 *)dest;
|
|
|
|
|
int const squeeze_count = dest_size / keccak->absorb_size;
|
|
|
|
|
int squeeze_index = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
for (; squeeze_index < squeeze_count; squeeze_index++)
|
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
if (squeeze_index) Dqn_Keccak__Permute(state);
|
|
|
|
|
DQN_KECCAK_MEMCPY(dest_u8, state, keccak->absorb_size);
|
|
|
|
|
dest_u8 += keccak->absorb_size;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// Squeeze Finalisation Step: Remainder bytes in hash //////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
int const remainder = dest_size % keccak->absorb_size;
|
|
|
|
|
if (remainder)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
if (squeeze_index) Dqn_Keccak__Permute(state);
|
|
|
|
|
DQN_KECCAK_MEMCPY(dest_u8, state, remainder);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
void Dqn_KeccakSHA3Hash(bool sha3, int hash_size_bits, void const *src, Dqn_KeccakU64 src_size, void *dest, int dest_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakState keccak = Dqn_KeccakSHA3Init(sha3, hash_size_bits);
|
|
|
|
|
Dqn_KeccakUpdate(&keccak, src, src_size);
|
|
|
|
|
Dqn_KeccakFinish(&keccak, dest, dest_size);
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: SHA3 Helpers //////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes28 Dqn_SHA3_224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes28 result;
|
|
|
|
|
Dqn_SHA3_224(bytes, bytes_size, result.data, sizeof(result));
|
|
|
|
|
return result;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes32 Dqn_SHA3_256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes32 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_SHA3_256(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes48 Dqn_SHA3_384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes48 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_SHA3_384(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes64 Dqn_SHA3_512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes64 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_SHA3_512(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Keccak Helpers ////////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes28 Dqn_Keccak224ToBytes28(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes28 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_Keccak224(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes32 Dqn_Keccak256ToBytes32(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes32 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_Keccak256(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes48 Dqn_Keccak384ToBytes48(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes48 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_Keccak384(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes64 Dqn_Keccak512ToBytes64(void *bytes, Dqn_KeccakU64 bytes_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes64 result;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_Keccak512(bytes, bytes_size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if defined(DQN_H)
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: SHA3 - Helpers for Dqn data structures ////////////////////////////////////////////////////
|
|
|
|
|
Dqn_KeccakBytes28 Dqn_SHA3_224StringToBytes28(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes28 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_SHA3_224(string.data, string.size, result.data, sizeof(result));
|
2021-12-16 13:07:33 +00:00
|
|
|
|
return result;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes32 Dqn_SHA3_256StringToBytes32(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes32 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_SHA3_256(string.data, string.size, result.data, sizeof(result));
|
2021-12-16 13:07:33 +00:00
|
|
|
|
return result;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes48 Dqn_SHA3_384StringToBytes48(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes48 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_SHA3_384(string.data, string.size, result.data, sizeof(result));
|
2021-12-16 13:07:33 +00:00
|
|
|
|
return result;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes64 Dqn_SHA3_512StringToBytes64(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakBytes64 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_SHA3_512(string.data, string.size, result.data, sizeof(result));
|
2021-12-16 13:07:33 +00:00
|
|
|
|
return result;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
}
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#endif // DQN_H
|
2021-09-19 11:49:56 +00:00
|
|
|
|
|
|
|
|
|
#if defined(DQN_H)
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Keccak - Helpers for Dqn data structures //////////////////////////////////////////////////
|
|
|
|
|
Dqn_KeccakBytes28 Dqn_Keccak224StringToBytes28(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes28 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_Keccak224(string.data, string.size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes32 Dqn_Keccak256StringToBytes32(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes32 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_Keccak256(string.data, string.size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes48 Dqn_Keccak384StringToBytes48(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes48 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_Keccak384(string.data, string.size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
Dqn_KeccakBytes64 Dqn_Keccak512StringToBytes64(Dqn_Str8 string)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakBytes64 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_Keccak512(string.data, string.size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endif // DQN_H
|
|
|
|
|
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Helper functions //////////////////////////////////////////////////////////////////////////
|
2021-12-16 13:07:33 +00:00
|
|
|
|
void Dqn_KeccakBytesToHex(void const *src, Dqn_KeccakU64 src_size, char *dest, Dqn_KeccakU64 dest_size)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
(void)src_size; (void)dest_size;
|
|
|
|
|
DQN_KECCAK_ASSERT(dest_size >= src_size * 2);
|
|
|
|
|
|
|
|
|
|
unsigned char *src_u8 = (unsigned char *)src;
|
2021-12-16 13:07:33 +00:00
|
|
|
|
for (Dqn_KeccakU64 src_index = 0, dest_index = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
src_index < src_size;
|
|
|
|
|
src_index += 1, dest_index += 2)
|
|
|
|
|
{
|
|
|
|
|
char byte = src_u8[src_index];
|
|
|
|
|
char hex01 = (byte >> 4) & 0b1111;
|
|
|
|
|
char hex02 = (byte >> 0) & 0b1111;
|
|
|
|
|
dest[dest_index + 0] = hex01 < 10 ? (hex01 + '0') : (hex01 - 10) + 'a';
|
|
|
|
|
dest[dest_index + 1] = hex02 < 10 ? (hex02 + '0') : (hex02 - 10) + 'a';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakString56 Dqn_KeccakBytes28ToHex(Dqn_KeccakBytes28 const *bytes)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakString56 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
|
|
|
|
result.data[sizeof(result.data) - 1] = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakString64 Dqn_KeccakBytes32ToHex(Dqn_KeccakBytes32 const *bytes)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakString64 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
|
|
|
|
result.data[sizeof(result.data) - 1] = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakString96 Dqn_KeccakBytes48ToHex(Dqn_KeccakBytes48 const *bytes)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakString96 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
|
|
|
|
result.data[sizeof(result.data) - 1] = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
Dqn_KeccakString128 Dqn_KeccakBytes64ToHex(Dqn_KeccakBytes64 const *bytes)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dqn_KeccakString128 result;
|
2022-08-06 06:43:20 +00:00
|
|
|
|
Dqn_KeccakBytesToHex(bytes->data, sizeof(bytes->data), result.data, sizeof(result.data));
|
|
|
|
|
result.data[sizeof(result.data) - 1] = 0;
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
int Dqn_KeccakBytes28Equals(Dqn_KeccakBytes28 const *a, Dqn_KeccakBytes28 const *b)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
int Dqn_KeccakBytes32Equals(Dqn_KeccakBytes32 const *a, Dqn_KeccakBytes32 const *b)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
int Dqn_KeccakBytes48Equals(Dqn_KeccakBytes48 const *a, Dqn_KeccakBytes48 const *b)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
int Dqn_KeccakBytes64Equals(Dqn_KeccakBytes64 const *a, Dqn_KeccakBytes64 const *b)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
int result = DQN_KECCAK_MEMCMP(a->data, b->data, sizeof(*a)) == 0;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#if defined(DQN_H) && defined(DQN_WITH_HEX)
|
2024-02-25 13:15:09 +00:00
|
|
|
|
// NOTE: Other helper functions for Dqn data structures ////////////////////////////////////////////
|
|
|
|
|
Dqn_KeccakBytes32 Dqn_KeccakHex64StringToBytes(Dqn_Str8 hex)
|
2021-09-19 11:49:56 +00:00
|
|
|
|
{
|
|
|
|
|
DQN_KECCAK_ASSERT(hex.size == 64);
|
|
|
|
|
Dqn_KeccakBytes32 result;
|
2023-03-11 14:28:17 +00:00
|
|
|
|
Dqn_Hex_CString8ToByteBuffer(hex.data, hex.size, result.data, sizeof(result));
|
2021-09-19 11:49:56 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2021-12-16 13:07:33 +00:00
|
|
|
|
#endif // DQN_H && DQN_WITH_HEX
|
2021-09-19 11:49:56 +00:00
|
|
|
|
#endif // DQN_KECCAK_IMPLEMENTATION
|