#include "orconfig.h"
#include "lib/math/laplace.h"
#include "lib/math/fp.h"
#include "lib/log/util_bug.h"
#include <math.h>
#include <stdlib.h>
int64_t
sample_laplace_distribution(double mu, double b, double p)
{
double result;
tor_assert(p >= 0.0 && p < 1.0);
if (p <= 0.0) {
return INT64_MIN;
}
result = mu - b * (p > 0.5 ? 1.0 : -1.0)
* tor_mathlog(1.0 - 2.0 * fabs(p - 0.5));
return clamp_double_to_int64(result);
}
int64_t
add_laplace_noise(int64_t signal_, double random_, double delta_f,
double epsilon)
{
int64_t noise;
tor_assert(epsilon > 0.0 && epsilon <= 1.0);
tor_assert(delta_f > 0.0);
noise = sample_laplace_distribution(0.0,
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;
}