//template int64_t binary_to_decimal(int64_t* inp, size_t logn) { int64_t output = 0; for(size_t j = 0; j < logn; ++j) { output += (1ULL << j) * inp[j]; } return output; } struct shareconversion { int64_t PM, PM_recv, rb, FCWshare_reconstruction; }; struct shareconversion_Pb { int64_t PM, FCW; }; /** * @brief This function is used to convert the XOR-ed shared flag bits into additive shares of the same * * @param sockets0 * @param sockets1 * @param socket_no */ void convert_sharesP2 ( size_t db_nitems, __m128i** output0, int8_t ** flags0, __m128i** output1, int8_t ** flags1, int64_t ** leaves0, int64_t ** leafbits0, int64_t ** leaves1, int64_t ** leafbits1, std::vector& sockets0, std::vector& sockets1, size_t i, size_t socket_no = 0) { du_attalah_P2(sockets0, sockets1, socket_no); shareconversion shareconversionP0, shareconversionP1; boost::asio::read(sockets0[i], boost::asio::buffer(&shareconversionP0, sizeof(shareconversion))); boost::asio::read(sockets1[i], boost::asio::buffer(&shareconversionP1, sizeof(shareconversion))); for(size_t j = 0; j < db_nitems; ++j) { output1[i][j] = -output1[i][j]; flags1[i][j] = -flags1[i][j]; } int64_t * flags0_ = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t)); int64_t * flags1_ = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t)); for(size_t j = 0; j < db_nitems; ++j) { leaves0[i][j] = output0[i][j][0]; leaves1[i][j] = output1[i][j][0]; flags0_[j] = (flags0[i][j] * shareconversionP0.PM) + (flags0[i][j] * shareconversionP0.PM_recv) + (flags0[i][j] * shareconversionP0.rb); flags0_[j] += output0[i][j][1]; flags1_[j] = (flags1[i][j] * shareconversionP1.PM) + (flags1[i][j] * shareconversionP1.PM_recv) + (flags1[i][j] * shareconversionP1.rb); flags1_[j] += output1[i][j][1]; flags0_[j] -= (flags0[i][j] * shareconversionP0.FCWshare_reconstruction); flags1_[j] -= (flags1[i][j] * shareconversionP1.FCWshare_reconstruction); flags0[i][j] = flags0_[j]; flags1[i][j] = flags1_[j]; if(flags0[i][j] == 128 || flags0[i][j] == -128) flags0[i][j] = 0; leafbits0[i][j] = flags0[i][j]; if(flags1[i][j] == 128 || flags1[i][j] == -128) flags1[i][j] = 0; leafbits1[i][j] = flags1[i][j]; } std::free(flags0_); std::free(flags1_); #ifdef VERBOSE for(size_t j = 0; j < db_nitems; ++j) { int64_t leafbit_reconstruction = leafbits0[i][j] + leafbits1[i][j]; if(leafbit_reconstruction != 0) std::cout << std::dec << j << ":-> " << leafbit_reconstruction << std::endl; } #endif } void P2_xor_to_additive(tcp::socket& s0, tcp::socket& s1, size_t socket_no) { uint64_t x0, x1, y0, y1, gamma0, gamma1, alpha; arc4random_buf(&x0, sizeof(uint64_t)); arc4random_buf(&x1, sizeof(uint64_t)); arc4random_buf(&y0, sizeof(uint64_t)); arc4random_buf(&y1, sizeof(uint64_t)); arc4random_buf(&alpha, sizeof(uint64_t)); gamma0 = (x0 * y1) - alpha; gamma1 = alpha; #ifdef VERBOSE std::cout << "x0 = " << x0 << std::endl; std::cout << "x1 = " << x1 << std::endl; std::cout << "gamma0 = " << gamma0 << std::endl; #endif boost::asio::write(s0, boost::asio::buffer(&x0, sizeof(x0))); boost::asio::write(s0, boost::asio::buffer(&gamma0, sizeof(gamma0))); boost::asio::write(s1, boost::asio::buffer(&y1, sizeof(y1))); boost::asio::write(s1, boost::asio::buffer(&gamma1, sizeof(gamma1))); } void xor_to_additive(bool party, uint8_t * target_share_read, tcp::socket& sb, tcp::socket& s2, const size_t height, int64_t& R_share) { const size_t logn = height; int64_t b[64], b_blinded[64], b_recv[64]; for(size_t j = 0; j < logn; ++j) { b[j] = target_share_read[logn-j - 1]; #ifdef DEBUG uint8_t target_bit_rec; boost::asio::write(sb, boost::asio::buffer(&target_share_read[j], sizeof(uint8_t))); boost::asio::read(sb, boost::asio::buffer(&target_bit_rec, sizeof(uint8_t))); if(target_bit_rec != target_share_read[j]) std::cout << "non-zero XOR index = " << j << std::endl; #endif } #ifdef DEBUG uint64_t b_ = binary_to_decimal(b, logn);; std::cout << "b_ = " << b_ << std::endl; #endif int64_t * c_mul = (int64_t*) malloc(logn * sizeof(int64_t)); int64_t * d = (int64_t*) malloc(logn * sizeof(int64_t)); int64_t BLIND, Gamma; boost::asio::read(s2, boost::asio::buffer(&BLIND, sizeof(int64_t))); boost::asio::read(s2, boost::asio::buffer(&Gamma, sizeof(int64_t))); for(size_t j = 0; j < logn; ++j) { b_blinded[j] = b[j] + BLIND; } boost::asio::write(sb, boost::asio::buffer(&b_blinded, logn * sizeof(b_blinded[0]))); boost::asio::read (sb, boost::asio::buffer(&b_recv, logn * sizeof(b_recv[0]))); #ifdef DEBUG std::cout << "BLIND = " << BLIND << std::endl; std::cout << "Gamma = " << Gamma << std::endl; #endif if(!party) { for(size_t j = 0; j < logn; ++j) { c_mul[j] = (b[j] * b_recv[j]) + Gamma; d[j] = (b[j] - 2 * c_mul[j]); R_share += (1ULL << j) * d[j]; } } if(party) { for(size_t j = 0; j < logn; ++j) { c_mul[j] = -(BLIND * b_recv[j]) + Gamma; d[j] = (b[j] - 2 * c_mul[j]); R_share += (1ULL << j) * d[j]; } } #ifdef DEBUG for(size_t j = 0; j < 1; ++j) { std::cout << "b = " << b[j] << std::endl; int64_t mul_Rec = 0; boost::asio::write(sb, boost::asio::buffer(&c_mul[j], sizeof(c_mul[j]))); boost::asio::read(sb, boost::asio::buffer(&mul_Rec, sizeof(mul_Rec))); std::cout << "c_mul = " << c_mul[j] << std::endl; mul_Rec = mul_Rec + c_mul[j]; std::cout << "mul_Rec = " << mul_Rec << std::endl; } int64_t * b_reconstruction_ = (int64_t*) malloc(logn * sizeof(int64_t)); int64_t * d_reconstruction_ = (int64_t*) malloc(logn * sizeof(int64_t)); int64_t * d_recv = (int64_t*) malloc(logn * sizeof(int64_t)); for(size_t j = 0; j < logn; ++j) { boost::asio::write(sb, boost::asio::buffer(&d[j], sizeof(d[j]))); boost::asio::read(sb, boost::asio::buffer(&d_recv[j], sizeof(d_recv[j]))); } boost::asio::write(sb, boost::asio::buffer(&b, logn * sizeof(b[0]))); boost::asio::read (sb, boost::asio::buffer(&b_recv, logn * sizeof(b_recv[0]))); for(size_t j = 0; j < logn; ++j) { int64_t d_reconstruction = d[j] + d_recv[j]; d_reconstruction_[j] = d_reconstruction; int64_t b_reconstruction = b[j] ^ b_recv[j]; b_reconstruction_[j] = b_reconstruction; assert(d_reconstruction == b_reconstruction); } int64_t b_value = binary_to_decimal(b_reconstruction_, logn); std::cout << "b_value = " << b_value << std::endl; std::cout << "logn = " << logn << std::endl; std::cout << "R_share = " << R_share << std::endl; #endif R_share = binary_to_decimal(d, logn); #ifdef DEBUG std::cout << "R_share = " << R_share << std::endl; int64_t R_share_reconstruction; boost::asio::write(sb, boost::asio::buffer(&R_share, sizeof(R_share))); boost::asio::read(sb, boost::asio::buffer(&R_share_reconstruction, sizeof(R_share_reconstruction))); R_share_reconstruction = R_share_reconstruction + R_share; std::cout << "R_share_reconstruction = " << R_share_reconstruction << std::endl; std::cout << "b_value = " << b_value << std::endl; std::cout << "d_recons = " << binary_to_decimal(d_reconstruction_, logn) << std::endl; std::free(b_reconstruction_); std::free(d_reconstruction_); std::free(d_recv); #endif std::free(c_mul); std::free(d); } void convert_shares(size_t i, __m128i ** output, int8_t ** flags, size_t n_threads, size_t db_nitems, __m128i * final_correction_word, int64_t ** leaves, int64_t ** leafbits, std::vector& socketsb, std::vector& sockets2, bool party) { #ifdef DEBUG std::cout << "share conversion " << i << "-th, thread started runing" << std::endl << std::endl; #endif for(size_t j = 0; j < db_nitems; ++j) { if(party) { output[i][j] = -output[i][j]; flags[i][j] = -flags[i][j]; } } int64_t pm = 0; int64_t rb; arc4random_buf(&rb, sizeof(rb)); for(size_t j = 0; j < db_nitems; ++j) { if(party) { if(flags[i][j] != 0) pm -= 1; } if(!party) { if(flags[i][j] != 0) pm += 1; } } int64_t FCWshare = du_attalah_Pb(final_correction_word[i][1], pm, sockets2[i], socketsb[i]); //FCWshare+=rb; //int64_t FCWshare_reconstruction; shareconversion_Pb share_b, share_b_recv; // boost::asio::write(socketsb[i], boost::asio::buffer(&FCWshare, sizeof(FCWshare))); // boost::asio::read(socketsb[i], boost::asio::buffer(&FCWshare_reconstruction, sizeof(FCWshare_reconstruction))); // FCWshare_reconstruction = FCWshare_reconstruction + FCWshare; // int64_t PM = pm + rb; share_b.PM = pm + rb;// PM; share_b.FCW = FCWshare+=rb; boost::asio::write(socketsb[i], boost::asio::buffer(&share_b, sizeof(share_b))); boost::asio::read(socketsb[i], boost::asio::buffer(&share_b_recv, sizeof(share_b_recv))); share_b_recv.FCW = share_b_recv.FCW + share_b.FCW; // int64_t PM_recv; // boost::asio::write(socketsb[i], boost::asio::buffer(&PM, sizeof(PM))); //Sending the blinded shares of +/- 1 // boost::asio::read(socketsb[i], boost::asio::buffer(&PM_recv, sizeof(PM_recv))); //Receiving the blinded shares of +/- 1 int64_t * flags_ = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t)); shareconversion P2_shareconversion; P2_shareconversion.PM = pm; P2_shareconversion.PM_recv = share_b_recv.PM;// PM_recv; P2_shareconversion.rb = rb; P2_shareconversion.FCWshare_reconstruction = share_b_recv.FCW; //FCWshare_reconstruction; boost::asio::write(sockets2[i], boost::asio::buffer(&P2_shareconversion, sizeof(shareconversion))); for(size_t j = 0; j < db_nitems; ++j) { leaves[i][j] = output[i][j][0]; flags_[j] = (flags[i][j] * pm) + (flags[i][j] * share_b_recv.PM) + (flags[i][j] * rb); flags_[j] += output[i][j][1]; flags_[j] -= (flags[i][j] * P2_shareconversion.FCWshare_reconstruction); #ifdef DEBUG int64_t flags_rec; boost::asio::write(socketsb[i], boost::asio::buffer(&flags_[j], sizeof(flags_[j]))); boost::asio::read(socketsb[i], boost::asio::buffer(&flags_rec, sizeof(flags_rec))); flags_rec = flags_rec + flags_[j]; if(flags_rec != 0) { std::cout << j << " ---> Flag Reconstruction = " << flags_rec << std::endl; } #endif flags[i][j] = flags_[j]; if(flags[i][j] == 128 || flags[i][j] == -128) flags[i][j] = 0; leafbits[i][j] = flags[i][j]; #ifdef DEBUG int8_t flags_rec2; boost::asio::write(socketsb[i], boost::asio::buffer(&flags[i][j], sizeof(flags[i][j]))); boost::asio::read(socketsb[i], boost::asio::buffer(&flags_rec2, sizeof(flags_rec2))); flags_rec2 = flags_rec2 + flags[i][j]; int64_t flags_rec3; boost::asio::write(socketsb[i], boost::asio::buffer(&flags_[j], sizeof(flags_[j]))); boost::asio::read(socketsb[i], boost::asio::buffer(&flags_rec3, sizeof(flags_rec3))); flags_rec3 = flags_rec3 + flags_[j]; if(flags_rec2 != 0) { std::cout << j << " ---> Flag Reconstruction = " << (int) flags_rec2 << "----->>>>> " << flags_rec3 << std::endl; if(flags_rec2 != 1) std::cout << (int) flags[i][j] << "-> " << flags_[j] << std::endl; } #endif } free(flags_); // write_evalfull_outs_into_a_file(party, i, db_nitems, flags[i], leaves[i], final_correction_word[i]); }