mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-26 11:20:51 -04:00
MINOR: tools: provide a function to generate a hashed random pair
A lot of places call two ha_random64() in a row to generate a 128-bit random. While it's now safe against linear analysis thanks to the XXH64 call, it's still particularly expensive due to the lock. Here we introduce a new function ha_random64_pair_hashed(), that feeds two uint64_t with a hash of the PRNG's internal state, and make it advance. This will cut in half the number of calls to ha_random64() and should recover a part of the performance lost in the lock. For now it's not used.
This commit is contained in:
parent
de266d9a99
commit
7b7b33df53
3 changed files with 38 additions and 0 deletions
|
|
@ -188,4 +188,12 @@ struct file_name_node {
|
|||
char name[VAR_ARRAY]; /* storage, used with cebus_*() */
|
||||
};
|
||||
|
||||
/* a pair of uint64_t. It's purposely arranged in little endian to help
|
||||
* being vectorized on modern processors.
|
||||
*/
|
||||
struct uint64_pair {
|
||||
uint64_t l;
|
||||
uint64_t h;
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_TOOLS_T_H */
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,8 @@ static inline void _ha_aligned_free(void *ptr)
|
|||
int parse_dotted_uints(const char *s, unsigned int **nums, size_t *sz);
|
||||
|
||||
/* PRNG */
|
||||
struct uint64_pair _ha_random64_pair_hashed(void);
|
||||
|
||||
void ha_generate_uuid_v4(struct buffer *output);
|
||||
void ha_generate_uuid_v7(struct buffer *output);
|
||||
void ha_random_seed(const unsigned char *seed, size_t len);
|
||||
|
|
@ -1295,6 +1297,17 @@ void ha_random_jump96(uint32_t dist);
|
|||
uint64_t ha_random64(void);
|
||||
uint64_t ha_random64_internal(void);
|
||||
|
||||
/* Returns a pair of uint64_t randoms hashed so as not to disclose the internal
|
||||
* PRNG state.
|
||||
*/
|
||||
static inline void ha_random64_pair_hashed(uint64_t *l, uint64_t *h)
|
||||
{
|
||||
struct uint64_pair ret = _ha_random64_pair_hashed();
|
||||
|
||||
*l = ret.l;
|
||||
*h = ret.h;
|
||||
}
|
||||
|
||||
static inline uint32_t ha_random32()
|
||||
{
|
||||
return ha_random64() >> 32;
|
||||
|
|
|
|||
17
src/tools.c
17
src/tools.c
|
|
@ -6297,6 +6297,23 @@ uint64_t ha_random64(void)
|
|||
now_ns);
|
||||
}
|
||||
|
||||
/* Returns a pair of uint64_t randoms hashed so as not to disclose the internal
|
||||
* PRNG state. This function shouldn't be used directly, better use the public
|
||||
* ha_random64_pair_hashed() which calls it. The function uses a local XXH
|
||||
* secret that is created at boot, and now_ns as the seed to limit remote
|
||||
* analysis.
|
||||
*/
|
||||
struct uint64_pair _ha_random64_pair_hashed(void)
|
||||
{
|
||||
XXH128_hash_t ret;
|
||||
ret = XXH3_128bits_withSecretandSeed(ha_random_state, 2*sizeof(uint64_t),
|
||||
ha_random_xxh_secret, sizeof(ha_random_xxh_secret),
|
||||
now_ns);
|
||||
/* update the internal state */
|
||||
ha_random64_internal();
|
||||
return (struct uint64_pair){ .l = ret.low64, .h = ret.high64 };
|
||||
}
|
||||
|
||||
/* seeds the random state using up to <len> bytes from <seed>, starting with
|
||||
* the first non-zero byte.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue