mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-30 13:24:48 +00:00
shared: expose siphash24() related functionality in nm-hash-utils.h
CSiphash is a first class citizen, it's fine to use everwhere where we need it. NMHash wraps CSiphash and provides three things: 1) Convenience macros that make hashing nicer to use. 2) it uses a randomly generated, per-run hash seed, that can be combined with a guint static seed. 3) it's a general API for hashing data. It nowhere promises that it actually uses siphash24, although currently it does everywhere. NMHash is not (officially) siphash24. Add API nm_hash_siphash42_init() and nm_hash_siphash42() to "nm-hash-utils.h", that exposes (2) for use with regular CSiphash. You of course no longer get the convenice macros (1) but you get plain siphash24 (which NMHash does not give (3)). While at it, also add a nm_hash_complete_u64(). Usually, for hasing we want guint types. But we don't need to hide the fact, that the underlying value is first uint64. Expose it.
This commit is contained in:
parent
3e0177f7d5
commit
db791db4e1
|
@ -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
|
||||
|
|
|
@ -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); \
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue