Skip to content

Commit 393649e

Browse files
verbabuilders-engAndyBurecovics
authored andcommitted
Reject NaN in ClampFloat64 and check L1 sensitivity overflow in Laplace noise
1 parent 78d08ac commit 393649e

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

go/dpagg/helpers.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,15 @@ var LargestRepresentableDelta = 1 - math.Pow(2, -53)
2727
// ClampFloat64 clamps e within lower and upper, such that lower is returned
2828
// if e < lower, and upper is returned if e > upper. Otherwise, e is returned.
2929
func ClampFloat64(e, lower, upper float64) (float64, error) {
30+
if math.IsNaN(lower) || math.IsNaN(upper) {
31+
return 0, fmt.Errorf("bounds must not be NaN, got lower = %v, upper = %v", lower, upper)
32+
}
3033
if lower > upper {
3134
return 0, fmt.Errorf("lower must be less than or equal to upper, got lower = %v, upper = %v", lower, upper)
3235
}
33-
36+
if math.IsNaN(e) || math.IsInf(e, 0) {
37+
return lower, nil
38+
}
3439
if e > upper {
3540
return upper, nil
3641
}

go/noise/laplace_noise.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package noise
1818

1919
import (
20+
"fmt"
2021
"math"
2122

2223
"github.com/google/differential-privacy/go/v4/checks"
@@ -61,7 +62,11 @@ func (laplace) AddNoiseFloat64(x float64, l0Sensitivity int64, lInfSensitivity,
6162
if err := checkArgsLaplace(l0Sensitivity, lInfSensitivity, epsilon, delta); err != nil {
6263
return 0, err
6364
}
64-
return addLaplaceFloat64(x, epsilon, lInfSensitivity*float64(l0Sensitivity) /* l1Sensitivity */), nil
65+
l1Sensitivity := lInfSensitivity * float64(l0Sensitivity)
66+
if math.IsInf(l1Sensitivity, 0) || math.IsNaN(l1Sensitivity) {
67+
return 0, fmt.Errorf("l1Sensitivity overflows: lInfSensitivity=%v * l0Sensitivity=%v produces %v", lInfSensitivity, l0Sensitivity, l1Sensitivity)
68+
}
69+
return addLaplaceFloat64(x, epsilon, l1Sensitivity), nil
6570
}
6671

6772
// AddNoiseInt64 adds Laplace noise to the specified int64 x so that the
@@ -71,7 +76,11 @@ func (laplace) AddNoiseInt64(x, l0Sensitivity, lInfSensitivity int64, epsilon, d
7176
if err := checkArgsLaplace(l0Sensitivity, float64(lInfSensitivity), epsilon, delta); err != nil {
7277
return 0, err
7378
}
74-
return addLaplaceInt64(x, epsilon, lInfSensitivity*l0Sensitivity /* l1Sensitivity */), nil
79+
l1Sensitivity := lInfSensitivity * l0Sensitivity
80+
if (l0Sensitivity != 0 && l1Sensitivity/l0Sensitivity != lInfSensitivity) || l1Sensitivity < 0 {
81+
return 0, fmt.Errorf("l1Sensitivity overflows: lInfSensitivity=%v * l0Sensitivity=%v wraps to %v", lInfSensitivity, l0Sensitivity, l1Sensitivity)
82+
}
83+
return addLaplaceInt64(x, epsilon, l1Sensitivity), nil
7584
}
7685

7786
// Threshold returns the smallest threshold k to use in a differentially private

0 commit comments

Comments
 (0)