summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 50097dac93..c52b279f1c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -513,6 +513,51 @@ round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
return number;
}
+/** Return the lowest x in [INT64_MIN, INT64_MAX] such that x is at least
+ * <b>number</b>, and x modulo <b>divisor</b> == 0. */
+int64_t
+round_int64_to_next_multiple_of(int64_t number, int64_t divisor)
+{
+ tor_assert(divisor > 0);
+ if (number >= 0 && INT64_MAX - divisor + 1 >= number)
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/** Transform a random value <b>p</b> from the uniform distribution in
+ * [0.0, 1.0[ into a Laplace distributed value with location parameter
+ * <b>mu</b> and scale parameter <b>b</b> in [-Inf, Inf[. */
+double
+sample_laplace_distribution(double mu, double b, double p)
+{
+ tor_assert(p >= 0.0 && p < 1.0);
+ /* This is the "inverse cumulative distribution function" from:
+ * http://en.wikipedia.org/wiki/Laplace_distribution */
+ return mu - b * (p > 0.5 ? 1.0 : -1.0)
+ * tor_mathlog(1.0 - 2.0 * fabs(p - 0.5));
+}
+
+/** Add random noise between INT64_MIN and INT64_MAX coming from a
+ * Laplace distribution with mu = 0 and b = <b>delta_f</b>/<b>epsilon</b>
+ * to <b>signal</b> based on the provided <b>random</b> value in
+ * [0.0, 1.0[. */
+int64_t
+add_laplace_noise(int64_t signal, double random, double delta_f,
+ double epsilon)
+{
+ /* cast to int64_t intended */
+ int64_t noise = sample_laplace_distribution(
+ 0.0, /* just add noise, no further signal */
+ delta_f / epsilon, random);
+ if (noise > 0 && INT64_MAX - noise < signal)
+ return INT64_MAX;
+ else if (noise < 0 && INT64_MIN - noise > signal)
+ return INT64_MIN;
+ else
+ return signal + noise;
+}
+
/** Return the number of bits set in <b>v</b>. */
int
n_bits_set_u8(uint8_t v)