Implement Discrete Laplace in Java, various minor improvements overall
Python Accountant:
- Remove dependence on `six` and use `super()` in rdp_privacy_accountant
- Add Laplace DpEvent
- Fix typos
C++:
- Enables support for partition selection when counts can be larger than max int32
Go & PoB:
- Prepare for v2 release
Java:
- Add Discrete Laplace noise class which adds the discrete version of
laplace noise (aka symmetric geometric noise) that is DP for
integer-value function with given sensitivities.
Change-Id: I5e61d3fa74a0b2071e9df0531c94d9419c67a7ad
GitOrigin-RevId: 3d471c0db206a3df06b710a1cf7269f8207f6d0d
diff --git a/cc/algorithms/partition-selection.h b/cc/algorithms/partition-selection.h
index d5cc07f..189f2a8 100644
--- a/cc/algorithms/partition-selection.h
+++ b/cc/algorithms/partition-selection.h
@@ -104,7 +104,7 @@
// ShouldKeep returns true when a partition with a given number of users
// should be kept and false otherwise.
- virtual bool ShouldKeep(int num_users) = 0;
+ virtual bool ShouldKeep(double num_users) = 0;
protected:
PartitionSelectionStrategy(double epsilon, double delta,
@@ -221,7 +221,7 @@
double GetSecondCrossover() const { return crossover_2_; }
- bool ShouldKeep(int num_users) override {
+ bool ShouldKeep(double num_users) override {
// generate a random number between 0 and 1
double rand_num = UniformDouble();
// only keep partition if random number < expected probability of keep
@@ -326,7 +326,7 @@
virtual ~LaplacePartitionSelection() = default;
- bool ShouldKeep(int num_users) override {
+ bool ShouldKeep(double num_users) override {
return mechanism_->NoisedValueAboveThreshold(num_users, threshold_);
}
@@ -468,7 +468,7 @@
double GetNoiseDelta() const { return noise_delta_; }
- bool ShouldKeep(int num_users) override {
+ bool ShouldKeep(double num_users) override {
return mechanism_->NoisedValueAboveThreshold(num_users, threshold_);
}
diff --git a/examples/go/.bazelversion b/examples/go/.bazelversion
index ee74734..28cbf7c 100644
--- a/examples/go/.bazelversion
+++ b/examples/go/.bazelversion
@@ -1 +1 @@
-4.1.0
+5.0.0
\ No newline at end of file
diff --git a/examples/go/BUILD.bazel b/examples/go/BUILD.bazel
index b2a4f8a..726c1ee 100644
--- a/examples/go/BUILD.bazel
+++ b/examples/go/BUILD.bazel
@@ -30,7 +30,7 @@
importpath = "github.com/google/differential-privacy/examples/go",
visibility = ["//visibility:public"],
deps = [
- "@com_google_go_differential_privacy//dpagg:go_default_library",
- "@com_google_go_differential_privacy//noise:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//dpagg:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//noise:go_default_library",
],
)
diff --git a/examples/go/WORKSPACE b/examples/go/WORKSPACE
index e33c20c..7a30eb0 100644
--- a/examples/go/WORKSPACE
+++ b/examples/go/WORKSPACE
@@ -14,10 +14,10 @@
# limitations under the License.
#
-workspace(name = "examples_go")
+workspace(name = "com_github_google_differential_privacy_examples_go_v2")
local_repository(
- name = "com_google_go_differential_privacy",
+ name = "com_github_google_differential_privacy_go_v2",
path = "../../go",
)
@@ -25,10 +25,10 @@
http_archive(
name = "io_bazel_rules_go",
- sha256 = "87f0fb9747854cb76a0a82430adccb6269f7d394237104a4523b51061c469171",
+ sha256 = "d6b2513456fe2229811da7eb67a444be7785f5323c6708b38d851d2b51e54d83",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.1/rules_go-v0.23.1.tar.gz",
- "https://github.com/bazelbuild/rules_go/releases/download/v0.23.1/rules_go-v0.23.1.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.30.0/rules_go-v0.30.0.zip",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.30.0/rules_go-v0.30.0.zip",
],
)
@@ -36,14 +36,14 @@
go_rules_dependencies()
-go_register_toolchains()
+go_register_toolchains(version = "1.16.7")
http_archive(
name = "bazel_gazelle",
- sha256 = "bfd86b3cbe855d6c16c6fce60d76bd51f5c8dbc9cfcaef7a2bb5c1aafd0710e8",
+ sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.0/bazel-gazelle-v0.21.0.tar.gz",
- "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.0/bazel-gazelle-v0.21.0.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
+ "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
],
)
@@ -52,6 +52,6 @@
gazelle_dependencies()
# Load Go DP library dependencies.
-load("@com_google_go_differential_privacy//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")
+load("@com_github_google_differential_privacy_go_v2//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")
go_differential_privacy_deps()
diff --git a/examples/go/go.mod b/examples/go/go.mod
index 4223120..fc4d024 100644
--- a/examples/go/go.mod
+++ b/examples/go/go.mod
@@ -4,8 +4,8 @@
require (
github.com/golang/glog v1.0.0
- github.com/google/differential-privacy/go v0.0.0-local // a nonexistent version number
+ github.com/google/differential-privacy/go/v2 v2.0.0-local // a nonexistent version number
)
// To ensure the main branch works with the go tool when checked out locally.
-replace github.com/google/differential-privacy/go v0.0.0-local => ../../go // see https://golang.org/doc/modules/managing-dependencies#local_directory
\ No newline at end of file
+replace github.com/google/differential-privacy/go v2.0.0-local => ../../go // see https://golang.org/doc/modules/managing-dependencies#local_directory
\ No newline at end of file
diff --git a/examples/go/scenarios.go b/examples/go/scenarios.go
index 7b835b0..9d4e769 100644
--- a/examples/go/scenarios.go
+++ b/examples/go/scenarios.go
@@ -23,8 +23,8 @@
"math/rand"
"time"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
)
const (
diff --git a/go/BUILD.bazel b/go/BUILD.bazel
index 4af6527..8c9b68e 100644
--- a/go/BUILD.bazel
+++ b/go/BUILD.bazel
@@ -16,5 +16,5 @@
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/go
+# gazelle:prefix github.com/google/differential-privacy/go/v2
gazelle(name = "gazelle")
diff --git a/go/README.md b/go/README.md
index 2c1c56a..b9c3296 100644
--- a/go/README.md
+++ b/go/README.md
@@ -9,7 +9,7 @@
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/dpagg).
+Full documentation of the API is available as [godoc](https://godoc.org/github.com/google/differential-privacy/go/v2/dpagg).
## Using with the "go" Command
diff --git a/go/WORKSPACE b/go/WORKSPACE
index 3e79d13..433bc0c 100644
--- a/go/WORKSPACE
+++ b/go/WORKSPACE
@@ -14,7 +14,7 @@
# limitations under the License.
#
-workspace(name = "com_google_go_differential_privacy")
+workspace(name = "com_github_google_differential_privacy_go_v2")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
diff --git a/go/checks/BUILD.bazel b/go/checks/BUILD.bazel
index 24b4670..23b2f54 100644
--- a/go/checks/BUILD.bazel
+++ b/go/checks/BUILD.bazel
@@ -17,13 +17,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/go/checks
+# gazelle:prefix github.com/google/differential-privacy/go/v2/checks
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["checks.go"],
- importpath = "github.com/google/differential-privacy/go/checks",
+ importpath = "github.com/google/differential-privacy/go/v2/checks",
visibility = ["//visibility:public"],
deps = ["@com_github_golang_glog//:go_default_library"],
)
diff --git a/go/dpagg/BUILD.bazel b/go/dpagg/BUILD.bazel
index 97ed1c4..999a62d 100644
--- a/go/dpagg/BUILD.bazel
+++ b/go/dpagg/BUILD.bazel
@@ -17,7 +17,7 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/go/dpagg
+# gazelle:prefix github.com/google/differential-privacy/go/v2/dpagg
gazelle(name = "gazelle")
go_library(
@@ -34,7 +34,7 @@
"sum.go",
"variance.go",
],
- importpath = "github.com/google/differential-privacy/go/dpagg",
+ importpath = "github.com/google/differential-privacy/go/v2/dpagg",
visibility = ["//visibility:public"],
deps = [
"//checks:go_default_library",
diff --git a/go/dpagg/count.go b/go/dpagg/count.go
index 99bb76b..963a099 100644
--- a/go/dpagg/count.go
+++ b/go/dpagg/count.go
@@ -20,7 +20,7 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// Count calculates a differentially private count of a collection of values
diff --git a/go/dpagg/count_confidence_interval_test.go b/go/dpagg/count_confidence_interval_test.go
index 81f2cad..700097c 100644
--- a/go/dpagg/count_confidence_interval_test.go
+++ b/go/dpagg/count_confidence_interval_test.go
@@ -19,7 +19,7 @@
import (
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
)
func getCount(t *testing.T, n noise.Noise) *Count {
diff --git a/go/dpagg/count_test.go b/go/dpagg/count_test.go
index 742fe77..4d07d8b 100644
--- a/go/dpagg/count_test.go
+++ b/go/dpagg/count_test.go
@@ -21,7 +21,7 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
"github.com/google/go-cmp/cmp"
"github.com/grd/stat"
)
diff --git a/go/dpagg/dpagg_test.go b/go/dpagg/dpagg_test.go
index de2b1de..9a0a83e 100644
--- a/go/dpagg/dpagg_test.go
+++ b/go/dpagg/dpagg_test.go
@@ -19,7 +19,7 @@
import (
"math"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
diff --git a/go/dpagg/mean.go b/go/dpagg/mean.go
index 9e9f967..5729c48 100644
--- a/go/dpagg/mean.go
+++ b/go/dpagg/mean.go
@@ -20,8 +20,8 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// BoundedMean calculates a differentially private mean of a collection of
diff --git a/go/dpagg/mean_confidence_interval_test.go b/go/dpagg/mean_confidence_interval_test.go
index 124e62e..5198f95 100644
--- a/go/dpagg/mean_confidence_interval_test.go
+++ b/go/dpagg/mean_confidence_interval_test.go
@@ -19,7 +19,7 @@
import (
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
)
func getBoundedMeanFloat64(t *testing.T, n noise.Noise, lower, upper float64) *BoundedMean {
diff --git a/go/dpagg/mean_test.go b/go/dpagg/mean_test.go
index dda90e2..c9cec3c 100644
--- a/go/dpagg/mean_test.go
+++ b/go/dpagg/mean_test.go
@@ -21,8 +21,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/go/v2/rand"
"github.com/google/go-cmp/cmp"
)
diff --git a/go/dpagg/quantiles.go b/go/dpagg/quantiles.go
index f145cae..df93eda 100644
--- a/go/dpagg/quantiles.go
+++ b/go/dpagg/quantiles.go
@@ -20,8 +20,8 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// Constants used for QuantileTrees.
diff --git a/go/dpagg/quantiles_test.go b/go/dpagg/quantiles_test.go
index 6e2ff0f..0339467 100644
--- a/go/dpagg/quantiles_test.go
+++ b/go/dpagg/quantiles_test.go
@@ -23,7 +23,7 @@
"sort"
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
diff --git a/go/dpagg/select_partition.go b/go/dpagg/select_partition.go
index e1eedd4..c8ea56f 100644
--- a/go/dpagg/select_partition.go
+++ b/go/dpagg/select_partition.go
@@ -20,9 +20,9 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/go/v2/rand"
)
// PreAggSelectPartition is used to compute an (ε,δ)-differentially private decision
diff --git a/go/dpagg/standard_deviation.go b/go/dpagg/standard_deviation.go
index e61881c..9e76bd8 100644
--- a/go/dpagg/standard_deviation.go
+++ b/go/dpagg/standard_deviation.go
@@ -20,7 +20,7 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// BoundedStandardDeviation calculates a differentially private standard deviation
diff --git a/go/dpagg/standard_deviation_test.go b/go/dpagg/standard_deviation_test.go
index 14f6f43..d8cf86e 100644
--- a/go/dpagg/standard_deviation_test.go
+++ b/go/dpagg/standard_deviation_test.go
@@ -21,8 +21,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/go/v2/rand"
"github.com/google/go-cmp/cmp"
)
diff --git a/go/dpagg/sum.go b/go/dpagg/sum.go
index 5d2809a..d7f555e 100644
--- a/go/dpagg/sum.go
+++ b/go/dpagg/sum.go
@@ -22,8 +22,8 @@
"math"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// BoundedSumInt64 calculates a differentially private sum of a collection of
diff --git a/go/dpagg/sum_confidence_interval_test.go b/go/dpagg/sum_confidence_interval_test.go
index e8d9b2d..61d14cc 100644
--- a/go/dpagg/sum_confidence_interval_test.go
+++ b/go/dpagg/sum_confidence_interval_test.go
@@ -19,7 +19,7 @@
import (
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
)
func getBoundedSumInt64(t *testing.T, n noise.Noise, lower, upper int64) *BoundedSumInt64 {
diff --git a/go/dpagg/sum_test.go b/go/dpagg/sum_test.go
index c4487e6..22e8264 100644
--- a/go/dpagg/sum_test.go
+++ b/go/dpagg/sum_test.go
@@ -21,7 +21,7 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/noise"
"github.com/google/go-cmp/cmp"
"github.com/grd/stat"
)
diff --git a/go/dpagg/variance.go b/go/dpagg/variance.go
index ad171b3..c3975f7 100644
--- a/go/dpagg/variance.go
+++ b/go/dpagg/variance.go
@@ -20,8 +20,8 @@
"fmt"
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
)
// BoundedVariance calculates a differentially private variance of a collection of
diff --git a/go/dpagg/variance_test.go b/go/dpagg/variance_test.go
index 0da0ab0..b1da93a 100644
--- a/go/dpagg/variance_test.go
+++ b/go/dpagg/variance_test.go
@@ -21,8 +21,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/go/v2/rand"
"github.com/google/go-cmp/cmp"
)
diff --git a/go/go.mod b/go/go.mod
index 3396904..5c6ee89 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -1,4 +1,4 @@
-module github.com/google/differential-privacy/go
+module github.com/google/differential-privacy/go/v2
go 1.16
diff --git a/go/noise/BUILD.bazel b/go/noise/BUILD.bazel
index a10a2bd..a4d2d5f 100644
--- a/go/noise/BUILD.bazel
+++ b/go/noise/BUILD.bazel
@@ -17,7 +17,7 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/go/noise
+# gazelle:prefix github.com/google/differential-privacy/go/v2/noise
gazelle(name = "gazelle")
go_library(
@@ -28,7 +28,7 @@
"noise.go",
"secure_noise_math.go",
],
- importpath = "github.com/google/differential-privacy/go/noise",
+ importpath = "github.com/google/differential-privacy/go/v2/noise",
visibility = ["//visibility:public"],
deps = [
"//checks:go_default_library",
diff --git a/go/noise/gaussian_noise.go b/go/noise/gaussian_noise.go
index f5b0a67..a5e2a21 100644
--- a/go/noise/gaussian_noise.go
+++ b/go/noise/gaussian_noise.go
@@ -19,8 +19,8 @@
import (
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/rand"
"gonum.org/v1/gonum/stat/distuv"
)
diff --git a/go/noise/laplace_noise.go b/go/noise/laplace_noise.go
index d1e9bb5..2ed63dd 100644
--- a/go/noise/laplace_noise.go
+++ b/go/noise/laplace_noise.go
@@ -19,8 +19,8 @@
import (
"math"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/rand"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/rand"
)
var (
diff --git a/go/rand/BUILD.bazel b/go/rand/BUILD.bazel
index 433d32c..9218d10 100644
--- a/go/rand/BUILD.bazel
+++ b/go/rand/BUILD.bazel
@@ -1,13 +1,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/go/rand
+# gazelle:prefix github.com/google/differential-privacy/go/v2/rand
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["rand.go"],
- importpath = "github.com/google/differential-privacy/go/rand",
+ importpath = "github.com/google/differential-privacy/go/v2/rand",
visibility = ["//visibility:public"],
deps = ["@com_github_golang_glog//:go_default_library"],
)
diff --git a/java/main/com/google/privacy/differentialprivacy/DiscreteLaplaceNoise.java b/java/main/com/google/privacy/differentialprivacy/DiscreteLaplaceNoise.java
new file mode 100644
index 0000000..ef5d848
--- /dev/null
+++ b/java/main/com/google/privacy/differentialprivacy/DiscreteLaplaceNoise.java
@@ -0,0 +1,127 @@
+//
+// Copyright 2022 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 com.google.privacy.differentialprivacy;
+
+import com.google.privacy.differentialprivacy.proto.SummaryOuterClass.MechanismType;
+import java.security.SecureRandom;
+import java.util.Random;
+import javax.annotation.Nullable;
+
+/**
+ * Generates and adds Discrete Laplace noise to a raw piece of numerical data such that the result
+ * is securely differentially private.
+ */
+public class DiscreteLaplaceNoise implements Noise {
+ private final Random random;
+
+ /** Returns a Noise instance initialized with a secure randomness source. */
+ public DiscreteLaplaceNoise() {
+ this(new SecureRandom());
+ }
+
+ private DiscreteLaplaceNoise(Random random) {
+ this.random = random;
+ }
+
+ /**
+ * Returns a Noise instance initialized with a specified randomness source. This should only be
+ * used for testing and may only be called via the static methods in {@link TestNoiseFactory}.
+ *
+ * <p>This method is package-private for use by the factory.
+ */
+ static DiscreteLaplaceNoise createForTesting(Random random) {
+ return new DiscreteLaplaceNoise(random);
+ }
+
+ @Override
+ public double addNoise(
+ double x, int l0Sensitivity, double lInfSensitivity, double epsilon, @Nullable Double delta) {
+ throw new IllegalArgumentException("Discrete Laplace Mechanism only applies to integers.");
+ }
+
+ /**
+ * Adds Discrete Laplace noise to the integer {@code x} such that the output is {@code
+ * epsilon}-differentially private, with respect to the specified L_0 and L_inf sensitivities.
+ * Note that {@code delta} must be set to {@code null} because it does not parameterize Laplace
+ * noise. Moreover, {@code epsilon} must be at least 2^-50.
+ */
+ @Override
+ public long addNoise(
+ long x, int l0Sensitivity, long lInfSensitivity, double epsilon, @Nullable Double delta) {
+ DpPreconditions.checkSensitivities(l0Sensitivity, lInfSensitivity);
+
+ return addNoise(
+ x, (long) Noise.getL1Sensitivity(l0Sensitivity, lInfSensitivity), epsilon, delta);
+ }
+
+ /**
+ * See {@link #addNoise(long, int, long, double, Double)}.
+ *
+ * <p>As opposed to the latter method, this accepts the L_1 sensitivity of {@code x} directly
+ * instead of the L_0 and L_Inf proxies. This should be used in settings where it is feasible or
+ * more convenient to calculate the L_1 sensitivity directly.
+ */
+ public long addNoise(long x, long l1Sensitivity, double epsilon, @Nullable Double delta) {
+ checkParameters(l1Sensitivity, epsilon, delta);
+
+ return x + SamplingUtil.sampleTwoSidedGeometric(random, epsilon / l1Sensitivity);
+ }
+
+ @Override
+ public MechanismType getMechanismType() {
+ return MechanismType.DISCRETE_LAPLACE;
+ }
+
+ @Override
+ public ConfidenceInterval computeConfidenceInterval(
+ long noisedX,
+ int l0Sensitivity,
+ long lInfSensitivity,
+ double epsilon,
+ @Nullable Double delta,
+ double alpha) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ @Override
+ public ConfidenceInterval computeConfidenceInterval(
+ double noisedX,
+ int l0Sensitivity,
+ double lInfSensitivity,
+ double epsilon,
+ @Nullable Double delta,
+ double alpha) {
+ throw new IllegalArgumentException("Discrete Laplace Mechanism only outputs integers.");
+ }
+
+ @Override
+ public double computeQuantile(
+ double rank,
+ double x,
+ int l0Sensitivity,
+ double lInfSensitivity,
+ double epsilon,
+ @Nullable Double delta) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ private void checkParameters(double l1Sensitivity, double epsilon, @Nullable Double delta) {
+ DpPreconditions.checkEpsilon(epsilon);
+ DpPreconditions.checkNoiseDelta(delta, this);
+ DpPreconditions.checkL1Sensitivity(l1Sensitivity);
+ }
+}
diff --git a/java/main/com/google/privacy/differentialprivacy/DpPreconditions.java b/java/main/com/google/privacy/differentialprivacy/DpPreconditions.java
index 44786ab..3031086 100644
--- a/java/main/com/google/privacy/differentialprivacy/DpPreconditions.java
+++ b/java/main/com/google/privacy/differentialprivacy/DpPreconditions.java
@@ -39,10 +39,11 @@
}
static void checkNoiseDelta(Double delta, Noise noise) {
- if (noise.getMechanismType() == MechanismType.LAPLACE) {
+ if (noise.getMechanismType() == MechanismType.LAPLACE
+ || noise.getMechanismType() == MechanismType.DISCRETE_LAPLACE) {
checkArgument(
delta == null,
- "delta should not be set when Laplace noise is used. Provided value: %s",
+ "delta should not be set when (Discrete) Laplace noise is used. Provided value: %s",
delta);
} else if (noise.getMechanismType() == MechanismType.GAUSSIAN) {
checkNotNull(delta);
diff --git a/java/tests/com/google/privacy/differentialprivacy/DiscreteLaplaceNoiseTest.java b/java/tests/com/google/privacy/differentialprivacy/DiscreteLaplaceNoiseTest.java
new file mode 100644
index 0000000..4061228
--- /dev/null
+++ b/java/tests/com/google/privacy/differentialprivacy/DiscreteLaplaceNoiseTest.java
@@ -0,0 +1,296 @@
+//
+// Copyright 2022 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 com.google.privacy.differentialprivacy;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.privacy.differentialprivacy.proto.SummaryOuterClass.MechanismType.DISCRETE_LAPLACE;
+import static org.junit.Assert.assertThrows;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.math.Stats;
+import com.google.testing.junit.testparameterinjector.TestParameterInjector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(TestParameterInjector.class)
+public final class DiscreteLaplaceNoiseTest {
+
+ private static final DiscreteLaplaceNoise NOISE = new DiscreteLaplaceNoise();
+ private static final int NUM_SAMPLES = 100000;
+ private static final double LN_3 = Math.log(3);
+ private static final long DEFAULT_X = 0;
+ private static final double DEFAULT_EPSILON = LN_3;
+ private static final int DEFAULT_L_0_SENSITIVITY = 1;
+ private static final long DEFAULT_L_INF_SENSITIVITY = 1;
+
+ /** Returns variance of Discrete Laplace noise for given parameters. */
+ double getVariance(double epsilon, int l0sensitivty, double lInfSensitivty) {
+ double l1Sensitivity = l0sensitivty * lInfSensitivty;
+ double pGeometric = 1 - Math.exp(-epsilon / l1Sensitivity);
+ return 2 * (1 - pGeometric) / Math.pow(pGeometric, 2);
+ }
+
+ @Test
+ public void addNoise_hasAccurateStatisticalProperties() {
+ ImmutableList.Builder<Long> samples = ImmutableList.builder();
+
+ for (int i = 0; i < NUM_SAMPLES; i++) {
+ samples.add(
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ double variance =
+ getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
+ // The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
+ // of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
+ double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
+ double sampleVarianceTolerance = 4.41717 * Math.sqrt(5.0 * variance * variance / NUM_SAMPLES);
+ Stats stats = Stats.of(samples.build());
+ assertThat(stats.mean()).isWithin(sampleMeanTolerance).of(DEFAULT_X);
+ assertThat(stats.populationVariance()).isWithin(sampleVarianceTolerance).of(variance);
+ }
+
+ @Test
+ public void addNoise_differentX_hasAccurateStatisticalProperties() {
+ ImmutableList.Builder<Long> samples = ImmutableList.builder();
+
+ for (int i = 0; i < NUM_SAMPLES; i++) {
+ samples.add(
+ NOISE.addNoise(
+ /* x= */ 42,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ double mean = 42;
+ double variance =
+ getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
+ // The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
+ // of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
+ double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
+ double sampleVarianceTolerance = 4.41717 * Math.sqrt(5.0 * variance * variance / NUM_SAMPLES);
+ Stats stats = Stats.of(samples.build());
+ assertThat(stats.mean()).isWithin(sampleMeanTolerance).of(mean);
+ assertThat(stats.populationVariance()).isWithin(sampleVarianceTolerance).of(variance);
+ }
+
+ @Test
+ public void addNoise_differentSensitivity_hasAccurateStatisticalProperties() {
+ ImmutableList.Builder<Long> samples = ImmutableList.builder();
+
+ for (int i = 0; i < NUM_SAMPLES; i++) {
+ samples.add(
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ /* lInfSensitivity= */ 2,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ double variance = getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, 2);
+ // The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
+ // of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
+ double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
+ double sampleVarianceTolerance = 4.41717 * Math.sqrt(5.0 * variance * variance / NUM_SAMPLES);
+ Stats stats = Stats.of(samples.build());
+ assertThat(stats.mean()).isWithin(sampleMeanTolerance).of(DEFAULT_X);
+ assertThat(stats.populationVariance()).isWithin(sampleVarianceTolerance).of(variance);
+ }
+
+ @Test
+ public void addNoise_differentEpsilon_hasAccurateStatisticalProperties() {
+ ImmutableList.Builder<Long> samples = ImmutableList.builder();
+
+ for (int i = 0; i < NUM_SAMPLES; i++) {
+ samples.add(
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ /* epsilon= */ 0.5 * LN_3,
+ /* delta= */ null));
+ }
+
+ double variance = getVariance(0.5 * LN_3, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
+ // The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
+ // of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
+ double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
+ double sampleVarianceTolerance = 4.41717 * Math.sqrt(5.0 * variance * variance / NUM_SAMPLES);
+ Stats stats = Stats.of(samples.build());
+ assertThat(stats.mean()).isWithin(sampleMeanTolerance).of(DEFAULT_X);
+ assertThat(stats.populationVariance()).isWithin(sampleVarianceTolerance).of(variance);
+ }
+
+ @Test
+ public void addNoise_epsilonTooSmall_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ /* epsilon= */ 1.0 / (1L << 51),
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_epsilonPosInfinity_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ /* epsilon= */ Double.POSITIVE_INFINITY,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_epsilonNan_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ /* epsilon= */ Double.NaN,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_deltaNonnul_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ DEFAULT_L_INF_SENSITIVITY,
+ DEFAULT_EPSILON,
+ /* delta= */ 0.0));
+ }
+
+ @Test
+ public void addNoise_lInfSensitivityTooHigh_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ /* lInfSensitivity= */ Double.MAX_VALUE,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_lInfSensitivityNan_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ /* lInfSensitivity= */ Double.NaN,
+ /* epsilon= */ 1.0,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_lInfSensitivityNegative_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ /* lInfSensitivity= */ -1.0,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_lInfSensitivityZero_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ DEFAULT_L_0_SENSITIVITY,
+ /* lInfSensitivity= */ 0.0,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_l0SensitivityNegative_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ /* l0Sensitivity= */ -1,
+ DEFAULT_L_INF_SENSITIVITY,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_l0SensitivityZero_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(
+ DEFAULT_X,
+ /* l0Sensitivity= */ 0,
+ DEFAULT_L_INF_SENSITIVITY,
+ DEFAULT_EPSILON,
+ /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_l1SensitivityNegative_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(DEFAULT_X, /* l1Sensitivity= */ -1, DEFAULT_EPSILON, /* delta= */ null));
+ }
+
+ @Test
+ public void addNoise_l1SensitivityZero_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ NOISE.addNoise(DEFAULT_X, /* l1Sensitivity= */ 0, DEFAULT_EPSILON, /* delta= */ null));
+ }
+
+ @Test
+ public void getMechanismType_returnsDiscreteLaplace() {
+ assertThat(NOISE.getMechanismType()).isEqualTo(DISCRETE_LAPLACE);
+ }
+}
diff --git a/java/tests/com/google/privacy/differentialprivacy/LaplaceNoiseTest.java b/java/tests/com/google/privacy/differentialprivacy/LaplaceNoiseTest.java
index 3c1fb6b..c5a72f8 100644
--- a/java/tests/com/google/privacy/differentialprivacy/LaplaceNoiseTest.java
+++ b/java/tests/com/google/privacy/differentialprivacy/LaplaceNoiseTest.java
@@ -38,6 +38,12 @@
private static final int DEFAULT_L_0_SENSITIVITY = 1;
private static final double DEFAULT_L_INF_SENSITIVITY = 1.0;
+ /** Returns variance of Laplace noise for given parameters. */
+ double getVariance(double epsilon, int l0sensitivty, double lInfSensitivty) {
+ double l1Sensitivity = l0sensitivty * lInfSensitivty;
+ return 2 * Math.pow(l1Sensitivity / epsilon, 2);
+ }
+
@Test
public void addNoise_hasAccurateStatisticalProperties() {
ImmutableList.Builder<Double> samples = ImmutableList.builder();
@@ -52,7 +58,8 @@
}
Stats stats = Stats.of(samples.build());
- double variance = 2.0 / (LN_3 * LN_3);
+ double variance =
+ getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
// The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
// of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
@@ -76,7 +83,8 @@
Stats stats = Stats.of(samples.build());
double mean = 42.0;
- double variance = 2.0 / (LN_3 * LN_3);
+ double variance =
+ getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
// The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
// of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
@@ -99,7 +107,7 @@
}
Stats stats = Stats.of(samples.build());
- double variance = 2.0 / (4.0 * LN_3 * LN_3);
+ double variance = getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, 0.5);
// The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
// of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
@@ -122,7 +130,7 @@
}
Stats stats = Stats.of(samples.build());
- double variance = 2.0 / (4.0 * LN_3 * LN_3);
+ double variance = getVariance(2 * LN_3, DEFAULT_L_0_SENSITIVITY, DEFAULT_L_INF_SENSITIVITY);
// The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
// of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
double sampleMeanTolerance = 4.41717 * Math.sqrt(variance / NUM_SAMPLES);
@@ -146,7 +154,7 @@
Stats stats = Stats.of(samples.build());
double mean = 0.0;
- double approxVariance = 1.75;
+ double approxVariance = getVariance(DEFAULT_EPSILON, DEFAULT_L_0_SENSITIVITY, 1);
// The tolerance is chosen according to the 99.9995% quantile of the anticipated distributions
// of the sample mean and variance. Thus, the test falsely rejects with a probability of 10^-5.
double sampleMeanTolerance = 4.41717 * Math.sqrt(approxVariance / NUM_SAMPLES);
@@ -387,7 +395,7 @@
}
@Test
- public void getMechanismType_returnsGaussian() {
+ public void getMechanismType_returnsLaplace() {
assertThat(NOISE.getMechanismType()).isEqualTo(LAPLACE);
}
diff --git a/privacy-on-beam/BUILD.bazel b/privacy-on-beam/BUILD.bazel
index f690a02..ee9268a 100644
--- a/privacy-on-beam/BUILD.bazel
+++ b/privacy-on-beam/BUILD.bazel
@@ -16,6 +16,6 @@
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2
gazelle(name = "gazelle")
# gazelle:proto disable_global
diff --git a/privacy-on-beam/README.md b/privacy-on-beam/README.md
index 32c1191..cfdf79d 100644
--- a/privacy-on-beam/README.md
+++ b/privacy-on-beam/README.md
@@ -23,7 +23,7 @@
the [codelab/](codelab)
directory.
-Full documentation of the API is available as [godoc](https://godoc.org/github.com/google/differential-privacy/privacy-on-beam/pbeam).
+Full documentation of the API is available as [godoc](https://godoc.org/github.com/google/differential-privacy/privacy-on-beam/v2/pbeam).
## Using with the "go" Command
diff --git a/privacy-on-beam/WORKSPACE b/privacy-on-beam/WORKSPACE
index ff91448..5f5f148 100644
--- a/privacy-on-beam/WORKSPACE
+++ b/privacy-on-beam/WORKSPACE
@@ -14,7 +14,7 @@
# limitations under the License.
#
-workspace(name = "com_google_privacy_on_beam")
+workspace(name = "com_github_google_differential_privacy_privacy_on_beam_v2")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@@ -53,7 +53,7 @@
)
local_repository(
- name = "com_google_go_differential_privacy",
+ name = "com_github_google_differential_privacy_go_v2",
path = "../go",
)
@@ -71,7 +71,7 @@
privacy_on_beam_deps()
# Load Go DP library dependencies.
-load("@com_google_go_differential_privacy//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")
+load("@com_github_google_differential_privacy_go_v2//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps")
go_differential_privacy_deps()
diff --git a/privacy-on-beam/codelab/BUILD.bazel b/privacy-on-beam/codelab/BUILD.bazel
index db1615b..fb193c3 100644
--- a/privacy-on-beam/codelab/BUILD.bazel
+++ b/privacy-on-beam/codelab/BUILD.bazel
@@ -17,7 +17,7 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/codelab
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/codelab
gazelle(name = "gazelle")
go_library(
@@ -30,7 +30,7 @@
"sum.go",
"visit.go",
],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/codelab",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/codelab",
visibility = ["//visibility:public"],
deps = [
"//pbeam:go_default_library",
diff --git a/privacy-on-beam/codelab/count.go b/privacy-on-beam/codelab/count.go
index 4c5f80d..519d452 100644
--- a/privacy-on-beam/codelab/count.go
+++ b/privacy-on-beam/codelab/count.go
@@ -20,7 +20,7 @@
import (
"math"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
)
diff --git a/privacy-on-beam/codelab/main/BUILD.bazel b/privacy-on-beam/codelab/main/BUILD.bazel
index 200c8ca..6a49823 100644
--- a/privacy-on-beam/codelab/main/BUILD.bazel
+++ b/privacy-on-beam/codelab/main/BUILD.bazel
@@ -17,7 +17,7 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/codelab/main
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/codelab/main
gazelle(name = "gazelle")
# keep
@@ -30,7 +30,7 @@
data = [
"//codelab/main:day_data.csv",
],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/codelab/main",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/codelab/main",
visibility = ["//visibility:public"],
deps = [
"//codelab:go_default_library",
diff --git a/privacy-on-beam/codelab/main/main.go b/privacy-on-beam/codelab/main/main.go
index 86eb667..2e10b36 100644
--- a/privacy-on-beam/codelab/main/main.go
+++ b/privacy-on-beam/codelab/main/main.go
@@ -39,7 +39,7 @@
"flag"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/privacy-on-beam/codelab"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/codelab"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
// The following import is required for accessing local files.
diff --git a/privacy-on-beam/codelab/main/utils.go b/privacy-on-beam/codelab/main/utils.go
index 8c82700..923340a 100644
--- a/privacy-on-beam/codelab/main/utils.go
+++ b/privacy-on-beam/codelab/main/utils.go
@@ -24,7 +24,7 @@
"strings"
"github.com/apache/beam/sdks/v2/go/pkg/beam/io/textio"
- "github.com/google/differential-privacy/privacy-on-beam/codelab"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/codelab"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
diff --git a/privacy-on-beam/codelab/mean.go b/privacy-on-beam/codelab/mean.go
index 2bf285d..1efbfc9 100644
--- a/privacy-on-beam/codelab/mean.go
+++ b/privacy-on-beam/codelab/mean.go
@@ -17,7 +17,7 @@
package codelab
import (
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
)
diff --git a/privacy-on-beam/codelab/multiple.go b/privacy-on-beam/codelab/multiple.go
index cb62ab2..711e188 100644
--- a/privacy-on-beam/codelab/multiple.go
+++ b/privacy-on-beam/codelab/multiple.go
@@ -17,7 +17,7 @@
package codelab
import (
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
)
diff --git a/privacy-on-beam/codelab/public_partitions.go b/privacy-on-beam/codelab/public_partitions.go
index 6bf0470..9a5d46d 100644
--- a/privacy-on-beam/codelab/public_partitions.go
+++ b/privacy-on-beam/codelab/public_partitions.go
@@ -17,7 +17,7 @@
package codelab
import (
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
)
diff --git a/privacy-on-beam/codelab/sum.go b/privacy-on-beam/codelab/sum.go
index 9f8698c..23f6d61 100644
--- a/privacy-on-beam/codelab/sum.go
+++ b/privacy-on-beam/codelab/sum.go
@@ -17,7 +17,7 @@
package codelab
import (
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
)
diff --git a/privacy-on-beam/go.mod b/privacy-on-beam/go.mod
index 8eccbc5..0c4ce0a 100644
--- a/privacy-on-beam/go.mod
+++ b/privacy-on-beam/go.mod
@@ -1,11 +1,11 @@
-module github.com/google/differential-privacy/privacy-on-beam
+module github.com/google/differential-privacy/privacy-on-beam/v2
go 1.16
require (
github.com/apache/beam/sdks/v2 v2.36.0
github.com/golang/glog v1.0.0
- github.com/google/differential-privacy/go v0.0.0-local // a nonexistent version number
+ github.com/google/differential-privacy/go/v2 v2.0.0-local // a nonexistent version number
github.com/google/go-cmp v0.5.6
gonum.org/v1/plot v0.10.0
google.golang.org/grpc v1.40.0 // indirect
@@ -17,4 +17,4 @@
// for now, i.e. building with the go tool after
// "go get github.com/google/differential-privacy/privacy-on-beam@main" will
// fail.
-replace github.com/google/differential-privacy/go v0.0.0-local => ../go // see https://golang.org/doc/modules/managing-dependencies#local_directory
\ No newline at end of file
+replace github.com/google/differential-privacy/go/v2 v2.0.0-local => ../go // see https://golang.org/doc/modules/managing-dependencies#local_directory
\ No newline at end of file
diff --git a/privacy-on-beam/internal/generated/BUILD.bazel b/privacy-on-beam/internal/generated/BUILD.bazel
index 1c321c4..520ce60 100644
--- a/privacy-on-beam/internal/generated/BUILD.bazel
+++ b/privacy-on-beam/internal/generated/BUILD.bazel
@@ -17,13 +17,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/internal/generated
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/internal/generated
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["generated_functions.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/internal/generated",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/internal/generated",
visibility = ["//:__subpackages__"],
deps = [
"//internal/kv:go_default_library",
diff --git a/privacy-on-beam/internal/generated/generated_functions.go b/privacy-on-beam/internal/generated/generated_functions.go
index 39c29a5..3b0c1c0 100644
--- a/privacy-on-beam/internal/generated/generated_functions.go
+++ b/privacy-on-beam/internal/generated/generated_functions.go
@@ -21,7 +21,7 @@
"context"
"reflect"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx"
)
diff --git a/privacy-on-beam/internal/kv/BUILD.bazel b/privacy-on-beam/internal/kv/BUILD.bazel
index dd1ac83..00fd216 100644
--- a/privacy-on-beam/internal/kv/BUILD.bazel
+++ b/privacy-on-beam/internal/kv/BUILD.bazel
@@ -1,13 +1,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/internal/kv
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["kv.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/internal/kv",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv",
visibility = ["//:__subpackages__"],
deps = [
"@com_github_apache_beam_sdks_v2//go/pkg/beam:go_default_library",
diff --git a/privacy-on-beam/internal/testoption/BUILD.bazel b/privacy-on-beam/internal/testoption/BUILD.bazel
index 8c14307..7a3fa49 100644
--- a/privacy-on-beam/internal/testoption/BUILD.bazel
+++ b/privacy-on-beam/internal/testoption/BUILD.bazel
@@ -17,12 +17,12 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/internal/testoption
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/internal/testoption
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["testoption.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/internal/testoption",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/internal/testoption",
visibility = ["//:__subpackages__"],
)
diff --git a/privacy-on-beam/pbeam/BUILD.bazel b/privacy-on-beam/pbeam/BUILD.bazel
index 26d4160..d95c40d 100644
--- a/privacy-on-beam/pbeam/BUILD.bazel
+++ b/privacy-on-beam/pbeam/BUILD.bazel
@@ -17,7 +17,7 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/pbeam
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/pbeam
gazelle(name = "gazelle")
go_library(
@@ -36,7 +36,7 @@
"select_partitions.go",
"sum.go",
],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/pbeam",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam",
visibility = ["//visibility:public"],
deps = [
"//internal/generated:go_default_library",
@@ -50,9 +50,9 @@
"@com_github_apache_beam_sdks_v2//go/pkg/beam/transforms/stats:go_default_library",
"@com_github_apache_beam_sdks_v2//go/pkg/beam/transforms/top:go_default_library",
"@com_github_golang_glog//:go_default_library",
- "@com_google_go_differential_privacy//checks:go_default_library",
- "@com_google_go_differential_privacy//dpagg:go_default_library",
- "@com_google_go_differential_privacy//noise:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//checks:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//dpagg:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//noise:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
],
@@ -91,10 +91,10 @@
"@com_github_apache_beam_sdks_v2//go/pkg/beam/testing/passert:go_default_library",
"@com_github_apache_beam_sdks_v2//go/pkg/beam/testing/ptest:go_default_library",
"@com_github_apache_beam_sdks_v2//go/pkg/beam/transforms/stats:go_default_library",
+ "@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_go_cmp//cmp:go_default_library",
"@com_github_google_go_cmp//cmp/cmpopts:go_default_library",
- "@com_google_go_differential_privacy//dpagg:go_default_library",
- "@com_google_go_differential_privacy//noise:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)
diff --git a/privacy-on-beam/pbeam/aggregations.go b/privacy-on-beam/pbeam/aggregations.go
index ef1ce63..2f503a4 100644
--- a/privacy-on-beam/pbeam/aggregations.go
+++ b/privacy-on-beam/pbeam/aggregations.go
@@ -25,10 +25,10 @@
"math/rand"
"reflect"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/typex"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/top"
diff --git a/privacy-on-beam/pbeam/aggregations_test.go b/privacy-on-beam/pbeam/aggregations_test.go
index 3b34557..c941e7f 100644
--- a/privacy-on-beam/pbeam/aggregations_test.go
+++ b/privacy-on-beam/pbeam/aggregations_test.go
@@ -20,8 +20,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/typex"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
diff --git a/privacy-on-beam/pbeam/count.go b/privacy-on-beam/pbeam/count.go
index ac77902..971c5ed 100644
--- a/privacy-on-beam/pbeam/count.go
+++ b/privacy-on-beam/pbeam/count.go
@@ -21,9 +21,9 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
)
diff --git a/privacy-on-beam/pbeam/count_test.go b/privacy-on-beam/pbeam/count_test.go
index dad91c3..4278982 100644
--- a/privacy-on-beam/pbeam/count_test.go
+++ b/privacy-on-beam/pbeam/count_test.go
@@ -20,9 +20,9 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/distinct_id.go b/privacy-on-beam/pbeam/distinct_id.go
index a47a7d7..83b9ff9 100644
--- a/privacy-on-beam/pbeam/distinct_id.go
+++ b/privacy-on-beam/pbeam/distinct_id.go
@@ -21,10 +21,10 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/filter"
)
diff --git a/privacy-on-beam/pbeam/distinct_id_test.go b/privacy-on-beam/pbeam/distinct_id_test.go
index d6670f7..15622c0 100644
--- a/privacy-on-beam/pbeam/distinct_id_test.go
+++ b/privacy-on-beam/pbeam/distinct_id_test.go
@@ -22,9 +22,9 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
- testpb "github.com/google/differential-privacy/privacy-on-beam/testdata"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
+ testpb "github.com/google/differential-privacy/privacy-on-beam/v2/testdata"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/passert"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
diff --git a/privacy-on-beam/pbeam/distinct_per_key.go b/privacy-on-beam/pbeam/distinct_per_key.go
index fe6ed3d..9eebc66 100644
--- a/privacy-on-beam/pbeam/distinct_per_key.go
+++ b/privacy-on-beam/pbeam/distinct_per_key.go
@@ -20,9 +20,9 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
)
diff --git a/privacy-on-beam/pbeam/distinct_per_key_test.go b/privacy-on-beam/pbeam/distinct_per_key_test.go
index 8b4320b..3771498 100644
--- a/privacy-on-beam/pbeam/distinct_per_key_test.go
+++ b/privacy-on-beam/pbeam/distinct_per_key_test.go
@@ -19,8 +19,8 @@
import (
"testing"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/example_pbeamtest_test.go b/privacy-on-beam/pbeam/example_pbeamtest_test.go
index c157b50..46e88c1 100644
--- a/privacy-on-beam/pbeam/example_pbeamtest_test.go
+++ b/privacy-on-beam/pbeam/example_pbeamtest_test.go
@@ -20,8 +20,8 @@
"context"
"fmt"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/pbeamtest"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/pbeamtest"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/io/textio"
"github.com/apache/beam/sdks/v2/go/pkg/beam/runners/direct"
diff --git a/privacy-on-beam/pbeam/example_test.go b/privacy-on-beam/pbeam/example_test.go
index 6224b87..8f3a923 100644
--- a/privacy-on-beam/pbeam/example_test.go
+++ b/privacy-on-beam/pbeam/example_test.go
@@ -20,7 +20,7 @@
"context"
"fmt"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/io/textio"
"github.com/apache/beam/sdks/v2/go/pkg/beam/runners/direct"
diff --git a/privacy-on-beam/pbeam/mean.go b/privacy-on-beam/pbeam/mean.go
index d3d924f..02f3fc5 100644
--- a/privacy-on-beam/pbeam/mean.go
+++ b/privacy-on-beam/pbeam/mean.go
@@ -22,10 +22,10 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
)
diff --git a/privacy-on-beam/pbeam/mean_test.go b/privacy-on-beam/pbeam/mean_test.go
index cf9373c..6ba72e3 100644
--- a/privacy-on-beam/pbeam/mean_test.go
+++ b/privacy-on-beam/pbeam/mean_test.go
@@ -20,9 +20,9 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/no_noise.go b/privacy-on-beam/pbeam/no_noise.go
index 4808a6d..2dcae65 100644
--- a/privacy-on-beam/pbeam/no_noise.go
+++ b/privacy-on-beam/pbeam/no_noise.go
@@ -16,7 +16,7 @@
package pbeam
-import "github.com/google/differential-privacy/go/noise"
+import "github.com/google/differential-privacy/go/v2/noise"
// noNoise is a Noise instance that doesn't add noise to the data, and has a
// threshold of 0. Used as the noise type only when testMode is enabled in PrivacySpec.
diff --git a/privacy-on-beam/pbeam/pardo.go b/privacy-on-beam/pbeam/pardo.go
index 99018c8..6ffcd77 100644
--- a/privacy-on-beam/pbeam/pardo.go
+++ b/privacy-on-beam/pbeam/pardo.go
@@ -21,8 +21,8 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/privacy-on-beam/internal/generated"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/generated"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/funcx"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx"
diff --git a/privacy-on-beam/pbeam/pardo_test.go b/privacy-on-beam/pbeam/pardo_test.go
index 0ccaa28..1ed30fc 100644
--- a/privacy-on-beam/pbeam/pardo_test.go
+++ b/privacy-on-beam/pbeam/pardo_test.go
@@ -26,9 +26,9 @@
"time"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/privacy-on-beam/internal/generated"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/generated"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/funcx"
"github.com/apache/beam/sdks/v2/go/pkg/beam/runners/direct"
diff --git a/privacy-on-beam/pbeam/pbeam.go b/privacy-on-beam/pbeam/pbeam.go
index 4d68c82..d052e24 100644
--- a/privacy-on-beam/pbeam/pbeam.go
+++ b/privacy-on-beam/pbeam/pbeam.go
@@ -115,9 +115,9 @@
"sync"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
- "github.com/google/differential-privacy/privacy-on-beam/internal/testoption"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/testoption"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/typex"
"google.golang.org/protobuf/proto"
diff --git a/privacy-on-beam/pbeam/pbeam_test.go b/privacy-on-beam/pbeam/pbeam_test.go
index d2e932d..53fff33 100644
--- a/privacy-on-beam/pbeam/pbeam_test.go
+++ b/privacy-on-beam/pbeam/pbeam_test.go
@@ -19,8 +19,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
- testpb "github.com/google/differential-privacy/privacy-on-beam/testdata"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
+ testpb "github.com/google/differential-privacy/privacy-on-beam/v2/testdata"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/passert"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
diff --git a/privacy-on-beam/pbeam/pbeamtest/BUILD.bazel b/privacy-on-beam/pbeam/pbeamtest/BUILD.bazel
index 7c73909..b92baaa 100644
--- a/privacy-on-beam/pbeam/pbeamtest/BUILD.bazel
+++ b/privacy-on-beam/pbeam/pbeamtest/BUILD.bazel
@@ -17,19 +17,19 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/pbeam/pbeamtest
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/pbeamtest
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
testonly = 1,
srcs = ["pbeamtest.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/pbeam/pbeamtest",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/pbeamtest",
visibility = ["//visibility:public"],
deps = [
"//internal/testoption:go_default_library",
"//pbeam:go_default_library",
- "@com_google_go_differential_privacy//dpagg:go_default_library",
+ "@com_github_google_differential_privacy_go_v2//dpagg:go_default_library",
],
)
diff --git a/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go b/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go
index 724710c..90ee771 100644
--- a/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go
+++ b/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go
@@ -21,9 +21,9 @@
import (
"math"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/privacy-on-beam/internal/testoption"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/testoption"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
)
// NewPrivacySpecNoNoiseWithContributionBounding creates a new PrivacySpec with
diff --git a/privacy-on-beam/pbeam/pbeamtest/pbeamtest_test.go b/privacy-on-beam/pbeam/pbeamtest/pbeamtest_test.go
index 4817e29..be5cfdf 100644
--- a/privacy-on-beam/pbeam/pbeamtest/pbeamtest_test.go
+++ b/privacy-on-beam/pbeam/pbeamtest/pbeamtest_test.go
@@ -19,8 +19,8 @@
import (
"testing"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/quantiles.go b/privacy-on-beam/pbeam/quantiles.go
index af70740..e40cfdc 100644
--- a/privacy-on-beam/pbeam/quantiles.go
+++ b/privacy-on-beam/pbeam/quantiles.go
@@ -21,10 +21,10 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
)
diff --git a/privacy-on-beam/pbeam/quantiles_test.go b/privacy-on-beam/pbeam/quantiles_test.go
index 4480a44..91bfeca 100644
--- a/privacy-on-beam/pbeam/quantiles_test.go
+++ b/privacy-on-beam/pbeam/quantiles_test.go
@@ -20,8 +20,8 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/select_partitions.go b/privacy-on-beam/pbeam/select_partitions.go
index de35af2..c40d07a 100644
--- a/privacy-on-beam/pbeam/select_partitions.go
+++ b/privacy-on-beam/pbeam/select_partitions.go
@@ -21,9 +21,9 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/filter"
)
diff --git a/privacy-on-beam/pbeam/select_partitions_test.go b/privacy-on-beam/pbeam/select_partitions_test.go
index 7905d2a..bb4aaa6 100644
--- a/privacy-on-beam/pbeam/select_partitions_test.go
+++ b/privacy-on-beam/pbeam/select_partitions_test.go
@@ -19,8 +19,8 @@
import (
"testing"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
)
diff --git a/privacy-on-beam/pbeam/sum.go b/privacy-on-beam/pbeam/sum.go
index d1e4772..af8d4bd 100644
--- a/privacy-on-beam/pbeam/sum.go
+++ b/privacy-on-beam/pbeam/sum.go
@@ -22,10 +22,10 @@
"reflect"
log "github.com/golang/glog"
- "github.com/google/differential-privacy/go/checks"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/checks"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/typex"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
diff --git a/privacy-on-beam/pbeam/sum_test.go b/privacy-on-beam/pbeam/sum_test.go
index ae01db6..79280c4 100644
--- a/privacy-on-beam/pbeam/sum_test.go
+++ b/privacy-on-beam/pbeam/sum_test.go
@@ -21,9 +21,9 @@
"reflect"
"testing"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/typex"
"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
diff --git a/privacy-on-beam/pbeam/testutils/BUILD.bazel b/privacy-on-beam/pbeam/testutils/BUILD.bazel
index 03abc34..3d6dff8 100644
--- a/privacy-on-beam/pbeam/testutils/BUILD.bazel
+++ b/privacy-on-beam/pbeam/testutils/BUILD.bazel
@@ -17,23 +17,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
testonly = 1,
srcs = ["testutils.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/pbeam/testutils",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/pbeam/testutils",
visibility = ["//:__subpackages__"],
deps = [
"//internal/kv:go_default_library",
"@com_github_apache_beam_sdks_v2//go/pkg/beam:go_default_library",
"@com_github_apache_beam_sdks_v2//go/pkg/beam/transforms/stats:go_default_library",
+ "@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_go_cmp//cmp:go_default_library",
"@com_github_google_go_cmp//cmp/cmpopts:go_default_library",
- "@com_google_go_differential_privacy//dpagg:go_default_library",
- "@com_google_go_differential_privacy//noise:go_default_library",
],
)
diff --git a/privacy-on-beam/pbeam/testutils/testutils.go b/privacy-on-beam/pbeam/testutils/testutils.go
index e11e481..b7bab0d 100644
--- a/privacy-on-beam/pbeam/testutils/testutils.go
+++ b/privacy-on-beam/pbeam/testutils/testutils.go
@@ -24,9 +24,9 @@
"math/big"
"reflect"
- "github.com/google/differential-privacy/go/dpagg"
- "github.com/google/differential-privacy/go/noise"
- "github.com/google/differential-privacy/privacy-on-beam/internal/kv"
+ "github.com/google/differential-privacy/go/v2/dpagg"
+ "github.com/google/differential-privacy/go/v2/noise"
+ "github.com/google/differential-privacy/privacy-on-beam/v2/internal/kv"
"github.com/apache/beam/sdks/v2/go/pkg/beam"
"github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats"
"github.com/google/go-cmp/cmp"
diff --git a/privacy-on-beam/testdata/BUILD.bazel b/privacy-on-beam/testdata/BUILD.bazel
index 9e2adc4..bb50387 100644
--- a/privacy-on-beam/testdata/BUILD.bazel
+++ b/privacy-on-beam/testdata/BUILD.bazel
@@ -17,13 +17,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
-# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/testdata
+# gazelle:prefix github.com/google/differential-privacy/privacy-on-beam/v2/testdata
gazelle(name = "gazelle")
go_library(
name = "go_default_library",
srcs = ["test.pb.go"],
- importpath = "github.com/google/differential-privacy/privacy-on-beam/testdata",
+ importpath = "github.com/google/differential-privacy/privacy-on-beam/v2/testdata",
visibility = ["//visibility:public"],
deps = [
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
diff --git a/proto/summary.proto b/proto/summary.proto
index 5059eae..92e37de 100644
--- a/proto/summary.proto
+++ b/proto/summary.proto
@@ -94,6 +94,7 @@
EMPTY = 0;
LAPLACE = 1;
GAUSSIAN = 2;
+ DISCRETE_LAPLACE = 3;
}
message BoundedMeanSummary {
diff --git a/python/dp_accounting/BUILD.bazel b/python/dp_accounting/BUILD.bazel
index 50caed1..a901390 100644
--- a/python/dp_accounting/BUILD.bazel
+++ b/python/dp_accounting/BUILD.bazel
@@ -186,6 +186,7 @@
py_library(
name = "dp_event",
srcs = ["dp_event.py"],
+ srcs_version = "PY3",
deps = [
requirement("attrs"),
],
@@ -194,6 +195,7 @@
py_library(
name = "dp_event_builder",
srcs = ["dp_event_builder.py"],
+ srcs_version = "PY3",
deps = [
":dp_event",
],
@@ -203,6 +205,7 @@
name = "dp_event_builder_test",
srcs = ["dp_event_builder_test.py"],
python_version = "PY3",
+ srcs_version = "PY3",
deps = [
":dp_event",
":dp_event_builder",
@@ -213,6 +216,7 @@
py_library(
name = "privacy_accountant",
srcs = ["privacy_accountant.py"],
+ srcs_version = "PY3",
deps = [
":dp_event",
":dp_event_builder",
@@ -222,6 +226,7 @@
py_library(
name = "privacy_accountant_test",
srcs = ["privacy_accountant_test.py"],
+ srcs_version = "PY3",
deps = [
":dp_event",
":privacy_accountant",
diff --git a/python/dp_accounting/common.py b/python/dp_accounting/common.py
index 5210b64..ea11014 100644
--- a/python/dp_accounting/common.py
+++ b/python/dp_accounting/common.py
@@ -13,10 +13,10 @@
# limitations under the License.
"""Common classes and functions for the accounting library."""
+import dataclasses
import math
import typing
-import dataclasses
import numpy as np
from scipy import fft
from scipy import signal
@@ -289,7 +289,7 @@
truncated_convolution_output = np.real(
fft.ifft(fft.fft(input_list, fast_len)**num_times))
- # Discrete Fourier Transform wraps around module fast_len. Extract the output
+ # Discrete Fourier Transform wraps around modulo fast_len. Extract the output
# values in the range of interest.
output_list = [
truncated_convolution_output[i % fast_len]
diff --git a/python/dp_accounting/dp_event.py b/python/dp_accounting/dp_event.py
index 3ae58e9..5d37b43 100644
--- a/python/dp_accounting/dp_event.py
+++ b/python/dp_accounting/dp_event.py
@@ -116,6 +116,20 @@
@attr.s(frozen=True, slots=True, auto_attribs=True)
+class LaplaceDpEvent(DpEvent):
+ """Represents an application of the Laplace mechanism.
+
+ For values v_i and noise z sampled coordinate-wise from the Laplace
+ distribution L(0, s), this mechanism returns sum_i v_i + z.
+ The probability density function of the Laplace distribution L(0, s) with
+ parameter s is given as exp(-|x|/s) * (0.5/s) at x for any real value x.
+ If the L_1 norm of the values are bounded ||v_i||_1 <= C, the noise_multiplier
+ is defined as s / C.
+ """
+ noise_multiplier: float
+
+
+@attr.s(frozen=True, slots=True, auto_attribs=True)
class SelfComposedDpEvent(DpEvent):
"""Represents repeated application of a mechanism.
diff --git a/python/dp_accounting/dp_event_builder_test.py b/python/dp_accounting/dp_event_builder_test.py
index 3599617..8f355c0 100644
--- a/python/dp_accounting/dp_event_builder_test.py
+++ b/python/dp_accounting/dp_event_builder_test.py
@@ -18,6 +18,7 @@
from dp_accounting import dp_event_builder
_gaussian_event = dp_event.GaussianDpEvent(1.0)
+_laplace_event = dp_event.LaplaceDpEvent(1.0)
_poisson_event = dp_event.PoissonSampledDpEvent(_gaussian_event, 0.1)
_self_composed_event = dp_event.SelfComposedDpEvent(_gaussian_event, 3)
@@ -28,11 +29,16 @@
builder = dp_event_builder.DpEventBuilder()
self.assertEqual(dp_event.NoOpDpEvent(), builder.build())
- def test_single(self):
+ def test_single_gaussian(self):
builder = dp_event_builder.DpEventBuilder()
builder.compose(_gaussian_event)
self.assertEqual(_gaussian_event, builder.build())
+ def test_single_laplace(self):
+ builder = dp_event_builder.DpEventBuilder()
+ builder.compose(_laplace_event)
+ self.assertEqual(_laplace_event, builder.build())
+
def test_compose_no_op(self):
builder = dp_event_builder.DpEventBuilder()
builder.compose(dp_event.NoOpDpEvent())
@@ -68,7 +74,8 @@
expected_event = dp_event.ComposedDpEvent([
_gaussian_event,
dp_event.SelfComposedDpEvent(composed_event, 3),
- dp_event.SelfComposedDpEvent(_poisson_event, 2)])
+ dp_event.SelfComposedDpEvent(_poisson_event, 2)
+ ])
self.assertEqual(expected_event, builder.build())
diff --git a/python/dp_accounting/privacy_accountant_test.py b/python/dp_accounting/privacy_accountant_test.py
index 1a5083e..bc47ae7 100644
--- a/python/dp_accounting/privacy_accountant_test.py
+++ b/python/dp_accounting/privacy_accountant_test.py
@@ -26,6 +26,7 @@
from dp_accounting import privacy_accountant
+@absltest.skipThisClass('only intended to be run by subclasses')
class PrivacyAccountantTest(absltest.TestCase):
def _make_test_accountants(
diff --git a/python/dp_accounting/rdp/BUILD.bazel b/python/dp_accounting/rdp/BUILD.bazel
index 98abec0..6c30470 100644
--- a/python/dp_accounting/rdp/BUILD.bazel
+++ b/python/dp_accounting/rdp/BUILD.bazel
@@ -29,11 +29,9 @@
srcs = ["rdp_privacy_accountant.py"],
deps = [
"//dp_accounting:dp_event",
- "//dp_accounting:dp_event_builder",
"//dp_accounting:privacy_accountant",
requirement("numpy"),
requirement("scipy"),
- requirement("six"),
],
)
diff --git a/python/dp_accounting/rdp/rdp_privacy_accountant.py b/python/dp_accounting/rdp/rdp_privacy_accountant.py
index ccd0124..50efe48 100644
--- a/python/dp_accounting/rdp/rdp_privacy_accountant.py
+++ b/python/dp_accounting/rdp/rdp_privacy_accountant.py
@@ -19,7 +19,6 @@
import numpy as np
from scipy import special
-import six
from dp_accounting import dp_event
from dp_accounting import privacy_accountant
@@ -75,7 +74,7 @@
def _compute_log_a_int(q, sigma, alpha):
"""Computes log(A_alpha) for integer alpha, 0 < q < 1."""
- assert isinstance(alpha, six.integer_types)
+ assert isinstance(alpha, int)
# Initialize with 0 in the log space.
log_a = -np.inf
@@ -431,7 +430,7 @@
"""
max_alpha = 256
- assert isinstance(alpha, six.integer_types)
+ assert isinstance(alpha, int)
if np.isinf(alpha):
return np.inf
@@ -522,7 +521,7 @@
def _compute_rdp_single_epoch_tree_aggregation(
noise_multiplier: float, step_counts: Union[int, Collection[int]],
- orders: Collection[float]) -> Collection[float]:
+ orders: Collection[float]) -> Union[float, np.ndarray]:
"""Computes RDP of the Tree Aggregation Protocol for Gaussian Mechanism.
This function implements the accounting when the tree is periodically
@@ -571,7 +570,7 @@
orders: Optional[Collection[float]] = None,
neighboring_relation: NeighborRel = NeighborRel.ADD_OR_REMOVE_ONE,
):
- super(RdpAccountant, self).__init__(neighboring_relation)
+ super().__init__(neighboring_relation)
if orders is None:
# Default orders chosen to give good coverage for Gaussian mechanism in
# the privacy regime of interest. In the future, more orders might be
diff --git a/python/requirements.txt b/python/requirements.txt
index 08c7032..5cd9133 100644
--- a/python/requirements.txt
+++ b/python/requirements.txt
@@ -1,5 +1,5 @@
numpy
-scipy>=1.5.0
+scipy>=1.5.0,<1.8.0
absl-py
dataclasses
attrs