From 7b02d985f49bd7d9a500d7e15c11d45efd15f9f0 Mon Sep 17 00:00:00 2001 From: Differential Privacy Team Date: Thu, 8 Feb 2024 04:14:27 -0800 Subject: [PATCH] PlumeGo CountParams improvements, updates to DP libraries, dependency fixes, deprecation cleanups. General: - Update freshness of documents and fix minor issues. - Remove documentation for deprecated functions Bounded Standard Deviation and Order Statistics. Plume Go: - Add option to CountParams to allow negative outputs to improve data quality of the output. C++ DP: - Fix Float-cast-overflow in quantiles. - Fix import and quantile test dependencies. Java DP: - Update bazel for java to 7.0.0. - Fix truth8 import style. Go DP: - Update go version to 1.21, upgrade Bazel & gazelle versions, upgrade Apache Beam dependency to the latest version. Privacy on Beam: - Mark PrivacySpec constructors of pbeamtest as deprecated. - Add missing doFn registers to fix tests failing with the new Prism runner. Change-Id: Ie08898ee34bdfeb6329701abefd22aa92b1c004a GitOrigin-RevId: 0aa22f05d11bb130df248e842b2ccc6a649c6b00 --- cc/algorithms/BUILD | 2 + cc/algorithms/binary-search.h | 1 + cc/algorithms/quantiles.h | 10 +- cc/algorithms/quantiles_test.cc | 13 + cc/algorithms/util.h | 4 + cc/base/percentile.h | 1 + cc/docs/algorithms/algorithm.md | 5 +- cc/docs/algorithms/approx-bounds.md | 4 +- cc/docs/algorithms/bounded-mean.md | 12 +- .../algorithms/bounded-standard-deviation.md | 43 --- cc/docs/algorithms/bounded-sum.md | 16 +- cc/docs/algorithms/bounded-variance.md | 20 +- cc/docs/algorithms/count.md | 6 +- cc/docs/algorithms/order-statistics.md | 52 ---- cc/docs/algorithms/quantiles.md | 4 +- cc/docs/protos.md | 8 +- cc/testing/sequence.h | 1 + examples/go/WORKSPACE | 20 +- examples/go/deps.bzl | 10 +- examples/go/go.mod | 6 +- examples/go/go.sum | 4 +- go/README.md | 24 +- go/WORKSPACE | 19 +- go/go.mod | 6 +- go/go.sum | 6 +- go/go_differential_privacy_deps.bzl | 51 ++-- java/.bazelversion | 2 +- java/dp_java_deps.bzl | 2 +- .../privacy/differentialprivacy/Noise.java | 6 + java/maven_install.json | 8 +- .../differentialprivacy/CountTest.java | 12 +- learning/WORKSPACE | 7 +- privacy-on-beam/README.md | 38 ++- privacy-on-beam/WORKSPACE | 28 +- privacy-on-beam/go.mod | 57 +++- privacy-on-beam/go.sum | 161 ++++++++++- privacy-on-beam/pbeam/aggregations.go | 2 +- privacy-on-beam/pbeam/count.go | 16 +- privacy-on-beam/pbeam/count_test.go | 67 +++-- privacy-on-beam/pbeam/pbeam_main_test.go | 2 +- privacy-on-beam/pbeam/pbeam_test.go | 18 +- privacy-on-beam/pbeam/pbeamtest/pbeamtest.go | 4 + privacy-on-beam/pbeam/testutils/BUILD.bazel | 3 +- privacy-on-beam/pbeam/testutils/testutils.go | 46 ++++ privacy-on-beam/privacy_on_beam_deps.bzl | 255 ++++++++++++------ python/BUILD.bazel | 15 -- python/{ => dp_accounting}/.bazelversion | 0 python/dp_accounting/BUILD.bazel | 116 -------- python/{ => dp_accounting}/README.md | 0 python/{ => dp_accounting}/VERSION | 0 python/{ => dp_accounting}/WORKSPACE | 0 .../accounting_py_deps.bzl | 0 .../accounting_py_deps_init.bzl | 0 .../dp_accounting/dp_accounting/BUILD.bazel | 131 +++++++++ .../{ => dp_accounting}/__init__.py | 8 +- .../{ => dp_accounting}/dp_event.py | 0 .../{ => dp_accounting}/dp_event_builder.py | 0 .../dp_event_builder_test.py | 0 .../{ => dp_accounting}/dp_event_test.py | 0 .../mechanism_calibration.py | 0 .../mechanism_calibration_test.py | 1 - .../{ => dp_accounting}/pld/BUILD.bazel | 9 +- .../{ => dp_accounting}/pld/__init__.py | 6 + .../{ => dp_accounting}/pld/accountant.py | 1 + .../pld/accountant_test.py | 1 + .../{ => dp_accounting}/pld/common.py | 0 .../{ => dp_accounting}/pld/common_test.py | 1 + .../{ => dp_accounting}/pld/pld_pmf.py | 1 + .../{ => dp_accounting}/pld/pld_pmf_test.py | 1 + .../pld/pld_privacy_accountant.py | 0 .../pld/pld_privacy_accountant_test.py | 0 .../pld/privacy_loss_distribution.py | 1 + ...privacy_loss_distribution_basic_example.py | 30 ++- .../pld/privacy_loss_distribution_test.py | 1 + .../pld/privacy_loss_mechanism.py | 1 + .../pld/privacy_loss_mechanism_test.py | 0 .../{ => dp_accounting}/pld/test_util.py | 0 .../{ => dp_accounting}/pld/test_util_test.py | 1 + .../{ => dp_accounting}/privacy_accountant.py | 0 .../privacy_accountant_test.py | 0 .../{ => dp_accounting}/rdp/BUILD.bazel | 0 .../{ => dp_accounting}/rdp/__init__.py | 1 + .../rdp/rdp_privacy_accountant.py | 0 .../rdp/rdp_privacy_accountant_test.py | 0 python/{ => dp_accounting}/requirements.txt | 0 python/{ => dp_accounting}/setup.py | 0 86 files changed, 886 insertions(+), 522 deletions(-) delete mode 100644 cc/docs/algorithms/bounded-standard-deviation.md delete mode 100644 cc/docs/algorithms/order-statistics.md delete mode 100644 python/BUILD.bazel rename python/{ => dp_accounting}/.bazelversion (100%) rename python/{ => dp_accounting}/README.md (100%) rename python/{ => dp_accounting}/VERSION (100%) rename python/{ => dp_accounting}/WORKSPACE (100%) rename python/{ => dp_accounting}/accounting_py_deps.bzl (100%) rename python/{ => dp_accounting}/accounting_py_deps_init.bzl (100%) create mode 100644 python/dp_accounting/dp_accounting/BUILD.bazel rename python/dp_accounting/{ => dp_accounting}/__init__.py (91%) rename python/dp_accounting/{ => dp_accounting}/dp_event.py (100%) rename python/dp_accounting/{ => dp_accounting}/dp_event_builder.py (100%) rename python/dp_accounting/{ => dp_accounting}/dp_event_builder_test.py (100%) rename python/dp_accounting/{ => dp_accounting}/dp_event_test.py (100%) rename python/dp_accounting/{ => dp_accounting}/mechanism_calibration.py (100%) rename python/dp_accounting/{ => dp_accounting}/mechanism_calibration_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/BUILD.bazel (95%) rename python/dp_accounting/{ => dp_accounting}/pld/__init__.py (70%) rename python/dp_accounting/{ => dp_accounting}/pld/accountant.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/accountant_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/common.py (100%) rename python/dp_accounting/{ => dp_accounting}/pld/common_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/pld_pmf.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/pld_pmf_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/pld_privacy_accountant.py (100%) rename python/dp_accounting/{ => dp_accounting}/pld/pld_privacy_accountant_test.py (100%) rename python/dp_accounting/{ => dp_accounting}/pld/privacy_loss_distribution.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/privacy_loss_distribution_basic_example.py (72%) rename python/dp_accounting/{ => dp_accounting}/pld/privacy_loss_distribution_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/privacy_loss_mechanism.py (99%) rename python/dp_accounting/{ => dp_accounting}/pld/privacy_loss_mechanism_test.py (100%) rename python/dp_accounting/{ => dp_accounting}/pld/test_util.py (100%) rename python/dp_accounting/{ => dp_accounting}/pld/test_util_test.py (99%) rename python/dp_accounting/{ => dp_accounting}/privacy_accountant.py (100%) rename python/dp_accounting/{ => dp_accounting}/privacy_accountant_test.py (100%) rename python/dp_accounting/{ => dp_accounting}/rdp/BUILD.bazel (100%) rename python/dp_accounting/{ => dp_accounting}/rdp/__init__.py (93%) rename python/dp_accounting/{ => dp_accounting}/rdp/rdp_privacy_accountant.py (100%) rename python/dp_accounting/{ => dp_accounting}/rdp/rdp_privacy_accountant_test.py (100%) rename python/{ => dp_accounting}/requirements.txt (100%) rename python/{ => dp_accounting}/setup.py (100%) diff --git a/cc/algorithms/BUILD b/cc/algorithms/BUILD index 8a84817d..fb6d95e7 100644 --- a/cc/algorithms/BUILD +++ b/cc/algorithms/BUILD @@ -683,6 +683,8 @@ cc_test( "//base/testing:proto_matchers", "//base/testing:status_matchers", "@com_google_absl//absl/random", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", "@com_google_googletest//:gtest_main", ], ) diff --git a/cc/algorithms/binary-search.h b/cc/algorithms/binary-search.h index 997a8460..49bdc499 100644 --- a/cc/algorithms/binary-search.h +++ b/cc/algorithms/binary-search.h @@ -18,6 +18,7 @@ #define DIFFERENTIAL_PRIVACY_ALGORITHMS_BINARY_SEARCH_H_ #include +#include #include #include "base/percentile.h" diff --git a/cc/algorithms/quantiles.h b/cc/algorithms/quantiles.h index 7f615d10..3d5313fe 100644 --- a/cc/algorithms/quantiles.h +++ b/cc/algorithms/quantiles.h @@ -17,6 +17,8 @@ #ifndef DIFFERENTIAL_PRIVACY_CPP_ALGORITHMS_QUANTILES_H_ #define DIFFERENTIAL_PRIVACY_CPP_ALGORITHMS_QUANTILES_H_ +#include + #include "absl/status/status.h" #include "absl/status/statusor.h" #include "algorithms/algorithm.h" @@ -115,10 +117,10 @@ class Quantiles : public Algorithm { private: Quantiles(std::unique_ptr> tree, - std::vector quantiles, double epsilon, double delta, - int max_contributions_per_partition, - int max_partitions_contributed_to, - std::unique_ptr mechanism_builder) + std::vector quantiles, double epsilon, double delta, + int max_contributions_per_partition, + int max_partitions_contributed_to, + std::unique_ptr mechanism_builder) : Algorithm(epsilon, delta), tree_(std::move(tree)), quantiles_(quantiles), diff --git a/cc/algorithms/quantiles_test.cc b/cc/algorithms/quantiles_test.cc index 2a71c866..5923aec4 100644 --- a/cc/algorithms/quantiles_test.cc +++ b/cc/algorithms/quantiles_test.cc @@ -17,13 +17,18 @@ #include "algorithms/quantiles.h" #include +#include +#include #include +#include #include "base/testing/proto_matchers.h" #include "base/testing/status_matchers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/random/random.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" #include "algorithms/numerical-mechanisms-testing.h" namespace differential_privacy { @@ -77,6 +82,14 @@ TEST(QuantilesTest, InvalidParametersTest) { .Build(), StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Lower bound cannot be greater than upper bound"))); + EXPECT_THAT( + Quantiles::Builder() + .SetLower(1) + .SetUpper(1) + .SetQuantiles({0.5}) + .Build(), + StatusIs(absl::StatusCode::kInvalidArgument, + HasSubstr("Lower bound cannot be equal to upper bound"))); EXPECT_THAT(Quantiles::Builder().SetQuantiles({0.5}).Build(), StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Lower and upper bounds must both be set"))); diff --git a/cc/algorithms/util.h b/cc/algorithms/util.h index fca1a77e..2b631c29 100644 --- a/cc/algorithms/util.h +++ b/cc/algorithms/util.h @@ -545,6 +545,10 @@ absl::Status ValidateBounds(absl::optional lower, absl::optional upper) { return absl::InvalidArgumentError( "Lower bound cannot be greater than upper bound."); } + if (lower.value() == upper.value()) { + return absl::InvalidArgumentError( + "Lower bound cannot be equal to upper bound."); + } return absl::OkStatus(); } diff --git a/cc/base/percentile.h b/cc/base/percentile.h index 946538d3..c6c016c3 100644 --- a/cc/base/percentile.h +++ b/cc/base/percentile.h @@ -18,6 +18,7 @@ #define DIFFERENTIAL_PRIVACY_BASE_PERCENTILE_H_ #include +#include #include "google/protobuf/repeated_field.h" #include "proto/util.h" diff --git a/cc/docs/algorithms/algorithm.md b/cc/docs/algorithms/algorithm.md index f5280b56..04a21e51 100644 --- a/cc/docs/algorithms/algorithm.md +++ b/cc/docs/algorithms/algorithm.md @@ -41,6 +41,7 @@ absl::StatusOr> algorithm = noise during testing. ### Partitions + Several of the parameters refer to the concept of a partition. We define a partition as a portion of the data for which a single statistic will be released. This is best explained through examples: if you're counting the number @@ -126,6 +127,6 @@ Note that whichever method of getting a result you use, you can only get a single result before your `epsilon` and `delta` are exhausted. Values are returned from `Result` in an [`Output`](../protos.md) proto. For most -algorithms, this is a single `int64` or `double` value. Some algorithms contain -additional data about accuracy and algorithm mechanisms. You can use +algorithms, this is a single `int64_t` or `double` value. Some algorithms +contain additional data about accuracy and algorithm mechanisms. You can use [`GetValue`](../protos.md) to get values out of `Output`s easily. diff --git a/cc/docs/algorithms/approx-bounds.md b/cc/docs/algorithms/approx-bounds.md index 6a0058ac..4e1299a8 100644 --- a/cc/docs/algorithms/approx-bounds.md +++ b/cc/docs/algorithms/approx-bounds.md @@ -8,7 +8,7 @@ bounds of input sets inside [bounded algorithms](bounded-algorithm.md). ## Input & Output -`ApproxBounds` supports `int64` and `double` type input sets. When successful, +`ApproxBounds` supports `int64_t` and `double` type input sets. When successful, the returned [`Output`](../protos.md) message will contain two elements. The first is the differentially private lower bound; the second is the upper. The `Output` message will contain an error status instead if not enough inputs were @@ -21,7 +21,7 @@ are additional parameters. ``` ApproxBounds::Builder builder = - ApproxBounds::Builder.SetNumBins(int64 num_bins) + ApproxBounds::Builder.SetNumBins(int64_t num_bins) .SetScale(double scale) .SetBase(double base) diff --git a/cc/docs/algorithms/bounded-mean.md b/cc/docs/algorithms/bounded-mean.md index c6a9a519..353a409c 100644 --- a/cc/docs/algorithms/bounded-mean.md +++ b/cc/docs/algorithms/bounded-mean.md @@ -5,7 +5,7 @@ computes the average of values in a dataset in a differentially private manner. ## Input & Output -`BoundedMean` supports `int64`s and `double`s as inputs. When successful, +`BoundedMean` supports `int64_t` and `double` types as input. When successful, the returned [`Output`](../protos.md) message will contain one element containing the differentially private mean. When bounds are inferred, the `Output` additionally contains a `BoundingReport`. The returned value is @@ -19,11 +19,11 @@ Information on how to construct a `BoundedMean` is found in the construction example. ``` -absl::StatusOr>> bounded_mean = - BoundedMean::Builder.SetEpsilon(1) - .SetLower(-10) - .SetUpper(10) - .Build(); +absl::StatusOr>> bounded_mean = + BoundedMean::Builder.SetEpsilon(1) + .SetLower(-10) + .SetUpper(10) + .Build(); ``` ## Use diff --git a/cc/docs/algorithms/bounded-standard-deviation.md b/cc/docs/algorithms/bounded-standard-deviation.md deleted file mode 100644 index 79f6512a..00000000 --- a/cc/docs/algorithms/bounded-standard-deviation.md +++ /dev/null @@ -1,43 +0,0 @@ -# Bounded Standard Deviation - -WARNING: `BoundedStandardDeviation` is deprecated. Please use -[`BoundedVariance`](bounded-variance.md) instead and take the square root of the -result. This documentation might be out of date. - -[`BoundedStandardDeviation`](https://github.com/google/differential-privacy/blob/main/cc/algorithms/bounded-standard-deviation.h) -computes the standard deviation of values in a dataset in a differentially -private manner. - -## Input & Output - -`BoundedStandardDeviation` supports `int64`s and `double`s as inputs. When -successful, the returned [`Output`](../protos.md) message will contain one -element containing the differentially private standard deviation. When bounds -are inferred, the `Output` additionally contains a `BoundingReport`. The -returned value is guaranteed to be non-negative, with a maximum possible value -of the size of the bounded interval. - -## Construction - -`BoundedStandardDeviation` is a bounded algorithm. There are no additional -parameters. Information on how to construct a `BoundedStandardDeviation` is -found in the [bounded algorithm documentation](bounded-algorithm.md). Below is a -minimal construction example. - -``` -absl::StatusOr>> bounded_stdev = - BoundedStandardDeviation::Builder.SetEpsilon(1) - .SetLower(-10) - .SetUpper(10) - .Build(); -``` - -## Use - -`BoundedStandardDeviation` is an [`Algorithm`](algorithm.md) and supports its -full API. - -### Result Performance - -For `BoundedStandardDeviation`, calling `Result` is an O(n) operation and -requires O(1) additional memory. diff --git a/cc/docs/algorithms/bounded-sum.md b/cc/docs/algorithms/bounded-sum.md index 69447ca8..e9138af7 100644 --- a/cc/docs/algorithms/bounded-sum.md +++ b/cc/docs/algorithms/bounded-sum.md @@ -5,9 +5,9 @@ computes the sum of values in a dataset in a differentially private manner. ## Input & Output -`BoundedSum` supports `int64`s and `double`s as input. When successful, the -returned [`Output`](../protos.md) message will contain one element with -the differentially private sum, and a `ConfidenceInterval` describing the 95% +`BoundedSum` supports `int64_t` and `double` types as input. When successful, +the returned [`Output`](../protos.md) message will contain one element with the +differentially private sum, and a `ConfidenceInterval` describing the 95% confidence interval of the noise added. When bounds are inferred, the `Output` also contains a `BoundingReport`. @@ -23,11 +23,11 @@ Information on how to construct a `BoundedSum` is found in the construction example. ``` -absl::StatusOr>> bounded_sum = - BoundedSum::Builder.SetEpsilon(1) - .SetLower(-10) - .SetUpper(10) - .Build(); +absl::StatusOr>> bounded_sum = + BoundedSum::Builder.SetEpsilon(1) + .SetLower(-10) + .SetUpper(10) + .Build(); ``` ## Use diff --git a/cc/docs/algorithms/bounded-variance.md b/cc/docs/algorithms/bounded-variance.md index 001fcda0..edc36638 100644 --- a/cc/docs/algorithms/bounded-variance.md +++ b/cc/docs/algorithms/bounded-variance.md @@ -5,12 +5,12 @@ variance of values in a dataset, in a differentially private manner. ## Input & Output -`BoundedVariance` supports `int64`s and `double`s as inputs. When +`BoundedVariance` supports `int64_t` and `double` types as input. When successful, the returned [`Output`](../protos.md) message will contain one -element with the differentially private variance. When bounds are -inferred, the `Output` additionally contains a `BoundingReport`. The returned -value is guaranteed to be non-negative, with a maximum possible value of the -maximum variance (length of the bounded interval squared divided by four). +element with the differentially private variance. When bounds are inferred, the +`Output` additionally contains a `BoundingReport`. The returned value is +guaranteed to be non-negative, with a maximum possible value of the maximum +variance (length of the bounded interval squared divided by four). ## Construction @@ -20,11 +20,11 @@ Information on how to construct a `BoundedVariance` is found in the construction example. ``` -absl::StatusOr>> bounded_var = - BoundedVariance::Builder.SetEpsilon(1) - .SetLower(-10) - .SetUpper(10) - .Build(); +absl::StatusOr>> bounded_var = + BoundedVariance::Builder.SetEpsilon(1) + .SetLower(-10) + .SetUpper(10) + .Build(); ``` ## Use diff --git a/cc/docs/algorithms/count.md b/cc/docs/algorithms/count.md index d00a291f..6206ef82 100644 --- a/cc/docs/algorithms/count.md +++ b/cc/docs/algorithms/count.md @@ -25,9 +25,9 @@ additional parameters. minimal construction example. ``` -absl::StatusOr>> count = - Count::Builder.SetEpsilon(1) - .Build(); +absl::StatusOr>> count = + Count::Builder.SetEpsilon(1) + .Build(); ``` ### Result Performance diff --git a/cc/docs/algorithms/order-statistics.md b/cc/docs/algorithms/order-statistics.md deleted file mode 100644 index 7be969af..00000000 --- a/cc/docs/algorithms/order-statistics.md +++ /dev/null @@ -1,52 +0,0 @@ -# Order Statistics - -WARNING: These algorithms are deprecated and may be removed soon. Please use -[Quantiles](quantiles.md) (which is more accurate) instead. - -We have a set of algorithms for calculating -[order statistics](https://github.com/google/differential-privacy/blob/main/cc/algorithms/order-statistics.h) -(aka quantiles, percentiles). The following are supported: - -* `Max` -* `Min` -* `Median` -* `Percentile` for percentile `p`. - -`Max`, `Min`, and `Median` are convenience wrappers around `Percentile`, which -can be used to calculate any of the other quantities. - -## Input & Output - -The order statistics algorithms support any numeric type. Their `Output`s -contain an element with a single value. `ConfidenceInterval` and -`BoundingReport` are not provided. - -## Construction - -The order statistics algorithms are [bounded algorithms](bounded-algorithm.md). -However, when bounds are not manually set, the algorithms do not infer input -bounds by spending privacy budget. Instead, they use the numeric limits of the -input type as bounds. The `Percentile` algorithm requires the additional -parameter `percentile`. For example, when constructing the `Percentile` -algorithm: - -``` -absl::StatusOr>> percentile = - Percentile::Builder.SetPercentile(double percentile) - .Build(); -``` - -* `T`: The input type, for example `double` or `int64`. -* `double percentile`: This parameter is required for the `Percentile` - algorithm and cannot be set for the other order statistics algorithms. It is - the percentile you wish to find. - -## Use - -The order statistics algorithms are [`Algorithm`s](algorithm.md) and supports -its full API. - -### Result Performance - -For order statistics algorithms, calling `Result` has a time complexity of O(n). -Since all inputs are stored in an internal vector, space complexity is O(n). diff --git a/cc/docs/algorithms/quantiles.md b/cc/docs/algorithms/quantiles.md index 3b619fc3..276d5d45 100644 --- a/cc/docs/algorithms/quantiles.md +++ b/cc/docs/algorithms/quantiles.md @@ -58,7 +58,7 @@ absl::StatusOr>> quantile = .Build(); ``` -* `T`: The input type, for example `double` or `int64`. +* `T`: The input type, for example `double` or `int64_t`. * `T upper, lower`: The upper and lower bounds on each input element. If any input elements are greater than `upper` or less than `lower`, they will be replaced with `upper` or `lower` respectively. @@ -93,7 +93,7 @@ absl::StatusOr>> quantile_tree = .Build(); ``` -* `T`: The input type, for example `double` or `int64`. +* `T`: The input type, for example `double` or `int64_t`. * `T upper, lower`: The upper and lower bounds for each input element. If any inputs are greater than `upper` or less than `lower` they will be replaced with `upper` or `lower` respectively. diff --git a/cc/docs/protos.md b/cc/docs/protos.md index 1becb581..898e8f87 100644 --- a/cc/docs/protos.md +++ b/cc/docs/protos.md @@ -58,7 +58,7 @@ functions for the common cases. We outline some of these functions below. See the [utility function file](https://github.com/google/differential-privacy/blob/main/cc/proto/util.h) for the full list. -### GetValue<T> +### `GetValue` ``` template @@ -69,7 +69,7 @@ Extracts the first element from the provided `Output` proto. `T` is the requested return type; the value in the proto must match that type. For example, if `T` is an integral type, the element must have `int_value` set. -### MakeOutput +### `MakeOutput` Creates an `Output` with one element. Which field gets set depends on the type of the template parameter `T`. For example, `MakeOutput(7)` will set @@ -80,7 +80,7 @@ template MakeOutput(T value); ``` -### AddToOutput +### `AddToOutput` Adds an element to the given output. Which field gets set depends on the type of the template parameter `T`. For example, `AddToOutput(&output, 7.0)` will add an @@ -88,5 +88,5 @@ element to `output` and set the `float_value`. ``` template -void AddToOutput(Output* output, T value) { +void AddToOutput(Output* output, T value); ``` diff --git a/cc/testing/sequence.h b/cc/testing/sequence.h index 8483b690..16abbfc6 100644 --- a/cc/testing/sequence.h +++ b/cc/testing/sequence.h @@ -18,6 +18,7 @@ #define DIFFERENTIAL_PRIVACY_TESTING_SEQUENCE_H_ #include +#include #include #include diff --git a/examples/go/WORKSPACE b/examples/go/WORKSPACE index b5351799..7dac74d6 100644 --- a/examples/go/WORKSPACE +++ b/examples/go/WORKSPACE @@ -27,28 +27,27 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", - sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f", + sha256 = "b6828eb2d03bb5ef76f2077f8670b211fe792e77ddb83450ea9f887df04db9c7", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", ], ) http_archive( name = "bazel_gazelle", - sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d", + sha256 = "b7387f72efb59f876e4daae42f1d3912d0d45563eac7cb23d1de0b094ab588cf", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") -load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") go_rules_dependencies() -go_register_toolchains(version = "1.19.5") +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") @@ -61,4 +60,7 @@ load("//:deps.bzl", "go_differential_privacy_examples_deps") # gazelle:repository_macro deps.bzl%go_differential_privacy_examples_deps go_differential_privacy_examples_deps() -gazelle_dependencies() +# Gazelle dependencies must be added last. +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") + +gazelle_dependencies() \ No newline at end of file diff --git a/examples/go/deps.bzl b/examples/go/deps.bzl index a141662c..381575da 100644 --- a/examples/go/deps.bzl +++ b/examples/go/deps.bzl @@ -54,14 +54,12 @@ def go_differential_privacy_examples_deps(): sum = "h1:FSii2UQeSLngl3jFoR4tUKZLprO7qUlh/TKKticc0BM=", version = "v0.0.0-20230228185258-2292f9e40198", ) - go_repository( name = "com_github_golang_freetype", importpath = "github.com/golang/freetype", sum = "h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=", version = "v0.0.0-20170609003504-e2365dfdc4a0", ) - go_repository( name = "com_github_golang_glog", importpath = "github.com/golang/glog", @@ -74,7 +72,6 @@ def go_differential_privacy_examples_deps(): sum = "h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=", version = "v0.6.0", ) - go_repository( name = "ht_sr_git_sbinet_gg", importpath = "git.sr.ht/~sbinet/gg", @@ -87,12 +84,11 @@ def go_differential_privacy_examples_deps(): sum = "h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=", version = "v0.1.1", ) - go_repository( name = "org_golang_x_exp", importpath = "golang.org/x/exp", - sum = "h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=", - version = "v0.0.0-20231127185646-65229373498e", + sum = "h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=", + version = "v0.0.0-20231226003508-02704c960a9b", ) go_repository( name = "org_golang_x_image", @@ -106,7 +102,6 @@ def go_differential_privacy_examples_deps(): sum = "h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=", version = "v0.14.0", ) - go_repository( name = "org_golang_x_text", importpath = "golang.org/x/text", @@ -119,7 +114,6 @@ def go_differential_privacy_examples_deps(): sum = "h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=", version = "v0.16.0", ) - go_repository( name = "org_gonum_v1_gonum", importpath = "gonum.org/v1/gonum", diff --git a/examples/go/go.mod b/examples/go/go.mod index 11750cc2..8ebd9b1c 100644 --- a/examples/go/go.mod +++ b/examples/go/go.mod @@ -1,6 +1,6 @@ module github.com/google/differential-privacy/examples/go -go 1.19 +go 1.21 require ( github.com/golang/glog v1.2.0 @@ -8,6 +8,6 @@ require ( ) require ( - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect gonum.org/v1/gonum v0.14.0 // indirect -) +) \ No newline at end of file diff --git a/examples/go/go.sum b/examples/go/go.sum index d71503f4..8ca27657 100644 --- a/examples/go/go.sum +++ b/examples/go/go.sum @@ -5,5 +5,7 @@ github.com/google/differential-privacy/go/v2 v2.1.1-0.20230822150926-c89810faa5a github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= \ No newline at end of file diff --git a/go/README.md b/go/README.md index 1c321445..9827112f 100644 --- a/go/README.md +++ b/go/README.md @@ -54,22 +54,22 @@ use [Gazelle](https://github.com/bazelbuild/bazel-gazelle): load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( - name = "io_bazel_rules_go", - sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - ], + name = "io_bazel_rules_go", + sha256 = "b6828eb2d03bb5ef76f2077f8670b211fe792e77ddb83450ea9f887df04db9c7", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + ], ) - http_archive( + http_archive( name = "bazel_gazelle", - sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d", + sha256 = "b7387f72efb59f876e4daae42f1d3912d0d45563eac7cb23d1de0b094ab588cf", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", ], - ) + ) http_archive( name = "com_google_protobuf", @@ -82,7 +82,7 @@ use [Gazelle](https://github.com/bazelbuild/bazel-gazelle): go_rules_dependencies() - go_register_toolchains(version = "1.19.5") + go_register_toolchains(version = "1.21.5") # Protobuf transitive dependencies. load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") diff --git a/go/WORKSPACE b/go/WORKSPACE index 454498cb..2cd6740d 100644 --- a/go/WORKSPACE +++ b/go/WORKSPACE @@ -20,28 +20,27 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", - sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f", + sha256 = "b6828eb2d03bb5ef76f2077f8670b211fe792e77ddb83450ea9f887df04db9c7", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", ], ) http_archive( name = "bazel_gazelle", - sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d", + sha256 = "b7387f72efb59f876e4daae42f1d3912d0d45563eac7cb23d1de0b094ab588cf", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") -load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") go_rules_dependencies() -go_register_toolchains(version = "1.19.5") +go_register_toolchains(version = "1.21.5") load("//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps") @@ -49,4 +48,6 @@ load("//:go_differential_privacy_deps.bzl", "go_differential_privacy_deps") go_differential_privacy_deps() # Gazelle dependencies must be added last. -gazelle_dependencies() +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") + +gazelle_dependencies() \ No newline at end of file diff --git a/go/go.mod b/go/go.mod index 5c571894..4a667fd9 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,11 +1,11 @@ module github.com/google/differential-privacy/go/v2 -go 1.19 +go 1.21 require ( - github.com/golang/glog v1.1.2 + github.com/golang/glog v1.2.0 github.com/google/go-cmp v0.6.0 gonum.org/v1/gonum v0.14.0 ) -require golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect +require golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect \ No newline at end of file diff --git a/go/go.sum b/go/go.sum index e64134f1..d5d20f8a 100644 --- a/go/go.sum +++ b/go/go.sum @@ -1,8 +1,12 @@ github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= \ No newline at end of file diff --git a/go/go_differential_privacy_deps.bzl b/go/go_differential_privacy_deps.bzl index 2d5df766..c0f7cf79 100644 --- a/go/go_differential_privacy_deps.bzl +++ b/go/go_differential_privacy_deps.bzl @@ -30,19 +30,17 @@ def go_differential_privacy_deps(): sum = "h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=", version = "v0.0.0-20211024235047-1546f124cd8b", ) - go_repository( name = "com_github_go_fonts_liberation", importpath = "github.com/go-fonts/liberation", - sum = "h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXWo5VM=", - version = "v0.2.0", + sum = "h1:3BI2iaE7R/s6uUUtzNCjo3QijJu3aS4wmrMgfSpYQ+8=", + version = "v0.3.0", ) - go_repository( name = "com_github_go_latex_latex", importpath = "github.com/go-latex/latex", - sum = "h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ=", - version = "v0.0.0-20210823091927-c0d11ff05a81", + sum = "h1:NxXI5pTAtpEaU49bpLpQoDsu1zrteW/vxzTz8Cd2UAs=", + version = "v0.0.0-20230307184459-12ec69307ad9", ) go_repository( name = "com_github_go_pdf_fpdf", @@ -50,6 +48,12 @@ def go_differential_privacy_deps(): sum = "h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8=", version = "v0.6.0", ) + go_repository( + name = "com_github_goccmack_gocc", + importpath = "github.com/goccmack/gocc", + sum = "h1:FSii2UQeSLngl3jFoR4tUKZLprO7qUlh/TKKticc0BM=", + version = "v0.0.0-20230228185258-2292f9e40198", + ) go_repository( name = "com_github_golang_freetype", importpath = "github.com/golang/freetype", @@ -59,8 +63,8 @@ def go_differential_privacy_deps(): go_repository( name = "com_github_golang_glog", importpath = "github.com/golang/glog", - sum = "h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=", - version = "v1.1.2", + sum = "h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=", + version = "v1.2.0", ) go_repository( name = "com_github_google_go_cmp", @@ -68,7 +72,6 @@ def go_differential_privacy_deps(): sum = "h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=", version = "v0.6.0", ) - go_repository( name = "ht_sr_git_sbinet_gg", importpath = "git.sr.ht/~sbinet/gg", @@ -81,46 +84,36 @@ def go_differential_privacy_deps(): sum = "h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=", version = "v0.1.1", ) - go_repository( name = "org_golang_x_exp", importpath = "golang.org/x/exp", - sum = "h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=", - version = "v0.0.0-20231110203233-9a3e6036ecaa", + sum = "h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=", + version = "v0.0.0-20231226003508-02704c960a9b", ) go_repository( name = "org_golang_x_image", importpath = "golang.org/x/image", - sum = "h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4=", - version = "v0.0.0-20220302094943-723b81ca9867", + sum = "h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4=", + version = "v0.6.0", ) - go_repository( name = "org_golang_x_mod", importpath = "golang.org/x/mod", - sum = "h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=", - version = "v0.6.0", - ) - - go_repository( - name = "org_golang_x_sys", - importpath = "golang.org/x/sys", - sum = "h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=", - version = "v0.1.0", + sum = "h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=", + version = "v0.14.0", ) go_repository( name = "org_golang_x_text", importpath = "golang.org/x/text", - sum = "h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=", - version = "v0.3.7", + sum = "h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=", + version = "v0.8.0", ) go_repository( name = "org_golang_x_tools", importpath = "golang.org/x/tools", - sum = "h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=", - version = "v0.2.0", + sum = "h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=", + version = "v0.16.0", ) - go_repository( name = "org_gonum_v1_gonum", importpath = "gonum.org/v1/gonum", diff --git a/java/.bazelversion b/java/.bazelversion index 19b860c1..66ce77b7 100644 --- a/java/.bazelversion +++ b/java/.bazelversion @@ -1 +1 @@ -6.4.0 +7.0.0 diff --git a/java/dp_java_deps.bzl b/java/dp_java_deps.bzl index 2188640e..5336d48d 100644 --- a/java/dp_java_deps.bzl +++ b/java/dp_java_deps.bzl @@ -19,7 +19,7 @@ def dp_java_deps(): "junit:junit:4.13.2", "com.google.truth:truth:1.1.5", "com.google.truth.extensions:truth-java8-extension:1.1.5", - "com.google.testparameterinjector:test-parameter-injector:1.14", + "com.google.testparameterinjector:test-parameter-injector:1.15", ], repositories = [ "https://jcenter.bintray.com/", diff --git a/java/main/com/google/privacy/differentialprivacy/Noise.java b/java/main/com/google/privacy/differentialprivacy/Noise.java index 6fed076d..046c8ec1 100644 --- a/java/main/com/google/privacy/differentialprivacy/Noise.java +++ b/java/main/com/google/privacy/differentialprivacy/Noise.java @@ -78,6 +78,12 @@ static double getL2Sensitivity(int l0Sensitivity, double lInfSensitivity) { return Math.sqrt(l0Sensitivity) * lInfSensitivity; } + /** + * Computes the quantile z satisfying Pr[Y <= z] = {@code rank} for a random variable Y + * whose distribution is given by applying the Noise mechanism to the raw value {@code x} using + * the specified privacy parameters {@code epsilon}, {@code delta}, {@code l0Sensitivity}, and + * {@code lInfSensitivity}. + */ double computeQuantile( double rank, double x, diff --git a/java/maven_install.json b/java/maven_install.json index 831bebc9..d709250b 100644 --- a/java/maven_install.json +++ b/java/maven_install.json @@ -1,7 +1,7 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": 1818957762, - "__RESOLVED_ARTIFACTS_HASH": -1022974526, + "__INPUT_ARTIFACTS_HASH": -131666651, + "__RESOLVED_ARTIFACTS_HASH": -1554454602, "artifacts": { "com.google.auto.value:auto-value": { "shasums": { @@ -59,9 +59,9 @@ }, "com.google.testparameterinjector:test-parameter-injector": { "shasums": { - "jar": "c8c39d34edfdd0719f2e671c8abd406268f39924bf483c2545b42d93051f1aae" + "jar": "a1ac1820becc772baaac57c4d2a4d49b6f7920e5dfd25b293ba8fb933a11dfe2" }, - "version": "1.14" + "version": "1.15" }, "com.google.truth.extensions:truth-java8-extension": { "shasums": { diff --git a/java/tests/com/google/privacy/differentialprivacy/CountTest.java b/java/tests/com/google/privacy/differentialprivacy/CountTest.java index 619f9a0f..6fe1961f 100644 --- a/java/tests/com/google/privacy/differentialprivacy/CountTest.java +++ b/java/tests/com/google/privacy/differentialprivacy/CountTest.java @@ -17,7 +17,6 @@ package com.google.privacy.differentialprivacy; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static com.google.privacy.differentialprivacy.proto.SummaryOuterClass.MechanismType.GAUSSIAN; import static com.google.privacy.differentialprivacy.proto.SummaryOuterClass.MechanismType.LAPLACE; import static org.junit.Assert.assertThrows; @@ -29,6 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.google.common.truth.Truth8; import com.google.privacy.differentialprivacy.proto.SummaryOuterClass.CountSummary; import com.google.privacy.differentialprivacy.proto.SummaryOuterClass.MechanismType; import com.google.protobuf.InvalidProtocolBufferException; @@ -531,7 +531,7 @@ public void computeThresholdedResult_countGreaterThanThreshold_returnsCount() { // noise) count is equal to 12, which passes the threshold and therefore 12 should be returned. count.incrementBy(12); Optional actualResult = count.computeThresholdedResult(THRESHOLD_DELTA); - assertThat(actualResult).hasValue(12); + Truth8.assertThat(actualResult).hasValue(12); } @Test @@ -573,8 +573,8 @@ public void computeThresholdedResult_forLaplace_appliesCorrectThreshold() { count.incrementBy(122); Optional ceiledThreshold = count.computeThresholdedResult(0.1); - assertThat(flooredThreshold).isEmpty(); - assertThat(ceiledThreshold).hasValue(122); + Truth8.assertThat(flooredThreshold).isEmpty(); + Truth8.assertThat(ceiledThreshold).hasValue(122); } @Test @@ -613,8 +613,8 @@ public void computeThresholdedResult_forGaussian_appliesCorrectThreshold() { count.incrementBy(72); Optional ceiledThreshold = count.computeThresholdedResult(0.1); - assertThat(flooredThreshold).isEmpty(); - assertThat(ceiledThreshold).hasValue(72); + Truth8.assertThat(flooredThreshold).isEmpty(); + Truth8.assertThat(ceiledThreshold).hasValue(72); } private Count.Params.Builder getCountBuilderWithFields() { diff --git a/learning/WORKSPACE b/learning/WORKSPACE index 5b347634..255e3463 100644 --- a/learning/WORKSPACE +++ b/learning/WORKSPACE @@ -17,19 +17,22 @@ workspace(name = "learning") load("@learning//:learning_py_deps.bzl", "learning_py_deps") + learning_py_deps() load("@learning//:learning_py_deps_init.bzl", "learning_py_deps_init") + learning_py_deps_init("learning") local_repository( name = "com_google_python_dp_accounting", - path = "../python", + path = "../python/dp_accounting/", ) load("@com_google_python_dp_accounting//:accounting_py_deps.bzl", "accounting_py_deps") + accounting_py_deps() load("@com_google_python_dp_accounting//:accounting_py_deps_init.bzl", "accounting_py_deps_init") -accounting_py_deps_init("com_google_python_dp_accounting") +accounting_py_deps_init("com_google_python_dp_accounting") diff --git a/privacy-on-beam/README.md b/privacy-on-beam/README.md index 8f2b4a8b..dd143ce9 100644 --- a/privacy-on-beam/README.md +++ b/privacy-on-beam/README.md @@ -66,22 +66,22 @@ In order to include Privacy on Beam in your Bazel project, we recommend you use load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( - name = "io_bazel_rules_go", - sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - ], + name = "io_bazel_rules_go", + sha256 = "b6828eb2d03bb5ef76f2077f8670b211fe792e77ddb83450ea9f887df04db9c7", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + ], ) - http_archive( + http_archive( name = "bazel_gazelle", - sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d", + sha256 = "b7387f72efb59f876e4daae42f1d3912d0d45563eac7cb23d1de0b094ab588cf", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", ], - ) + ) http_archive( name = "com_google_protobuf", @@ -94,7 +94,7 @@ In order to include Privacy on Beam in your Bazel project, we recommend you use go_rules_dependencies() - go_register_toolchains(version = "1.19.5") + go_register_toolchains(version = "1.21.5") # Protobuf transitive dependencies. load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") @@ -104,6 +104,20 @@ In order to include Privacy on Beam in your Bazel project, we recommend you use load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") gazelle_dependencies() + + # Googleapis needs to be included separately for dependencies to work: https://github.com/bazelbuild/rules_go/issues/3625#issuecomment-1643804054 + http_archive( + name = "googleapis", + sha256 = "78aae8879967e273044bc786e691d9a16db385bd137454e80cd0b53476adfc2d", + strip_prefix = "googleapis-c09efadc6785560333d967f0bd40f1d1c3232088", + urls = ["https://github.com/googleapis/googleapis/archive/c09efadc6785560333d967f0bd40f1d1c3232088.tar.gz"], + ) + + load("@googleapis//:repository_rules.bzl", "switched_rules_by_language") + + switched_rules_by_language( + name = "com_google_googleapis_imports", + ) ``` 1. Add the following code to your root `BUILD` or `BUILD.bazel` file: diff --git a/privacy-on-beam/WORKSPACE b/privacy-on-beam/WORKSPACE index 674c66cc..e98526da 100644 --- a/privacy-on-beam/WORKSPACE +++ b/privacy-on-beam/WORKSPACE @@ -30,19 +30,19 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", - sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f", + sha256 = "b6828eb2d03bb5ef76f2077f8670b211fe792e77ddb83450ea9f887df04db9c7", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.44.1/rules_go-v0.44.1.zip", ], ) http_archive( name = "bazel_gazelle", - sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d", + sha256 = "b7387f72efb59f876e4daae42f1d3912d0d45563eac7cb23d1de0b094ab588cf", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.34.0/bazel-gazelle-v0.34.0.tar.gz", ], ) @@ -50,7 +50,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe go_rules_dependencies() -go_register_toolchains(version = "1.19.5") +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") @@ -77,3 +77,17 @@ protobuf_deps() load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") gazelle_dependencies() + +# Googleapis needs to be included separately for dependencies to work: https://github.com/bazelbuild/rules_go/issues/3625#issuecomment-1643804054 +http_archive( + name = "googleapis", + sha256 = "78aae8879967e273044bc786e691d9a16db385bd137454e80cd0b53476adfc2d", + strip_prefix = "googleapis-c09efadc6785560333d967f0bd40f1d1c3232088", + urls = ["https://github.com/googleapis/googleapis/archive/c09efadc6785560333d967f0bd40f1d1c3232088.tar.gz"], +) + +load("@googleapis//:repository_rules.bzl", "switched_rules_by_language") + +switched_rules_by_language( + name = "com_google_googleapis_imports", +) \ No newline at end of file diff --git a/privacy-on-beam/go.mod b/privacy-on-beam/go.mod index daa7c1d5..23aa00f9 100644 --- a/privacy-on-beam/go.mod +++ b/privacy-on-beam/go.mod @@ -1,47 +1,76 @@ module github.com/google/differential-privacy/privacy-on-beam/v2 -go 1.19 +go 1.21 require ( - github.com/apache/beam/sdks/v2 v2.49.0 + github.com/apache/beam/sdks/v2 v2.52.0 github.com/golang/glog v1.2.0 github.com/google/differential-privacy/go/v2 v2.1.1-0.20230822150926-c89810faa5ad github.com/google/go-cmp v0.6.0 gonum.org/v1/plot v0.14.0 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 ) require ( - cloud.google.com/go v0.110.10 // indirect + cloud.google.com/go v0.111.0 // indirect + cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/profiler v0.4.0 // indirect - cloud.google.com/go/storage v1.35.1 // indirect + cloud.google.com/go/storage v1.36.0 // indirect git.sr.ht/~sbinet/gg v0.5.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect github.com/campoy/embedmd v1.0.0 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-fonts/liberation v0.3.2 // indirect github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-pdf/fpdf v0.9.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/pprof v0.0.0-20231127191134-f3a68a39ae15 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect golang.org/x/image v0.14.0 // indirect + golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.16.1 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/api v0.152.0 // indirect + google.golang.org/api v0.154.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/grpc v1.60.1 // indirect gopkg.in/retry.v1 v1.0.3 // indirect -) +) \ No newline at end of file diff --git a/privacy-on-beam/go.sum b/privacy-on-beam/go.sum index 5f90bdbe..8b3b1e65 100644 --- a/privacy-on-beam/go.sum +++ b/privacy-on-beam/go.sum @@ -1,27 +1,59 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM= +cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/profiler v0.4.0 h1:ZeRDZbsOBDyRG0OiK0Op1/XWZ3xeLwJc9zjkzczUxyY= cloud.google.com/go/profiler v0.4.0/go.mod h1:RvPlm4dilIr3oJtAOeFQU9Lrt5RoySHSDj4pTd6TWeU= cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo= git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8= git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/apache/beam/sdks/v2 v2.49.0 h1:Aim/7wEu39NThDEdk9ERyk8ojLRu59sv5+/22WLRbss= github.com/apache/beam/sdks/v2 v2.49.0/go.mod h1:eo95+Cuc18pasAQiwen/Kh3o36CSf9r8hws0EESWrwA= +github.com/apache/beam/sdks/v2 v2.52.0 h1:niIy5jl5sgRq4XkCSSwXsqsiss5eW05snpKmabWIfJI= +github.com/apache/beam/sdks/v2 v2.52.0/go.mod h1:fSZrtv7H4/Z8FAveEYA9uSUVKwZR9GsGsLjGWP0IXZc= github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.2.2 h1:xfmOhhoH5fGPgbEAlhLpJH9p0z/0Qizio9osmvn9IUY= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/go-fonts/dejavu v0.3.2 h1:3XlHi0JBYX+Cp8n98c6qSoHrxPa4AUKDMKdrh/0sUdk= @@ -30,68 +62,150 @@ github.com/go-fonts/liberation v0.3.2 h1:XuwG0vGHFBPRRI8Qwbi5tIvR3cku9LUfZGq/Ar1 github.com/go-fonts/liberation v0.3.2/go.mod h1:N0QsDLVUQPy3UYg9XAc3Uh3UDMp2Z7M1o4+X98dXkmI= github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea h1:DfZQkvEbdmOe+JK2TMtBM+0I9GSdzE2y/L1/AmD8xKc= github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea/go.mod h1:Y7Vld91/HRbTBm7JwoI7HejdDB0u+e9AUBO9MB7yuZk= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/differential-privacy/go/v2 v2.1.1-0.20230822150926-c89810faa5ad h1:iDEy82z1Uw4MeXs9IRC04dCtyPfIMjJr9lBwo5GXOPA= github.com/google/differential-privacy/go/v2 v2.1.1-0.20230822150926-c89810faa5ad/go.mod h1:KRaNc5O0mzJ6cBC3iJbQNk9OHTzRLdmp1IXMaFlOxt8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20231127191134-f3a68a39ae15 h1:t2sLhFuGXwoomaKLTuoxFfFqqlG1Gp2DpsupXq3UvZ0= github.com/google/pprof v0.0.0-20231127191134-f3a68a39ae15/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a h1:3QH7VyOaaiUHNrA9Se4YQIRkDTCw1EJls9xTUCaCeRM= github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= +golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -111,10 +225,19 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -127,21 +250,57 @@ gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY= google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050= +google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 h1:W12Pwm4urIbRdGhMEg2NM9O3TWKjNcxQhs46V0ypf/k= google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 h1:ZcOkrmX74HbKFYnpPY8Qsw93fC29TbJXspYKaBkSXDQ= google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE= google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= \ No newline at end of file diff --git a/privacy-on-beam/pbeam/aggregations.go b/privacy-on-beam/pbeam/aggregations.go index b5725d80..59ea9016 100644 --- a/privacy-on-beam/pbeam/aggregations.go +++ b/privacy-on-beam/pbeam/aggregations.go @@ -674,7 +674,7 @@ func dropThresholdedPartitionsFloat64(v beam.V, r *float64, emit func(beam.V, fl // dropThresholdedPartitionsFloat64Slice drops thresholded []float64 partitions, i.e. // those that have nil r, by emitting only non-thresholded partitions. func dropThresholdedPartitionsFloat64Slice(v beam.V, r []float64, emit func(beam.V, []float64)) { - if r != nil { + if len(r) != 0 { emit(v, r) } } diff --git a/privacy-on-beam/pbeam/count.go b/privacy-on-beam/pbeam/count.go index b565fb30..a480177b 100644 --- a/privacy-on-beam/pbeam/count.go +++ b/privacy-on-beam/pbeam/count.go @@ -104,6 +104,16 @@ type CountParams struct { // // Required. MaxValue int64 + // Allow negative counts in the output. Most users would expect a count + // aggregation to return non-negative values. However, to get better + // statistical properties, especially for subsequent post-processing + // steps, users can choose to allow negative outputs via this option. + // + // The default is to clamp the anonymized values and only return + // non-negative counts. + // + // Optional. + AllowNegativeOutputs bool } // Count counts the number of times a value appears in a PrivatePCollection, @@ -207,8 +217,10 @@ func Count(s beam.Scope, pcol PrivatePCollection, params CountParams) beam.PColl result = beam.ParDo(s, dropThresholdedPartitionsInt64, sums) } - // Clamp negative counts to zero and return. - result = beam.ParDo(s, clampNegativePartitionsInt64, result) + if !params.AllowNegativeOutputs { + // Clamp negative counts to zero. + result = beam.ParDo(s, clampNegativePartitionsInt64, result) + } return result } diff --git a/privacy-on-beam/pbeam/count_test.go b/privacy-on-beam/pbeam/count_test.go index 7068e921..7f1d09c8 100644 --- a/privacy-on-beam/pbeam/count_test.go +++ b/privacy-on-beam/pbeam/count_test.go @@ -439,27 +439,6 @@ func TestCountWithPartitionsCrossPartitionContributionBounding(t *testing.T) { } } -// Check that no negative values are returned from Count. -func TestCountReturnsNonNegative(t *testing.T) { - var pairs []testutils.PairII - for i := 0; i < 100; i++ { - pairs = append(pairs, testutils.PairII{i, i}) - } - p, s, col := ptest.CreateList(pairs) - col = beam.ParDo(s, testutils.PairToKV, col) - // Using a low epsilon and high maxValue adds a lot of noise and using - // a high delta keeps many partitions. - epsilon, delta, maxValue := 0.001, 0.999, int64(1e8) - pcol := MakePrivate(s, col, NewPrivacySpec(epsilon, delta)) - counts := Count(s, pcol, CountParams{MaxValue: maxValue, MaxPartitionsContributed: 1, NoiseKind: GaussianNoise{}}) - values := beam.DropKey(s, counts) - // Check if we have negative elements. - beam.ParDo0(s, testutils.CheckNoNegativeValuesInt64, values) - if err := ptest.Run(p); err != nil { - t.Errorf("TestCountReturnsNonNegative returned errors: %v", err) - } -} - // Check that no negative values are returned from Count with partitions. func TestCountWithPartitionsReturnsNonNegative(t *testing.T) { // We have two test cases, one for public partitions as a PCollection and one for public partitions as a slice (i.e., in-memory). @@ -994,3 +973,49 @@ func TestCountPreThresholding(t *testing.T) { t.Errorf("TestCountPreThresholding: Count(%v) = %v, expected %v: %v", col, got, want, err) } } + +func TestCountAllowNegativeOutputs(t *testing.T) { + // We use public partitions to noise zeros. For a larger number of + // public partitions, we expect that at least one noised zero is + // negative (in case AllowNegativeOutputs is true) or that all are + // non-negative (in case AllowNegativeOutputs is false). + for _, tc := range []struct { + allowNegativeOutputs bool + }{ + {true}, + {false}, + } { + privacySpec, err := NewPrivacySpecTemp(PrivacySpecParams{ + AggregationEpsilon: 0.1, + }) + if err != nil { + t.Fatalf("Test setup failed: %v", err) + } + p, s, col := ptest.CreateList([]testutils.PairII{}) + col = beam.ParDo(s, testutils.PairToKV, col) + pcol := MakePrivate(s, col, privacySpec) + var emptyPartitions []int + for i := 0; i < 10000; i++ { + emptyPartitions = append(emptyPartitions, i) + } + + countRes := Count(s, pcol, + CountParams{ + MaxValue: 1, + MaxPartitionsContributed: 1, + NoiseKind: LaplaceNoise{}, + PublicPartitions: emptyPartitions, + AllowNegativeOutputs: tc.allowNegativeOutputs, + }) + + values := beam.DropKey(s, countRes) + if tc.allowNegativeOutputs { + testutils.CheckAtLeastOneValueNegativeInt64(s, values) + } else { + beam.ParDo0(s, testutils.CheckNoNegativeValuesInt64, values) + } + if err := ptest.Run(p); err != nil { + t.Errorf("TestCountAllowNegativeOutputs: error with allowNegativeOutputs = %v: %v", tc.allowNegativeOutputs, err) + } + } +} diff --git a/privacy-on-beam/pbeam/pbeam_main_test.go b/privacy-on-beam/pbeam/pbeam_main_test.go index caec513b..8e192536 100644 --- a/privacy-on-beam/pbeam/pbeam_main_test.go +++ b/privacy-on-beam/pbeam/pbeam_main_test.go @@ -22,7 +22,7 @@ import ( ) func TestMain(m *testing.M) { - ptest.Main(m) + ptest.MainWithDefault(m, "direct") } // Used in various tests. diff --git a/privacy-on-beam/pbeam/pbeam_test.go b/privacy-on-beam/pbeam/pbeam_test.go index e4073213..64eb530a 100644 --- a/privacy-on-beam/pbeam/pbeam_test.go +++ b/privacy-on-beam/pbeam/pbeam_test.go @@ -22,6 +22,7 @@ import ( "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/register" "github.com/apache/beam/sdks/v2/go/pkg/beam/testing/passert" "github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest" "github.com/google/go-cmp/cmp" @@ -31,6 +32,11 @@ import ( func init() { beam.RegisterType(reflect.TypeOf((*testpb.TestAnon)(nil))) beam.RegisterType(reflect.TypeOf(protoPair{})) + + register.Function2x1[string, *testpb.TestAnon, protoPair](kvToProtoPair) + register.Function2x1[string, ComplexStruct, structPair](kvToStructPair) + register.Function1x2[int, int, int](addZeroIntKeyFn) + register.Function1x2[int, int, int](addZeroIntValueFn) } func TestNewPrivacySpecTemp(t *testing.T) { @@ -553,7 +559,7 @@ func TestDropKey(t *testing.T) { colKV := beam.ParDo(s, testutils.PairToKV, col) spec := NewPrivacySpec(1e10, 0) pcol := MakePrivate(s, colKV, spec) - pcol = ParDo(s, func(v int) (int, int) { return 0, v }, pcol) + pcol = ParDo(s, addZeroIntKeyFn, pcol) pcol = DropKey(s, pcol) // Assert that adding a test key of 0 and removing it is a no-op. @@ -590,7 +596,7 @@ func TestDropValue(t *testing.T) { colKV := beam.ParDo(s, testutils.PairToKV, col) spec := NewPrivacySpec(1e10, 0) pcol := MakePrivate(s, colKV, spec) - pcol = ParDo(s, func(k int) (int, int) { return k, 0 }, pcol) + pcol = ParDo(s, addZeroIntValueFn, pcol) pcol = DropValue(s, pcol) // Assert that adding a test value of 0 and removing it is a no-op. @@ -611,3 +617,11 @@ func TestDropValue(t *testing.T) { t.Error(err) } } + +func addZeroIntKeyFn(v int) (int, int) { + return 0, v +} + +func addZeroIntValueFn(k int) (int, int) { + return k, 0 +} diff --git a/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go b/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go index 90ee771e..ac668ab0 100644 --- a/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go +++ b/privacy-on-beam/pbeam/pbeamtest/pbeamtest.go @@ -37,6 +37,8 @@ import ( // // This does NOT provide any privacy protections, so should only be used in // test code in order to avoid dealing with random noise. +// +// Deprecated: Use pbeam.NewPrivacySpecTemp() with TestMode: TestModeWithContributionBounding instead. func NewPrivacySpecNoNoiseWithContributionBounding(epsilon, delta float64) *pbeam.PrivacySpec { return pbeam.NewPrivacySpec(epsilon, delta, testoption.EnableNoNoiseWithContributionBounding{}) } @@ -54,6 +56,8 @@ func NewPrivacySpecNoNoiseWithContributionBounding(epsilon, delta float64) *pbea // // This does NOT provide any privacy protections, so should only be used in // test code in order to avoid dealing with random noise. +// +// Deprecated: Use pbeam.NewPrivacySpecTemp() with TestMode: TestModeWithoutContributionBounding instead. func NewPrivacySpecNoNoiseWithoutContributionBounding(epsilon, delta float64) *pbeam.PrivacySpec { return pbeam.NewPrivacySpec(epsilon, delta, testoption.EnableNoNoiseWithoutContributionBounding{}) } diff --git a/privacy-on-beam/pbeam/testutils/BUILD.bazel b/privacy-on-beam/pbeam/testutils/BUILD.bazel index 6f7501cd..68db1556 100644 --- a/privacy-on-beam/pbeam/testutils/BUILD.bazel +++ b/privacy-on-beam/pbeam/testutils/BUILD.bazel @@ -14,8 +14,8 @@ # 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/privacy-on-beam/v2/pbeam/testutils gazelle(name = "gazelle") @@ -30,6 +30,7 @@ go_library( "//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/register:go_default_library", + "@com_github_apache_beam_sdks_v2//go/pkg/beam/transforms/filter: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", diff --git a/privacy-on-beam/pbeam/testutils/testutils.go b/privacy-on-beam/pbeam/testutils/testutils.go index 1da8da91..6706b69f 100644 --- a/privacy-on-beam/pbeam/testutils/testutils.go +++ b/privacy-on-beam/pbeam/testutils/testutils.go @@ -19,6 +19,7 @@ package testutils import ( + "errors" "fmt" "math" "math/big" @@ -29,6 +30,7 @@ import ( "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/register" + "github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/filter" "github.com/apache/beam/sdks/v2/go/pkg/beam/transforms/stats" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -47,10 +49,35 @@ func init() { register.DoFn3x1[int, func(*int) bool, func(*int) bool, error](&gotExpectedNumPartitionsFn{}) register.Iter1[int]() + register.Function1x1[int64, *int64](Int64Ptr) + register.Function1x1[float64, *float64](Float64Ptr) + register.Function1x1[beam.V, int](OneFn) register.Function1x1[int64, error](CheckNoNegativeValuesInt64) register.Function1x1[float64, error](CheckNoNegativeValuesFloat64) register.Function1x1[float64, error](CheckAllValuesNegativeFloat64) + register.Function2x1[int, int, PairII](KVToPair) + register.Function1x2[PairII, int, int](PairToKV) + register.Function2x1[int, int64, PairII64](KVToPairII64) + register.Function1x2[PairII64, int, int64](PairII64ToKV) + register.Function2x1[int, float64, PairIF64](KVToPairIF64) + register.Function1x2[PairIF64, int, float64](PairIF64ToKV) + register.Function2x1[int, []float64, PairIF64Slice](KVToPairIF64Slice) + register.Function1x2[PairIF64Slice, int, []float64](PairIF64SliceToKV) + register.Function2x1[int, kv.Pair, PairICodedKV](KVToPairICodedKV) + register.Function1x2[PairICodedKV, int, kv.Pair](PairICodedKVToKV) register.Function2x3[beam.V, []float64, beam.V, float64, error](DereferenceFloat64Slice) + register.Function1x2[TripleWithIntValue, int, int](TripleWithIntValueToKV) + register.Function1x2[TripleWithIntValue, int, TripleWithIntValue](ExtractIDFromTripleWithIntValue) + register.Function1x2[TripleWithFloatValue, int, float32](TripleWithFloatValueToKV) + register.Function1x2[TripleWithFloatValue, int, TripleWithFloatValue](ExtractIDFromTripleWithFloatValue) + register.Function3x1[int, func(*float64) bool, func(*float64) bool, string](lessThanOrEqualTo) + register.Function2x1[string, string, string](combineDiffs) + register.Function1x1[string, error](reportDiffs) + register.Function1x1[string, error](reportEquals) + register.Function1x1[string, error](reportGreaterThan) + register.Function3x1[beam.X, func(*int) bool, func(*int) bool, string](diffIntFn) + register.Function1x1[int64, bool](isNegativeInt64) + register.Function1x1[int, error](checkNumNegativeElemCountIsPositive) } // PairII, PairII64, PairIF64, PairICodedKV and the related functions are helpers @@ -803,6 +830,25 @@ func CheckNoNegativeValuesInt64(v int64) error { return nil } +func isNegativeInt64(v int64) bool { + return v < 0 +} + +func checkNumNegativeElemCountIsPositive(elemCount int) error { + if elemCount == 0 { + return errors.New("want at least one negative value, but got 0") + } + return nil +} + +// CheckAtLeastOneValueNegativeInt64 operates on a PCollection and will +// return an error during runtime if none of the int64 values is negative. +func CheckAtLeastOneValueNegativeInt64(s beam.Scope, col beam.PCollection) { + negativeValues := filter.Include(s, col, isNegativeInt64) + numNegativeValues := stats.CountElms(s, negativeValues) + beam.ParDo0(s, checkNumNegativeElemCountIsPositive, numNegativeValues) +} + // CheckNoNegativeValuesFloat64 returns an error if an float64 value is negative. func CheckNoNegativeValuesFloat64(v float64) error { if v < 0 { diff --git a/privacy-on-beam/privacy_on_beam_deps.bzl b/privacy-on-beam/privacy_on_beam_deps.bzl index 152e5fee..c43385ab 100644 --- a/privacy-on-beam/privacy_on_beam_deps.bzl +++ b/privacy-on-beam/privacy_on_beam_deps.bzl @@ -85,8 +85,8 @@ def privacy_on_beam_deps(): name = "com_github_apache_beam_sdks_v2", build_file_proto_mode = "disable_global", # See https://github.com/bazelbuild/rules_go/issues/2186#issuecomment-523028281 importpath = "github.com/apache/beam/sdks/v2", - sum = "h1:Aim/7wEu39NThDEdk9ERyk8ojLRu59sv5+/22WLRbss=", - version = "v2.49.0", + sum = "h1:niIy5jl5sgRq4XkCSSwXsqsiss5eW05snpKmabWIfJI=", + version = "v2.52.0", ) go_repository( name = "com_github_apache_thrift", @@ -373,8 +373,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_github_felixge_httpsnoop", importpath = "github.com/felixge/httpsnoop", - sum = "h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=", - version = "v1.0.2", + sum = "h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=", + version = "v1.0.4", ) go_repository( @@ -426,6 +426,19 @@ def privacy_on_beam_deps(): sum = "h1:DfZQkvEbdmOe+JK2TMtBM+0I9GSdzE2y/L1/AmD8xKc=", version = "v0.0.0-20231108140139-5c1ce85aa4ea", ) + go_repository( + name = "com_github_go_logr_logr", + importpath = "github.com/go-logr/logr", + sum = "h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=", + version = "v1.4.1", + ) + go_repository( + name = "com_github_go_logr_stdr", + importpath = "github.com/go-logr/stdr", + sum = "h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=", + version = "v1.2.2", + ) + go_repository( name = "com_github_go_ole_go_ole", importpath = "github.com/go-ole/go-ole", @@ -554,8 +567,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_github_google_pprof", importpath = "github.com/google/pprof", - sum = "h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=", - version = "v0.0.0-20231101202521-4ca4178f5c7a", + sum = "h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8=", + version = "v0.0.0-20231229205709-960ae82b1e42", ) go_repository( name = "com_github_google_renameio_v2", @@ -573,8 +586,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_github_google_uuid", importpath = "github.com/google/uuid", - sum = "h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=", - version = "v1.4.0", + sum = "h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=", + version = "v1.5.0", ) go_repository( name = "com_github_googleapis_enterprise_certificate_proxy", @@ -584,6 +597,11 @@ def privacy_on_beam_deps(): ) go_repository( name = "com_github_googleapis_gax_go_v2", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/3625#issuecomment-1643804054 + "gazelle:resolve proto proto google/rpc/code.proto @googleapis//google/rpc:code_proto", # keep + "gazelle:resolve proto go google/rpc/code.proto @org_golang_google_genproto_googleapis_rpc//code", # keep + ], importpath = "github.com/googleapis/gax-go/v2", sum = "h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=", version = "v2.12.0", @@ -912,8 +930,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_github_stretchr_testify", importpath = "github.com/stretchr/testify", - sum = "h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=", - version = "v1.8.1", + sum = "h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=", + version = "v1.8.4", ) go_repository( @@ -1019,8 +1037,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go", importpath = "cloud.google.com/go", - sum = "h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=", - version = "v0.110.10", + sum = "h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=", + version = "v0.111.0", ) go_repository( name = "com_google_cloud_go_accessapproval", @@ -1037,8 +1055,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_aiplatform", importpath = "cloud.google.com/go/aiplatform", - sum = "h1:wH7OYl9Vq/5tupok0BPTFY9xaTLb0GxkReHtB5PF7cI=", - version = "v1.54.0", + sum = "h1:xyCAfpI4yUMOQ4VtHN/bdmxPQ8xoEkTwFM1nbVmuQhs=", + version = "v1.58.0", ) go_repository( name = "com_google_cloud_go_analytics", @@ -1086,8 +1104,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_asset", importpath = "cloud.google.com/go/asset", - sum = "h1:uI8Bdm81s0esVWbWrTHcjFDFKNOa9aB7rI1vud1hO84=", - version = "v1.15.3", + sum = "h1:VjwWNtEVsbpXfJqZbb2RLOBzSgAjN69vf2UJADHnkxk=", + version = "v1.16.0", ) go_repository( name = "com_google_cloud_go_assuredworkloads", @@ -1110,8 +1128,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_batch", importpath = "cloud.google.com/go/batch", - sum = "h1:mPiIH20a5NU02rucbAmLeO4sLPO9hrTK0BLjdHyW8xw=", - version = "v1.6.3", + sum = "h1:AxuSPoL2fWn/rUyvWeNCNd0V2WCr+iHRCU9QO1PUmpY=", + version = "v1.7.0", ) go_repository( name = "com_google_cloud_go_beyondcorp", @@ -1135,14 +1153,14 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_billing", importpath = "cloud.google.com/go/billing", - sum = "h1:77/4kCqzH6Ou5CCDzNmqmboE+WvbwFBJmw1QZQz19AI=", - version = "v1.17.4", + sum = "h1:GvKy4xLy1zF1XPbwP5NJb2HjRxhnhxjjXxvyZ1S/IAo=", + version = "v1.18.0", ) go_repository( name = "com_google_cloud_go_binaryauthorization", importpath = "cloud.google.com/go/binaryauthorization", - sum = "h1:3R6WYn1JKIaVicBmo18jXubu7xh4mMkmbIgsTXk0cBA=", - version = "v1.7.3", + sum = "h1:PHS89lcFayWIEe0/s2jTBiEOtqghCxzc7y7bRNlifBs=", + version = "v1.8.0", ) go_repository( name = "com_google_cloud_go_certificatemanager", @@ -1177,6 +1195,11 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_compute", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "cloud.google.com/go/compute", sum = "h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=", version = "v1.23.3", @@ -1190,14 +1213,14 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_contactcenterinsights", importpath = "cloud.google.com/go/contactcenterinsights", - sum = "h1:wP41IUA4ucMVooj/TP53jd7vbNjWrDkAPOeulVJGT5U=", - version = "v1.12.0", + sum = "h1:EiGBeejtDDtr3JXt9W7xlhXyZ+REB5k2tBgVPVtmNb0=", + version = "v1.12.1", ) go_repository( name = "com_google_cloud_go_container", importpath = "cloud.google.com/go/container", - sum = "h1:/o82CFWXIYnT9p/07SnRgybqL3Pmmu86jYIlzlJVUBY=", - version = "v1.28.0", + sum = "h1:jIltU529R2zBFvP8rhiG1mgeTcnT27KhU0H/1d6SQRg=", + version = "v1.29.0", ) go_repository( name = "com_google_cloud_go_containeranalysis", @@ -1238,8 +1261,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_dataplex", importpath = "cloud.google.com/go/dataplex", - sum = "h1:AfFFR15Ifh4U+Me1IBztrSd5CrasTODzy3x8KtDyHdc=", - version = "v1.11.2", + sum = "h1:ACVOuxwe7gP0SqEso9SLyXbcZNk5l8hjcTX+XLntI5s=", + version = "v1.13.0", ) go_repository( name = "com_google_cloud_go_dataproc_v2", @@ -1270,14 +1293,14 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_deploy", importpath = "cloud.google.com/go/deploy", - sum = "h1:ZdmYzRMTGkVyP1nXEUat9FpbJGJemDcNcx82RSSOElc=", - version = "v1.15.0", + sum = "h1:5OVjzm8MPC5kP+Ywbs0mdE0O7AXvAUXksSyHAyMFyMg=", + version = "v1.16.0", ) go_repository( name = "com_google_cloud_go_dialogflow", importpath = "cloud.google.com/go/dialogflow", - sum = "h1:cK/f88KX+YVR4tLH4clMQlvrLWD2qmKJQziusjGPjmc=", - version = "v1.44.3", + sum = "h1:tLCWad8HZhlyUNfDzDP5m+oH6h/1Uvw/ei7B9AnsWMk=", + version = "v1.47.0", ) go_repository( name = "com_google_cloud_go_dlp", @@ -1288,8 +1311,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_documentai", importpath = "cloud.google.com/go/documentai", - sum = "h1:KAlzT+q8qvRxAmhsJUvLtfFHH0PNvz3M79H6CgVBKL8=", - version = "v1.23.5", + sum = "h1:hlYieOXUwiJ7HpBR/vEPfr8nfSxveLVzbqbUkSK0c/4=", + version = "v1.23.7", ) go_repository( name = "com_google_cloud_go_domains", @@ -1375,6 +1398,11 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_iam", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "cloud.google.com/go/iam", sum = "h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=", version = "v1.1.5", @@ -1399,6 +1427,11 @@ def privacy_on_beam_deps(): ) go_repository( name = "com_google_cloud_go_kms", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "cloud.google.com/go/kms", sum = "h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=", version = "v1.15.5", @@ -1418,8 +1451,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_logging", importpath = "cloud.google.com/go/logging", - sum = "h1:26skQWPeYhvIasWKm48+Eq7oUqdcdbwsCVwz5Ys0FvU=", - version = "v1.8.1", + sum = "h1:iEIOXFO9EmSiTjDmfpbRjOxECO7R8C7b8IXUGOj7xZw=", + version = "v1.9.0", ) go_repository( @@ -1437,8 +1470,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_maps", importpath = "cloud.google.com/go/maps", - sum = "h1:2+eMp/1MvMPp5qrSOd3vtnLKa/pylt+krVRqET3jWsM=", - version = "v1.6.1", + sum = "h1:WxxLo//b60nNFESefLgaBQevu8QGUmRV3+noOjCfIHs=", + version = "v1.6.2", ) go_repository( @@ -1461,9 +1494,14 @@ def privacy_on_beam_deps(): ) go_repository( name = "com_google_cloud_go_monitoring", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "cloud.google.com/go/monitoring", - sum = "h1:mf2SN9qSoBtIgiMA4R/y4VADPWZA7VCNJA079qLaZQ8=", - version = "v1.16.3", + sum = "h1:blrdvF0MkPPivSO041ihul7rFMhXdVp8Uq7F59DKXTU=", + version = "v1.17.0", ) go_repository( name = "com_google_cloud_go_networkconnectivity", @@ -1560,8 +1598,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_recaptchaenterprise_v2", importpath = "cloud.google.com/go/recaptchaenterprise/v2", - sum = "h1:KOlLHLv3h3HwcZAkx91ubM3Oztz3JtT3ZacAJhWDorQ=", - version = "v2.8.4", + sum = "h1:Zrd4LvT9PaW91X/Z13H0i5RKEv9suCLuk8zp+bfOpN4=", + version = "v2.9.0", ) go_repository( name = "com_google_cloud_go_recommendationengine", @@ -1572,8 +1610,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_recommender", importpath = "cloud.google.com/go/recommender", - sum = "h1:VndmgyS/J3+izR8V8BHa7HV/uun8//ivQ3k5eVKKyyM=", - version = "v1.11.3", + sum = "h1:tC+ljmCCbuZ/ybt43odTFlay91n/HLIhflvaOeb0Dh4=", + version = "v1.12.0", ) go_repository( name = "com_google_cloud_go_redis", @@ -1626,8 +1664,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_securitycenter", importpath = "cloud.google.com/go/securitycenter", - sum = "h1:qCEyXoJoxNKKA1bDywBjjqCB7ODXazzHnVWnG5Uqd1M=", - version = "v1.24.2", + sum = "h1:crdn2Z2rFIy8WffmmhdlX3CwZJusqCiShtnrGFRwpeE=", + version = "v1.24.3", ) go_repository( @@ -1646,8 +1684,8 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_spanner", importpath = "cloud.google.com/go/spanner", - sum = "h1:/NzWQJ1MEhdRcffiutRKbW/AIGVKhcTeivWTDjEyCCo=", - version = "v1.53.0", + sum = "h1:ttU+lhARPF/iZE3OkCpmfsemCz9mLaqBhGPd3Qub2sQ=", + version = "v1.54.0", ) go_repository( name = "com_google_cloud_go_speech", @@ -1658,9 +1696,14 @@ def privacy_on_beam_deps(): go_repository( name = "com_google_cloud_go_storage", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "cloud.google.com/go/storage", - sum = "h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w=", - version = "v1.35.1", + sum = "h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8=", + version = "v1.36.0", ) go_repository( name = "com_google_cloud_go_storagetransfer", @@ -1797,6 +1840,42 @@ def privacy_on_beam_deps(): sum = "h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=", version = "v0.24.0", ) + go_repository( + name = "io_opentelemetry_go_contrib_instrumentation_google_golang_org_grpc_otelgrpc", + importpath = "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc", + sum = "h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=", + version = "v0.46.1", + ) + go_repository( + name = "io_opentelemetry_go_contrib_instrumentation_net_http_otelhttp", + importpath = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", + sum = "h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=", + version = "v0.46.1", + ) + go_repository( + name = "io_opentelemetry_go_otel", + importpath = "go.opentelemetry.io/otel", + sum = "h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=", + version = "v1.21.0", + ) + go_repository( + name = "io_opentelemetry_go_otel_metric", + importpath = "go.opentelemetry.io/otel/metric", + sum = "h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=", + version = "v1.21.0", + ) + go_repository( + name = "io_opentelemetry_go_otel_sdk", + importpath = "go.opentelemetry.io/otel/sdk", + sum = "h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=", + version = "v1.19.0", + ) + go_repository( + name = "io_opentelemetry_go_otel_trace", + importpath = "go.opentelemetry.io/otel/trace", + sum = "h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=", + version = "v1.21.0", + ) go_repository( name = "io_rsc_pdf", @@ -1831,9 +1910,14 @@ def privacy_on_beam_deps(): go_repository( name = "org_golang_google_api", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "google.golang.org/api", - sum = "h1:FhfXLO/NFdJIzQtCqjpysWwqKk8AzGWBUhMIx67cVDU=", - version = "v0.151.0", + sum = "h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050=", + version = "v0.154.0", ) go_repository( name = "org_golang_google_appengine", @@ -1844,52 +1928,57 @@ def privacy_on_beam_deps(): go_repository( name = "org_golang_google_genproto", importpath = "google.golang.org/genproto", - sum = "h1:Vn+VyHU5guc9KjB5KrjI2q0wCOWEOIh0OEsleqakHJg=", - version = "v0.0.0-20231120223509-83a465c0220f", + sum = "h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=", + version = "v0.0.0-20240102182953-50ed04b92917", ) go_repository( name = "org_golang_google_genproto_googleapis_api", + build_directives = [ + # See https://github.com/bazelbuild/rules_go/issues/1877#issuecomment-1874616324 + "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations", # keep + "gazelle:resolve go google.golang.org/genproto/googleapis/api @org_golang_google_genproto//googleapis/api", # keep + ], importpath = "google.golang.org/genproto/googleapis/api", - sum = "h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY=", - version = "v0.0.0-20231120223509-83a465c0220f", + sum = "h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=", + version = "v0.0.0-20240102182953-50ed04b92917", ) go_repository( name = "org_golang_google_genproto_googleapis_bytestream", importpath = "google.golang.org/genproto/googleapis/bytestream", - sum = "h1:o4S3HvTUEXgRsNSUQsALDVog0O9F/U1JJlHmmUN8Uas=", - version = "v0.0.0-20231030173426-d783a09b4405", + sum = "h1:ueqXLNvvDP1mzaFYSfQwZsrl19KWunuuWq12PEuwoQY=", + version = "v0.0.0-20231127180814-3a041ad873d4", ) go_repository( name = "org_golang_google_genproto_googleapis_rpc", importpath = "google.golang.org/genproto/googleapis/rpc", - sum = "h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I=", - version = "v0.0.0-20231120223509-83a465c0220f", + sum = "h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ=", + version = "v0.0.0-20240102182953-50ed04b92917", ) go_repository( name = "org_golang_google_grpc", build_file_proto_mode = "disable_global", # See https://github.com/bazelbuild/rules_go/issues/2186#issuecomment-523028281 importpath = "google.golang.org/grpc", - sum = "h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=", - version = "v1.59.0", + sum = "h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=", + version = "v1.60.1", ) go_repository( name = "org_golang_google_protobuf", importpath = "google.golang.org/protobuf", - sum = "h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=", - version = "v1.31.0", + sum = "h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=", + version = "v1.32.0", ) go_repository( name = "org_golang_x_crypto", importpath = "golang.org/x/crypto", - sum = "h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=", - version = "v0.15.0", + sum = "h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=", + version = "v0.17.0", ) go_repository( name = "org_golang_x_exp", importpath = "golang.org/x/exp", - sum = "h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=", - version = "v0.0.0-20231110203233-9a3e6036ecaa", + sum = "h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=", + version = "v0.0.0-20231226003508-02704c960a9b", ) go_repository( name = "org_golang_x_exp_shiny", @@ -1919,14 +2008,14 @@ def privacy_on_beam_deps(): go_repository( name = "org_golang_x_net", importpath = "golang.org/x/net", - sum = "h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=", - version = "v0.18.0", + sum = "h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=", + version = "v0.19.0", ) go_repository( name = "org_golang_x_oauth2", importpath = "golang.org/x/oauth2", - sum = "h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=", - version = "v0.14.0", + sum = "h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=", + version = "v0.15.0", ) go_repository( name = "org_golang_x_sync", @@ -1937,14 +2026,14 @@ def privacy_on_beam_deps(): go_repository( name = "org_golang_x_sys", importpath = "golang.org/x/sys", - sum = "h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=", - version = "v0.14.0", + sum = "h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=", + version = "v0.15.0", ) go_repository( name = "org_golang_x_term", importpath = "golang.org/x/term", - sum = "h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=", - version = "v0.14.0", + sum = "h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=", + version = "v0.15.0", ) go_repository( name = "org_golang_x_text", @@ -1955,15 +2044,15 @@ def privacy_on_beam_deps(): go_repository( name = "org_golang_x_time", importpath = "golang.org/x/time", - sum = "h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=", - version = "v0.4.0", + sum = "h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=", + version = "v0.5.0", ) go_repository( name = "org_golang_x_tools", importpath = "golang.org/x/tools", - sum = "h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=", - version = "v0.15.0", + sum = "h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=", + version = "v0.16.1", ) go_repository( name = "org_golang_x_xerrors", @@ -1989,9 +2078,3 @@ def privacy_on_beam_deps(): sum = "h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=", version = "v1.12.1", ) - go_repository( - name = "tools_gotest_v3", - importpath = "gotest.tools/v3", - sum = "h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=", - version = "v3.5.1", - ) diff --git a/python/BUILD.bazel b/python/BUILD.bazel deleted file mode 100644 index 7ec19106..00000000 --- a/python/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/python/.bazelversion b/python/dp_accounting/.bazelversion similarity index 100% rename from python/.bazelversion rename to python/dp_accounting/.bazelversion diff --git a/python/dp_accounting/BUILD.bazel b/python/dp_accounting/BUILD.bazel index d4f55938..7ec19106 100644 --- a/python/dp_accounting/BUILD.bazel +++ b/python/dp_accounting/BUILD.bazel @@ -13,119 +13,3 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -# Tools for tracking privacy budget. - -load("@accounting_py_pip_deps//:requirements.bzl", "requirement") - -package(default_visibility = [ - "//visibility:public", -]) - -licenses(["notice"]) - -py_library( - name = "accounting", - srcs = ["__init__.py"], - deps = [ - ":dp_event", - ":dp_event_builder", - ":mechanism_calibration", - ":privacy_accountant", - "//dp_accounting/pld", - "//dp_accounting/rdp", - ], -) - -py_library( - name = "mechanism_calibration", - srcs = [ - "mechanism_calibration.py", - ], - srcs_version = "PY3", - deps = [ - ":dp_event", - ":privacy_accountant", - requirement("attrs"), - requirement("scipy"), - ], -) - -py_test( - name = "mechanism_calibration_test", - size = "small", - srcs = ["mechanism_calibration_test.py"], - python_version = "PY3", - deps = [ - ":dp_event", - ":mechanism_calibration", - ":privacy_accountant", - requirement("absl-py"), - requirement("attrs"), - requirement("numpy"), - ], -) - -py_library( - name = "dp_event", - srcs = ["dp_event.py"], - srcs_version = "PY3", - deps = [ - requirement("attrs"), - ], -) - -py_test( - name = "dp_event_test", - srcs = ["dp_event_test.py"], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - ":dp_event", - requirement("absl-py"), - requirement("attrs"), - requirement("dm-tree"), - ], -) - -py_library( - name = "dp_event_builder", - srcs = ["dp_event_builder.py"], - srcs_version = "PY3", - deps = [ - ":dp_event", - ], -) - -py_test( - name = "dp_event_builder_test", - srcs = ["dp_event_builder_test.py"], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - ":dp_event", - ":dp_event_builder", - requirement("absl-py"), - ], -) - -py_library( - name = "privacy_accountant", - srcs = ["privacy_accountant.py"], - srcs_version = "PY3", - deps = [ - ":dp_event", - ":dp_event_builder", - ], -) - -py_library( - name = "privacy_accountant_test", - srcs = ["privacy_accountant_test.py"], - srcs_version = "PY3", - deps = [ - ":dp_event", - ":privacy_accountant", - requirement("absl-py"), - ], -) diff --git a/python/README.md b/python/dp_accounting/README.md similarity index 100% rename from python/README.md rename to python/dp_accounting/README.md diff --git a/python/VERSION b/python/dp_accounting/VERSION similarity index 100% rename from python/VERSION rename to python/dp_accounting/VERSION diff --git a/python/WORKSPACE b/python/dp_accounting/WORKSPACE similarity index 100% rename from python/WORKSPACE rename to python/dp_accounting/WORKSPACE diff --git a/python/accounting_py_deps.bzl b/python/dp_accounting/accounting_py_deps.bzl similarity index 100% rename from python/accounting_py_deps.bzl rename to python/dp_accounting/accounting_py_deps.bzl diff --git a/python/accounting_py_deps_init.bzl b/python/dp_accounting/accounting_py_deps_init.bzl similarity index 100% rename from python/accounting_py_deps_init.bzl rename to python/dp_accounting/accounting_py_deps_init.bzl diff --git a/python/dp_accounting/dp_accounting/BUILD.bazel b/python/dp_accounting/dp_accounting/BUILD.bazel new file mode 100644 index 00000000..d4f55938 --- /dev/null +++ b/python/dp_accounting/dp_accounting/BUILD.bazel @@ -0,0 +1,131 @@ +# +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Tools for tracking privacy budget. + +load("@accounting_py_pip_deps//:requirements.bzl", "requirement") + +package(default_visibility = [ + "//visibility:public", +]) + +licenses(["notice"]) + +py_library( + name = "accounting", + srcs = ["__init__.py"], + deps = [ + ":dp_event", + ":dp_event_builder", + ":mechanism_calibration", + ":privacy_accountant", + "//dp_accounting/pld", + "//dp_accounting/rdp", + ], +) + +py_library( + name = "mechanism_calibration", + srcs = [ + "mechanism_calibration.py", + ], + srcs_version = "PY3", + deps = [ + ":dp_event", + ":privacy_accountant", + requirement("attrs"), + requirement("scipy"), + ], +) + +py_test( + name = "mechanism_calibration_test", + size = "small", + srcs = ["mechanism_calibration_test.py"], + python_version = "PY3", + deps = [ + ":dp_event", + ":mechanism_calibration", + ":privacy_accountant", + requirement("absl-py"), + requirement("attrs"), + requirement("numpy"), + ], +) + +py_library( + name = "dp_event", + srcs = ["dp_event.py"], + srcs_version = "PY3", + deps = [ + requirement("attrs"), + ], +) + +py_test( + name = "dp_event_test", + srcs = ["dp_event_test.py"], + python_version = "PY3", + srcs_version = "PY3", + deps = [ + ":dp_event", + requirement("absl-py"), + requirement("attrs"), + requirement("dm-tree"), + ], +) + +py_library( + name = "dp_event_builder", + srcs = ["dp_event_builder.py"], + srcs_version = "PY3", + deps = [ + ":dp_event", + ], +) + +py_test( + name = "dp_event_builder_test", + srcs = ["dp_event_builder_test.py"], + python_version = "PY3", + srcs_version = "PY3", + deps = [ + ":dp_event", + ":dp_event_builder", + requirement("absl-py"), + ], +) + +py_library( + name = "privacy_accountant", + srcs = ["privacy_accountant.py"], + srcs_version = "PY3", + deps = [ + ":dp_event", + ":dp_event_builder", + ], +) + +py_library( + name = "privacy_accountant_test", + srcs = ["privacy_accountant_test.py"], + srcs_version = "PY3", + deps = [ + ":dp_event", + ":privacy_accountant", + requirement("absl-py"), + ], +) diff --git a/python/dp_accounting/__init__.py b/python/dp_accounting/dp_accounting/__init__.py similarity index 91% rename from python/dp_accounting/__init__.py rename to python/dp_accounting/dp_accounting/__init__.py index 036610cb..286692c8 100644 --- a/python/dp_accounting/__init__.py +++ b/python/dp_accounting/dp_accounting/__init__.py @@ -14,9 +14,12 @@ """DP Accounting package.""" +from dp_accounting import dp_event +from dp_accounting import dp_event_builder +from dp_accounting import mechanism_calibration from dp_accounting import pld +from dp_accounting import privacy_accountant from dp_accounting import rdp - from dp_accounting.dp_event import ComposedDpEvent from dp_accounting.dp_event import DpEvent from dp_accounting.dp_event import GaussianDpEvent @@ -29,13 +32,10 @@ from dp_accounting.dp_event import SelfComposedDpEvent from dp_accounting.dp_event import SingleEpochTreeAggregationDpEvent from dp_accounting.dp_event import UnsupportedDpEvent - from dp_accounting.dp_event_builder import DpEventBuilder - from dp_accounting.mechanism_calibration import calibrate_dp_mechanism from dp_accounting.mechanism_calibration import ExplicitBracketInterval from dp_accounting.mechanism_calibration import LowerEndpointAndGuess - from dp_accounting.privacy_accountant import NeighboringRelation from dp_accounting.privacy_accountant import PrivacyAccountant from dp_accounting.privacy_accountant import UnsupportedEventError diff --git a/python/dp_accounting/dp_event.py b/python/dp_accounting/dp_accounting/dp_event.py similarity index 100% rename from python/dp_accounting/dp_event.py rename to python/dp_accounting/dp_accounting/dp_event.py diff --git a/python/dp_accounting/dp_event_builder.py b/python/dp_accounting/dp_accounting/dp_event_builder.py similarity index 100% rename from python/dp_accounting/dp_event_builder.py rename to python/dp_accounting/dp_accounting/dp_event_builder.py diff --git a/python/dp_accounting/dp_event_builder_test.py b/python/dp_accounting/dp_accounting/dp_event_builder_test.py similarity index 100% rename from python/dp_accounting/dp_event_builder_test.py rename to python/dp_accounting/dp_accounting/dp_event_builder_test.py diff --git a/python/dp_accounting/dp_event_test.py b/python/dp_accounting/dp_accounting/dp_event_test.py similarity index 100% rename from python/dp_accounting/dp_event_test.py rename to python/dp_accounting/dp_accounting/dp_event_test.py diff --git a/python/dp_accounting/mechanism_calibration.py b/python/dp_accounting/dp_accounting/mechanism_calibration.py similarity index 100% rename from python/dp_accounting/mechanism_calibration.py rename to python/dp_accounting/dp_accounting/mechanism_calibration.py diff --git a/python/dp_accounting/mechanism_calibration_test.py b/python/dp_accounting/dp_accounting/mechanism_calibration_test.py similarity index 99% rename from python/dp_accounting/mechanism_calibration_test.py rename to python/dp_accounting/dp_accounting/mechanism_calibration_test.py index 1a6fe690..8014b88e 100644 --- a/python/dp_accounting/mechanism_calibration_test.py +++ b/python/dp_accounting/dp_accounting/mechanism_calibration_test.py @@ -16,7 +16,6 @@ from absl.testing import absltest from absl.testing import parameterized import attr - import numpy as np from dp_accounting import dp_event diff --git a/python/dp_accounting/pld/BUILD.bazel b/python/dp_accounting/dp_accounting/pld/BUILD.bazel similarity index 95% rename from python/dp_accounting/pld/BUILD.bazel rename to python/dp_accounting/dp_accounting/pld/BUILD.bazel index 763feb6d..956cc7fa 100644 --- a/python/dp_accounting/pld/BUILD.bazel +++ b/python/dp_accounting/dp_accounting/pld/BUILD.bazel @@ -27,7 +27,14 @@ licenses(["notice"]) py_library( name = "pld", srcs = ["__init__.py"], - deps = [":pld_privacy_accountant"], + deps = [ + ":accountant", + ":common", + ":pld_pmf", + ":pld_privacy_accountant", + ":privacy_loss_distribution", + ":privacy_loss_mechanism", + ], ) py_library( diff --git a/python/dp_accounting/pld/__init__.py b/python/dp_accounting/dp_accounting/pld/__init__.py similarity index 70% rename from python/dp_accounting/pld/__init__.py rename to python/dp_accounting/dp_accounting/pld/__init__.py index cf5d9241..36f052bc 100644 --- a/python/dp_accounting/pld/__init__.py +++ b/python/dp_accounting/dp_accounting/pld/__init__.py @@ -14,4 +14,10 @@ """PLD Accounting package.""" +from dp_accounting.pld import accountant +from dp_accounting.pld import common +from dp_accounting.pld import pld_pmf +from dp_accounting.pld import pld_privacy_accountant +from dp_accounting.pld import privacy_loss_distribution +from dp_accounting.pld import privacy_loss_mechanism from dp_accounting.pld.pld_privacy_accountant import PLDAccountant diff --git a/python/dp_accounting/pld/accountant.py b/python/dp_accounting/dp_accounting/pld/accountant.py similarity index 99% rename from python/dp_accounting/pld/accountant.py rename to python/dp_accounting/dp_accounting/pld/accountant.py index a445078e..59d9b9c3 100644 --- a/python/dp_accounting/pld/accountant.py +++ b/python/dp_accounting/dp_accounting/pld/accountant.py @@ -15,6 +15,7 @@ import math from typing import Callable, Optional + from scipy import special from dp_accounting.pld import common diff --git a/python/dp_accounting/pld/accountant_test.py b/python/dp_accounting/dp_accounting/pld/accountant_test.py similarity index 99% rename from python/dp_accounting/pld/accountant_test.py rename to python/dp_accounting/dp_accounting/pld/accountant_test.py index bdf9d0e4..918f0762 100644 --- a/python/dp_accounting/pld/accountant_test.py +++ b/python/dp_accounting/dp_accounting/pld/accountant_test.py @@ -15,6 +15,7 @@ """Tests for accountant.""" import unittest + from absl.testing import parameterized from dp_accounting.pld import accountant diff --git a/python/dp_accounting/pld/common.py b/python/dp_accounting/dp_accounting/pld/common.py similarity index 100% rename from python/dp_accounting/pld/common.py rename to python/dp_accounting/dp_accounting/pld/common.py diff --git a/python/dp_accounting/pld/common_test.py b/python/dp_accounting/dp_accounting/pld/common_test.py similarity index 99% rename from python/dp_accounting/pld/common_test.py rename to python/dp_accounting/dp_accounting/pld/common_test.py index cdfac8a0..886b924a 100644 --- a/python/dp_accounting/pld/common_test.py +++ b/python/dp_accounting/dp_accounting/pld/common_test.py @@ -16,6 +16,7 @@ import math import unittest from unittest import mock + from absl.testing import parameterized from dp_accounting.pld import common diff --git a/python/dp_accounting/pld/pld_pmf.py b/python/dp_accounting/dp_accounting/pld/pld_pmf.py similarity index 99% rename from python/dp_accounting/pld/pld_pmf.py rename to python/dp_accounting/dp_accounting/pld/pld_pmf.py index 4f235abc..504b77ed 100644 --- a/python/dp_accounting/pld/pld_pmf.py +++ b/python/dp_accounting/dp_accounting/pld/pld_pmf.py @@ -24,6 +24,7 @@ import math import numbers from typing import Iterable, List, Mapping, Sequence, Tuple, Union + import numpy as np import numpy.typing from scipy import signal diff --git a/python/dp_accounting/pld/pld_pmf_test.py b/python/dp_accounting/dp_accounting/pld/pld_pmf_test.py similarity index 99% rename from python/dp_accounting/pld/pld_pmf_test.py rename to python/dp_accounting/dp_accounting/pld/pld_pmf_test.py index ad03fedc..c5c870c1 100644 --- a/python/dp_accounting/pld/pld_pmf_test.py +++ b/python/dp_accounting/dp_accounting/pld/pld_pmf_test.py @@ -14,6 +14,7 @@ """Tests for PLDPmf.""" import unittest + from absl.testing import parameterized import numpy as np diff --git a/python/dp_accounting/pld/pld_privacy_accountant.py b/python/dp_accounting/dp_accounting/pld/pld_privacy_accountant.py similarity index 100% rename from python/dp_accounting/pld/pld_privacy_accountant.py rename to python/dp_accounting/dp_accounting/pld/pld_privacy_accountant.py diff --git a/python/dp_accounting/pld/pld_privacy_accountant_test.py b/python/dp_accounting/dp_accounting/pld/pld_privacy_accountant_test.py similarity index 100% rename from python/dp_accounting/pld/pld_privacy_accountant_test.py rename to python/dp_accounting/dp_accounting/pld/pld_privacy_accountant_test.py diff --git a/python/dp_accounting/pld/privacy_loss_distribution.py b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution.py similarity index 99% rename from python/dp_accounting/pld/privacy_loss_distribution.py rename to python/dp_accounting/dp_accounting/pld/privacy_loss_distribution.py index c54b0b70..f4d11483 100644 --- a/python/dp_accounting/pld/privacy_loss_distribution.py +++ b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution.py @@ -24,6 +24,7 @@ import logging import math from typing import Any, Callable, Mapping, Optional, Sequence, Tuple, Union + import numpy as np from dp_accounting.pld import common diff --git a/python/dp_accounting/pld/privacy_loss_distribution_basic_example.py b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_basic_example.py similarity index 72% rename from python/dp_accounting/pld/privacy_loss_distribution_basic_example.py rename to python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_basic_example.py index bfe63c1f..47273078 100644 --- a/python/dp_accounting/pld/privacy_loss_distribution_basic_example.py +++ b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_basic_example.py @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Basic Example for Using Privacy Loss Distributions. -""" +"""Basic Example for Using Privacy Loss Distributions.""" from absl import app -from dp_accounting import privacy_loss_distribution +from dp_accounting.pld import privacy_loss_distribution def main(argv): @@ -29,7 +28,8 @@ def main(argv): # PLD for one execution of the Laplace Mechanism. (Throughout we assume that # sensitivity = 1.) laplace_pld = privacy_loss_distribution.from_laplace_mechanism( - parameter_laplace, value_discretization_interval=1e-3) + parameter_laplace, value_discretization_interval=1e-3 + ) # Number of times Laplace Mechanism is run num_laplace = 40 @@ -38,9 +38,11 @@ def main(argv): epsilon = 10 delta = composed_laplace_pld.get_delta_for_epsilon(epsilon) - print(f'An algorithm that executes the Laplace Mechanism with parameter ' - f'{parameter_laplace} for a total of {num_laplace} times is ' - f'({epsilon}, {delta})-DP.') + print( + 'An algorithm that executes the Laplace Mechanism with parameter ' + f'{parameter_laplace} for a total of {num_laplace} times is ' + f'({epsilon}, {delta})-DP.' + ) # PLDs for different mechanisms can also be composed. Below is an example in # which we compose PLDs for Laplace Mechanism and Gaussian Mechanism. @@ -49,7 +51,8 @@ def main(argv): standard_deviation = 5 # PLD for an execution of the Gaussian Mechanism. gaussian_pld = privacy_loss_distribution.from_gaussian_mechanism( - standard_deviation, value_discretization_interval=1e-3) + standard_deviation, value_discretization_interval=1e-3 + ) # PLD for num_laplace executions of the Laplace Mechanism and one execution of # the Gaussian Mechanism. @@ -57,10 +60,13 @@ def main(argv): epsilon = 10 delta = composed_laplace_and_gaussian_pld.get_delta_for_epsilon(epsilon) - print(f'An algorithm that executes the Laplace Mechanism with parameter ' - f'{parameter_laplace} for a total of {num_laplace} times and in ' - f'addition executes once the Gaussian Mechanism with STD ' - f'{standard_deviation} is ({epsilon}, {delta})-DP.') + print( + 'An algorithm that executes the Laplace Mechanism with parameter ' + f'{parameter_laplace} for a total of {num_laplace} times and in ' + 'addition executes once the Gaussian Mechanism with STD ' + f'{standard_deviation} is ({epsilon}, {delta})-DP.' + ) + if __name__ == '__main__': app.run(main) diff --git a/python/dp_accounting/pld/privacy_loss_distribution_test.py b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_test.py similarity index 99% rename from python/dp_accounting/pld/privacy_loss_distribution_test.py rename to python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_test.py index 7f4a389d..f2d661f9 100644 --- a/python/dp_accounting/pld/privacy_loss_distribution_test.py +++ b/python/dp_accounting/dp_accounting/pld/privacy_loss_distribution_test.py @@ -15,6 +15,7 @@ import math from typing import Any, Mapping, Optional import unittest + from absl.testing import parameterized from scipy import stats diff --git a/python/dp_accounting/pld/privacy_loss_mechanism.py b/python/dp_accounting/dp_accounting/pld/privacy_loss_mechanism.py similarity index 99% rename from python/dp_accounting/pld/privacy_loss_mechanism.py rename to python/dp_accounting/dp_accounting/pld/privacy_loss_mechanism.py index 1563a6a3..e9c189fc 100644 --- a/python/dp_accounting/pld/privacy_loss_mechanism.py +++ b/python/dp_accounting/dp_accounting/pld/privacy_loss_mechanism.py @@ -26,6 +26,7 @@ import math import numbers from typing import Iterable, List, Mapping, Optional, Union + import numpy as np from scipy import stats diff --git a/python/dp_accounting/pld/privacy_loss_mechanism_test.py b/python/dp_accounting/dp_accounting/pld/privacy_loss_mechanism_test.py similarity index 100% rename from python/dp_accounting/pld/privacy_loss_mechanism_test.py rename to python/dp_accounting/dp_accounting/pld/privacy_loss_mechanism_test.py diff --git a/python/dp_accounting/pld/test_util.py b/python/dp_accounting/dp_accounting/pld/test_util.py similarity index 100% rename from python/dp_accounting/pld/test_util.py rename to python/dp_accounting/dp_accounting/pld/test_util.py diff --git a/python/dp_accounting/pld/test_util_test.py b/python/dp_accounting/dp_accounting/pld/test_util_test.py similarity index 99% rename from python/dp_accounting/pld/test_util_test.py rename to python/dp_accounting/dp_accounting/pld/test_util_test.py index 750d9446..d47fa146 100644 --- a/python/dp_accounting/pld/test_util_test.py +++ b/python/dp_accounting/dp_accounting/pld/test_util_test.py @@ -15,6 +15,7 @@ """Tests for test_util.""" import unittest + from absl.testing import parameterized from dp_accounting.pld import test_util diff --git a/python/dp_accounting/privacy_accountant.py b/python/dp_accounting/dp_accounting/privacy_accountant.py similarity index 100% rename from python/dp_accounting/privacy_accountant.py rename to python/dp_accounting/dp_accounting/privacy_accountant.py diff --git a/python/dp_accounting/privacy_accountant_test.py b/python/dp_accounting/dp_accounting/privacy_accountant_test.py similarity index 100% rename from python/dp_accounting/privacy_accountant_test.py rename to python/dp_accounting/dp_accounting/privacy_accountant_test.py diff --git a/python/dp_accounting/rdp/BUILD.bazel b/python/dp_accounting/dp_accounting/rdp/BUILD.bazel similarity index 100% rename from python/dp_accounting/rdp/BUILD.bazel rename to python/dp_accounting/dp_accounting/rdp/BUILD.bazel diff --git a/python/dp_accounting/rdp/__init__.py b/python/dp_accounting/dp_accounting/rdp/__init__.py similarity index 93% rename from python/dp_accounting/rdp/__init__.py rename to python/dp_accounting/dp_accounting/rdp/__init__.py index 1a143a0b..c4b2feee 100644 --- a/python/dp_accounting/rdp/__init__.py +++ b/python/dp_accounting/dp_accounting/rdp/__init__.py @@ -14,5 +14,6 @@ """RDP Accounting package.""" +from dp_accounting.rdp import rdp_privacy_accountant from dp_accounting.rdp.rdp_privacy_accountant import compute_epsilon from dp_accounting.rdp.rdp_privacy_accountant import RdpAccountant diff --git a/python/dp_accounting/rdp/rdp_privacy_accountant.py b/python/dp_accounting/dp_accounting/rdp/rdp_privacy_accountant.py similarity index 100% rename from python/dp_accounting/rdp/rdp_privacy_accountant.py rename to python/dp_accounting/dp_accounting/rdp/rdp_privacy_accountant.py diff --git a/python/dp_accounting/rdp/rdp_privacy_accountant_test.py b/python/dp_accounting/dp_accounting/rdp/rdp_privacy_accountant_test.py similarity index 100% rename from python/dp_accounting/rdp/rdp_privacy_accountant_test.py rename to python/dp_accounting/dp_accounting/rdp/rdp_privacy_accountant_test.py diff --git a/python/requirements.txt b/python/dp_accounting/requirements.txt similarity index 100% rename from python/requirements.txt rename to python/dp_accounting/requirements.txt diff --git a/python/setup.py b/python/dp_accounting/setup.py similarity index 100% rename from python/setup.py rename to python/dp_accounting/setup.py