diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c index 9f164a119..80387c714 100644 --- a/shared/nm-utils/nm-hash-utils.c +++ b/shared/nm-utils/nm-hash-utils.c @@ -122,17 +122,17 @@ nm_hash_static (guint static_seed) } void -nm_hash_init (NMHashState *state, guint static_seed) +nm_hash_siphash42_init (CSipHash *h, guint static_seed) { const guint8 *g; guint seed[HASH_KEY_SIZE_GUINT]; - nm_assert (state); + nm_assert (h); g = _get_hash_key (); memcpy (seed, g, HASH_KEY_SIZE); seed[0] ^= static_seed; - c_siphash_init (&state->_state, (const guint8 *) seed); + c_siphash_init (h, (const guint8 *) seed); } guint diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index b797fb75a..cf71a7e9f 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -25,6 +25,39 @@ #include "c-siphash/src/c-siphash.h" #include "nm-macros-internal.h" +/*****************************************************************************/ + +void nm_hash_siphash42_init (CSipHash *h, guint static_seed); + +/* Siphash24 of binary buffer @arr and @len, using the randomized seed from + * other NMHash functions. + * + * Note, that this is guaranteed to use siphash42 under the hood (contrary to + * all other NMHash API, which leave this undefined). That matters at the point, + * where the caller needs to be sure that a reasonably strong hasing algorithm + * is used. (Yes, NMHash is all about siphash24, but otherwise that is not promised + * anywhere). + * + * Another difference is, that this returns guint64 (not guint like other NMHash functions). + * + * Another difference is, that this may also return zero (not like nm_hash_complete()). + * + * Then, why not use c_siphash_hash() directly? Because this also uses the randomized, + * per-run hash-seed like nm_hash_init(). So, you get siphash24 with a random + * seed (which is cached for the current run of the program). + */ +static inline guint64 +nm_hash_siphash42 (guint static_seed, const void *ptr, gsize n) +{ + CSipHash h; + + nm_hash_siphash42_init (&h, static_seed); + c_siphash_append (&h, ptr, n); + return c_siphash_finalize (&h); +} + +/*****************************************************************************/ + struct _NMHashState { CSipHash _state; }; @@ -33,16 +66,33 @@ typedef struct _NMHashState NMHashState; guint nm_hash_static (guint static_seed); -void nm_hash_init (NMHashState *state, guint static_seed); +static inline void +nm_hash_init (NMHashState *state, guint static_seed) +{ + nm_assert (state); + + nm_hash_siphash42_init (&state->_state, static_seed); +} + +static inline guint64 +nm_hash_complete_u64 (NMHashState *state) +{ + nm_assert (state); + + /* this returns the native u64 hash value. Note that this differs + * from nm_hash_complete() in two ways: + * + * - the type, guint64 vs. guint. + * - nm_hash_complete() never returns zero. */ + return c_siphash_finalize (&state->_state); +} static inline guint nm_hash_complete (NMHashState *state) { guint64 h; - nm_assert (state); - - h = c_siphash_finalize (&state->_state); + h = nm_hash_complete_u64 (state); /* we don't ever want to return a zero hash. * @@ -218,8 +268,8 @@ guint nm_str_hash (gconstpointer str); ({ \ NMHashState _h; \ \ - nm_hash_init (&_h, static_seed); \ - nm_hash_update_val (&_h, val); \ + nm_hash_init (&_h, (static_seed)); \ + nm_hash_update_val (&_h, (val)); \ nm_hash_complete (&_h); \ })