From: Vsevolod Stakhov Date: Tue, 19 Jul 2016 10:48:23 +0000 (+0100) Subject: [Feature] Add xoroshiro+ fast rng for non-crypto purposes X-Git-Tag: 1.3.0~53 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=244fa725db7cc475d95b4dc3e430350e9f2ff822;p=rspamd.git [Feature] Add xoroshiro+ fast rng for non-crypto purposes --- 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,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) { 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 @@ -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 */