blob: 6cf09f1bddf89a80898db9f3b1cc1bc65026cf0f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package main
import (
"math"
"math/rand"
"time"
)
var (
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
)
// Returns 0 if epsilon is less than or equal to 0.
// Otherwise it picks a number from the laplace
// distribution with the mean 0 and standard deviation
// sensitivity/epsilon.
// This follows the definition of differential privacy
// noise addition.
func diffpriv(value int, sensitivity, epsilon float64) int {
if epsilon <= 0 {
return 0
}
noise := laplaceDist(0, sensitivity/epsilon)
return round(math.Abs(float64(value) + noise))
}
// Returns a random value from a laplace
// distribution with parameters u and b.
func laplaceDist(u, b float64) float64 {
uniform := rnd.Float64() // Random [0.0,1.0)
uniform -= 0.5
return u - b*sgn(uniform)*math.Log(1-2*math.Abs(uniform))
}
// The signum function
func sgn(x float64) float64 {
if x < 0 {
return -1
}
if x > 0 {
return 1
}
return 0
}
func round(n float64) int {
if n < 0 {
return int(math.Ceil(n - 0.5))
}
return int(math.Floor(n + 0.5))
}
|