1 /*
2  * Copyright 2019 Google LLC.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     https://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "private_join_and_compute/util/elgamal_key_util.h"
17 
18 #include <memory>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "private_join_and_compute/crypto/context.h"
24 #include "private_join_and_compute/crypto/ec_point.h"
25 #include "private_join_and_compute/crypto/elgamal.pb.h"
26 #include "private_join_and_compute/util/elgamal_proto_util.h"
27 #include "private_join_and_compute/util/proto_util.h"
28 #include "private_join_and_compute/util/recordio.h"
29 #include "private_join_and_compute/util/status.inc"
30 
31 namespace private_join_and_compute::elgamal_key_util {
32 namespace {
33 using private_join_and_compute::OkStatus;
34 using private_join_and_compute::ProtoUtils;
35 }  // namespace
36 
GenerateElGamalKeyPair(int curve_id,absl::string_view pub_key_filename,absl::string_view prv_key_filename)37 Status GenerateElGamalKeyPair(int curve_id, absl::string_view pub_key_filename,
38                               absl::string_view prv_key_filename) {
39   Context context;
40   ASSIGN_OR_RETURN(ECGroup group, ECGroup::Create(curve_id, &context));
41   ASSIGN_OR_RETURN(auto key_pair,
42                    private_join_and_compute::elgamal::GenerateKeyPair(group));
43   ASSIGN_OR_RETURN(
44       auto public_key_proto,
45       elgamal_proto_util::SerializePublicKey(*key_pair.first.get()));
46   ASSIGN_OR_RETURN(
47       auto private_key_proto,
48       elgamal_proto_util::SerializePrivateKey(*key_pair.second.get()));
49   RETURN_IF_ERROR(
50       ProtoUtils::WriteProtoToFile(public_key_proto, pub_key_filename));
51   RETURN_IF_ERROR(
52       ProtoUtils::WriteProtoToFile(private_key_proto, prv_key_filename));
53   return OkStatus();
54 }
55 
ComputeJointElGamalPublicKey(int curve_id,const std::vector<std::string> & shares_filenames,absl::string_view join_pub_key_key_filename)56 Status ComputeJointElGamalPublicKey(
57     int curve_id, const std::vector<std::string>& shares_filenames,
58     absl::string_view join_pub_key_key_filename) {
59   if (shares_filenames.empty()) {
60     return InvalidArgumentError(
61         "elgmal_key_util::ComputeJointElGamalPublicKey() : empty shares files "
62         "provided");
63   }
64   Context context;
65   ASSIGN_OR_RETURN(ECGroup group, ECGroup::Create(curve_id, &context));
66   std::vector<std::unique_ptr<elgamal::PublicKey>> shares;
67   for (const auto& share_file : shares_filenames) {
68     ASSIGN_OR_RETURN(
69         auto key_share_proto,
70         ProtoUtils::ReadProtoFromFile<ElGamalPublicKey>(share_file));
71     ASSIGN_OR_RETURN(auto key_share, elgamal_proto_util::DeserializePublicKey(
72                                          &group, key_share_proto));
73     shares.push_back(std::move(key_share));
74   }
75   ASSIGN_OR_RETURN(
76       auto joint_key,
77       private_join_and_compute::elgamal::GeneratePublicKeyFromShares(shares));
78   ASSIGN_OR_RETURN(auto joint_key_proto,
79                    elgamal_proto_util::SerializePublicKey(*joint_key.get()));
80   RETURN_IF_ERROR(
81       ProtoUtils::WriteProtoToFile(joint_key_proto, join_pub_key_key_filename));
82   return OkStatus();
83 }
84 }  // namespace private_join_and_compute::elgamal_key_util
85