summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-07-19 11:48:23 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-07-19 11:48:23 +0100
commit244fa725db7cc475d95b4dc3e430350e9f2ff822 (patch)
tree08cff1b5fa36bbfa95a613657d0d72f6649e3398 /src
parente1e2c7f0b69adfdaa5e36aebb3f1b607e4f6f62a (diff)
downloadrspamd-244fa725db7cc475d95b4dc3e430350e9f2ff822.tar.gz
rspamd-244fa725db7cc475d95b4dc3e430350e9f2ff822.zip
[Feature] Add xoroshiro+ fast rng for non-crypto purposes
Diffstat (limited to 'src')
-rw-r--r--src/libutil/util.c62
-rw-r--r--src/libutil/util.h13
2 files changed, 70 insertions, 5 deletions
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 6a60f854a..762c8d557 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -2055,6 +2055,7 @@ rspamd_init_libs (void)
SSL_CTX_set_options (ctx->ssl_ctx, ssl_options);
#endif
g_random_set_seed (ottery_rand_uint32 ());
+ rspamd_random_seed_fast ();
/* Set stack size for pcre */
getrlimit (RLIMIT_STACK, &rlim);
@@ -2152,21 +2153,72 @@ rspamd_hash_seed (void)
return seed;
}
-gdouble
-rspamd_random_double (void)
+static inline gdouble
+rspamd_double_from_int64 (guint64 rnd_int)
{
- guint64 rnd_int;
double res;
const double transform_bias = 2.2204460492503130808472633361816e-16;
- rnd_int = ottery_rand_uint64 () >> 12;
- res = rnd_int;
+ res = rnd_int >> 12;
res *= transform_bias;
return res;
}
gdouble
+rspamd_random_double (void)
+{
+ guint64 rnd_int;
+
+ rnd_int = ottery_rand_uint64 ();
+
+ return rspamd_double_from_int64 (rnd_int);
+}
+
+
+static guint64 xorshifto_seed[2];
+
+static inline guint64
+xoroshiro_rotl (const guint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+
+gdouble
+rspamd_random_double_fast (void)
+{
+ const guint64 s0 = xorshifto_seed[0];
+ guint64 s1 = xorshifto_seed[1];
+ const guint64 result = s0 + s1;
+
+ s1 ^= s0;
+ xorshifto_seed[0] = xoroshiro_rotl(s0, 55) ^ s1 ^ (s1 << 14);
+ xorshifto_seed[1] = xoroshiro_rotl (s1, 36);
+
+ return rspamd_double_from_int64 (result);
+}
+
+guint64
+rspamd_random_uint64_fast (void)
+{
+ const guint64 s0 = xorshifto_seed[0];
+ guint64 s1 = xorshifto_seed[1];
+ const guint64 result = s0 + s1;
+
+ s1 ^= s0;
+ xorshifto_seed[0] = xoroshiro_rotl(s0, 55) ^ s1 ^ (s1 << 14);
+ xorshifto_seed[1] = xoroshiro_rotl (s1, 36);
+
+ return result;
+}
+
+void
+rspamd_random_seed_fast (void)
+{
+ ottery_rand_bytes (xorshifto_seed, sizeof (xorshifto_seed));
+}
+
+gdouble
rspamd_time_jitter (gdouble in, gdouble jitter)
{
if (jitter == 0) {
diff --git a/src/libutil/util.h b/src/libutil/util.h
index 2497d538f..76a02d198 100644
--- a/src/libutil/util.h
+++ b/src/libutil/util.h
@@ -430,6 +430,19 @@ gdouble rspamd_time_jitter (gdouble in, gdouble jitter);
gdouble rspamd_random_double (void);
/**
+ * Return random double in range [0..1) using xoroshiro128+ algorithm (not crypto secure)
+ * @return
+ */
+gdouble rspamd_random_double_fast (void);
+
+guint64 rspamd_random_uint64_fast (void);
+
+/**
+ * Seed fast rng
+ */
+void rspamd_random_seed_fast (void);
+
+/**
* Constant time version of memcmp
*/
gboolean rspamd_constant_memcmp (const guchar *a, const guchar *b, gsize len);