diff --git a/dpf/key_generation_protocol/BUILD b/dpf/key_generation_protocol/BUILD new file mode 100644 index 0000000..0d27da7 --- /dev/null +++ b/dpf/key_generation_protocol/BUILD @@ -0,0 +1,59 @@ +# Copyright 2023 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. + +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") +load("@rules_cc//cc:defs.bzl", "cc_library") +load("@rules_proto//proto:defs.bzl", "proto_library") + +package( + default_visibility = ["//visibility:public"], +) + +cc_library( + name = "key_generation_protocol", + srcs = ["key_generation_protocol.cc"], + hdrs = ["key_generation_protocol.h"], + deps = [ + ":key_generation_protocol_cc_proto", + "//dpf:distributed_point_function", + "//dpf:distributed_point_function_cc_proto", + "//dpf:status_macros", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/numeric:int128", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + ], +) + +cc_test( + name = "key_generation_protocol_test", + srcs = ["key_generation_protocol_test.cc"], + deps = [ + ":key_generation_protocol", + "//dpf:distributed_point_function_cc_proto", + "//dpf/internal:status_matchers", + "@com_github_google_googletest//:gtest_main", + ], +) + +cc_proto_library( + name = "key_generation_protocol_cc_proto", + deps = [":key_generation_protocol_proto"], +) + +proto_library( + name = "key_generation_protocol_proto", + srcs = ["key_generation_protocol.proto"], + deps = ["//dpf:distributed_point_function_proto"], +) diff --git a/dpf/key_generation_protocol/key_generation_protocol.cc b/dpf/key_generation_protocol/key_generation_protocol.cc new file mode 100644 index 0000000..03fe0f4 --- /dev/null +++ b/dpf/key_generation_protocol/key_generation_protocol.cc @@ -0,0 +1,39 @@ +// Copyright 2023 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. + +#include "dpf/key_generation_protocol/key_generation_protocol.h" + +#include "absl/memory/memory.h" +#include "absl/status/status.h" +#include "dpf/distributed_point_function.h" +#include "dpf/status_macros.h" + +namespace distributed_point_functions { + +KeyGenerationProtocol::KeyGenerationProtocol( + std::unique_ptr dpf, int party) + : dpf_(std::move(dpf)), party_(party) {} + +absl::StatusOr> +KeyGenerationProtocol::Create(absl::Span parameters, + int party) { + if (party != 0 && party != 1) { + return absl::InvalidArgumentError("`party` must be 0 or 1"); + } + DPF_ASSIGN_OR_RETURN(auto dpf, + DistributedPointFunction::CreateIncremental(parameters)); + return absl::WrapUnique(new KeyGenerationProtocol(std::move(dpf), party)); +} + +} // namespace distributed_point_functions \ No newline at end of file diff --git a/dpf/key_generation_protocol/key_generation_protocol.h b/dpf/key_generation_protocol/key_generation_protocol.h new file mode 100644 index 0000000..0db1492 --- /dev/null +++ b/dpf/key_generation_protocol/key_generation_protocol.h @@ -0,0 +1,132 @@ +/* + * Copyright 2023 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. + */ + +#ifndef DISTRIBUTED_POINT_FUNCTIONS_DPF_KEY_GENERATION_PROTOCOL_KEY_GENERATION_PROTOCOL_H_ +#define DISTRIBUTED_POINT_FUNCTIONS_DPF_KEY_GENERATION_PROTOCOL_KEY_GENERATION_PROTOCOL_H_ + +#include + +#include "absl/numeric/int128.h" +#include "absl/status/statusor.h" +#include "dpf/distributed_point_function.h" +#include "dpf/distributed_point_function.pb.h" +#include "dpf/key_generation_protocol/key_generation_protocol.pb.h" + +namespace distributed_point_functions { + +// A two-party protocol for generating a DPF key. +// For each level of the DPF evaluation tree, the following messages are +// exchanged between the parties. We refer to the corresponding lines in +// Algorithm 8 of https://eprint.iacr.org/2022/866.pdf. +// +// 1. Perform two parallel OTs to obtain shares of s_{CW} (Step 5) +// 2. Exchange shares of s_{CW}, t^L_{CW}, and t^R_{CW} (Step 5) +// 3. Perform two parallel OTs to obtain shares of W_{CW} (Step 11) +// 4. Exchange shares of W_{CW}. +// +// These steps correspond to the following functions in this class: +// +// 1a. ComputeSeedCorrectionOtReceiverMessage +// 1b. ComputeSeedCorrectionOtSenderMessage +// 2. ComputeSeedCorrectionShare +// 3a. ComputeValueCorrectionOtReceiverMessage +// 3b. ComputeValueCorrectionOtSenderMessage +// 4. ComputeValueCorrectionShare +// +// Each of these methods takes the other party's message from the previous +// round, as well as a ProtocolState message containing the party's local state. +// It updates the state and returns the computed message or a Status indicating +// any errors. +// +// NOTE: We may want to compute the value correction first, as done in +// DistributedPointFunction::GenerateIncremental. +class KeyGenerationProtocol { + public: + struct ProtocolState { + int tree_level; + // Add more local state variables here. + }; + + // Creates a new instance of the key generation protocol for a DPF with the + // given parameters. Party must be 0 or 1. + static absl::StatusOr> Create( + absl::Span parameters, int party); + + // Create ProtocolState given shares of alphas and betas. Arguments are given + // as Spans to allow batching. + absl::StatusOr Initialize( + absl::Span alpha_shares, + absl::Span> beta_shares) const; + + // Receiver OT message for the MUX in Step 5. Just takes the state as input. + absl::StatusOr + ComputeSeedCorrectionOtReceiverMessage(ProtocolState& state) const; + + // Computes the sender OT message given the receiver message and the state. + absl::StatusOr + ComputeSeedCorrectionOtSenderMessage( + const SeedCorrectionOtReceiverMessage& seed_ot_receiver_message, + ProtocolState& state) const; + + // Computes the share of the seed correction word given the sender OT message + // and the state. + absl::StatusOr ComputeSeedCorrectionOtShare( + const SeedCorrectionOtSenderMessage& seed_ot_sender_message, + ProtocolState& state) const; + + // Updates the state with the other party's seed correction share. + absl::Status ApplySeedCorrectionShare( + const SeedCorrectionShare& seed_correction_share, + ProtocolState& state) const; + + // Computes the OT receiver message for the MUX gate in Step 11 given the + // state. + absl::StatusOr + ComputeValueCorrectionOtReceiverMessage(ProtocolState& state) const; + + // Computes the OT sender message in Step 11 given the receiver message and + // the state. + absl::StatusOr + ComputeValueCorrectionOtSenderMessage( + const ValueCorrectionOtReceiverMessage& value_ot_receiver_message, + ProtocolState& state) const; + + // Computes the value correction share given the OT sender message and the + // state. + absl::StatusOr ComputeValueCorrectionOtShare( + const ValueCorrectionOtSenderMessage& value_ot_sender_message, + ProtocolState& state) const; + + // Updates the state with the other party's value correction share. + absl::Status ApplyValueCorrectionShare( + const ValueCorrectionShare& value_correction_share, + ProtocolState& state) const; + + // Finalizes the protocol after all tree levels have been computed and returns + // the generated DpfKey. + absl::StatusOr Finalize(ProtocolState& state) const; + + private: + explicit KeyGenerationProtocol(std::unique_ptr dpf, + int party); + + std::unique_ptr dpf_; + int party_; +}; + +} // namespace distributed_point_functions + +#endif // DISTRIBUTED_POINT_FUNCTIONS_DPF_KEY_GENERATION_PROTOCOL_KEY_GENERATION_PROTOCOL_H_ \ No newline at end of file diff --git a/dpf/key_generation_protocol/key_generation_protocol.proto b/dpf/key_generation_protocol/key_generation_protocol.proto new file mode 100644 index 0000000..cd5dfbe --- /dev/null +++ b/dpf/key_generation_protocol/key_generation_protocol.proto @@ -0,0 +1,50 @@ +// Copyright 2023 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. + +syntax = "proto3"; + +package distributed_point_functions; + +import "dpf/distributed_point_function.proto"; + +// For faster allocations of sub-messages. +option cc_enable_arenas = true; + +message SeedCorrectionOtSenderMessage { + repeated Block masked_message_one = 1; + repeated Block masked_message_two = 2; +} + +message SeedCorrectionOtReceiverMessage { + repeated bool choice_bit_mask = 1; +} + +message SeedCorrectionShare { + repeated Block seed = 1; + repeated bool control_bit_left = 2; + repeated bool control_bit_right = 3; +} + +message ValueCorrectionOtSenderMessage { + repeated Value masked_message_one = 1; + repeated Value masked_message_two = 2; +} + +message ValueCorrectionOtReceiverMessage { + repeated bool choice_bit_mask = 1; +} + +message ValueCorrectionShare { + repeated Value value = 1; +} diff --git a/dpf/key_generation_protocol/key_generation_protocol_test.cc b/dpf/key_generation_protocol/key_generation_protocol_test.cc new file mode 100644 index 0000000..52e262c --- /dev/null +++ b/dpf/key_generation_protocol/key_generation_protocol_test.cc @@ -0,0 +1,56 @@ +// Copyright 2023 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. + +#include "dpf/key_generation_protocol/key_generation_protocol.h" + +#include "dpf/distributed_point_function.pb.h" +#include "dpf/internal/status_matchers.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace distributed_point_functions { +namespace { + +using dpf_internal::IsOkAndHolds; +using dpf_internal::StatusIs; +using ::testing::HasSubstr; +using ::testing::NotNull; + +class KeyGenerationProtocolTest : public testing::Test { + protected: + void SetUp() override { + parameters_.resize(2); + parameters_[0].set_log_domain_size(5); + parameters_[0].mutable_value_type()->mutable_integer()->set_bitsize(64); + parameters_[1].set_log_domain_size(10); + parameters_[1].mutable_value_type()->mutable_integer()->set_bitsize(64); + } + std::vector parameters_; +}; + +TEST_F(KeyGenerationProtocolTest, CreateSucceeds) { + constexpr int party = 0; + + EXPECT_THAT(KeyGenerationProtocol::Create(parameters_, party), + IsOkAndHolds(NotNull())); +} + +TEST_F(KeyGenerationProtocolTest, CreateFailsIfPartyIsNot0Or1) { + constexpr int party = 2; + + EXPECT_THAT(KeyGenerationProtocol::Create(parameters_, party), + StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("party"))); +} +} // namespace +} // namespace distributed_point_functions \ No newline at end of file