htable: FNV1a: honor offset basis

The FNV1a implementation used in the hashtable threw away the
algorithm's offset basis in preference of the seed value to
ensure different instances of the hashtable produced different
output for the same keys to prevent against hash collision
attacks.

Throwing away the offset basis completely could lead to some
non-uniformity, so instead we are now XORing the seed and the
algorithm-defined offset basis as the new offset basis to use
which should rectify this.

In the current c-ares use cases, this will probably have little
to no impact, but future hash table uses may benefit from the
better distribution.

Authored-By: Brad House (@bradh352)
pull/863/head
Brad House 3 months ago
parent 9533298810
commit 5b70955d51
  1. 10
      src/lib/dsa/ares__htable.c

@ -418,13 +418,12 @@ size_t ares__htable_num_keys(const ares__htable_t *htable)
unsigned int ares__htable_hash_FNV1a(const unsigned char *key, size_t key_len,
unsigned int seed)
{
/* recommended seed is 2166136261U, but we don't want collisions */
unsigned int hv = seed;
unsigned int hv = seed ^ 2166136261U;
size_t i;
for (i = 0; i < key_len; i++) {
hv ^= (unsigned int)key[i];
/* hv *= 0x01000193 */
/* hv *= 16777619 (0x01000193) */
hv += (hv << 1) + (hv << 4) + (hv << 7) + (hv << 8) + (hv << 24);
}
@ -435,13 +434,12 @@ unsigned int ares__htable_hash_FNV1a(const unsigned char *key, size_t key_len,
unsigned int ares__htable_hash_FNV1a_casecmp(const unsigned char *key,
size_t key_len, unsigned int seed)
{
/* recommended seed is 2166136261U, but we don't want collisions */
unsigned int hv = seed;
unsigned int hv = seed ^ 2166136261U;
size_t i;
for (i = 0; i < key_len; i++) {
hv ^= (unsigned int)ares__tolower(key[i]);
/* hv *= 0x01000193 */
/* hv *= 16777619 (0x01000193) */
hv += (hv << 1) + (hv << 4) + (hv << 7) + (hv << 8) + (hv << 24);
}

Loading…
Cancel
Save