• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2021 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "fl/armour/cipher/cipher_shares.h"
18 #include "fl/server/common.h"
19 #include "fl/armour/cipher/cipher_meta_storage.h"
20 
21 namespace mindspore {
22 namespace armour {
ShareSecrets(const int cur_iterator,const schema::RequestShareSecrets * share_secrets_req,const std::shared_ptr<fl::server::FBBuilder> & share_secrets_resp_builder,const string next_req_time)23 bool CipherShares::ShareSecrets(const int cur_iterator, const schema::RequestShareSecrets *share_secrets_req,
24                                 const std::shared_ptr<fl::server::FBBuilder> &share_secrets_resp_builder,
25                                 const string next_req_time) {
26   MS_LOG(INFO) << "CipherShares::ShareSecrets START";
27   if (share_secrets_req == nullptr) {
28     std::string reason = "Request is nullptr";
29     MS_LOG(ERROR) << reason;
30     BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_RequestError, reason, next_req_time,
31                          cur_iterator);
32     return false;
33   }
34   if (cipher_init_ == nullptr) {
35     std::string reason = "cipher_init_ is nullptr";
36     MS_LOG(ERROR) << reason;
37     BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_SystemError, reason, next_req_time,
38                          cur_iterator);
39     return false;
40   }
41   // step 1: get client list and share secrets from memory server.
42   clock_t start_time = clock();
43 
44   int iteration = share_secrets_req->iteration();
45   std::vector<std::string> get_keys_clients;
46   cipher_init_->cipher_meta_storage_.GetClientListFromServer(fl::server::kCtxGetKeysClientList, &get_keys_clients);
47   std::vector<std::string> clients_share_list;
48   cipher_init_->cipher_meta_storage_.GetClientListFromServer(fl::server::kCtxShareSecretsClientList,
49                                                              &clients_share_list);
50 
51   std::map<std::string, std::vector<clientshare_str>> encrypted_shares_all;
52   cipher_init_->cipher_meta_storage_.GetClientSharesFromServer(fl::server::kCtxClientsEncryptedShares,
53                                                                &encrypted_shares_all);
54 
55   MS_LOG(INFO) << "Client of get keys size : " << get_keys_clients.size()
56                << "client of update shares size : " << clients_share_list.size()
57                << "updated shares size: " << encrypted_shares_all.size();
58 
59   // step 2: update new item to memory server. serialise: update pb struct to memory server.
60 
61   std::string fl_id_src = share_secrets_req->fl_id()->str();
62   if (find(get_keys_clients.begin(), get_keys_clients.end(), fl_id_src) == get_keys_clients.end()) {
63     // the client not in get keys clients
64     BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_RequestError,
65                          ("client share secret is not in getkeys list. && client is illegal"), next_req_time,
66                          iteration);
67     return false;
68   }
69 
70   if (encrypted_shares_all.find(fl_id_src) != encrypted_shares_all.end()) {  // the client is already exists
71     BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_SUCCEED,
72                          ("client sharesecret already exists."), next_req_time, iteration);
73     return false;
74   }
75 
76   // update new item to memory server.
77   const flatbuffers::Vector<flatbuffers::Offset<mindspore::schema::ClientShare>> *encrypted_shares =
78     (share_secrets_req->encrypted_shares());
79   bool retcode_client =
80     cipher_init_->cipher_meta_storage_.UpdateClientToServer(fl::server::kCtxShareSecretsClientList, fl_id_src);
81   bool retcode_share = cipher_init_->cipher_meta_storage_.UpdateClientShareToServer(
82     fl::server::kCtxClientsEncryptedShares, fl_id_src, encrypted_shares);
83   if (!(retcode_share && retcode_client)) {
84     BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_OutOfTime,
85                          "update client of shares and shares failed", next_req_time, iteration);
86     MS_LOG(ERROR) << "CipherShares::ShareSecrets update client of shares and shares failed ";
87     return false;
88   }
89   BuildShareSecretsRsp(share_secrets_resp_builder, schema::ResponseCode_SUCCEED, "OK", next_req_time, iteration);
90   MS_LOG(INFO) << "CipherShares::ShareSecrets Success";
91   clock_t end_time = clock();
92   double duration = static_cast<double>((end_time - start_time) * 1.0 / CLOCKS_PER_SEC);
93   MS_LOG(INFO) << "ShareSecrets get + deal + update data time is : " << duration;
94   return true;
95 }
96 
GetSecrets(const schema::GetShareSecrets * get_secrets_req,const std::shared_ptr<fl::server::FBBuilder> & fbb,const std::string & next_req_time)97 bool CipherShares::GetSecrets(const schema::GetShareSecrets *get_secrets_req,
98                               const std::shared_ptr<fl::server::FBBuilder> &fbb, const std::string &next_req_time) {
99   MS_LOG(INFO) << "CipherShares::GetSecrets START";
100   clock_t start_time = clock();
101   // step 0: check whether the parameters are legal.
102   if (get_secrets_req == nullptr) {
103     BuildGetSecretsRsp(fbb, schema::ResponseCode_RequestError, 0, next_req_time, nullptr);
104     MS_LOG(ERROR) << "GetSecrets: get_secrets_req is nullptr.";
105     return false;
106   }
107   int iteration = get_secrets_req->iteration();
108   if (cipher_init_ == nullptr) {
109     MS_LOG(ERROR) << "cipher_init_ is nullptr";
110     BuildGetSecretsRsp(fbb, schema::ResponseCode_SystemError, IntToSize(iteration), next_req_time, nullptr);
111     return false;
112   }
113   // step 1: get client list and client shares list from memory server.
114   std::map<std::string, std::vector<clientshare_str>> encrypted_shares_all;
115   cipher_init_->cipher_meta_storage_.GetClientSharesFromServer(fl::server::kCtxClientsEncryptedShares,
116                                                                &encrypted_shares_all);
117   size_t encrypted_shares_num = encrypted_shares_all.size();
118   if (cipher_init_->share_secrets_threshold > encrypted_shares_num) {  // the client num is not enough, return false.
119     BuildGetSecretsRsp(fbb, schema::ResponseCode_SucNotReady, IntToSize(iteration), next_req_time, nullptr);
120     MS_LOG(INFO) << "GetSecrets: the encrypted shares num is not enough: share_secrets_threshold: "
121                  << cipher_init_->share_secrets_threshold << "encrypted_shares_num: " << encrypted_shares_num;
122     return false;
123   }
124 
125   std::string fl_id = get_secrets_req->fl_id()->str();
126   // the client is not in share secrets client list.
127   if (encrypted_shares_all.find(fl_id) == encrypted_shares_all.end()) {
128     BuildGetSecretsRsp(fbb, schema::ResponseCode_RequestError, IntToSize(iteration), next_req_time, nullptr);
129     MS_LOG(ERROR) << "GetSecrets: client is not in share secrets client list.";
130     return false;
131   }
132 
133   bool retcode_client =
134     cipher_init_->cipher_meta_storage_.UpdateClientToServer(fl::server::kCtxGetSecretsClientList, fl_id);
135   if (!retcode_client) {
136     MS_LOG(ERROR) << "update get secrets clients failed";
137     BuildGetSecretsRsp(fbb, schema::ResponseCode_SucNotReady, IntToSize(iteration), next_req_time, nullptr);
138     return false;
139   }
140 
141   // get the result client shares.
142   std::vector<clientshare_str> encrypted_shares_add;
143   for (auto encrypted_shares_iterator = encrypted_shares_all.begin();
144        encrypted_shares_iterator != encrypted_shares_all.end(); ++encrypted_shares_iterator) {
145     std::string fl_id_src_now = encrypted_shares_iterator->first;
146     std::vector<clientshare_str> &clientshare_str_now = encrypted_shares_iterator->second;
147     clientshare_str client_share_str_new;
148     bool find_flag = false;
149     for (size_t index_clientshare = 0; index_clientshare < clientshare_str_now.size(); ++index_clientshare) {
150       std::string fl_id_des = clientshare_str_now[index_clientshare].fl_id;
151       if (fl_id_des == fl_id) {
152         client_share_str_new.fl_id = fl_id_src_now;
153         client_share_str_new.index = clientshare_str_now[index_clientshare].index;
154         client_share_str_new.share = clientshare_str_now[index_clientshare].share;
155         find_flag = true;
156         break;
157       }
158     }
159     if (find_flag) {
160       encrypted_shares_add.push_back(client_share_str_new);
161     }
162   }
163 
164   // serialise clientshares
165   size_t size_shares = encrypted_shares_add.size();
166   std::vector<flatbuffers::Offset<mindspore::schema::ClientShare>> encrypted_shares;
167   std::vector<clientshare_str>::iterator ptr_start = encrypted_shares_add.begin();
168   std::vector<clientshare_str>::iterator ptr_end = ptr_start + size_shares;
169   for (std::vector<clientshare_str>::iterator ptr = ptr_start; ptr < ptr_end; ++ptr) {
170     auto one_fl_id = fbb->CreateString(ptr->fl_id);
171     auto two_share = fbb->CreateVector(ptr->share.data(), ptr->share.size());
172     auto third_index = ptr->index;
173     auto one_clientshare = schema::CreateClientShare(*fbb, one_fl_id, two_share, third_index);
174     encrypted_shares.push_back(one_clientshare);
175   }
176 
177   BuildGetSecretsRsp(fbb, schema::ResponseCode_SUCCEED, IntToSize(iteration), next_req_time, &encrypted_shares);
178   MS_LOG(INFO) << "CipherShares::GetSecrets Success";
179   clock_t end_time = clock();
180   double duration = static_cast<double>((end_time - start_time) * 1.0 / CLOCKS_PER_SEC);
181   MS_LOG(INFO) << "Getsecrets Duration Time is : " << duration;
182   return true;
183 }
184 
BuildGetSecretsRsp(const std::shared_ptr<fl::server::FBBuilder> & fbb,const schema::ResponseCode retcode,size_t iteration,const std::string & next_req_time,const std::vector<flatbuffers::Offset<mindspore::schema::ClientShare>> * encrypted_shares)185 void CipherShares::BuildGetSecretsRsp(
186   const std::shared_ptr<fl::server::FBBuilder> &fbb, const schema::ResponseCode retcode, size_t iteration,
187   const std::string &next_req_time,
188   const std::vector<flatbuffers::Offset<mindspore::schema::ClientShare>> *encrypted_shares) {
189   int rsp_retcode = retcode;
190   int rsp_iteration = SizeToInt(iteration);
191   auto rsp_next_req_time = fbb->CreateString(next_req_time);
192   if (encrypted_shares == nullptr) {
193     auto get_secrets_rsp = schema::CreateReturnShareSecrets(*fbb, rsp_retcode, rsp_iteration, 0, rsp_next_req_time);
194     fbb->Finish(get_secrets_rsp);
195   } else {
196     auto encrypted_shares_rsp = fbb->CreateVector(*encrypted_shares);
197     auto get_secrets_rsp =
198       CreateReturnShareSecrets(*fbb, rsp_retcode, rsp_iteration, encrypted_shares_rsp, rsp_next_req_time);
199     fbb->Finish(get_secrets_rsp);
200   }
201   return;
202 }
203 
BuildShareSecretsRsp(const std::shared_ptr<fl::server::FBBuilder> & share_secrets_resp_builder,const schema::ResponseCode retcode,const string & reason,const string & next_req_time,const int iteration)204 void CipherShares::BuildShareSecretsRsp(const std::shared_ptr<fl::server::FBBuilder> &share_secrets_resp_builder,
205                                         const schema::ResponseCode retcode, const string &reason,
206                                         const string &next_req_time, const int iteration) {
207   auto rsp_reason = share_secrets_resp_builder->CreateString(reason);
208   auto rsp_next_req_time = share_secrets_resp_builder->CreateString(next_req_time);
209   auto share_secrets_rsp =
210     schema::CreateResponseShareSecrets(*share_secrets_resp_builder, retcode, rsp_reason, rsp_next_req_time, iteration);
211   share_secrets_resp_builder->Finish(share_secrets_rsp);
212   return;
213 }
214 
ClearShareSecrets()215 void CipherShares::ClearShareSecrets() {
216   fl::server::DistributedMetadataStore::GetInstance().ResetMetadata(fl::server::kCtxShareSecretsClientList);
217   fl::server::DistributedMetadataStore::GetInstance().ResetMetadata(fl::server::kCtxClientsEncryptedShares);
218   fl::server::DistributedMetadataStore::GetInstance().ResetMetadata(fl::server::kCtxGetSecretsClientList);
219 }
220 }  // namespace armour
221 }  // namespace mindspore
222