Add implementation for siphash
Release / release (push) Successful in 4s

This commit is contained in:
2026-08-31 02:15:01 +01:00
parent bca2e720ad
commit 900c16415b
13 changed files with 848 additions and 2 deletions
+4 -2
View File
@@ -9,9 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `wpMur3HasherIO` to setup the hash IO struct
- `wpX64Mur3Hasher128` implementation for the x64 128-bit variant of the MurmurHash3 algorithm
- `wpMiscUtilsRotl64` utility
- `wpMur3HasherIO` to setup the MurmurHash3 IO struct
- `wpX64Mur3Hasher128` implementation for the x64 128-bit variant of the MurmurHash3 algorithm
- `wpSip24Hasher128IO`, `wpSip48Hasher128IO`, `wpSip24Hasher64IO` and `wpSip48Hasher64IO` to setup the siphash IO structs for the different variants
- `wpSipHasher128` and `wpSipHasher64` implementation for the 128 and 64 variants of siphash
## [2.4.0] - 2026-08-30
+177
View File
@@ -0,0 +1,177 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "siphash.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include <stdint.h>
wp_intern inline void _siphash(WpStream *bytes, const WpSipHasherParams *params, u8 *out, u64 outlen);
wp_intern inline void _validate128IO(const WpSipHasher128IO *io);
wp_intern inline void _validate64IO(const WpSipHasher64IO *io);
wp_intern inline b8 _checkRounds(const WpSipHasherParams *params);
#define _u32To8LE(p, v) \
(p)[0] = (u8)((v)); \
(p)[1] = (u8)((v) >> 8); \
(p)[2] = (u8)((v) >> 16); \
(p)[3] = (u8)((v) >> 24);
#define _u64To8LE(p, v) \
_u32To8LE((p), (u32)((v))); \
_u32To8LE((p) + 4, (u32)((v) >> 32));
#define _u8To64LE(p) \
(((u64)((p)[0])) | ((u64)((p)[1]) << 8) | \
((u64)((p)[2]) << 16) | ((u64)((p)[3]) << 24) | \
((u64)((p)[4]) << 32) | ((u64)((p)[5]) << 40) | \
((u64)((p)[6]) << 48) | ((u64)((p)[7]) << 56))
#define _sipRound \
do { \
v0 += v1; \
v1 = wpMiscUtilsRotl64(v1, 13); \
v1 ^= v0; \
v0 = wpMiscUtilsRotl64(v0, 32); \
v2 += v3; \
v3 = wpMiscUtilsRotl64(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = wpMiscUtilsRotl64(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = wpMiscUtilsRotl64(v1, 17); \
v1 ^= v2; \
v2 = wpMiscUtilsRotl64(v2, 32); \
} while (0)
void wpSipHasher128(WpStream *bytes, void *hasher_io) {
WpSipHasher128IO *io = (WpSipHasher128IO *)hasher_io;
_validate128IO(io);
_siphash(bytes, &io->params, (u8 *)&io->hash, sizeof(u64) * 2);
}
void wpSipHasher64(WpStream *bytes, void *hasher_io) {
WpSipHasher64IO *io = (WpSipHasher64IO *)hasher_io;
_validate64IO(io);
_siphash(bytes, &io->params, (u8 *)&io->hash, sizeof(u64));
}
wp_intern inline void _siphash(WpStream *bytes, const WpSipHasherParams *params, u8 *out,
u64 outlen) {
const u8 *kk = (const u8 *)&params->key;
u64 inlen = bytes->count * bytes->item_size;
wpRuntimeAssert((outlen == 8) || (outlen == 16), "outlen should be 8 or 16");
u64 v0 = UINT64_C(0x736f6d6570736575);
u64 v1 = UINT64_C(0x646f72616e646f6d);
u64 v2 = UINT64_C(0x6c7967656e657261);
u64 v3 = UINT64_C(0x7465646279746573);
u64 k0 = _u8To64LE(kk);
u64 k1 = _u8To64LE(kk + 8);
u64 m;
u64 i;
const i32 left = inlen & 7;
u64 b = ((u64)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16) {
v1 ^= 0xee;
}
u8 *data;
while (wpStreamHasCount(bytes, sizeof(u64))) {
data = wpStreamConsumeCount(u8, bytes, sizeof(u64));
m = _u8To64LE(data);
v3 ^= m;
for (i = 0; i < params->compression; ++i) {
_sipRound;
}
v0 ^= m;
}
data = wpStreamConsume(u8, bytes);
switch (left) {
case 7:
b |= ((u64)data[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((u64)data[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((u64)data[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((u64)data[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((u64)data[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((u64)data[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((u64)data[0]);
break;
case 0:
break;
}
v3 ^= b;
for (i = 0; i < params->compression; ++i) {
_sipRound;
}
v0 ^= b;
if (outlen == 16) {
v2 ^= 0xee;
} else {
v2 ^= 0xff;
}
for (i = 0; i < params->finalisation; ++i) {
_sipRound;
}
b = v0 ^ v1 ^ v2 ^ v3;
_u64To8LE(out, b);
if (outlen == 8) {
return;
}
v1 ^= 0xdd;
for (i = 0; i < params->finalisation; ++i) {
_sipRound;
}
b = v0 ^ v1 ^ v2 ^ v3;
_u64To8LE(out + 8, b);
}
wp_intern inline void _validate128IO(const WpSipHasher128IO *io) {
b8 magic_match = io->params.magic == WP_SIP_HASHER_128_MAGIC;
b8 rounds = _checkRounds(&io->params);
wpRuntimeAssert(magic_match && rounds, "Invalid Siphash 128 IO");
}
wp_intern inline void _validate64IO(const WpSipHasher64IO *io) {
b8 magic_match = io->params.magic == WP_SIP_HASHER_64_MAGIC;
b8 rounds = _checkRounds(&io->params);
wpRuntimeAssert(magic_match && rounds, "Invalid Siphash 64 IO");
}
wp_intern inline b8 _checkRounds(const WpSipHasherParams *params) {
b8 rounds24 = params->compression == 2 && params->finalisation == 4;
b8 rounds48 = params->compression == 4 && params->finalisation == 8;
return rounds24 || rounds48;
}
+103
View File
@@ -0,0 +1,103 @@
// vim:fileencoding=utf-8:foldmethod=marker
/**
* Implementations of the SipHash-2-4-128, SipHash4-8-128, SipHash-2-4-64 and SipHash4-8-64
* algorithms based on https://github.com/veorq/SipHash/blob/master/siphash.c
*/
#ifndef SIPHASH_H
#define SIPHASH_H
#include "../../stream/stream.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#define WP_SIP_HASHER_128_MAGIC ((u64)0x5750534950313238)
#define WP_SIP_HASHER_64_MAGIC ((u64)0x57505349503634)
typedef struct {
u64 lo;
u64 hi;
} WpSipHasherKey;
typedef struct {
WpSipHasherKey key;
u64 magic;
u64 compression;
u64 finalisation;
} WpSipHasherParams;
typedef struct {
WpSipHasherParams params;
u64 hash[2];
} WpSipHasher128IO;
typedef struct {
WpSipHasherParams params;
u64 hash;
} WpSipHasher64IO;
#ifdef WP_PLATFORM_CPP
#define wpSip24Hasher128IO(KEY) (WpSipHasher128IO{ \
WpSipHasherParams{KEY, WP_SIP_HASHER_128_MAGIC, 2, 4}, \
{}, \
})
#define wpSip48Hasher128IO(KEY) (WpSipHasher128IO{ \
WpSipHasherParams{KEY, WP_SIP_HASHER_128_MAGIC, 4, 8}, \
{}, \
})
#define wpSip24Hasher64IO(KEY) (WpSipHasher64IO{ \
WpSipHasherParams{KEY, WP_SIP_HASHER_64_MAGIC, 2, 4}, \
0, \
})
#define wpSip48Hasher64IO(KEY) (WpSipHasher64IO{ \
WpSipHasherParams{KEY, WP_SIP_HASHER_64_MAGIC, 4, 8}, \
0, \
})
#else
#define wpSip24Hasher128IO(KEY) ((WpSipHasher128IO){ \
.params = (WpSipHasherParams){ \
.key = KEY, \
.magic = WP_SIP_HASHER_128_MAGIC, \
.compression = 2, \
.finalisation = 4, \
} \
})
#define wpSip48Hasher128IO(KEY) ((WpSipHasher128IO){ \
.params = (WpSipHasherParams){ \
.key = KEY, \
.magic = WP_SIP_HASHER_128_MAGIC, \
.compression = 4, \
.finalisation = 8, \
} \
})
#define wpSip24Hasher64IO(KEY) ((WpSipHasher64IO){ \
.params = (WpSipHasherParams){ \
.key = KEY, \
.magic = WP_SIP_HASHER_64_MAGIC, \
.compression = 2, \
.finalisation = 4, \
} \
})
#define wpSip48Hasher64IO(KEY) ((WpSipHasher64IO){ \
.params = (WpSipHasherParams){ \
.key = KEY, \
.magic = WP_SIP_HASHER_64_MAGIC, \
.compression = 4, \
.finalisation = 8, \
} \
})
#endif
void wpSipHasher128(WpU8Stream *bytes, void *hasher_io);
void wpSipHasher64(WpU8Stream *bytes, void *hasher_io);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#endif // !SIPHASH_H
+1
View File
@@ -7,6 +7,7 @@
#include "array/array.c"
#include "dbl_list/dbl_list.c"
#include "hash/hasher/murmur3.c"
#include "hash/hasher/siphash.c"
#include "queue/queue.c"
#include "stream/stream.c"
#include "mem/allocator/mem_allocator.c"
+1
View File
@@ -7,6 +7,7 @@
#include "dbl_list/dbl_list.h"
#include "hash/hasher/hasher.h"
#include "hash/hasher/murmur3.h"
#include "hash/hasher/siphash.h"
#include "queue/queue.h"
#include "stream/stream.h"
#include "mem/allocator/mem_allocator.h"
+185
View File
@@ -0,0 +1,185 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2022 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "siphash.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
/* default: SipHash-2-4 */
#ifndef cROUNDS
#define cROUNDS 2
#endif
#ifndef dROUNDS
#define dROUNDS 4
#endif
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG_SIPHASH
#include <stdio.h>
#define TRACE \
do { \
printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
} while (0)
#else
#define TRACE
#endif
/*
Computes a SipHash value
*in: pointer to input data (read-only)
inlen: input data length in bytes (any size_t value)
*k: pointer to the key data (read-only), must be 16 bytes
*out: pointer to output data (write-only), outlen bytes must be allocated
outlen: length of the output in bytes, must be 8 or 16
*/
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen) {
const unsigned char *ni = (const unsigned char *)in;
const unsigned char *kk = (const unsigned char *)k;
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
uint64_t k0 = U8TO64_LE(kk);
uint64_t k1 = U8TO64_LE(kk + 8);
uint64_t m;
int i;
const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; ni != end; ni += 8) {
m = U8TO64_LE(ni);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)ni[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((uint64_t)ni[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((uint64_t)ni[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((uint64_t)ni[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((uint64_t)ni[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((uint64_t)ni[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((uint64_t)ni[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}
+185
View File
@@ -0,0 +1,185 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2022 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "siphash.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
/* default: SipHash-2-4 */
#ifndef cROUNDS
#define cROUNDS 2
#endif
#ifndef dROUNDS
#define dROUNDS 4
#endif
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG_SIPHASH
#include <stdio.h>
#define TRACE \
do { \
printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
} while (0)
#else
#define TRACE
#endif
/*
Computes a SipHash value
*in: pointer to input data (read-only)
inlen: input data length in bytes (any size_t value)
*k: pointer to the key data (read-only), must be 16 bytes
*out: pointer to output data (write-only), outlen bytes must be allocated
outlen: length of the output in bytes, must be 8 or 16
*/
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen) {
const unsigned char *ni = (const unsigned char *)in;
const unsigned char *kk = (const unsigned char *)k;
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
uint64_t k0 = U8TO64_LE(kk);
uint64_t k1 = U8TO64_LE(kk + 8);
uint64_t m;
int i;
const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; ni != end; ni += 8) {
m = U8TO64_LE(ni);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)ni[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((uint64_t)ni[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((uint64_t)ni[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((uint64_t)ni[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((uint64_t)ni[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((uint64_t)ni[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((uint64_t)ni[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2021 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <inttypes.h>
#include <string.h>
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen);
+81
View File
@@ -2,6 +2,7 @@
#include "test_hasher.h"
#include "MurmurHash3.h"
#include "siphash.h"
#include "wapp.h"
WpTestFuncResult test_murmur3(void) {
@@ -39,3 +40,83 @@ WpTestFuncResult test_murmur3(void) {
return wpTesterResult(result);
}
WpTestFuncResult test_siphash_128(void) {
b8 result = true;
WpStr8 str = wpStr8Lit("Hello world");
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324;
WpSipHasherKey key = { .lo = 238742, .hi = 671734 };
WpSipHasher128IO io = wpSip24Hasher128IO(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
WpU8Stream num_bytes = wpStream(u8, (u8 *)&num, sizeof(u64));
u64 hash[2] = {0};
// Sring hash
wpSipHasher128(&str_bytes, (void *)&io);
siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
// Array hash
wpSipHasher128(&arr_bytes, (void *)&io);
siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
// Number hash
wpSipHasher128(&num_bytes, (void *)&io);
siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
return wpTesterResult(result);
}
WpTestFuncResult test_siphash_64(void) {
b8 result = true;
WpStr8 str = wpStr8Lit("Hello world");
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324;
WpSipHasherKey key = { .lo = 238742, .hi = 671734 };
WpSipHasher64IO io = wpSip24Hasher64IO(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
WpU8Stream num_bytes = wpStream(u8, (u8 *)&num, sizeof(u64));
u64 hash = {0};
// Sring hash
wpSipHasher64(&str_bytes, (void *)&io);
siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
// Array hash
wpSipHasher64(&arr_bytes, (void *)&io);
siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
// Number hash
wpSipHasher64(&num_bytes, (void *)&io);
siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
return wpTesterResult(result);
}
+81
View File
@@ -2,6 +2,7 @@
#include "test_hasher.h"
#include "MurmurHash3.h"
#include "siphash.h"
#include "wapp.h"
WpTestFuncResult test_murmur3(void) {
@@ -39,3 +40,83 @@ WpTestFuncResult test_murmur3(void) {
return wpTesterResult(result);
}
WpTestFuncResult test_siphash_128(void) {
b8 result = true;
WpStr8 str = wpStr8Lit("Hello world");
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324;
WpSipHasherKey key = { 238742, 671734 };
WpSipHasher128IO io = wpSip24Hasher128IO(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
WpU8Stream num_bytes = wpStream(u8, (u8 *)&num, sizeof(u64));
u64 hash[2] = {0};
// Sring hash
wpSipHasher128(&str_bytes, (void *)&io);
siphash((void *)str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
// Array hash
wpSipHasher128(&arr_bytes, (void *)&io);
siphash((void *)arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
// Number hash
wpSipHasher128(&num_bytes, (void *)&io);
siphash((void *)num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&io.params.key,
(u8 *)hash, sizeof(u64) * 2);
result = result && io.hash[0] == hash[0] && io.hash[1] == hash[1];
return wpTesterResult(result);
}
WpTestFuncResult test_siphash_64(void) {
b8 result = true;
WpStr8 str = wpStr8Lit("Hello world");
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324;
WpSipHasherKey key = { 238742, 671734 };
WpSipHasher64IO io = wpSip24Hasher64IO(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
WpU8Stream num_bytes = wpStream(u8, (u8 *)&num, sizeof(u64));
u64 hash = {0};
// Sring hash
wpSipHasher64(&str_bytes, (void *)&io);
siphash((void *)str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
// Array hash
wpSipHasher64(&arr_bytes, (void *)&io);
siphash((void *)arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
// Number hash
wpSipHasher64(&num_bytes, (void *)&io);
siphash((void *)num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&io.params.key,
(u8 *)&hash, sizeof(u64));
result = result && io.hash == hash;
return wpTesterResult(result);
}
+4
View File
@@ -8,4 +8,8 @@
// Test Murmur3 hash implementation against the reference implementation
WpTestFuncResult test_murmur3(void);
// Test Sip hash implementation against the reference implementation
WpTestFuncResult test_siphash_128(void);
WpTestFuncResult test_siphash_64(void);
#endif // !TEST_HASHER_H
+2
View File
@@ -103,6 +103,8 @@ int main(void) {
test_wapp_file_rename,
test_wapp_file_remove,
test_murmur3,
test_siphash_128,
test_siphash_64,
test_commander_cmd_success,
test_commander_cmd_failure,
test_commander_cmd_out_buf_success,
+2
View File
@@ -103,6 +103,8 @@ int main(void) {
test_wapp_file_rename,
test_wapp_file_remove,
test_murmur3,
test_siphash_128,
test_siphash_64,
test_commander_cmd_success,
test_commander_cmd_failure,
test_commander_cmd_out_buf_success,