Skip to content

Instantly share code, notes, and snippets.

@methane
Created October 8, 2021 05:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save methane/5bb59a0563a025994e49fac509b49bf9 to your computer and use it in GitHub Desktop.
Save methane/5bb59a0563a025994e49fac509b49bf9 to your computer and use it in GitHub Desktop.
create known hashes for siphash13
// create known hash in test_hash
#include <cstdint>
#include <iostream>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
// copied from initconfig.c
typedef union {
/* ensure 24 bytes */
unsigned char uc[24];
/* two uint64 for SipHash24 */
struct {
uint64_t k0;
uint64_t k1;
} siphash;
} hashseed_t;
static void
lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
{
size_t index;
unsigned int x;
x = x0;
for (index=0; index < size; index++) {
x *= 214013;
x += 2531011;
/* modulo 2 ^ (8 * sizeof(int)) */
buffer[index] = (x >> 16) & 0xff;
}
}
// copied from https://tociyuki.hatenablog.jp/entry/20170310/1489133310
uint64_t siphash13 (uint8_t const key[16], uint8_t const *s, std::size_t const len);
static inline void
sipround (uint64_t& v0, uint64_t& v1, uint64_t& v2, uint64_t& v3)
{
v0 += v1;
v1 = (v1 << 13) | (v1 >> 51);
v1 ^= v0;
v0 = (v0 << 32) | (v0 >> 32);
v2 += v3;
v3 = (v3 << 16) | (v3 >> 48);
v3 ^= v2;
v0 += v3;
v3 = (v3 << 21) | (v3 >> 43);
v3 ^= v0;
v2 += v1;
v1 = (v1 << 17) | (v1 >> 47);
v1 ^= v2;
v2 = (v2 << 32) | (v2 >> 32);
}
static inline uint64_t
u8to64_le(uint8_t const *s)
{
return (uint64_t)(s[0]) | ((uint64_t)(s[1]) << 8)
| ((uint64_t)(s[2]) << 16) | ((uint64_t)(s[3]) << 24)
| ((uint64_t)(s[4]) << 32) | ((uint64_t)(s[5]) << 40)
| ((uint64_t)(s[6]) << 48) | ((uint64_t)(s[7]) << 56);
}
uint64_t
siphash13 (uint64_t k0, uint64_t k1, uint8_t const *s, std::size_t const len)
{
uint64_t m;
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
std::size_t n = len;
for (; n >= 8; s += 8, n -= 8) {
m = u8to64_le (s);
v3 ^= m;
sipround (v0, v1, v2, v3);
#ifdef SIPHASH24
sipround (v0, v1, v2, v3);
#endif
v0 ^= m;
}
uint64_t b = ((uint64_t) len) << 56;
switch (n) {
case 7: b ^= ((uint64_t)s[6]) << 48;
case 6: b ^= ((uint64_t)s[5]) << 40;
case 5: b ^= ((uint64_t)s[4]) << 32;
case 4: b ^= ((uint64_t)s[3]) << 24;
case 3: b ^= ((uint64_t)s[2]) << 16;
case 2: b ^= ((uint64_t)s[1]) << 8;
case 1: b ^= ((uint64_t)s[0]);
}
v3 ^= b;
sipround (v0, v1, v2, v3);
#ifdef SIPHASH24
sipround (v0, v1, v2, v3);
#endif
v0 ^= b;
v2 ^= UINT64_C(0xff);
sipround (v0, v1, v2, v3);
sipround (v0, v1, v2, v3);
sipround (v0, v1, v2, v3);
#ifdef SIPHASH24
sipround (v0, v1, v2, v3);
#endif
b = v0 ^ v1 ^ v2 ^ v3;
return b;
}
// end
void report(int seed, uint64_t k0, uint64_t k1, const char *name, const char *little, const char *big, size_t len)
{
uint64_t hl = siphash13(k0, k1, (const uint8_t*)little, len);
uint64_t hb = siphash13(k0, k1, (const uint8_t*)big, len);
printf("# seed %d, '%s'\n", seed, name);
printf("[%d, %ld, %d, %ld],\n", (int32_t)hl, (int64_t)hl, (int32_t)hb, (int64_t)hb);
}
int main()
{
uint64_t h;
int seed;
const char *s;
size_t len;
const char *s1 = "abc";
const char *s2 = "abcdefghijk";
const char *name = "äú∑ℇ";
const char *s3 = "\xe4\x00\xfa\x00\x11\"\x07!";
const char *s4 = "\x00\xe4\x00\xfa\"\x11!\x07";
// PYTHONHASHSEED=42
hashseed_t seed42;
lcg_urandom(42, seed42.uc, 16);
uint64_t k0 = seed42.siphash.k0;
uint64_t k1 = seed42.siphash.k1;
report(0, 0, 0, s1, s1, s1, 3);
report(42, k0, k1, s1, s1, s1, 3);
report(42, k0, k1, s2, s2, s2, strlen(s2));
report(0, 0, 0, name, s3, s4, 8);
report(42, k0, k1, name, s3, s4, 8);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment