-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Connect the IR translator to the DP analysis.
This change connects the IR translator to the DP analysis. It introduces a new kind of policy object, indicating global limits on DP parameters, and shows this policy being used to cause the analysis to return a pass and a fail on the same IR graph depending upon those parameters. PiperOrigin-RevId: 468717689
- Loading branch information
Showing
7 changed files
with
247 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//----------------------------------------------------------------------------- | ||
// Copyright 2022 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://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. | ||
//---------------------------------------------------------------------------- | ||
#ifndef SRC_BACKENDS_POLICY_ENGINE_DP_PARAMETER_POLICY_H_ | ||
#define SRC_BACKENDS_POLICY_ENGINE_DP_PARAMETER_POLICY_H_ | ||
|
||
#include <filesystem> | ||
#include <optional> | ||
|
||
#include "absl/strings/str_format.h" | ||
#include "src/backends/policy_engine/policy.h" | ||
|
||
namespace raksha::backends::policy_engine { | ||
|
||
// A policy where the contents of the policy are just differential privacy | ||
// parameters. For now, we only send over Epsilon and Delta, but we can extend | ||
// this to send more in the future. | ||
class DpParameterPolicy : public Policy { | ||
public: | ||
// Note: The SQL frontend hands us these parameters as floating point | ||
// numbers, so we do eventually want to represent these as `double`s. But | ||
// the IR parser hasn't landed floating point numbers yet, so using | ||
// `uint64_t`s for now. | ||
using DpParameterNumericType = uint64_t; | ||
|
||
explicit DpParameterPolicy(DpParameterNumericType epsilon, | ||
DpParameterNumericType delta) | ||
: epsilon_(epsilon), delta_(delta) {} | ||
|
||
// Always use the checker compiled from the DP policy verifier interface. | ||
std::string GetPolicyAnalysisCheckerName() const override { | ||
return "dp_policy_verifier_cxx"; | ||
} | ||
|
||
// This policy always populates the `isDPParameter` relation. | ||
std::optional<std::string> GetPolicyFactName() const override { | ||
return "isDPParameter"; | ||
} | ||
|
||
std::optional<std::string> GetPolicyString() const override { | ||
return absl::StrFormat( | ||
R"($EpsilonValue(%lu) | ||
$DeltaValue(%lu))", | ||
epsilon_, delta_); | ||
} | ||
|
||
private: | ||
// The epsilon differential privacy parameter. | ||
DpParameterNumericType epsilon_; | ||
// The delta differential privacy parameter. | ||
DpParameterNumericType delta_; | ||
}; | ||
|
||
} // namespace raksha::backends::policy_engine | ||
|
||
#endif |
56 changes: 0 additions & 56 deletions
56
src/backends/policy_engine/dp_parameter_policy_rule_policy.h
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#include "src/backends/policy_engine/dp_parameter_policy.h" | ||
|
||
#include <optional> | ||
|
||
#include "absl/strings/numbers.h" | ||
#include "absl/strings/str_split.h" | ||
#include "src/common/testing/gtest.h" | ||
|
||
namespace raksha::backends::policy_engine { | ||
namespace { | ||
|
||
using DpParameter = DpParameterPolicy::DpParameterNumericType; | ||
using testing::Combine; | ||
using testing::ValuesIn; | ||
|
||
class DpParamaterPolicyRulePolicyTest | ||
: public testing::TestWithParam<std::tuple<DpParameter, DpParameter>> { | ||
protected: | ||
explicit DpParamaterPolicyRulePolicyTest() | ||
: epsilon_(std::get<0>(GetParam())), | ||
delta_(std::get<1>(GetParam())), | ||
policy_(epsilon_, delta_) {} | ||
|
||
DpParameter epsilon_; | ||
DpParameter delta_; | ||
DpParameterPolicy policy_; | ||
}; | ||
|
||
TEST_P(DpParamaterPolicyRulePolicyTest, TestCheckerName) { | ||
EXPECT_EQ(policy_.GetPolicyAnalysisCheckerName(), "dp_policy_verifier_cxx"); | ||
} | ||
|
||
TEST_P(DpParamaterPolicyRulePolicyTest, TestPolicyFactName) { | ||
std::optional<std::string> policy_fact_name = policy_.GetPolicyFactName(); | ||
ASSERT_TRUE(policy_fact_name.has_value()); | ||
EXPECT_EQ(*policy_fact_name, "isDPParameter"); | ||
} | ||
|
||
// Convert a DpParameter to a string, checking our transformation to ensure that | ||
// that string can be perfectly converted back to the input parameter. This may | ||
// seems silly so long as `DpParameter`s are integers, but this will make more | ||
// sense when we switch to floats, as %f and %g will print a fixed-precision | ||
// (and thus possibly lossy) representation (unlike %a). | ||
std::string ConvertParamToStringExpectLossless(DpParameter parameter) { | ||
std::string result = absl::StrFormat("%lu", parameter); | ||
DpParameter parsed_param = 0; | ||
EXPECT_TRUE(absl::SimpleAtoi(result, &parsed_param)); | ||
EXPECT_EQ(parsed_param, parameter); | ||
return result; | ||
} | ||
|
||
// GetPolicyString constructs a Datalog string from the policy given the | ||
// parameters. Here, we deconstruct that same policy to extract those parameters | ||
// and ensure that they are what we expect. | ||
TEST_P(DpParamaterPolicyRulePolicyTest, TestPolicyString) { | ||
std::optional<std::string> optional_policy_string = policy_.GetPolicyString(); | ||
ASSERT_TRUE(optional_policy_string.has_value()); | ||
std::string policy_string = *optional_policy_string; | ||
std::vector<std::string> lines = | ||
absl::StrSplit(policy_string, '\n', absl::SkipEmpty()); | ||
EXPECT_EQ(lines.size(), 2); | ||
|
||
std::string epsilon_value_string = | ||
ConvertParamToStringExpectLossless(epsilon_); | ||
std::string delta_value_string = ConvertParamToStringExpectLossless(delta_); | ||
|
||
std::vector<std::string> expected_lines = { | ||
absl::StrFormat("$EpsilonValue(%s)", epsilon_value_string), | ||
absl::StrFormat("$DeltaValue(%s)", delta_value_string)}; | ||
|
||
EXPECT_THAT(lines, testing::UnorderedElementsAreArray(expected_lines)); | ||
} | ||
|
||
// Note: some of the parameter values will be duplicated until the DpParameter | ||
// type switches to floating point numbers. | ||
constexpr DpParameter kSampleParameters[] = { | ||
0, | ||
1, | ||
std::numeric_limits<DpParameter>::min(), | ||
std::numeric_limits<DpParameter>::max(), | ||
std::numeric_limits<DpParameter>::lowest(), | ||
std::numeric_limits<DpParameter>::epsilon()}; | ||
|
||
INSTANTIATE_TEST_SUITE_P(DpParameterPolicyRuleTest, | ||
DpParamaterPolicyRulePolicyTest, | ||
Combine(ValuesIn(kSampleParameters), | ||
ValuesIn(kSampleParameters))); | ||
|
||
} // namespace | ||
} // namespace raksha::backends::policy_engine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.