Skip to content

Commit

Permalink
Preparations for v3 release, PLD Mixture of Gaussians updates.
Browse files Browse the repository at this point in the history
Python DP PLD:

- Update PLD supplementary material with PLD for Mixture of Gaussians mechanism.
- Adds case for composing MixtureOfGaussiansDpEvent to PLDAccountant.
- Add a DpEvent for a mixture of Gaussians mechanism.

Go and Privacy on Beam:
- Prepare for v3 release.

Privacy on Beam:
- Improve error messages for epsilon & delta checks.

Change-Id: Ie759b107a8f076d9642b6342da1e6c0c588ccc60
GitOrigin-RevId: 3edd28f6f89660b336a793b2ed27b6b2e006371f
  • Loading branch information
Differential Privacy Team authored and jspacek committed Mar 6, 2024
1 parent af761ba commit 7126f61
Show file tree
Hide file tree
Showing 90 changed files with 383 additions and 246 deletions.
Binary file modified common_docs/Privacy_Loss_Distributions.pdf
Binary file not shown.
6 changes: 3 additions & 3 deletions examples/go/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
# limitations under the License.
#

load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@io_bazel_rules_go//go:def.bzl", "go_library")

# gazelle:prefix github.com/google/differential-privacy/examples/go
gazelle(name = "gazelle")
Expand All @@ -40,7 +40,7 @@ go_library(
importpath = "github.com/google/differential-privacy/examples/go",
visibility = ["//visibility:public"],
deps = [
"@com_github_google_differential_privacy_go_v2//dpagg:go_default_library",
"@com_github_google_differential_privacy_go_v2//noise:go_default_library",
"@com_github_google_differential_privacy_go_v3//dpagg:go_default_library",
"@com_github_google_differential_privacy_go_v3//noise:go_default_library",
],
)
6 changes: 3 additions & 3 deletions examples/go/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
# limitations under the License.
#

workspace(name = "com_github_google_differential_privacy_examples_go_v2")
workspace(name = "com_github_google_differential_privacy_examples_go_v3")

# Use the local Go DP Lib version. Do not remove this line. If this line is
# not present, Gazelle will resolve the Go DP Library from GitHub.
local_repository(
name = "com_github_google_differential_privacy_go_v2",
name = "com_github_google_differential_privacy_go_v3",
path = "../../go",
)

Expand Down Expand Up @@ -50,7 +50,7 @@ go_rules_dependencies()
go_register_toolchains(version = "1.21.5")

# Load Go DP Library dependencies.
load("@com_github_google_differential_privacy_go_v2//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")
load("@com_github_google_differential_privacy_go_v3//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")

go_differential_privacy_deps()

Expand Down
7 changes: 5 additions & 2 deletions examples/go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ go 1.21

require (
github.com/golang/glog v1.2.0
github.com/google/differential-privacy/go/v2 v2.1.1-0.20230822150926-c89810faa5ad
github.com/google/differential-privacy/go/v3 // a nonexistent version number
)

require (
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
gonum.org/v1/gonum v0.14.0 // indirect
)
)

// To ensure the main branch works with the go tool when checked out locally.
replace github.com/google/differential-privacy/go v3.0.0-local => ../../go // see https://golang.org/doc/modules/managing-dependencies#local_directory
4 changes: 2 additions & 2 deletions examples/go/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
"math/rand"
"time"

"github.com/google/differential-privacy/go/v2/dpagg"
"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/dpagg"
"github.com/google/differential-privacy/go/v3/noise"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion go/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

load("@bazel_gazelle//:def.bzl", "gazelle")

# gazelle:prefix github.com/google/differential-privacy/go/v2
# gazelle:prefix github.com/google/differential-privacy/go/v3
gazelle(name = "gazelle")

