]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add xoroshiro+ fast rng for non-crypto purposes
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 Jul 2016 10:48:23 +0000 (11:48 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 19 Jul 2016 10:48:23 +0000 (11:48 +0100)
src/libutil/util.c
src/libutil/util.h

index 6a60f854ab5e36cf6eae4b3c578e165a1bd6a57d..762c8d55725bfccdfaff1f3e8c8911ee7bd909c4 100644 (file)
@@ -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,20 +2153,71 @@ 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)
 {
index 2497d538f0a883fb3792bf055b59c7d4b8e9ea75..76a02d19820d54dcab7cc1e3b5da6e431bc67be9 100644 (file)
@@ -429,6 +429,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
  */