Skip to content

Commit 2d07a0c

Browse files
Differential Privacy TeamMashaTelyatnikova
authored andcommitted
Fixes and cleanups in Accounting libraries,Privacy on Beam and Go DP library.
C++ accounting library: - Change float-based artifacts to double-based - Check when composing two PLDs (both pessimistic or both optimistic) Python accounting library: - Use vectorized call when exponentiate during computation of delta from epsilon - Fast computation of delta without convolution Privacy on Beam: - Small cleanup changes. - Refactoring to prepare for adding QuantilesPerKey. Go DP library: - Update dependencies - Simplify BoundedQuantiles algorithm and increase alpha General updates: - Update README: new supported algorithms, new reference links GitOrigin-RevId: c904cb1ba8ce14c61a69bad25f8adabdbe68f27d Change-Id: I47805ba7b4927d162767510225214935c51f43b5
1 parent f3e565a commit 2d07a0c

26 files changed

+493
-319
lines changed

README.md

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,34 @@ private statistics over datasets. It contains the following tools.
1313
make the differential privacy property no longer hold.
1414
* A [differential privacy accounting library](python/dp_accounting), used for
1515
tracking privacy budget.
16-
* A [command line interface](examples/zetasql) for running DP queries with
17-
[ZetaSQL](https://github.com/google/zetasql).
16+
* A [command line interface](examples/zetasql) for running differentially
17+
private SQL queries with [ZetaSQL](https://github.com/google/zetasql).
1818

1919
To get started on generating differentially private data, we recomend you follow
2020
the [Privacy on Beam codelab](https://codelabs.developers.google.com/codelabs/privacy-on-beam/).
2121

2222
Currently, the DP building block libraries support the following algorithms:
2323

24-
| Algorithm | C++ | Go |Java |
25-
| ------------- |:-------------:|:---------:|:--------:|
26-
| Count | Supported | Supported |Supported |
27-
| Sum | Supported | Supported |Supported |
28-
| Mean | Supported | Supported |Supported |
29-
| Variance | Supported | Planned |Planned |
30-
| Standard deviation | Supported | Planned |Planned |
31-
| Order statistics (incl. min, max, and median) | Supported | Planned | Supported |
32-
| Automatic bounds approximation | Supported | Planned | Planned |
33-
34-
They also contain [safe implementations](common_docs/Secure_Noise_Generation.pdf)
35-
of Laplace and Gaussian mechanisms, which can be used to perform computations
36-
that aren't covered by the algorithms implemented in our libraries.
24+
| Algorithm | C++ | Go | Java |
25+
| :------------------------------- | :-------: | :-------: | :-------: |
26+
| Laplace mechanism | Supported | Supported | Supported |
27+
| Gaussian mechanism | Supported | Supported | Supported |
28+
| Count | Supported | Supported | Supported |
29+
| Sum | Supported | Supported | Supported |
30+
| Mean | Supported | Supported | Supported |
31+
| Variance | Supported | Planned | Planned |
32+
| Standard deviation | Supported | Planned | Planned |
33+
| Quantiles | Supported | Supported | Supported |
34+
| Automatic bounds approximation | Supported | Planned | Planned |
35+
| Truncated geometric thresholding | Supported | Supported | Supported |
36+
| Laplace thresholding | Supported | Supported | Supported |
37+
| Gaussian thresholding | Planned | Supported | Supported |
38+
39+
Implementations of the Laplace mechanism and the Gaussian mechanism use [secure
40+
noise generation]. These mechanisms can be used to perform computations that
41+
aren't covered by the algorithms implemented in our libraries.
42+
43+
[secure noise generation]: ./common_docs/Secure_Noise_Generation.pdf
3744

3845
The DP building block libraries are suitable for research, experimental or
3946
production use cases, while the other tools are currently experimental, and
@@ -135,3 +142,11 @@ it helps you to solve. We have two communication channels:
135142
Please refrain from sending any personal identifiable information. If you wish
136143
to delete a message you've previously sent, please contact us.
137144

145+
## Related projects
146+
147+
- [PyDP](https://github.com/OpenMined/PyDP), a Python wrapper of our C++ DP
148+
building block library.
149+
- [OpenDP](https://opendp.org) tools for statistical analysis of sensitive
150+
private data.
151+
- [TensorFlow Privacy](https://github.com/tensorflow/privacy), a library to
152+
train machine learning models with differential privacy.

cc/accounting/accountant.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ base::StatusOr<double> AdvancedComposition(
7171
}
7272
}
7373

74-
return absl::NotFoundError(absl::StrFormat(
75-
"Total delta %f is too small for %d queries each with delta equal to %f.",
76-
total_delta, k, delta));
74+
return absl::NotFoundError(
75+
absl::StrFormat("Total delta %lf is too small for %d queries each with "
76+
"delta equal to %lf.",
77+
total_delta, k, delta));
7778
}
7879
} // namespace accounting
7980
} // namespace differential_privacy

cc/accounting/accountant_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace accounting {
2727

2828
namespace {
2929

30-
constexpr double kMaxError = 1e-1f;
30+
constexpr double kMaxError = 1e-1;
3131
using ::testing::Values;
3232
using ::differential_privacy::base::testing::StatusIs;
3333

cc/accounting/common/common.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ base::StatusOr<double> InverseMonotoneFunction(
3939
}
4040
if (min_value > value) {
4141
return absl::NotFoundError(absl::StrFormat(
42-
"Cannot find x in range (%f, %f) whose value is at most %f.", lower_x,
43-
upper_x, value));
42+
"Cannot find x in range (%lf, %lf) whose value is at most %lf.",
43+
lower_x, upper_x, value));
4444
}
4545

4646
std::function<bool(const double)> solution_above_current_x;

cc/accounting/common/common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ struct EpsilonDelta {
3535
absl::Status Validate() const {
3636
if (epsilon < 0) {
3737
return absl::InvalidArgumentError(
38-
absl::StrFormat("epsilon should be positive: %f.", epsilon));
38+
absl::StrFormat("epsilon should be positive: %lf.", epsilon));
3939
}
4040
if (delta < 0 || delta > 1) {
4141
return absl::InvalidArgumentError(
42-
absl::StrFormat("delta should be between 0 and 1: %f.", delta));
42+
absl::StrFormat("delta should be between 0 and 1: %lf.", delta));
4343
}
4444
return absl::OkStatus();
4545
}

cc/accounting/common/common_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace {
2727
using ::testing::Values;
2828
using ::differential_privacy::base::testing::StatusIs;
2929

30-
constexpr double kMaxError = 1e-4f;
30+
constexpr double kMaxError = 1e-4;
3131

3232
struct EpsilonDeltaParam {
3333
double epsilon;

cc/accounting/example.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ int main(int argc, char **argv) {
4747

4848
PrintF(
4949
"An algorithm that executes the Laplace Mechansim with parameter"
50-
" %.0f for a total of %d times is (%.0f, %.8f)-DP.\n",
50+
" %.0lf for a total of %d times is (%.0lf, %.8lf)-DP.\n",
5151
parameter_laplace, num_laplace, epsilon, delta);
5252

5353
// PLDs for different mechanisms can also be composed. Below is an example in
@@ -69,8 +69,8 @@ int main(int argc, char **argv) {
6969

7070
PrintF(
7171
"An algorithm that executes the Laplace Mechansim with parameter"
72-
" %.0f for a total of %d times and in addition executes once the"
73-
" Gaussian Mechanism with STD %.0f is (%.0f, %.8f)-DP.\n",
72+
" %.0lf for a total of %d times and in addition executes once the"
73+
" Gaussian Mechanism with STD %.0lf is (%.0lf, %.8lf)-DP.\n",
7474
parameter_laplace, num_laplace, standard_deviation, epsilon, delta);
7575

7676
return EXIT_SUCCESS;

cc/accounting/privacy_loss_distribution.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ PrivacyLossDistribution::CreateForRandomizedResponse(
147147
double discretization_interval) {
148148
if (noise_parameter <= 0 || noise_parameter >= 1) {
149149
return absl::InvalidArgumentError(absl::StrFormat(
150-
"Noise parameter %f should be strictly between 0 and 1.",
150+
"Noise parameter %lf should be strictly between 0 and 1.",
151151
noise_parameter));
152152
}
153153
if (num_buckets <= 1) {
@@ -211,10 +211,15 @@ absl::Status PrivacyLossDistribution::Compose(
211211
if (other_pld.DiscretizationInterval() != discretization_interval_) {
212212
return absl::InvalidArgumentError(absl::StrFormat(
213213
"Cannot compose, discretization intervals are different "
214-
"- %f vs %f",
214+
"- %lf vs %lf",
215215
other_pld.DiscretizationInterval(), discretization_interval_));
216216
}
217217

218+
if (other_pld.GetEstimateType() != estimate_type_) {
219+
return absl::InvalidArgumentError(
220+
"Cannot compose, estimate types are different");
221+
}
222+
218223
double new_infinity_mass = infinity_mass_ + other_pld.InfinityMass() -
219224
infinity_mass_ * other_pld.InfinityMass();
220225

cc/accounting/privacy_loss_distribution.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ class PrivacyLossDistribution {
158158

159159
double DiscretizationInterval() const { return discretization_interval_; }
160160

161+
EstimateType GetEstimateType() const { return estimate_type_; }
162+
161163
// The probability mass of mu_upper over all the outcomes that
162164
// can occur only in mu_upper but not in mu_lower. (These outcomes result in
163165
// privacy loss ln(mu_upper(o) / mu_lower(o)) of infinity.)

cc/accounting/privacy_loss_distribution_test.cc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ class PrivacyLossDistributionTestPeer {
2929
public:
3030
static std::unique_ptr<PrivacyLossDistribution> Create(
3131
const ProbabilityMassFunction& probability_mass_function,
32-
double infinity_mass = 0, double discretization_interval = 1e-4f) {
33-
return absl::WrapUnique(new PrivacyLossDistribution(
34-
discretization_interval, infinity_mass, probability_mass_function));
32+
double infinity_mass = 0, double discretization_interval = 1e-4,
33+
EstimateType estimate_type = EstimateType::kPessimistic) {
34+
return absl::WrapUnique(
35+
new PrivacyLossDistribution(discretization_interval, infinity_mass,
36+
probability_mass_function, estimate_type));
3537
}
3638
};
3739

@@ -198,7 +200,8 @@ TEST(PrivacyLossDistributionTest, ComposeNumTimes) {
198200
FieldsAre(Eq(4), DoubleNear(0.16, kMaxError))));
199201
}
200202

201-
TEST(PrivacyLossDistributionTest, ComposeError) {
203+
TEST(PrivacyLossDistributionTest,
204+
ComposeErrorDifferentDiscretizationIntervals) {
202205
ProbabilityMassFunction pmf = {};
203206
std::unique_ptr<PrivacyLossDistribution> pld =
204207
PrivacyLossDistributionTestPeer::Create(pmf, 0.3, 1e-4);
@@ -212,6 +215,23 @@ TEST(PrivacyLossDistributionTest, ComposeError) {
212215
"are different - 0.000200 vs 0.000100")));
213216
}
214217

218+
TEST(PrivacyLossDistributionTest, ComposeErrorDifferentEstimateTypes) {
219+
ProbabilityMassFunction pmf;
220+
std::unique_ptr<PrivacyLossDistribution> pld =
221+
PrivacyLossDistributionTestPeer::Create(
222+
pmf, /*infinity_mass=*/0.3, /*discretization_interval=*/1e-4,
223+
/*estimate_type=*/EstimateType::kPessimistic);
224+
225+
std::unique_ptr<PrivacyLossDistribution> pld_other =
226+
PrivacyLossDistributionTestPeer::Create(
227+
pmf, /*infinity_mass=*/0.3, /*discretization_interval=*/1e-4,
228+
/*estimate_type=*/EstimateType::kOptimistic);
229+
230+
EXPECT_THAT(pld->Compose(*pld_other),
231+
StatusIs(absl::StatusCode::kInvalidArgument,
232+
Eq("Cannot compose, estimate types are different")));
233+
}
234+
215235
struct GetEpsilonFromDeltaParam {
216236
double discretization_interval;
217237
double infinity_mass;

0 commit comments

Comments
 (0)