From 846d379b50b4f4790a9fe2ec88746748e0fab2b7 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 13 Mar 2019 15:15:03 +0200 Subject: [PATCH] circpad/prob_distr: Use crypto_fast_rng() instead of the old RNG. --- changes/bug28636 | 8 +++++++ src/core/or/circuitpadding.c | 9 ++++---- src/lib/crypt_ops/crypto_rand.h | 3 +++ src/lib/crypt_ops/crypto_rand_numeric.c | 30 ++++++++++++++++++++++++- src/lib/math/prob_distr.c | 16 ++++++------- 5 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 changes/bug28636 diff --git a/changes/bug28636 b/changes/bug28636 new file mode 100644 index 0000000000..240655cbea --- /dev/null +++ b/changes/bug28636 @@ -0,0 +1,8 @@ + o Minor bugfixes (circuit padding): + - The circuit padding subsystem does not schedule padding if dormant mode + is enabled. Fixes bug 28636; bugfix on 0.4.0.1-alpha. + + o Minor feature (circuit padding): + - We now use a fast RNG when scheduling circuit padding. Part of ticket + 28636. + diff --git a/src/core/or/circuitpadding.c b/src/core/or/circuitpadding.c index 599d88f493..4514111a96 100644 --- a/src/core/or/circuitpadding.c +++ b/src/core/or/circuitpadding.c @@ -449,7 +449,8 @@ circpad_machine_sample_delay(circpad_machine_state_t *mi) histogram_total_tokens = state->histogram_total_tokens; } - bin_choice = crypto_rand_uint64(histogram_total_tokens); + bin_choice = crypto_fast_rng_get_uint64(get_thread_fast_rng(), + histogram_total_tokens); /* Skip all the initial zero bins */ while (!histogram[curr_bin]) { @@ -498,12 +499,12 @@ circpad_machine_sample_delay(circpad_machine_state_t *mi) bin_end = circpad_histogram_bin_to_usec(mi, curr_bin+1); /* Bin edges are monotonically increasing so this is a bug. Handle it. */ - if (BUG(bin_start > bin_end)) { + if (BUG(bin_start >= bin_end)) { return bin_start; } - /* Sample randomly from within the bin width */ - return (circpad_delay_t)crypto_rand_uint64_range(bin_start, bin_end); + return (circpad_delay_t)crypto_fast_rng_uint64_range(get_thread_fast_rng(), + bin_start, bin_end); } /** diff --git a/src/lib/crypt_ops/crypto_rand.h b/src/lib/crypt_ops/crypto_rand.h index 6f09aedf6a..c51d6a4480 100644 --- a/src/lib/crypt_ops/crypto_rand.h +++ b/src/lib/crypt_ops/crypto_rand.h @@ -66,6 +66,9 @@ void crypto_fast_rng_free_(crypto_fast_rng_t *); unsigned crypto_fast_rng_get_uint(crypto_fast_rng_t *rng, unsigned limit); uint64_t crypto_fast_rng_get_uint64(crypto_fast_rng_t *rng, uint64_t limit); +uint32_t crypto_fast_rng_get_u32(crypto_fast_rng_t *rng); +uint64_t crypto_fast_rng_uint64_range(crypto_fast_rng_t *rng, + uint64_t min, uint64_t max); double crypto_fast_rng_get_double(crypto_fast_rng_t *rng); /** diff --git a/src/lib/crypt_ops/crypto_rand_numeric.c b/src/lib/crypt_ops/crypto_rand_numeric.c index d02c5cdcfa..ffbfa2d56c 100644 --- a/src/lib/crypt_ops/crypto_rand_numeric.c +++ b/src/lib/crypt_ops/crypto_rand_numeric.c @@ -155,7 +155,34 @@ crypto_fast_rng_get_uint64(crypto_fast_rng_t *rng, uint64_t limit) } /** - * As crypto_rand_, but extract the result from a crypto_fast_rng_t. + * As crypto_rand_u32, but extract the result from a crypto_fast_rng_t. + */ +uint32_t +crypto_fast_rng_get_u32(crypto_fast_rng_t *rng) +{ + uint32_t val; + crypto_fast_rng_getbytes(rng, (void*)&val, sizeof(val)); + return val; +} + +/** + * As crypto_rand_uint64_range(), but extract the result from a + * crypto_fast_rng_t. + */ +uint64_t +crypto_fast_rng_uint64_range(crypto_fast_rng_t *rng, + uint64_t min, uint64_t max) +{ + /* Handle corrupted input */ + if (BUG(min >= max)) { + return min; + } + + return min + crypto_fast_rng_get_uint64(rng, max - min); +} + +/** + * As crypto_rand_get_double() but extract the result from a crypto_fast_rng_t. */ double crypto_fast_rng_get_double(crypto_fast_rng_t *rng) @@ -164,3 +191,4 @@ crypto_fast_rng_get_double(crypto_fast_rng_t *rng) crypto_fast_rng_getbytes(rng, (void*)&u, sizeof(u)); return ((double)u) / UINT_MAX_AS_DOUBLE; } + diff --git a/src/lib/math/prob_distr.c b/src/lib/math/prob_distr.c index bfad06963d..d44dc28265 100644 --- a/src/lib/math/prob_distr.c +++ b/src/lib/math/prob_distr.c @@ -459,7 +459,7 @@ random_uniform_01(void) * system is broken. */ z = 0; - while ((x = crypto_rand_u32()) == 0) { + while ((x = crypto_fast_rng_get_u32(get_thread_fast_rng())) == 0) { if (z >= 1088) /* Your bit sampler is broken. Go home. */ return 0; @@ -473,8 +473,8 @@ random_uniform_01(void) * occur only with measure zero in the uniform distribution on * [0, 1]. */ - hi = crypto_rand_u32() | UINT32_C(0x80000000); - lo = crypto_rand_u32() | UINT32_C(0x00000001); + hi = crypto_fast_rng_get_u32(get_thread_fast_rng()) | UINT32_C(0x80000000); + lo = crypto_fast_rng_get_u32(get_thread_fast_rng()) | UINT32_C(0x00000001); /* Round to nearest scaled significand in [2^63, 2^64]. */ s = hi*(double)4294967296 + lo; @@ -1437,7 +1437,7 @@ static double logistic_sample(const struct dist *dist) { const struct logistic *L = dist_to_const_logistic(dist); - uint32_t s = crypto_rand_u32(); + uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double t = random_uniform_01(); double p0 = random_uniform_01(); @@ -1487,7 +1487,7 @@ static double log_logistic_sample(const struct dist *dist) { const struct log_logistic *LL = dist_to_const_log_logistic(dist); - uint32_t s = crypto_rand_u32(); + uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); return sample_log_logistic_scaleshape(s, p0, LL->alpha, LL->beta); @@ -1536,7 +1536,7 @@ static double weibull_sample(const struct dist *dist) { const struct weibull *W = dist_to_const_weibull(dist); - uint32_t s = crypto_rand_u32(); + uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); return sample_weibull(s, p0, W->lambda, W->k); @@ -1585,7 +1585,7 @@ static double genpareto_sample(const struct dist *dist) { const struct genpareto *GP = dist_to_const_genpareto(dist); - uint32_t s = crypto_rand_u32(); + uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); return sample_genpareto_locscale(s, p0, GP->mu, GP->sigma, GP->xi); @@ -1634,7 +1634,7 @@ static double geometric_sample(const struct dist *dist) { const struct geometric *G = dist_to_const_geometric(dist); - uint32_t s = crypto_rand_u32(); + uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); return sample_geometric(s, p0, G->p);