gazelle(
Expand Down
6 changes: 3 additions & 3 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This document describes Go-specific aspects.
Usage of the Go Differential Privacy library is demonstrated in the
[codelab](../examples/go/).

Full documentation of the API is available as [godoc](https://godoc.org/github.com/google/differential-privacy/go/v2/dpagg).
Full documentation of the API is available as [godoc](https://godoc.org/github.com/google/differential-privacy/go/v3/dpagg).

## Using with the "go" Command

Expand Down Expand Up @@ -103,10 +103,10 @@ use [Gazelle](https://github.com/bazelbuild/bazel-gazelle):

1. Run `bazel run //:gazelle -- update-repos -from_file=go.mod`, which will add
dependencies to your `WORKSPACE` file (you need a valid go.mod file with your
dependencies, e.g. `github.com/google/differential-privacy/go/v2`).
dependencies, e.g. `github.com/google/differential-privacy/go/v3`).

1. Run `bazel run //:gazelle -- -go_naming_convention_external=go_default_library`
to automatically generate or update your `BUILD` files and build targets.
Alternatively, you can manually add
`@com_github_google_differential_privacy_go_v2` as a dependency
`@com_github_google_differential_privacy_go_v3` as a dependency
to targets in your `BUILD` files.
2 changes: 1 addition & 1 deletion go/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
#

workspace(name = "com_github_google_differential_privacy_go_v2")
workspace(name = "com_github_google_differential_privacy_go_v3")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

Expand Down
6 changes: 3 additions & 3 deletions go/checks/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
# limitations under the License.
#

load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

# gazelle:prefix github.com/google/differential-privacy/go/v2/checks
# gazelle:prefix github.com/google/differential-privacy/go/v3/checks
gazelle(name = "gazelle")

go_library(
name = "go_default_library",
srcs = ["checks.go"],
importpath = "github.com/google/differential-privacy/go/v2/checks",
importpath = "github.com/google/differential-privacy/go/v3/checks",
visibility = ["//visibility:public"],
deps = ["@com_github_golang_glog//:go_default_library"],
)
Expand Down
75 changes: 59 additions & 16 deletions go/checks/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,62 +24,105 @@ import (
log "github.com/golang/glog"
)

const (
epsilonName = "Epsilon"
deltaName = "Delta"
)

func verifyName(defaultName string, nameSlice []string) (string, error) {
var name string
switch len(nameSlice) {
case 0:
name = defaultName
case 1:
name = nameSlice[0]
default:
// TODO Add instructions for filing bugs.
return "", fmt.Errorf("This should never happen. There should be 0 or 1 'name' parameter, got %d", len(nameSlice))
}
return name, nil
}

// CheckEpsilonVeryStrict returns an error if ε is +∞ or less than 2⁻⁵⁰.
func CheckEpsilonVeryStrict(epsilon float64) error {
func CheckEpsilonVeryStrict(epsilon float64, name ...string) error {
epsName, err := verifyName(epsilonName, name)
if err != nil {
return err
}
if epsilon < math.Exp2(-50.0) || math.IsInf(epsilon, 0) || math.IsNaN(epsilon) {
return fmt.Errorf("Epsilon is %f, must be at least 2^-50 and finite", epsilon)
return fmt.Errorf("%s is %f, must be at least 2^-50 and finite", epsName, epsilon)
}
return nil
}

// CheckEpsilonStrict returns an error if ε is nonpositive or +∞.
func CheckEpsilonStrict(epsilon float64) error {
func CheckEpsilonStrict(epsilon float64, name ...string) error {
epsName, err := verifyName(epsilonName, name)
if err != nil {
return err
}
if epsilon <= 0 || math.IsInf(epsilon, 0) || math.IsNaN(epsilon) {
return fmt.Errorf("Epsilon is %f, must be strictly positive and finite", epsilon)
return fmt.Errorf("%s is %f, must be strictly positive and finite", epsName, epsilon)
}
return nil
}

// CheckEpsilon returns an error if ε is strictly negative or +∞.
func CheckEpsilon(epsilon float64) error {
func CheckEpsilon(epsilon float64, name ...string) error {
epsName, err := verifyName(epsilonName, name)
if err != nil {
return err
}
if epsilon < 0 || math.IsInf(epsilon, 0) || math.IsNaN(epsilon) {
return fmt.Errorf("Epsilon is %f, must be nonnegative and finite", epsilon)
return fmt.Errorf("%s is %f, must be nonnegative and finite", epsName, epsilon)
}
return nil
}

// CheckDelta returns an error if δ is negative or greater than or equal to 1.
func CheckDelta(delta float64) error {
func CheckDelta(delta float64, name ...string) error {
delName, err := verifyName(deltaName, name)
if err != nil {
return err
}
if math.IsNaN(delta) {
return fmt.Errorf("Delta is %e, cannot be NaN", delta)
return fmt.Errorf("%s is %e, cannot be NaN", delName, delta)
}
if delta < 0 {
return fmt.Errorf("Delta is %e, cannot be negative", delta)
return fmt.Errorf("%s is %e, cannot be negative", delName, delta)
}
if delta >= 1 {
return fmt.Errorf("Delta is %e, must be strictly less than 1", delta)
return fmt.Errorf("%s is %e, must be strictly less than 1", delName, delta)
}
return nil
}

// CheckDeltaStrict returns an error if δ is nonpositive or greater than or equal to 1.
func CheckDeltaStrict(delta float64) error {
func CheckDeltaStrict(delta float64, name ...string) error {
delName, err := verifyName(deltaName, name)
if err != nil {
return err
}
if math.IsNaN(delta) {
return fmt.Errorf("Delta is %e, cannot be NaN", delta)
return fmt.Errorf("%s is %e, cannot be NaN", delName, delta)
}
if delta <= 0 {
return fmt.Errorf("Delta is %e, must be strictly positive", delta)
return fmt.Errorf("%s is %e, must be strictly positive", delName, delta)
}
if delta >= 1 {
return fmt.Errorf("Delta is %e, must be strictly less than 1", delta)
return fmt.Errorf("%s is %e, must be strictly less than 1", delName, delta)
}
return nil
}

// CheckNoDelta returns an error if δ is non-zero.
func CheckNoDelta(delta float64) error {
func CheckNoDelta(delta float64, name ...string) error {
delName, err := verifyName(deltaName, name)
if err != nil {
return err
}
if delta != 0 {
return fmt.Errorf("Delta is %e, must be 0", delta)
return fmt.Errorf("%s is %e, must be 0", delName, delta)
}
return nil
}
Expand Down
22 changes: 22 additions & 0 deletions go/checks/checks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ import (
"testing"
)

func TestVerifyName(t *testing.T) {
tests := []struct {
defaultName string
nameSlice []string
want string
wantErr bool
}{
{"Epsilon", []string{}, "Epsilon", false},
{"Epsilon", []string{"AggregationEpsilon"}, "AggregationEpsilon", false},
{"Epsilon", []string{"AggregationEpsilon", "PartitionSelectionEpsilon"}, "", true},
}
for _, tc := range tests {
got, err := verifyName(tc.defaultName, tc.nameSlice)
if (err != nil) != tc.wantErr {
t.Errorf("verifyName(%v, %v) returned an unexpected error: %v", tc.defaultName, tc.nameSlice, err)
}
if got != tc.want {
t.Errorf("verifyName(%v, %v) = %v, want: %v", tc.defaultName, tc.nameSlice, got, tc.want)
}
}
}

func TestCheckEpsilonVeryStrict(t *testing.T) {
for _, tc := range []struct {
desc string
Expand Down
6 changes: 3 additions & 3 deletions go/dpagg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
# limitations under the License.
#

load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

# gazelle:prefix github.com/google/differential-privacy/go/v2/dpagg
# gazelle:prefix github.com/google/differential-privacy/go/v3/dpagg
gazelle(name = "gazelle")

go_library(
Expand All @@ -34,7 +34,7 @@ go_library(
"sum.go",
"variance.go",
],
importpath = "github.com/google/differential-privacy/go/v2/dpagg",
importpath = "github.com/google/differential-privacy/go/v3/dpagg",
visibility = ["//visibility:public"],
deps = [
"//checks:go_default_library",
Expand Down
4 changes: 2 additions & 2 deletions go/dpagg/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"fmt"
"math"

"github.com/google/differential-privacy/go/v2/checks"
"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/checks"
"github.com/google/differential-privacy/go/v3/noise"
)

// Count calculates a differentially private count of a collection of values
Expand Down
2 changes: 1 addition & 1 deletion go/dpagg/count_confidence_interval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package dpagg
import (
"testing"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/noise"
)

func getCount(t *testing.T, n noise.Noise) *Count {
Expand Down
4 changes: 2 additions & 2 deletions go/dpagg/count_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
"reflect"
"testing"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v2/stattestutils"
"github.com/google/differential-privacy/go/v3/noise"
"github.com/google/differential-privacy/go/v3/stattestutils"
"github.com/google/go-cmp/cmp"
)

Expand Down
2 changes: 1 addition & 1 deletion go/dpagg/dpagg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package dpagg
import (
"math"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/noise"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
Expand Down
4 changes: 2 additions & 2 deletions go/dpagg/mean.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"fmt"
"math"

"github.com/google/differential-privacy/go/v2/checks"
"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/checks"
"github.com/google/differential-privacy/go/v3/noise"
)

// BoundedMean calculates a differentially private mean of a collection of
Expand Down
2 changes: 1 addition & 1 deletion go/dpagg/mean_confidence_interval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package dpagg
import (
"testing"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/noise"
)

func getBoundedMeanFloat64(t *testing.T, n noise.Noise, lower, upper float64) *BoundedMean {
Expand Down
4 changes: 2 additions & 2 deletions go/dpagg/mean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
"reflect"
"testing"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v2/rand"
"github.com/google/differential-privacy/go/v3/noise"
"github.com/google/differential-privacy/go/v3/rand"
"github.com/google/go-cmp/cmp"
)

Expand Down
4 changes: 2 additions & 2 deletions go/dpagg/quantiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"fmt"
"math"

"github.com/google/differential-privacy/go/v2/checks"
"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/checks"
"github.com/google/differential-privacy/go/v3/noise"
)

// Constants used for QuantileTrees.
Expand Down
2 changes: 1 addition & 1 deletion go/dpagg/quantiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"sort"
"testing"

"github.com/google/differential-privacy/go/v2/noise"
"github.com/google/differential-privacy/go/v3/noise"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
Expand Down
Loading

0 comments on commit 7126f61

Please sign in to comment.