commit f57cb60: [Minor] Use wyrand for fast random as we already use mumhash for fast hashing

Vsevolod Stakhov vsevolod at highsecure.ru
Fri Mar 18 21:35:04 UTC 2022


Author: Vsevolod Stakhov
Date: 2022-03-18 21:32:53 +0000
URL: https://github.com/rspamd/rspamd/commit/f57cb6099e5f9f4dfc5208c36b9130c9837410e6

[Minor] Use wyrand for fast random as we already use mumhash for fast hashing

---
 src/libutil/util.c | 92 ++++++++++++++++++++++++++----------------------------
 src/libutil/util.h |  2 +-
 2 files changed, 45 insertions(+), 49 deletions(-)

diff --git a/src/libutil/util.c b/src/libutil/util.c
index 44f40280b..ec86d22ea 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -1757,80 +1757,76 @@ rspamd_random_double (void)
 
 
 static guint64*
-xorshifto_seed (void)
+rspamd_fast_random_seed (void)
 {
-	static guint64 xorshifto_seed[4];
-	static bool initialized = false;
+	static guint64 seed;
 
-	if (G_UNLIKELY(!initialized)) {
-		ottery_rand_bytes((void *)xorshifto_seed, sizeof (xorshifto_seed));
-		initialized = true;
+	if (G_UNLIKELY(seed == 0)) {
+		ottery_rand_bytes((void *)&seed, sizeof (seed));
 	}
 
-	return xorshifto_seed;
+	return &seed;
 }
 
-static inline guint64
-xoroshiro_rotl (const guint64 x, int k) {
-	return (x << k) | (x >> (64 - k));
+/* wyrand */
+static inline uint64_t
+rspamd_random_uint64_fast_seed (uint64_t *seed)
+{
+	*seed += UINT64_C(0xa0761d6478bd642f);
+#ifdef __SIZEOF_INT128__
+# if defined(__aarch64__)
+	uint64_t lo, hi, p = *seed ^ UINT64_C(0xe7037ed1a0b428db), v = *seed;
+	lo = v * p;
+	__asm__ ("umulh %0, %1, %2" : "=r" (hi) : "r" (v), "r" (p));
+	return lo ^ hi;
+# else
+	__uint128_t t = (__uint128_t)*seed * (*seed ^ UINT64_C(0xe7037ed1a0b428db));
+	return (t >> 64) ^ t;
+# endif
+#else
+	/* Implementation of 64x64->128-bit multiplication by four 32x32->64
+	 * bit multiplication.  */
+	uint64_t lo, hi, p = *seed ^ UINT64_C(0xe7037ed1a0b428db), v = *seed;
+	uint64_t hv = v >> 32, hp = p >> 32;
+	uint64_t lv = (uint32_t) v, lp = (uint32_t) p;
+	uint64_t rh =  hv * hp;
+	uint64_t rm_0 = hv * lp;
+	uint64_t rm_1 = hp * lv;
+	uint64_t rl =  lv * lp;
+	uint64_t t;
+
+	/* We could ignore a carry bit here if we did not care about the
+	   same hash for 32-bit and 64-bit targets.  */
+	t = rl + (rm_0 << 32);
+	lo = t + (rm_1 << 32);
+	hi = rh + (rm_0 >> 32) + (rm_1 >> 32);
+	return lo ^ hi;
+#endif
 }
 
 gdouble
 rspamd_random_double_fast (void)
 {
-	return rspamd_random_double_fast_seed (xorshifto_seed());
+	return rspamd_random_double_fast_seed (rspamd_fast_random_seed());
 }
 
 /* xoshiro256+ */
 inline gdouble
-rspamd_random_double_fast_seed (guint64 seed[4])
-{
-	const uint64_t result = seed[0] + seed[3];
-
-	const uint64_t t = seed[1] << 17;
-
-	seed[2] ^= seed[0];
-	seed[3] ^= seed[1];
-	seed[1] ^= seed[2];
-	seed[0] ^= seed[3];
-
-	seed[2] ^= t;
-
-	seed[3] = xoroshiro_rotl (seed[3], 45);
-
-	return rspamd_double_from_int64 (result);
-}
-
-/* xoroshiro256** */
-static inline guint64
-rspamd_random_uint64_fast_seed (guint64 seed[4])
+rspamd_random_double_fast_seed (guint64 *seed)
 {
-	const uint64_t result = xoroshiro_rotl (seed[1] * 5, 7) * 9;
-
-	const uint64_t t = seed[1] << 17;
-
-	seed[2] ^= seed[0];
-	seed[3] ^= seed[1];
-	seed[1] ^= seed[2];
-	seed[0] ^= seed[3];
-
-	seed[2] ^= t;
-
-	seed[3] = xoroshiro_rotl (seed[3], 45);
-
-	return result;
+	return rspamd_double_from_int64 (rspamd_random_uint64_fast_seed(seed));
 }
 
 guint64
 rspamd_random_uint64_fast (void)
 {
-	return rspamd_random_uint64_fast_seed (xorshifto_seed());
+	return rspamd_random_uint64_fast_seed (rspamd_fast_random_seed());
 }
 
 void
 rspamd_random_seed_fast (void)
 {
-	(void)xorshifto_seed();
+	(void)rspamd_fast_random_seed();
 }
 
 gdouble
diff --git a/src/libutil/util.h b/src/libutil/util.h
index 1d53807d4..f9be15d28 100644
--- a/src/libutil/util.h
+++ b/src/libutil/util.h
@@ -372,7 +372,7 @@ gdouble rspamd_random_double (void);
  * @return
  */
 gdouble rspamd_random_double_fast (void);
-gdouble rspamd_random_double_fast_seed (guint64 seed[4]);
+gdouble rspamd_random_double_fast_seed (guint64 *seed);
 guint64 rspamd_random_uint64_fast (void);
 
 /**


More information about the Commits mailing list