diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-07-19 11:48:23 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-07-19 11:48:23 +0100 |
commit | 244fa725db7cc475d95b4dc3e430350e9f2ff822 (patch) | |
tree | 08cff1b5fa36bbfa95a613657d0d72f6649e3398 /src | |
parent | e1e2c7f0b69adfdaa5e36aebb3f1b607e4f6f62a (diff) | |
download | rspamd-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.c | 62 | ||||
-rw-r--r-- | src/libutil/util.h | 13 |
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); |