blob: d59e2e221210c628138785dbfdb37953475b45b0 [file] [log] [blame]
//
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Package noise contains methods to generate and add noise to data.
package noise
import (
"math"
log "github.com/golang/glog"
)
// Kind is an enum type. Its values are the supported noise distributions types
// for differential privacy operations.
type Kind int
// Noise distributions used to achieve Differential Privacy.
const (
GaussianNoise Kind = iota
LaplaceNoise
Unrecognised
)
// ToNoise converts a Kind into a Noise instance.
func ToNoise(k Kind) Noise {
switch k {
case GaussianNoise:
return Gaussian()
case LaplaceNoise:
return Laplace()
case Unrecognised:
log.Warningf("ToNoise: Unrecognised noise specified, returning nil")
default:
log.Warningf("ToNoise: unknown kind (%v) specified, returning nil", k)
}
return nil
}
// ToKind converts a Noise instance into a Kind.
func ToKind(n Noise) Kind {
switch n {
case Gaussian():
return GaussianNoise
case Laplace():
return LaplaceNoise
case nil:
log.Warningf("ToKind: nil noise specified, returning Unresognised")
default:
log.Warningf("ToKind: unknown Noise (%v) specified, returning Unresognised", n)
}
return Unrecognised
}
// ConfidenceInterval holds lower and upper bounds as float64 for the confidence interval.
type ConfidenceInterval struct {
LowerBound, UpperBound float64
}
// roundToInt64 rounds the lower and upper bounds of a ConfidenceInterval struct for
// integer valued noise operations.
func (confInt ConfidenceInterval) roundToInt64() ConfidenceInterval {
return ConfidenceInterval{LowerBound: math.Round(confInt.LowerBound), UpperBound: math.Round(confInt.UpperBound)}
}
// Noise is an interface for primitives that add noise to data to make it differentially private.
type Noise interface {
// AddNoiseInt64 noise to the specified int64 x so that the output is ε-differentially
// private given the L_0 and L_∞ sensitivities of the database.
AddNoiseInt64(x, l0sensitivity, lInfSensitivity int64, epsilon, delta float64) int64
// AddNoiseFloat64 noise to the specified float64 x so that the output is ε-differentially
// private given the L_0 and L_∞ sensitivities of the database.
AddNoiseFloat64(x float64, l0sensitivity int64, lInfSensitivity, epsilon, delta float64) float64
// Threshold returns the smallest threshold k needed in settings where the Noise instance
// is used to achieve differential privacy on histograms where the inclusion of histogram
// partitions depends on which privacy units are present in the database.
//
// Inputs:
// l0Sensitivity: The maximum number of partitions that a privacy unit can contribute to.
// lInfSensitivity: How much any single partition's value can change from
// the contribution of a single privacy unit. When adding a privacy unit results in the
// creation of a new partition, this bounds the magnitude of that partition.
// epsilon: The parameter ε passed to AddNoise.
// noiseDelta: The parameter δ passed to AddNoise.
// thresholdDelta: Differential privacy loss (0, delta) incurred by thresholding,
// i.e. the probability to output a partition that only has one privacy unit in it.
//
// More precisely, Threshold returns the smallest k such that the following algorithm:
//
// func Histogram(records []struct{key string, value float64}) map[string]float64 {
// sums := make(map[string]float64)
// for _, record := range records {
// sums[record.key] = sums[record.key]+record.value
// }
// noisySums := make(map[string]float64)
// for key, sum := range sums {
// noisySum := AddNoiseFloat64(sum, sensitivity, epsilon, noiseDelta)
// if noisySum ≥ k:
// noisySums[key] = noisySum
// }
// return noisySums
// }
//
// satisfies (epsilon,noiseDelta+thresholdDelta)-differential privacy under the
// given assumptions of L_0 and L_∞ sensitivities.
Threshold(l0Sensitivity int64, lInfSensitivity, epsilon, noiseDelta, thresholdDelta float64) float64
// ComputeConfidenceIntervalInt64 computes a confidence interval that contains the raw integer value x from which int64
// noisedX is computed with a probability greater or equal to 1 - alpha based on the specified noise parameters.
ComputeConfidenceIntervalInt64(noisedX, l0Sensitivity, lInfSensitivity int64, epsilon, delta, alpha float64) (ConfidenceInterval, error)
// ComputeConfidenceIntervalFloat64 computes a confidence interval that contains the raw value x from which float64
// noisedX is computed with a probability equal to 1 - alpha based on the specified noise parameters.
ComputeConfidenceIntervalFloat64(noisedX float64, l0Sensitivity int64, lInfSensitivity, epsilon, delta, alpha float64) (ConfidenceInterval, error)
}