This is the code for node C
#include "openfhe.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include <chrono>
#include <fstream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <functional>
#include <map>
#include <memory>
#include <utility>
//#include "pybind11/pybind11.h"
//#include "pybind11/stl.h"
//namespace py = pybind11;
// header files needed for serialization
#include "ciphertext-ser.h"
#include "cryptocontext-ser.h"
#include "key/key-ser.h"
#include "scheme/ckksrns/ckksrns-ser.h"
#define BUFFER_SIZE 4096
using namespace std;
using namespace lbcrypto;
const std::string DATAFOLDER = "demoData3";
int receive(int listeningPort, std::string saveFilename){
// int listeningPort = 12345;
// std::string saveFilename = "cryptocontext.txt";
// 创建监听套接字
int listeningSocketFD = socket(AF_INET, SOCK_STREAM, 0);
if (listeningSocketFD == -1) {
std::cerr << "无法创建监听套接字" << std::endl;
return 1;
}
// 设置本地地址信息
sockaddr_in localAddress{};
localAddress.sin_family = AF_INET;
localAddress.sin_addr.s_addr = INADDR_ANY;
localAddress.sin_port = htons(listeningPort);
// 绑定监听套接字到本地地址
if (bind(listeningSocketFD, (struct sockaddr*)&localAddress, sizeof(localAddress)) < 0) {
std::cerr << "绑定套接字失败" << std::endl;
return 1;
}
// 开始监听
if (listen(listeningSocketFD, 1) < 0) {
std::cerr << "开始监听失败" << std::endl;
return 1;
}
std::cout << "等待连接..." << std::endl;
// 接受连接请求
sockaddr_in clientAddress{};
socklen_t clientAddressLength = sizeof(clientAddress);
int connectionSocketFD = accept(listeningSocketFD, (struct sockaddr*)&clientAddress, &clientAddressLength);
if (connectionSocketFD < 0) {
std::cerr << "接受连接失败" << std::endl;
return 1;
}
std::cout << "已连接" << std::endl;
// 创建文件来保存接收的数据
std::ofstream outputFile(saveFilename);
if (!outputFile) {
std::cerr << "无法创建文件:" << saveFilename << std::endl;
return 1;
}
// 接收数据并写入文件
char buffer[BUFFER_SIZE];
ssize_t bytesRead;
while ((bytesRead = recv(connectionSocketFD, buffer, BUFFER_SIZE, 0)) > 0) {
// 写入文件
outputFile.write(buffer, bytesRead);
}
// char buffer[BUFFER_SIZE];
// int bytesRead;
// while ((bytesRead = recv(connectionSocketFD, buffer, BUFFER_SIZE, 0)) > 0) {
// // 写入文件
// outputFile.write(buffer, bytesRead);
// }
// 关闭套接字和文件
close(connectionSocketFD);
close(listeningSocketFD);
outputFile.close();
std::cout << "文件接收完成" << std::endl;
return 0;
}
int send(int serverPort, std::string serverIP, std::string filename){
// std::string serverIP = "192.168.1.103";
// int serverPort = 12345;
// std::string filename = "demoData/cryptocontext.txt";
// 打开文件
std::ifstream file(filename);
if (!file) {
std::cerr << "无法打开文件:" << filename << std::endl;
return 1;
}
// 创建套接字
int socketFD = socket(AF_INET, SOCK_STREAM, 0);
if (socketFD == -1) {
std::cerr << "无法创建套接字" << std::endl;
return 1;
}
// 设置目标服务器的地址信息
sockaddr_in serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(serverPort);
if (inet_pton(AF_INET, serverIP.c_str(), &(serverAddress.sin_addr)) <= 0) {
std::cerr << "无效的IP地址:" << serverIP << std::endl;
return 1;
}
// 连接到目标服务器
int i = 0;
for ( ; i < 50; ++i) {
if (connect(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
std::cerr << "尝试连接失败,继续等待" << std::endl;
sleep(1);
}
else break;
}
if (i == 5)
return 1;
// if (connect(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
// std::cerr << "连接失败" << std::endl;
// return 1;
// }
// if (!connectWithTimeout(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress), 5)) {
// std::cerr << "连接到目标主机失败" << std::endl;
// return 1;
// }
// 逐行读取文件并发送数据
char buffer[BUFFER_SIZE];
while (!file.eof()) {
file.read(buffer, BUFFER_SIZE);
ssize_t bytesRead = file.gcount();
// 发送数据
ssize_t bytesSent = send(socketFD, buffer, bytesRead, 0);
if (bytesSent == -1) {
std::cerr << "发送数据失败" << std::endl;
break;
}
}
// std::string line;
// while (std::getline(file, line)) {
// // 发送数据
// if (send(socketFD, line.c_str(), line.length(), 0) == -1) {
// std::cerr << "发送数据失败" << std::endl;
// return 1;
// }
// }
// 关闭套接字和文件
close(socketFD);
file.close();
std::cout << "文件发送完成" << std::endl;
return 0;
}
int main() {
receive(10306, DATAFOLDER + "/cryptocontext.txt");
CryptoContext<DCRTPoly> cc;
if (!Serial::DeserializeFromFile(DATAFOLDER + "/cryptocontext.txt", cc, SerType::BINARY)) {
std::cerr << "I cannot read serialization from " << DATAFOLDER + "/cryptocontext.txt" << std::endl;
return 1;
}
std::cout << "The cryptocontext has been deserialized." << std::endl;
////////////////////////////////////////////////////////////
// Set-up of parameters
////////////////////////////////////////////////////////////
// Output the generated parameters
std::cout << "p = " << cc->GetCryptoParameters()->GetPlaintextModulus() << std::endl;
std::cout << "n = " << cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2 << std::endl;
std::cout << "log2 q = " << log2(cc->GetCryptoParameters()->GetElementParams()->GetModulus().ConvertToDouble())
<< std::endl;
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
cc->Enable(MULTIPARTY);
// Initialize Public Key Containers for two parties A and B
receive(10506, DATAFOLDER + "/publickey2.txt");
PublicKey<DCRTPoly> pk2;
if (Serial::DeserializeFromFile(DATAFOLDER + "/publickey2.txt", pk2, SerType::BINARY) == false) {
std::cerr << "Could not read publickey2" << std::endl;
return 1;
}
std::cout << "The publickey2 has been deserialized." << std::endl;
auto kp_3 = cc->MultipartyKeyGen(pk2);
// auto start_multkeygen = std::chrono::high_resolution_clock::now();
// Generate evalmult key part for A
receive(10306, DATAFOLDER + "/evalMultKey.txt");
EvalKey<DCRTPoly> evalMultKey;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalMultKey.txt", evalMultKey, SerType::BINARY) == false) {
std::cerr << "Could not read evalMultKey" << std::endl;
return 1;
}
std::cout << "The evalMultKey has been deserialized." << std::endl;
auto evalMultKey3 = cc->MultiKeySwitchGen(kp_3.secretKey, kp_3.secretKey, evalMultKey);
receive(10506, DATAFOLDER + "/evalMultAB.txt");
EvalKey<DCRTPoly> evalMultAB;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalMultAB.txt", evalMultAB, SerType::BINARY) == false) {
std::cerr << "Could not read evalMultAB" << std::endl;
return 1;
}
std::cout << "The evalMultAB has been deserialized." << std::endl;
auto evalMultABC = cc->MultiAddEvalKeys(evalMultAB, evalMultKey3, kp_3.publicKey->GetKeyTag());
if (!Serial::SerializeToFile(DATAFOLDER + "/evalMultABC.txt", evalMultABC, SerType::BINARY)) {
std::cerr << "Error writing serialization of evalMultABC to evalMultABC.txt" << std::endl;
return 1;
}
std::cout << "The evalMultABC has been serialized." << std::endl;
send(10603, "192.168.1.103", DATAFOLDER + "/evalMultABC.txt");
send(10605, "192.168.1.105", DATAFOLDER + "/evalMultABC.txt");
// Serialize the public key
if (!Serial::SerializeToFile(DATAFOLDER + "/publickey3.txt", kp_3.publicKey, SerType::BINARY)) {
std::cerr << "Error writing serialization of public key to keypublic3.txt" << std::endl;
return 1;
}
std::cout << "The publickey3 has been serialized." << std::endl;
send(10603, "192.168.1.103", DATAFOLDER + "/publickey3.txt");
send(10605, "192.168.1.105", DATAFOLDER + "/publickey3.txt");
auto evalMultCABC = cc->MultiMultEvalKey(kp_3.secretKey, evalMultABC, kp_3.publicKey->GetKeyTag());
receive(10506, DATAFOLDER + "/evalMultBABC.txt");
EvalKey<DCRTPoly> evalMultBABC;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalMultBABC.txt", evalMultBABC, SerType::BINARY) == false) {
std::cerr << "Could not read evalMultBABC" << std::endl;
return 1;
}
std::cout << "The evalMultBABC has been deserialized." << std::endl;
auto evalMultBCABC = cc->MultiAddEvalMultKeys(evalMultCABC, evalMultBABC, evalMultCABC->GetKeyTag());
receive(10306, DATAFOLDER + "/evalMultAABC.txt");
EvalKey<DCRTPoly> evalMultAABC;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalMultAABC.txt", evalMultAABC, SerType::BINARY) == false) {
std::cerr << "Could not read evalMultAABC" << std::endl;
return 1;
}
std::cout << "The evalMultAABC has been deserialized." << std::endl;
auto evalMultFinal = cc->MultiAddEvalMultKeys(evalMultAABC, evalMultBCABC, kp_3.publicKey->GetKeyTag());
cc->InsertEvalMultKey({evalMultFinal});
std::cout << "The evalMultFinal have been generated." << std::endl;
// Serialize the relinearization (evaluation) key for homomorphic // multiplication
std::ofstream emkeyfile2(DATAFOLDER + "/" + "evalMultFinal.txt", std::ios::out | std::ios::binary);
if (emkeyfile2.is_open()) {
if (cc->SerializeEvalMultKey(emkeyfile2, SerType::BINARY) == false) {
std::cerr << "Error writing serialization of the eval mult keys to "
"evalMultFinal.txt"
<< std::endl;
return 1;
}
std::cout << "The evalMultFinal have been serialized." << std::endl;
emkeyfile2.close();
}
else {
std::cerr << "Error serializing evalMultFinal" << std::endl;
return 1;
}
send(10603, "192.168.1.103", DATAFOLDER + "/evalMultFinal.txt");
send(10605, "192.168.1.105", DATAFOLDER + "/evalMultFinal.txt");
//---------------------------------------------------
std::cout << "Running evalsum key generation (used for source data)..." << std::endl;
// Generate evalsum key part for A
receive(10306, DATAFOLDER + "/evalSumKeys.txt");
std::shared_ptr<std::map<unsigned int, std::shared_ptr<lbcrypto::EvalKeyImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<lbcrypto::EvalKeyImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > > > > > > evalSumKeys;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalSumKeys.txt", evalSumKeys, SerType::BINARY) == false) {
std::cerr << "Could not read evalSumKeys" << std::endl;
return 1;
}
std::cout << "The evalSumKeys has been deserialized." << std::endl;
auto evalSumKeysC = cc->MultiEvalSumKeyGen(kp_3.secretKey, evalSumKeys, kp_3.publicKey->GetKeyTag());
receive(10506, DATAFOLDER + "/evalSumKeysB.txt");
std::shared_ptr<std::map<unsigned int, std::shared_ptr<lbcrypto::EvalKeyImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<lbcrypto::EvalKeyImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > > > > > > evalSumKeysB;
if (Serial::DeserializeFromFile(DATAFOLDER + "/evalSumKeysB.txt", evalSumKeysB, SerType::BINARY) == false) {
std::cerr << "Could not read evalSumKeysB" << std::endl;
return 1;
}
std::cout << "The evalSumKeysB has been deserialized." << std::endl;
auto evalSumKeysAB = cc->MultiAddEvalSumKeys(evalSumKeys, evalSumKeysB, pk2->GetKeyTag());
auto evalSumKeysJoin = cc->MultiAddEvalSumKeys(evalSumKeysC, evalSumKeysAB, kp_3.publicKey->GetKeyTag());
cc->InsertEvalSumKey(evalSumKeysJoin);
std::cout << "The eval sum keys have been generated." << std::endl;
// auto end_sumkeygen = std::chrono::high_resolution_clock::now();
////////////////////////////////////////////////////////////
// Encode source data
////////////////////////////////////////////////////////////
std::vector<double> vectorOfInts3 = {2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0};
Plaintext plaintext3 = cc->MakeCKKSPackedPlaintext(vectorOfInts3);
////////////////////////////////////////////////////////////
// Encryption
////////////////////////////////////////////////////////////
Ciphertext<DCRTPoly> ciphertext3;
// Ciphertext<DCRTPoly> ciphertext4;//new
ciphertext3 = cc->Encrypt(kp_3.publicKey, plaintext3);
if (!Serial::SerializeToFile(DATAFOLDER + "/" + "ciphertext3.txt", ciphertext3, SerType::BINARY)) {
std::cerr << "Error writing serialization of ciphertext 3 to ciphertext3.txt" << std::endl;
return 1;
}
std::cout << "The first ciphertext has been serialized." << std::endl;
receive(103063, DATAFOLDER + "/" + "ciphertext1.txt");
Ciphertext<DCRTPoly> ciphertext1;
if (Serial::DeserializeFromFile(DATAFOLDER + "/ciphertext1.txt", ciphertext1, SerType::BINARY) == false) {
std::cerr << "Could not read the ciphertext1" << std::endl;
return 1;
}
std::cout << "The first ciphertext 1 has been deserialized." << std::endl;
Ciphertext<DCRTPoly> ciphertext2;
receive(105063, DATAFOLDER + "/" + "ciphertext2.txt");
if (Serial::DeserializeFromFile(DATAFOLDER + "/ciphertext2.txt", ciphertext2, SerType::BINARY) == false) {
std::cerr << "Could not read the ciphertext2" << std::endl;
return 1;
}
std::cout << "The second ciphertext 2 has been deserialized." << std::endl;
////////////////////////////////////////////////////////////
// EvalAdd Operation on Re-Encrypted Data
////////////////////////////////////////////////////////////
Ciphertext<DCRTPoly> ciphertextAdd12;
Ciphertext<DCRTPoly> ciphertextAdd123;
ciphertextAdd12 = cc->EvalAdd(ciphertext1, ciphertext2);
ciphertextAdd123 = cc->EvalAdd(ciphertextAdd12, ciphertext3);
auto ciphertextMult = cc->EvalMult(ciphertext1, ciphertext3);
////////////////////////////////////////////////////////////
// Decryption after Accumulation Operation on Encrypted Data with Multiparty
////////////////////////////////////////////////////////////
Plaintext plaintextAddNew1;
Plaintext plaintextAddNew2;
Plaintext plaintextAddNew3;
DCRTPoly partialPlaintext1;
DCRTPoly partialPlaintext2;
DCRTPoly partialPlaintext3;
Plaintext plaintextMultipartyNew;
// distributed decryption
if (!Serial::SerializeToFile(DATAFOLDER + "/" + "ciphertextAdd123.txt", ciphertextAdd123, SerType::BINARY)) {
std::cerr << "Error writing serialization of ciphertextAdd123 to ciphertextAdd123.txt" << std::endl;
return 1;
}
std::cout << "The ciphertextAdd123 has been serialized." << std::endl;
send(10603, "192.168.1.103", DATAFOLDER + "/" + "ciphertextAdd123.txt");
send(10605, "192.168.1.105", DATAFOLDER + "/" + "ciphertextAdd123.txt");
receive(10306, DATAFOLDER + "/" + "sumciphertextPartial1.txt");
Ciphertext<DCRTPoly> sumciphertextPartial1;
if (Serial::DeserializeFromFile(DATAFOLDER + "/sumciphertextPartial1.txt", sumciphertextPartial1, SerType::BINARY) == false) {
std::cerr << "Could not read the sumciphertextPartial1" << std::endl;
return 1;
}
std::cout << "The sumciphertextPartial1 has been deserialized." << std::endl;
receive(10506, DATAFOLDER + "/" + "sumciphertextPartial2.txt");
Ciphertext<DCRTPoly> sumciphertextPartial2;
if (Serial::DeserializeFromFile(DATAFOLDER + "/sumciphertextPartial2.txt", sumciphertextPartial2, SerType::BINARY) == false) {
std::cerr << "Could not read the sumciphertextPartial2" << std::endl;
return 1;
}
std::cout << "The sumciphertextPartial2 has been deserialized." << std::endl;
auto sumciphertextPartial3 = cc->MultipartyDecryptMain({ciphertextAdd123}, kp_3.secretKey);
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVec;
partialCiphertextVec.push_back(sumciphertextPartial1);
partialCiphertextVec.push_back(sumciphertextPartial2);
partialCiphertextVec.push_back(sumciphertextPartial3[0]);
cc->MultipartyDecryptFusion(partialCiphertextVec, &plaintextMultipartyNew);
plaintextMultipartyNew->SetLength(plaintext3->GetLength());
std::cout << "\n Resulting Fused Plaintext: \n" << std::endl;
std::cout << plaintextMultipartyNew << std::endl;
std::cout << "\n";
// auto start_multdecrypt = std::chrono::high_resolution_clock::now();
Plaintext plaintextMultipartyMult;
if (!Serial::SerializeToFile(DATAFOLDER + "/" + "ciphertextMult.txt", ciphertextMult, SerType::BINARY)) {
std::cerr << "Error writing serialization of ciphertextMult to ciphertextMult.txt" << std::endl;
return 1;
}
std::cout << "The ciphertextMult has been serialized." << std::endl;
send(10603, "192.168.1.103", DATAFOLDER + "/" + "ciphertextMult.txt");
send(10605, "192.168.1.105", DATAFOLDER + "/" + "ciphertextMult.txt");
receive(10306, DATAFOLDER + "/" + "multciphertextPartial1.txt");
Ciphertext<DCRTPoly> multciphertextPartial1;
if (Serial::DeserializeFromFile(DATAFOLDER + "/multciphertextPartial1.txt", multciphertextPartial1, SerType::BINARY) == false) {
std::cerr << "Could not read the multciphertextPartial1" << std::endl;
return 1;
}
std::cout << "The multciphertextPartial1 has been deserialized." << std::endl;
receive(10506, DATAFOLDER + "/" + "multciphertextPartial2.txt");
Ciphertext<DCRTPoly> multciphertextPartial2;
if (Serial::DeserializeFromFile(DATAFOLDER + "/multciphertextPartial2.txt", multciphertextPartial2, SerType::BINARY) == false) {
std::cerr << "Could not read the multciphertextPartial2" << std::endl;
return 1;
}
std::cout << "The multciphertextPartial2 has been deserialized." << std::endl;
auto multciphertextPartial3 = cc->MultipartyDecryptMain({ciphertextMult}, kp_3.secretKey);
std::cout<<"ciphertextPartial1 NoiseScaleDeg is : "<<multciphertextPartial1->GetNoiseScaleDeg()<<std::endl;
std::cout<<"ciphertextPartial1 ScalingFactor is : "<<multciphertextPartial1->GetScalingFactor()<<std::endl;
std::cout<<"ciphertextPartial2 NoiseScaleDeg is : "<<multciphertextPartial2->GetNoiseScaleDeg()<<std::endl;
std::cout<<"ciphertextPartial2 ScalingFactor is : "<<multciphertextPartial2->GetScalingFactor()<<std::endl;
std::cout<<"ciphertextPartial3 NoiseScaleDeg is : "<<multciphertextPartial3[0]->GetNoiseScaleDeg()<<std::endl;
std::cout<<"ciphertextPartial3 ScalingFactor is : "<<multciphertextPartial3[0]->GetScalingFactor()<<std::endl;
std::cout << "3 fenbushijiemi meiwenti" << std::endl;
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVecMult;
partialCiphertextVecMult.push_back(multciphertextPartial1);
partialCiphertextVecMult.push_back(multciphertextPartial2);
partialCiphertextVecMult.push_back(multciphertextPartial3[0]);
cc->MultipartyDecryptFusion(partialCiphertextVecMult, &plaintextMultipartyMult);
plaintextMultipartyMult->SetLength(plaintext3->GetLength());
std::cout << "\n Resulting Fused Plaintext after Multiplication of plaintexts 1 "
"and 3: \n"
<< std::endl;
std::cout << plaintextMultipartyMult << std::endl;
std::cout << "\n";
std::cout << "\n Fused result after the Summation of ciphertext 3: "//new
"\n"
<< std::endl;
}