siphash: Clean up hash finalisation with posthash_final() function
The POSTAMBLE macro implements the finalisation steps of SipHash. It relies on some variables in the environment, including returning the final hash value that way. That isn't great hygeine. In addition the PREAMBLE macro takes a length parameter which is used only to initialize the 'b' value that's not used until the finalisation and is also sometimes modified in a non-obvious way by the callers. The 'b' value is always composed from the total length of the hash input plus up to 7 bytes of "tail" data - that is the remainder of the hash input after a multiple of 8 bytes has been consumed. Simplify all this by replacing the POSTAMBLE macro with a siphash_final() function which takes the length and tail data as parameters and returns the final hash value. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
7a3153cbfb
commit
831067f483
1 changed files with 28 additions and 30 deletions
58
siphash.c
58
siphash.c
|
@ -51,16 +51,16 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "siphash.h"
|
#include "siphash.h"
|
||||||
|
|
||||||
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
||||||
|
|
||||||
#define PREAMBLE(len) \
|
#define PREAMBLE \
|
||||||
uint64_t v[4] = { 0x736f6d6570736575ULL, 0x646f72616e646f6dULL, \
|
uint64_t v[4] = { 0x736f6d6570736575ULL, 0x646f72616e646f6dULL, \
|
||||||
0x6c7967656e657261ULL, 0x7465646279746573ULL }; \
|
0x6c7967656e657261ULL, 0x7465646279746573ULL }; \
|
||||||
uint64_t b = (uint64_t)(len) << 56; \
|
|
||||||
int __i; \
|
int __i; \
|
||||||
\
|
\
|
||||||
do { \
|
do { \
|
||||||
|
@ -103,13 +103,21 @@ static inline void siphash_feed(uint64_t *v, uint64_t in)
|
||||||
v[0] ^= in;
|
v[0] ^= in;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define POSTAMBLE \
|
/**
|
||||||
do { \
|
* siphash_final - Finalize SipHash calculations
|
||||||
siphash_feed(v, b); \
|
* @v: siphash state (4 x 64-bit integers)
|
||||||
v[2] ^= 0xff; \
|
* @len: Total length of input data
|
||||||
sipround(v, 4); \
|
* @tail: Final data for the hash (<= 7 bytes)
|
||||||
b = (v[0] ^ v[1]) ^ (v[2] ^ v[3]); \
|
*/
|
||||||
} while (0)
|
static inline uint64_t siphash_final(uint64_t *v, size_t len, uint64_t tail)
|
||||||
|
{
|
||||||
|
uint64_t b = (uint64_t)(len) << 56 | tail;
|
||||||
|
|
||||||
|
siphash_feed(v, b);
|
||||||
|
v[2] ^= 0xff;
|
||||||
|
sipround(v, 4);
|
||||||
|
return v[0] ^ v[1] ^ v[2] ^ v[3];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* siphash_8b() - Table index or timestamp offset for TCP over IPv4 (8 bytes in)
|
* siphash_8b() - Table index or timestamp offset for TCP over IPv4 (8 bytes in)
|
||||||
|
@ -132,11 +140,11 @@ __attribute__((optimize("-fno-strict-aliasing")))
|
||||||
/* cppcheck-suppress unusedFunction */
|
/* cppcheck-suppress unusedFunction */
|
||||||
uint64_t siphash_8b(const uint8_t *in, const uint64_t *k)
|
uint64_t siphash_8b(const uint8_t *in, const uint64_t *k)
|
||||||
{
|
{
|
||||||
PREAMBLE(8);
|
PREAMBLE;
|
||||||
siphash_feed(v, *(uint64_t *)in);
|
siphash_feed(v, *(uint64_t *)in);
|
||||||
POSTAMBLE;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
|
return siphash_final(v, 8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,12 +161,10 @@ uint64_t siphash_12b(const uint8_t *in, const uint64_t *k)
|
||||||
{
|
{
|
||||||
uint32_t *in32 = (uint32_t *)in;
|
uint32_t *in32 = (uint32_t *)in;
|
||||||
|
|
||||||
PREAMBLE(12);
|
PREAMBLE;
|
||||||
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
||||||
b |= *(in32 + 2);
|
|
||||||
POSTAMBLE;
|
|
||||||
|
|
||||||
return b;
|
return siphash_final(v, 12, *(in32 + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,15 +181,12 @@ uint64_t siphash_20b(const uint8_t *in, const uint64_t *k)
|
||||||
uint32_t *in32 = (uint32_t *)in;
|
uint32_t *in32 = (uint32_t *)in;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PREAMBLE(20);
|
PREAMBLE;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++, in32 += 2)
|
for (i = 0; i < 2; i++, in32 += 2)
|
||||||
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
||||||
|
|
||||||
b |= *in32;
|
return siphash_final(v, 20, *in32);
|
||||||
POSTAMBLE;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,14 +204,12 @@ uint64_t siphash_32b(const uint8_t *in, const uint64_t *k)
|
||||||
uint64_t *in64 = (uint64_t *)in;
|
uint64_t *in64 = (uint64_t *)in;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PREAMBLE(32);
|
PREAMBLE;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++, in64++)
|
for (i = 0; i < 4; i++, in64++)
|
||||||
siphash_feed(v, *in64);
|
siphash_feed(v, *in64);
|
||||||
|
|
||||||
POSTAMBLE;
|
return siphash_final(v, 32, 0);
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,13 +226,10 @@ uint64_t siphash_36b(const uint8_t *in, const uint64_t *k)
|
||||||
uint32_t *in32 = (uint32_t *)in;
|
uint32_t *in32 = (uint32_t *)in;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PREAMBLE(36);
|
PREAMBLE;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++, in32 += 2)
|
for (i = 0; i < 4; i++, in32 += 2)
|
||||||
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
siphash_feed(v, (uint64_t)(*(in32 + 1)) << 32 | *in32);
|
||||||
|
|
||||||
b |= *in32;
|
return siphash_final(v, 36, *in32);
|
||||||
POSTAMBLE;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue