Browse Source

compute cw function merged with compute cw bits

avadapal 1 year ago
parent
commit
ba83344a40

+ 1 - 6
preprocessing/block.h

@@ -147,12 +147,7 @@ inline block<__mX> & operator<<=(block<__mX> & block, const long & shift)
 template<typename __mX>
 inline block<__mX> operator>>(const block<__mX> & block, const long & shift);
 
-// template<>
-// inline block<__m256i> operator>>(const block<__m256i> & block, const long & shift)
-// {
-// 	return _mm256_or_si256(_mm256_srli_epi64(block, shift), _mm256_blend_epi32(_mm256_setzero_si256(), _mm256_permute4x64_epi64(_mm256_slli_epi64(block, 64 - shift), _MM_SHUFFLE(0,3,2,1)), _MM_SHUFFLE(0,3,3,3)));
-// }
-
+ 
 template<>
 inline block<__m256i> operator>>(const block<__m256i> & block, const long & shift)
 {

+ 138 - 88
preprocessing/dpfgen.h

@@ -1,14 +1,14 @@
-	struct dpfP2
-	{
-		__m128i root;
-		__m128i CW[26];
-		uint8_t cwt_L[26];
-		uint8_t cwt_R[26];
+struct dpfP2
+{
+	__m128i root;
+	__m128i CW[26];
+	uint8_t cwt_L[26];
+	uint8_t cwt_R[26];
 	};
 
 void generate_random_targets(uint8_t ** target_share_read, size_t n_threads, bool party, size_t expo)
 {
-    for(size_t i = 0; i < n_threads; i++)
+ for(size_t i = 0; i < n_threads; i++)
 	{
 		target_share_read[i] = new uint8_t[64];
 	}
@@ -39,34 +39,41 @@ struct BlindsCW
 	uint8_t blinded_bit;
 };
 
+ struct reconstructioncw
+ {
+  __m128i cw;
+  uint8_t cwbit[2];
+ };
 
-void compute_CW_bits(tcp::socket& sout,   __m128i L, __m128i R, uint8_t bit, uint8_t &cwt_L, uint8_t &cwt_R)
-{
+// void compute_CW_bits(tcp::socket& sout,   __m128i L, __m128i R, uint8_t bit, uint8_t &cwt_L, uint8_t &cwt_R)
+// {
 
-	uint8_t advice_L = get_lsb(L) ^ bit;
-	uint8_t advice_R = get_lsb(R) ^ bit;
+// 	uint8_t advice_L = get_lsb(L) ^ bit;
+// 	uint8_t advice_R = get_lsb(R) ^ bit;
 
-	uint8_t advice[2];
-	uint8_t cwts[2];	
+// 	uint8_t advice[2];
+// 	uint8_t cwts[2];	
 
-	advice[0] = advice_L;
-	advice[1] = advice_R;
+// 	advice[0] = advice_L;
+// 	advice[1] = advice_R;
 		
-	boost::asio::write(sout, boost::asio::buffer(&advice, sizeof(advice)));
-	boost::asio::read(sout, boost::asio::buffer(&cwts, sizeof(cwts)));
+// 	boost::asio::write(sout, boost::asio::buffer(&advice, sizeof(advice)));
+// 	boost::asio::read(sout, boost::asio::buffer(&cwts, sizeof(cwts)));
 		
-	cwt_L = cwts[0];
-	cwt_R = cwts[1];
+// 	cwt_L = cwts[0];
+// 	cwt_R = cwts[1];
 
-	cwt_L = cwt_L ^ advice_L ^ 1;
-	cwt_R = cwt_R ^ advice_R;	
-}
+// 	cwt_L = cwt_L ^ advice_L ^ 1;
+// 	cwt_R = cwt_R ^ advice_R;	
+// }
 
-void compute_CW(tcp::socket& sout, tcp::socket& sin, __m128i L, __m128i R, uint8_t bit, __m128i & CW)
+void compute_CW(tcp::socket& sout, tcp::socket& sin, __m128i L, __m128i R, uint8_t bit, __m128i & CW, uint8_t &cwt_L, uint8_t &cwt_R)
 {
 
 	cw_construction computecw;
 
+ 
+ reconstructioncw cwsent, cwrecv;
 	//Communication from P2 
 	read(sin, boost::asio::buffer(&computecw, sizeof(computecw)));
 
@@ -75,18 +82,18 @@ void compute_CW(tcp::socket& sout, tcp::socket& sin, __m128i L, __m128i R, uint8
 	uint8_t bit_b   = computecw.bit_b;
 	
 	#ifdef DEBUG 
-		__m128i rand_b2, gamma_b2;
-		uint8_t bit_b2;
-	 	read(sin, boost::asio::buffer(&rand_b2, sizeof(rand_b)));
-	    read(sin, boost::asio::buffer(&gamma_b2, sizeof(gamma_b)));
-	    read(sin, boost::asio::buffer(&bit_b2, sizeof(bit_b)));
-
-	    assert(rand_b2[0] == rand_b[0]);
-	    assert(rand_b2[1] == rand_b[1]);
-		assert(gamma_b2[0] == gamma_b[0]);
-	    assert(gamma_b2[1] == gamma_b[1]);
-		assert(bit_b2 == bit_b);
- 	#endif
+	__m128i rand_b2, gamma_b2;
+	uint8_t bit_b2;
+	read(sin, boost::asio::buffer(&rand_b2, sizeof(rand_b)));
+	read(sin, boost::asio::buffer(&gamma_b2, sizeof(gamma_b)));
+	read(sin, boost::asio::buffer(&bit_b2, sizeof(bit_b)));
+
+	assert(rand_b2[0] == rand_b[0]);
+	assert(rand_b2[1] == rand_b[1]);
+	assert(gamma_b2[0] == gamma_b[0]);
+	assert(gamma_b2[1] == gamma_b[1]);
+	assert(bit_b2 == bit_b);
+ #endif
 
 	uint8_t blinded_bit, blinded_bit_read;
 	blinded_bit = bit ^ bit_b;
@@ -99,58 +106,102 @@ void compute_CW(tcp::socket& sout, tcp::socket& sin, __m128i L, __m128i R, uint8
 	blinds_sent.blinded_message = blinded_L;
 
 	//exchange blinded shares for OSWAP.
- 	boost::asio::write(sout, boost::asio::buffer(&blinds_sent, sizeof(BlindsCW)));
+ boost::asio::write(sout, boost::asio::buffer(&blinds_sent, sizeof(BlindsCW)));
 	boost::asio::read(sout, boost::asio::buffer(&blinds_recv, sizeof(BlindsCW)));
 	
 	blinded_bit_read = blinds_recv.blinded_bit;
 	blinded_L_read   =  blinds_recv.blinded_message;
 
-	__m128i out_ = R ^ gamma_b;//_mm_setzero_si128;
+	//__m128i out_ = R ^ gamma_b;//_mm_setzero_si128;
+ cwsent.cw = R ^ gamma_b;
 
 	if(bit)
 	{
-	 out_ ^= (L ^ R ^ blinded_L_read);
+	  cwsent.cw ^= (L ^ R ^ blinded_L_read);
 	}
 	if(blinded_bit_read)
 	{
-	 out_ ^= rand_b;
+	  cwsent.cw ^= rand_b;
 	}
 
+
+
+	// uint8_t advice_L = get_lsb(L) ^ bit;
+	// uint8_t advice_R = get_lsb(R) ^ bit;
+
+	// uint8_t advice[2];
+	// // uint8_t cwts[2];	
+
+	// advice[0] = advice_L;
+	// advice[1] = advice_R;
+
+
 	//__m128i out_reconstruction; 
-	boost::asio::write(sout, boost::asio::buffer(&out_, sizeof(out_)));
-	boost::asio::read(sout, boost::asio::buffer(&CW, sizeof(CW)));
-	CW = out_ ^ CW;
+	
+
+ //cwsent.cw = out_; 
+ cwsent.cwbit[0] = get_lsb(L) ^ bit;//advice[0];
+ cwsent.cwbit[1] = get_lsb(R) ^ bit;//advice[1];
+
+ boost::asio::write(sout, boost::asio::buffer(&cwsent, sizeof(cwsent)));
+	boost::asio::read(sout, boost::asio::buffer(&cwrecv, sizeof(cwrecv)));
+
+ // boost::asio::write(sout, boost::asio::buffer(&out_, sizeof(out_)));
+	// boost::asio::read(sout, boost::asio::buffer(&CW, sizeof(CW)));
+	// CW = out_ ^ CW;
+
+ cwrecv.cw ^= cwsent.cw;
+ cwrecv.cwbit[0] ^= (cwsent.cwbit[0] ^ 1);
+ cwrecv.cwbit[1] ^= (cwsent.cwbit[1]);
+ 
+ // assert(CW[0] == cwrecv.cw[0]);
+	// assert(CW[1] == cwrecv.cw[1]);
 
-	// The following asserts the correctness of ComputeCW
+	// boost::asio::write(sout, boost::asio::buffer(&advice, sizeof(advice)));
+	// boost::asio::read(sout, boost::asio::buffer(&cwts, sizeof(cwts)));
+		
+	// cwt_L = cwts[0];
+	// cwt_R = cwts[1];
+
+	// cwt_L = cwt_L ^ advice_L ^ 1;
+	// cwt_R = cwt_R ^ advice_R;	
+	
+ // assert(cwt_L == cwrecv.cwbit[0]);
+ // assert(cwt_R == cwrecv.cwbit[1]);
+ cwt_L = cwrecv.cwbit[0];
+ cwt_R = cwrecv.cwbit[1];
+ CW = cwrecv.cw;
+
+ // The following asserts the correctness of ComputeCW
 	#ifdef DEBUG
-		uint8_t bit_reconstruction; 
-		boost::asio::write(sout, boost::asio::buffer(&bit, sizeof(bit)));
-		boost::asio::read(sout, boost::asio::buffer(&bit_reconstruction, sizeof(bit_reconstruction)));
-		bit_reconstruction = bit ^ bit_reconstruction;
+	uint8_t bit_reconstruction; 
+	boost::asio::write(sout, boost::asio::buffer(&bit, sizeof(bit)));
+	boost::asio::read(sout, boost::asio::buffer(&bit_reconstruction, sizeof(bit_reconstruction)));
+	bit_reconstruction = bit ^ bit_reconstruction;
 
-		__m128i L_reconstruction; 
-		boost::asio::write(sout, boost::asio::buffer(&L, sizeof(L)));
-		boost::asio::read(sout, boost::asio::buffer(&L_reconstruction, sizeof(L_reconstruction)));
-		L_reconstruction = L ^ L_reconstruction;
+	__m128i L_reconstruction; 
+	boost::asio::write(sout, boost::asio::buffer(&L, sizeof(L)));
+	boost::asio::read(sout, boost::asio::buffer(&L_reconstruction, sizeof(L_reconstruction)));
+	L_reconstruction = L ^ L_reconstruction;
 
-		__m128i R_reconstruction; 
-		boost::asio::write(sout, boost::asio::buffer(&R, sizeof(R)));
-		boost::asio::read(sout, boost::asio::buffer(&R_reconstruction, sizeof(R_reconstruction)));
-		R_reconstruction = R ^ R_reconstruction;
+	__m128i R_reconstruction; 
+	boost::asio::write(sout, boost::asio::buffer(&R, sizeof(R)));
+	boost::asio::read(sout, boost::asio::buffer(&R_reconstruction, sizeof(R_reconstruction)));
+	R_reconstruction = R ^ R_reconstruction;
 
-	 	__m128i CW_debug;
+	__m128i CW_debug;
 
-		if(bit_reconstruction != 0)
-		{
-		  CW_debug = L_reconstruction;
-		}
-		else
-		{
-		  CW_debug = R_reconstruction;
-		}
+	if(bit_reconstruction != 0)
+	{
+	 CW_debug = L_reconstruction;
+	}
+	else
+	{
+	 CW_debug = R_reconstruction;
+	}
 
-		assert(CW_debug[0] == CW[0]);
-		assert(CW_debug[1] == CW[1]);
+	assert(CW_debug[0] == CW[0]);
+	assert(CW_debug[1] == CW[1]);
 	#endif
 }
 
@@ -181,22 +232,23 @@ static inline void traverse(const prgkey_t & prgkey, const node_t & seed,	node_t
  * @param party Party
  * @param socket_no 
  */
-inline void create_dpfs (size_t db_nitems,
-						 const AES_KEY& prgkey,  uint8_t target_share[64], std::vector<socket_t>& socketsPb, std::vector<socket_t>& socketsP2,
-						 const size_t from, const size_t to, __m128i * output, int8_t * _t, __m128i& final_correction_word, dpfP2 * dpf_instance   ,bool party, size_t socket_no, size_t ind = 0)
+inline void create_dpfs ( size_t db_nitems, const AES_KEY& prgkey,  uint8_t target_share[64], std::vector<socket_t>& socketsPb, std::vector<socket_t>& socketsP2,
+						                    const size_t from, const size_t to, __m128i * output, int8_t * _t, __m128i& final_correction_word, dpfP2 * dpf_instance, 
+                          bool party, size_t socket_no, size_t ind = 0)
 {
-    const size_t bits_per_leaf = std::is_same<leaf_t, bool>::value ? 1 : sizeof(leaf_t) * CHAR_BIT;
+ 
+ const size_t bits_per_leaf = std::is_same<leaf_t, bool>::value ? 1 : sizeof(leaf_t) * CHAR_BIT;
 	const bool  is_packed = (sizeof(leaf_t) < sizeof(node_t));
 	const size_t nodes_per_leaf = is_packed ? 1 : std::ceil(static_cast<double>(bits_per_leaf) / (sizeof(node_t) * CHAR_BIT));
 
-    const size_t depth = std::ceil(std::log2(db_nitems));
+ const size_t depth = std::ceil(std::log2(db_nitems));
 	const size_t nbits = std::ceil(std::log2(db_nitems));
 	const size_t nodes_in_interval = db_nitems-1; 
 	
-	__m128i root;
-	
+	__m128i root;	
+
 	arc4random_buf(&root, sizeof(root));
-    
+
  root =	set_lsb(root, party);
 
 	const size_t from_node = std::floor(static_cast<double>(from) / nodes_per_leaf);
@@ -223,13 +275,12 @@ inline void create_dpfs (size_t db_nitems,
 		}
 	#endif
 
- 
- 
 	dpf_instance[ind].root = root;
-	for (size_t layer = 0; layer < depth; ++layer)
+	
+ for (size_t layer = 0; layer < depth; ++layer)
 	{
 			#ifdef VERBOSE	
-				printf("layer = %zu\n", layer);
+			printf("layer = %zu\n", layer);
 			#endif
 
 			curlayer = 1-curlayer;
@@ -259,13 +310,14 @@ inline void create_dpfs (size_t db_nitems,
 				}
 			}
 
+  	uint8_t cwt_L, cwt_R;
 			// Computes the correction word using OSWAP
-			compute_CW(socketsPb[socket_no], socketsP2[socket_no], L,  R, target_share[layer], CW[layer]);
+			compute_CW(socketsPb[socket_no], socketsP2[socket_no], L,  R, target_share[layer], CW[layer], cwt_L,  cwt_R);
 
-			uint8_t cwt_L, cwt_R;
+		
 
 			// Computes the correction word bits
-			compute_CW_bits(socketsPb[socket_no+1], L,  R, target_share[layer], cwt_L,  cwt_R);
+			//compute_CW_bits(socketsPb[socket_no+1], L,  R, target_share[layer], cwt_L,  cwt_R);
 			
 			#ifdef DEBUG
 				if(ind == 0) 
@@ -310,14 +362,14 @@ inline void create_dpfs (size_t db_nitems,
  		boost::asio::read(socketsPb[socket_no + 3], boost::asio::buffer(&final_correction_word, sizeof(final_correction_word)));
 	#endif
 
- 	final_correction_word = Gamma;  
+ final_correction_word = Gamma;  
 
 } // create_dpfs
 
 
 
 inline void evaluate_dpfs( size_t db_nitems,  dpfP2 dpfinstance,  const AES_KEY& prgkey,   const size_t from, const size_t to, 
-							__m128i * output, int8_t * _t,  bool party,  size_t ind)
+							                   __m128i * output, int8_t * _t,  bool party,  size_t ind)
 {
 
  const size_t bits_per_leaf = std::is_same<leaf_t, bool>::value ? 1 : sizeof(leaf_t) * CHAR_BIT;
@@ -336,7 +388,7 @@ inline void evaluate_dpfs( size_t db_nitems,  dpfP2 dpfinstance,  const AES_KEY&
 	
 	for(size_t j = 0; j < depth; ++j)
 	{
-		CW[j] 	  = dpfinstance.CW[j];
+		CW[j] 	   = dpfinstance.CW[j];
 		cwt_L[j]  = dpfinstance.cwt_L[j];
 		cwt_R[j]  = dpfinstance.cwt_R[j];
 	}
@@ -350,11 +402,9 @@ inline void evaluate_dpfs( size_t db_nitems,  dpfP2 dpfinstance,  const AES_KEY&
 	    reinterpret_cast<__m128i *>(output) + nodes_in_interval * (nodes_per_leaf - 1),
 	    s[0] + nodes_in_interval / 2
 	};
-	
-	int8_t * t[2] = { _t, _t + nodes_in_interval / 2};
 
+	int8_t * t[2] = { _t, _t + nodes_in_interval / 2};
 	int curlayer = depth % 2;
-
 	s[curlayer][0] = root;
 	t[curlayer][0] = get_lsb(root, 0b01);
 	
@@ -379,7 +429,7 @@ inline void evaluate_dpfs( size_t db_nitems,  dpfP2 dpfinstance,  const AES_KEY&
 			size_t nodes_in_prev_layer = std::ceil(static_cast<double>(nodes_in_interval) / (1ULL << (depth-layer)));
 			size_t nodes_in_cur_layer = std::ceil(static_cast<double>(nodes_in_interval) / (1ULL << (depth-layer-1)));
 			
- 			for (i = nextbit, j = nextbit; j < nodes_in_prev_layer-1; ++j, i+=2)
+ 		for (i = nextbit, j = nextbit; j < nodes_in_prev_layer-1; ++j, i+=2)
 			{
 				traverse(prgkey, s[1-curlayer][j], &s[curlayer][i]);
 			}

+ 12 - 6
preprocessing/filesio.h

@@ -1,3 +1,14 @@
+/**
+ * @brief The function writes the flag vectors into /preprocflags/ directory in duoram-online
+ * 
+ * @param party 
+ * @param i 
+ * @param db_nitems 
+ * @param flags 
+ * @param outs_ 
+ * @param final_correction_word 
+ */
+
 void write_evalfull_outs_into_a_file(bool party, size_t i, size_t db_nitems,  int8_t * flags, int64_t * outs_, __m128i  final_correction_word)
 {
  if(!party) 
@@ -187,9 +198,6 @@ void write_evalfull_outs_into_a_file(bool party, size_t i, size_t db_nitems,  in
  
 }
 
-
-
-
 void P2_write_evalfull_outs_into_a_file(bool party, size_t i, size_t db_nitems,  int8_t * flags, int64_t * outs_)
 {
  if(!party) 
@@ -347,9 +355,7 @@ void P2_write_evalfull_outs_into_a_file(bool party, size_t i, size_t db_nitems,
     written = write(w6, outs_, db_nitems * sizeof(int64_t));
     if(written<0)  perror("Write error");   
 	   close(w6);
-  }
-
- 
+  } 
 }
 
 

+ 92 - 103
preprocessing/p2preprocessing.cpp

@@ -56,67 +56,61 @@ void mpc_gen(const size_t depth, AES_KEY& prgkey, const size_t db_nitems, const
   for(size_t j = 0; j < depth; ++j)
   {
    
-      __m128i rand0, rand1, gamma0, gamma1;
-
-      arc4random_buf(&rand0, sizeof(__m128i));
-      arc4random_buf(&rand1, sizeof(__m128i));
-      uint8_t bit0, bit1; 
-      bit0 = rand();
-      bit0 = bit0 % 2;
-      bit1 = rand();
-      bit1 = bit1 %2;
-
-      gamma0 = (bit1 == 1) ? rand0 : _mm_setzero_si128();
-      gamma1 = (bit0 == 1) ? rand1 : _mm_setzero_si128();
-
-      struct cw_construction
-      {
-        __m128i rand_b, gamma_b;
-        uint8_t bit_b;
-      };
-      
-      cw_construction computecw0, computecw1;
-      
-      computecw0.rand_b   = rand0;
-      computecw0.gamma_b  = gamma0;
-      computecw0.bit_b    = bit0;
-
-      computecw1.rand_b   = rand1;
-      computecw1.gamma_b  = gamma1;
-      computecw1.bit_b    = bit1;
-      
-      boost::asio::write(sockets0[socket_no], boost::asio::buffer(&computecw0, sizeof(computecw0)));
-      boost::asio::write(sockets1[socket_no], boost::asio::buffer(&computecw1, sizeof(computecw1)));
-
-
-      #ifdef DEBUG
-        boost::asio::write(sockets0[socket_no], boost::asio::buffer(&rand0, sizeof(rand0)));
-        boost::asio::write(sockets0[socket_no], boost::asio::buffer(&gamma0, sizeof(gamma0)));
-        boost::asio::write(sockets0[socket_no], boost::asio::buffer(&bit0, sizeof(bit0)));
-
-        boost::asio::write(sockets1[socket_no], boost::asio::buffer(&rand1, sizeof(rand1)));
-        boost::asio::write(sockets1[socket_no], boost::asio::buffer(&gamma1, sizeof(gamma1)));
-        boost::asio::write(sockets1[socket_no], boost::asio::buffer(&bit1, sizeof(bit1)));
-      #endif
+    __m128i rand0, rand1, gamma0, gamma1;
 
+    arc4random_buf(&rand0, sizeof(__m128i));
+    arc4random_buf(&rand1, sizeof(__m128i));
+    uint8_t bit0, bit1; 
+    bit0 = rand();
+    bit0 = bit0 % 2;
+    bit1 = rand();
+    bit1 = bit1 %2;
+
+    gamma0 = (bit1 == 1) ? rand0 : _mm_setzero_si128();
+    gamma1 = (bit0 == 1) ? rand1 : _mm_setzero_si128();
+
+    struct cw_construction
+    {
+      __m128i rand_b, gamma_b;
+      uint8_t bit_b;
+    };
+    
+    cw_construction computecw0, computecw1;
+    
+    computecw0.rand_b   = rand0;
+    computecw0.gamma_b  = gamma0;
+    computecw0.bit_b    = bit0;
+
+    computecw1.rand_b   = rand1;
+    computecw1.gamma_b  = gamma1;
+    computecw1.bit_b    = bit1;
+    
+    boost::asio::write(sockets0[socket_no], boost::asio::buffer(&computecw0, sizeof(computecw0)));
+    boost::asio::write(sockets1[socket_no], boost::asio::buffer(&computecw1, sizeof(computecw1)));
+
+    #ifdef DEBUG
+     boost::asio::write(sockets0[socket_no], boost::asio::buffer(&rand0, sizeof(rand0)));
+     boost::asio::write(sockets0[socket_no], boost::asio::buffer(&gamma0, sizeof(gamma0)));
+     boost::asio::write(sockets0[socket_no], boost::asio::buffer(&bit0, sizeof(bit0)));
+
+     boost::asio::write(sockets1[socket_no], boost::asio::buffer(&rand1, sizeof(rand1)));
+     boost::asio::write(sockets1[socket_no], boost::asio::buffer(&gamma1, sizeof(gamma1)));
+     boost::asio::write(sockets1[socket_no], boost::asio::buffer(&bit1, sizeof(bit1)));
+    #endif
   } 
   
   boost::asio::read(sockets0[socket_no+1], boost::asio::buffer(&dpf_instance0[ind], sizeof(dpfP2)));
-  boost::asio::read(sockets1[socket_no+1], boost::asio::buffer(&dpf_instance1[ind], sizeof(dpfP2)));
- 
+  boost::asio::read(sockets1[socket_no+1], boost::asio::buffer(&dpf_instance1[ind], sizeof(dpfP2))); 
 
   evaluate_dpfs(db_nitems,  dpf_instance0[ind],   prgkey,  0, db_nitems-1,	output0[ind],  flags0[ind],  false,  ind);
   evaluate_dpfs(db_nitems,  dpf_instance1[ind],   prgkey,  0, db_nitems-1, output1[ind],  flags1[ind],  true ,  ind);
 
-
-  // P2_write_evalfull_outs_into_a_file(false, 0, db_nitems,  flags0[0], 	output0[0]);
-  // P2_write_evalfull_outs_into_a_file(true,  0, db_nitems,  flags1[0], 	output1[0]);
- #ifdef DEBUG
-    for(size_t j = 0; j < db_nitems; ++j)
-    {
-      std::cout << j << "-> "  << (int) flags0[0][j] << " <-> " << (int) flags1[0][j] << std::endl;
-      std::cout << j << "-> " << output0[0][j][0] << " <-> " << output1[0][j][0] << std::endl << std::endl;
-    }
+  #ifdef DEBUG
+   for(size_t j = 0; j < db_nitems; ++j)
+   {
+     std::cout << j << "-> "  << (int) flags0[0][j] << " <-> " << (int) flags1[0][j] << std::endl;
+     std::cout << j << "-> " << output0[0][j][0] << " <-> " << output1[0][j][0] << std::endl << std::endl;
+   }
   #endif
 }
  
@@ -126,34 +120,34 @@ void accept_conncections_from_Pb(boost::asio::io_context&io_context, std::vector
   tcp::socket s2(acceptor2_.accept());
   sockets0[j] = std::move(s2);
 }
+
 int main(int argc, char* argv[])
 { 
   
-  AES_KEY aeskey;
-  boost::asio::io_context io_context;
-  tcp::resolver resolver(io_context);
-   
-  const std::string host0 = (argc < 2) ? "127.0.0.1" : argv[1];
-  const std::string host1 = (argc < 3) ? "127.0.0.1" : argv[2];
+ AES_KEY aeskey;
+ boost::asio::io_context io_context;
+ tcp::resolver resolver(io_context);
    
-  const size_t n_threads = atoi(argv[3]);
-  const size_t number_of_sockets = 5 * n_threads;
-  const size_t db_nitems = 1ULL << atoi(argv[4]);
-  const size_t depth = std::ceil(std::log2(db_nitems));
+ const std::string host0 = (argc < 2) ? "127.0.0.1" : argv[1];
+ const std::string host1 = (argc < 3) ? "127.0.0.1" : argv[2];  
+ const size_t n_threads = atoi(argv[3]);
+ const size_t number_of_sockets = 5 * n_threads;
+ const size_t db_nitems = 1ULL << atoi(argv[4]);
+ const size_t depth = std::ceil(std::log2(db_nitems));
     
-  std::vector<int> ports2_0;
-  for(size_t j = 0; j < number_of_sockets; ++j) 
-  {
-    int port = 20000;
-    ports2_0.push_back(port + j);
-  }
+ std::vector<int> ports2_0;
+ for(size_t j = 0; j < number_of_sockets; ++j) 
+ {
+   int port = 20000;
+   ports2_0.push_back(port + j);
+ }
 
-  std::vector<int> ports2_1;
-  for(size_t j = 0; j < number_of_sockets; ++j) 
-  {
-    int port = 40000;
-    ports2_1.push_back(port + j);
-  }
+ std::vector<int> ports2_1;
+ for(size_t j = 0; j < number_of_sockets; ++j) 
+ {
+   int port = 40000;
+   ports2_1.push_back(port + j);
+ }
 
 
  std::vector<socket_t> sockets0;
@@ -168,7 +162,6 @@ int main(int argc, char* argv[])
    boost::asio::post(pool2, std::bind(accept_conncections_from_Pb,  std::ref(io_context), std::ref(sockets1), ports2_1[j],  j));
  }
 
-  
  for(size_t j = 0; j < number_of_sockets; ++j)
  {
   boost::asio::post(pool2, std::bind(accept_conncections_from_Pb,  std::ref(io_context), std::ref(sockets0), ports2_0[j],  j));
@@ -186,8 +179,6 @@ int main(int argc, char* argv[])
 		output0[j] = (__m128i *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(__m128i));
 		flags0[j]  = (int8_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(uint8_t));
 	}
-
-
   
 	__m128i ** output1 = (__m128i ** ) malloc(sizeof(__m128i *) * n_threads);
 	int8_t  ** flags1  = (int8_t ** ) malloc(sizeof(uint8_t *) * n_threads);
@@ -204,7 +195,7 @@ int main(int argc, char* argv[])
  for(size_t j = 0; j < n_threads; ++j)
  {
    boost::asio::post(pool, std::bind(mpc_gen,  std::ref(depth), std::ref(aeskey), db_nitems, n_threads,  std::ref(sockets0), std::ref(sockets1), 
-                                       output0, flags0,  output1, flags1,  std::ref(dpf_instance0), std::ref(dpf_instance1), j, 5 * j));    
+                                     output0, flags0,  output1, flags1,  std::ref(dpf_instance0), std::ref(dpf_instance1), j, 5 * j));    
  }
 
   pool.join();
@@ -212,18 +203,18 @@ int main(int argc, char* argv[])
 
   boost::asio::thread_pool pool3(n_threads); 
   
-  int64_t ** leaves0    = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
-	 int64_t ** leafbits0  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
-  int64_t ** leaves1    = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
-	 int64_t ** leafbits1  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
-	
-  for(size_t j = 0; j < n_threads; ++j)
-	 {
-		 leaves0[j]    = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-		 leafbits0[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-   leaves1[j]    = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-		 leafbits1[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-	 }
+ int64_t ** leaves0    = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
+ int64_t ** leafbits0  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
+ int64_t ** leaves1    = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
+ int64_t ** leafbits1  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
+
+ for(size_t j = 0; j < n_threads; ++j)
+ {
+  leaves0[j]    = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+  leafbits0[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+  leaves1[j]    = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+  leafbits1[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+ }
 
  /* The function convert_sharesP2 appears in share-conversion.h */
   for(size_t j = 0; j < n_threads; ++j)
@@ -237,29 +228,27 @@ int main(int argc, char* argv[])
   boost::asio::thread_pool pool4(n_threads); 
   for(size_t j = 0; j < n_threads; ++j)
   {
-     boost::asio::post(pool4,  std::bind(P2_xor_to_additive, std::ref(sockets0[j]), std::ref(sockets1[j]), j));
+   boost::asio::post(pool4,  std::bind(P2_xor_to_additive, std::ref(sockets0[j]), std::ref(sockets1[j]), j));
   }
   pool4.join();
 
-
-
   for(size_t i = 0; i < n_threads; ++i)
   {
-      P2_write_evalfull_outs_into_a_file(false, i, db_nitems,  flags0[i], 	leaves0[i]);
-      P2_write_evalfull_outs_into_a_file(true,  i, db_nitems,  flags1[i], 	leaves1[i]);
+   P2_write_evalfull_outs_into_a_file(false, i, db_nitems,  flags0[i], 	leaves0[i]);
+   P2_write_evalfull_outs_into_a_file(true,  i, db_nitems,  flags1[i], 	leaves1[i]);
   }
 
   #ifdef DEBUG
-    for(size_t ind = 0; ind < n_threads; ++ind)
+   for(size_t ind = 0; ind < n_threads; ++ind)
+   {
+    for(size_t j = 0; j < db_nitems; ++j)
     {
-     for(size_t j = 0; j < db_nitems; ++j)
+     if(flags0[ind][j] + flags1[ind][j] != 0)
      {
-      if(flags0[ind][j] + flags1[ind][j] != 0)
-      {
-       std::cout << j << "-> "  << (int) (flags0[ind][j] + flags1[ind][j]) << " = " << (int) (flags0[ind][j])  << " + " << (int) (flags1[ind][j]) << std::endl;
-       std::cout << j << "-> " << output0[ind][j][0] << " <-> " << output1[ind][j][0] << std::endl << std::endl;
-      }
+      std::cout << j << "-> "  << (int) (flags0[ind][j] + flags1[ind][j]) << " = " << (int) (flags0[ind][j])  << " + " << (int) (flags1[ind][j]) << std::endl;
+      std::cout << j << "-> " << output0[ind][j][0] << " <-> " << output1[ind][j][0] << std::endl << std::endl;
      }
+    }
    }
   #endif
   

+ 84 - 90
preprocessing/preprocessing.cpp

@@ -23,8 +23,7 @@
 #include <fstream>
 #include <future>
 #include <mutex>
-
-typedef unsigned char byte_t;
+ 
 typedef __m128i node_t;
 constexpr size_t leaf_size = 1;
 typedef __m128i leaf_type;
@@ -38,7 +37,6 @@ typedef std::array<leaf_type, leaf_size> leaf_t;
 using boost::asio::ip::tcp;
 using socket_t = boost::asio::ip::tcp::socket;
  
-
 using namespace dpf;  // The namespace is found in bitutils.h
 
 #include "mpc.h"
@@ -47,47 +45,46 @@ using namespace dpf;  // The namespace is found in bitutils.h
 #include "share-conversion.h"
 
 int main(int argc, char * argv[])
-{ 	
-    
-    boost::asio::io_context io_context;
-    std::string addr = "127.0.0.1";
-    
-    const std::string host1 = (argc < 2) ? "127.0.0.1" : argv[1];
-    const std::string host2 = (argc < 3) ? "127.0.0.1" : argv[2];
-    const size_t n_threads = atoi(argv[3]);
-    const size_t expo = atoi(argv[4]);
-    const size_t number_of_sockets = 5 * n_threads;
-
-    std::vector<socket_t> socketsPb, socketsP2;
-    std::vector<int> ports, ports2_1, ports2_0;
+{     
+   boost::asio::io_context io_context;
+   std::string addr = "127.0.0.1";  
+   const std::string host1 = (argc < 2) ? "127.0.0.1" : argv[1];
+   const std::string host2 = (argc < 3) ? "127.0.0.1" : argv[2];
+   const size_t n_threads = atoi(argv[3]);
+   const size_t expo = atoi(argv[4]);
+   const size_t number_of_sockets = 5 * n_threads;
+
+   std::vector<socket_t> socketsPb, socketsP2;
+   std::vector<int> ports, ports2_1, ports2_0;
  
-      bool party;
+   bool party;
 
     /* The function make_connections appears in network.h */
-    make_connections(party, host1, host2,  io_context, socketsPb, socketsP2, ports,  ports2_1, ports2_0, number_of_sockets);
+   make_connections(party, host1, host2,  io_context, socketsPb, socketsP2, ports,  ports2_1, ports2_0, number_of_sockets);
  
-    const size_t db_nitems = 1ULL << atoi(argv[4]);
+   const size_t db_nitems = 1ULL << atoi(argv[4]);
 
-     auto start = std::chrono::steady_clock::now(); 
+   auto start = std::chrono::steady_clock::now(); 
     
-    uint8_t ** target_share_read = new uint8_t*[n_threads];
-
-    generate_random_targets(target_share_read,  n_threads, party, expo);
+   uint8_t ** target_share_read = new uint8_t*[n_threads];
+
+   generate_random_targets(target_share_read,  n_threads, party, expo);
+   
+   AES_KEY aeskey;
+   
+   __m128i * final_correction_word = (__m128i *) std::aligned_alloc(sizeof(__m256i), n_threads * sizeof(__m128i));
+   __m128i ** output = (__m128i ** ) malloc(sizeof(__m128i *) * n_threads);
     
-    AES_KEY aeskey;
-
-    __m128i * final_correction_word = (__m128i *) std::aligned_alloc(sizeof(__m256i), n_threads * sizeof(__m128i));
-    __m128i ** output = (__m128i ** ) malloc(sizeof(__m128i *) * n_threads);
-    int8_t  ** flags  = (int8_t ** ) malloc(sizeof(uint8_t *) * n_threads);
+   int8_t  ** flags  = (int8_t ** ) malloc(sizeof(uint8_t *) * n_threads);
      
-    for(size_t j = 0; j < n_threads; ++j)
-    {
-        output[j] = (__m128i *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(__m128i));
-        flags[j]  = (int8_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(uint8_t));
-    }
+   for(size_t j = 0; j < n_threads; ++j)
+   {
+     output[j] = (__m128i *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(__m128i));
+     flags[j]  = (int8_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(uint8_t));
+   }
      
-    boost::asio::thread_pool pool(n_threads);
-    boost::asio::thread_pool pool_share_conversion(n_threads);
+   boost::asio::thread_pool pool(n_threads);
+   boost::asio::thread_pool pool_share_conversion(n_threads);
     
 
     
@@ -96,75 +93,72 @@ int main(int argc, char * argv[])
     // the leaves are stored in output
     // the final correctionword is stored in final_correction_word
 
-    dpfP2 * dpf_instance = (dpfP2 * ) malloc (sizeof(dpfP2) * n_threads);
+   dpfP2 * dpf_instance = (dpfP2 * ) malloc (sizeof(dpfP2) * n_threads);
 
-    /* The function create_dpfs appears in dpf-gen.h*/
+   /* The function create_dpfs appears in dpf-gen.h*/
+   for(size_t j = 0; j < n_threads; ++j)
+   {
+     boost::asio::post(pool,  std::bind(create_dpfs,  db_nitems,	std::ref(aeskey),  target_share_read[j],  std::ref(socketsPb), std::ref(socketsP2), 0, db_nitems-1, 
+                                         output[j],  flags[j], std::ref(final_correction_word[j]), std::ref(dpf_instance),  party, 5 * j, j));	 	  
+   }
+   
+   pool.join();  
+
+   #ifdef DEBUG
     for(size_t j = 0; j < n_threads; ++j)
     {
-        boost::asio::post(pool,  std::bind(create_dpfs,  db_nitems,	std::ref(aeskey),  target_share_read[j],  std::ref(socketsPb), std::ref(socketsP2), 0, db_nitems-1, 
-                          output[j],  flags[j], std::ref(final_correction_word[j]), std::ref(dpf_instance),  party, 5 * j, j));	 	  
-    }
-    pool.join();  
-
-    #ifdef DEBUG
-        for(size_t j = 0; j < n_threads; ++j)
-        {
-   std::cout << "n_threads = " << j << std::endl;
-            for(size_t i = 0; i < db_nitems; ++i)
-            {
-                int8_t flags_reconstruction;
-                boost::asio::write(socketsPb[0], boost::asio::buffer(&flags[j][i], sizeof(flags[j][i])));
-                boost::asio::read(socketsPb[0], boost::asio::buffer(&flags_reconstruction, sizeof(flags_reconstruction)));
-                flags_reconstruction -= flags[j][i];
-                if(flags_reconstruction != 0) std::cout << i << " (flag) ---> " << (int) flags_reconstruction << std::endl;
-
-                int64_t output_reconstruction;
-                boost::asio::write(socketsPb[0], boost::asio::buffer(&output[j][i][0], sizeof(output[j][i][0])));
-                boost::asio::read(socketsPb[0], boost::asio::buffer(&output_reconstruction, sizeof(output_reconstruction)));
-                output_reconstruction -= output[j][i][0];
-                if(output_reconstruction != 0) std::cout << i << " (output) ---> " << output_reconstruction << std::endl;
-            }
-
-            int64_t final_correction_word_reconstruction = 0;
-            boost::asio::write(socketsPb[0], boost::asio::buffer(&final_correction_word[j][0], sizeof(final_correction_word[j][0])));
-            boost::asio::read(socketsPb[0], boost::asio::buffer(&final_correction_word_reconstruction, sizeof(final_correction_word_reconstruction)));
-            final_correction_word_reconstruction = final_correction_word_reconstruction + final_correction_word[j][0];
-            std::cout << "final_correction_word_reconstruction = " << final_correction_word_reconstruction << std::endl << std::endl;
+      std::cout << "n_threads = " << j << std::endl;
+      for(size_t i = 0; i < db_nitems; ++i)
+       {
+        int8_t flags_reconstruction;
+          boost::asio::write(socketsPb[0], boost::asio::buffer(&flags[j][i], sizeof(flags[j][i])));
+          boost::asio::read(socketsPb[0], boost::asio::buffer(&flags_reconstruction, sizeof(flags_reconstruction)));
+          flags_reconstruction -= flags[j][i];
+          if(flags_reconstruction != 0) std::cout << i << " (flag) ---> " << (int) flags_reconstruction << std::endl;
+
+          int64_t output_reconstruction;
+          boost::asio::write(socketsPb[0], boost::asio::buffer(&output[j][i][0], sizeof(output[j][i][0])));
+          boost::asio::read(socketsPb[0], boost::asio::buffer(&output_reconstruction, sizeof(output_reconstruction)));
+          output_reconstruction -= output[j][i][0];
+          if(output_reconstruction != 0) std::cout << i << " (output) ---> " << output_reconstruction << std::endl;
         }
+
+        int64_t final_correction_word_reconstruction = 0;
+        boost::asio::write(socketsPb[0], boost::asio::buffer(&final_correction_word[j][0], sizeof(final_correction_word[j][0])));
+        boost::asio::read(socketsPb[0], boost::asio::buffer(&final_correction_word_reconstruction, sizeof(final_correction_word_reconstruction)));
+        final_correction_word_reconstruction = final_correction_word_reconstruction + final_correction_word[j][0];
+        std::cout << "final_correction_word_reconstruction = " << final_correction_word_reconstruction << std::endl << std::endl;
+     }
     #endif
  
-
-
-
     /* 
-        leaves is a additive shares of the outputs (leaves of the DPF)
-        leafbits is the additive shares of flag bits of the DPFs
+     leaves is a additive shares of the outputs (leaves of the DPF)
+     leafbits is the additive shares of flag bits of the DPFs
     */
-    int64_t ** leaves = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
-    int64_t ** leafbits  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
-    for(size_t j = 0; j < n_threads; ++j)
-    {
-        leaves[j] = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-        leafbits[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
-    }
+   int64_t ** leaves = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads);
+   int64_t ** leafbits  = (int64_t ** ) malloc(sizeof(int64_t *) * n_threads); 
+   for(size_t j = 0; j < n_threads; ++j)
+   {
+    leaves[j] = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+    leafbits[j]  = (int64_t *)std::aligned_alloc(sizeof(node_t), db_nitems * sizeof(int64_t));
+   }
 
 
 
     /* The function convert_shares appears in share-conversion.h */
-    for(size_t j = 0; j < n_threads; ++j)
-    {
-        boost::asio::post(pool_share_conversion,  std::bind(convert_shares, j, output, flags, n_threads, db_nitems, final_correction_word, 	leaves, leafbits, 
-                                                        std::ref(socketsPb), std::ref(socketsP2),  party ));	 	
-    }
+   for(size_t j = 0; j < n_threads; ++j)
+   {
+     boost::asio::post(pool_share_conversion,  std::bind(convert_shares, j, output, flags, n_threads, db_nitems, final_correction_word, 	leaves, leafbits, 
+                                                          std::ref(socketsPb), std::ref(socketsP2), party));	 	
+   }
     
     pool_share_conversion.join();
 
-
     boost::asio::thread_pool pool_xor_to_additive(n_threads); 
 
     for(size_t j = 0; j < n_threads; ++j)
     {
-         boost::asio::post(pool_xor_to_additive, std::bind(xor_to_additive, party, target_share_read[j], std::ref(socketsPb[j]), std::ref(socketsP2[j])));
+     boost::asio::post(pool_xor_to_additive, std::bind(xor_to_additive, party, target_share_read[j], std::ref(socketsPb[j]), std::ref(socketsP2[j])));
     }
 
     pool_xor_to_additive.join();
@@ -173,10 +167,10 @@ int main(int argc, char * argv[])
     std::chrono::duration<double> elapsed_seconds = end-start;
     std::cout << "time to generate and evaluate " << n_threads << " dpfs of size 2^" << atoi(argv[4]) << " is: " << elapsed_seconds.count() << "s\n";
 
- for(size_t i = 0; i < n_threads; ++i)
- {
-   write_evalfull_outs_into_a_file(party, i, db_nitems, flags[i],  leaves[i], final_correction_word[i]); 
- }
+    for(size_t i = 0; i < n_threads; ++i)
+    {
+     write_evalfull_outs_into_a_file(party, i, db_nitems, flags[i],  leaves[i], final_correction_word[i]); 
+    }
 
-return 0;
+    return 0;
 }

+ 168 - 186
preprocessing/share-conversion.h

@@ -1,12 +1,10 @@
 uint64_t binary_to_decimal(std::array<uint64_t, 64> inp)
 {
-
 	uint64_t output = 0;		
 	for(size_t j = 0; j < 64; ++j)
 	{
 		output += (1ULL << j) * inp[j];
 	}
-
 	return output;
 }
 
@@ -15,6 +13,10 @@ 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
  * 
@@ -22,76 +24,71 @@ struct shareconversion
  * @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<socket_t>& sockets0, std::vector<socket_t>& sockets1, size_t i, size_t socket_no = 0)
+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<socket_t>& sockets0, std::vector<socket_t>& 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]; 	 
-	}
+   du_attalah_P2(sockets0, sockets1, socket_no); 
 
- 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)
-	{
+   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));
  
-		  leaves0[i][j]  = output0[i][j][0];
-    leaves1[i][j]  = output1[i][j][0];
+   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]; 
+     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]; 
+     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]; 
-	 }
+   
+     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]; 
+   }
 
     #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;   
-        }
+     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
-
-    
-      // P2_write_evalfull_outs_into_a_file(false, i, db_nitems,  flags0[i], 	leaves0[i]);
-      // P2_write_evalfull_outs_into_a_file(true,  i, db_nitems,  flags1[i], 	leaves1[i]);
 } 
 
-void  P2_xor_to_additive(tcp::socket& s0, tcp::socket& s1, size_t socket_no)
+void P2_xor_to_additive(tcp::socket& s0, tcp::socket& s1, size_t socket_no)
 {
-   uint64_t x0, x1, y0, y1, gamma0, gamma1, alpha;
+  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));
+  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;
+  gamma0 = (x0 * y1) - alpha;
+  gamma1 =  alpha;
 
   #ifdef VERBOSE
     std::cout << "x0 = " << x0 << std::endl;
@@ -100,43 +97,35 @@ void  P2_xor_to_additive(tcp::socket& s0, tcp::socket& s1, size_t socket_no)
   #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)));
-
 }
 
 int64_t xor_to_additive(bool party, uint8_t * target_share_read, tcp::socket& sb, tcp::socket& s2)
 {
     const size_t logn = 64;
-
-    
     std::array<uint64_t, logn> b, b_blinded, b_recv;
- 
     for(size_t j = 0; j < logn; ++j)
     {
-        b[j] = target_share_read[j];
-
-        #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
+      b[j] = target_share_read[j];
+
+      #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);
-        std::cout << "b_ = " << b_ << std::endl;
+     uint64_t b_ = binary_to_decimal(b);
+     std::cout << "b_ = " << b_ << std::endl;
     #endif
     
     std::array<uint64_t, logn> c_mul;
     std::array<uint64_t, logn> d;
-   
-
-    
+  
     uint64_t BLIND, Gamma;
     boost::asio::read(s2, boost::asio::buffer(&BLIND, sizeof(uint64_t)));
     boost::asio::read(s2, boost::asio::buffer(&Gamma, sizeof(uint64_t)));
@@ -144,98 +133,94 @@ int64_t xor_to_additive(bool party, uint8_t * target_share_read, tcp::socket& sb
 
     for(size_t j = 0; j < logn; ++j)
     {
-        b_blinded[j] = b[j] + BLIND;
+     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;
+    std::cout << "BLIND = " << BLIND << std::endl;
+    std::cout << "Gamma = " << Gamma << std::endl;
     #endif
     
     uint64_t R_share = 0;
     
     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];
-        }
+     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];
-        }
+      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;
-            uint64_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;
-        }
- 
-        std::array<uint64_t, logn> b_reconstruction_;
-        std::array<uint64_t, logn> d_reconstruction_;
-            std::array<uint64_t, logn> d_recv;
-        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)
-        {
-            uint64_t d_reconstruction = d[j] + d_recv[j];
-            d_reconstruction_[j] = d_reconstruction;
-            uint64_t b_reconstruction = b[j] ^ b_recv[j];
-            b_reconstruction_[j] = b_reconstruction;
-            assert(d_reconstruction == b_reconstruction);
-        }
-        
-        uint64_t b_value =	binary_to_decimal(b_reconstruction_);
-        std::cout << "b_value = " << b_value << std::endl;
-        std::cout << "logn = " << logn << std::endl;
- 
-        std::cout << "R_share = " << R_share << std::endl;
-        R_share = binary_to_decimal(d);
-        std::cout << "R_share = " << R_share << std::endl;
-        uint64_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_)<< std::endl;
+     for(size_t j = 0; j < 1; ++j)
+     {
+       std::cout << "b = " << b[j] << std::endl;
+       uint64_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;
+     }
+
+     std::array<uint64_t, logn> b_reconstruction_;
+     std::array<uint64_t, logn> d_reconstruction_;
+     std::array<uint64_t, logn> d_recv;
+     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)
+     {
+      uint64_t d_reconstruction = d[j] + d_recv[j];
+      d_reconstruction_[j] = d_reconstruction;
+      uint64_t b_reconstruction = b[j] ^ b_recv[j];
+      b_reconstruction_[j] = b_reconstruction;
+      assert(d_reconstruction == b_reconstruction);
+     }
+      
+     uint64_t b_value =	binary_to_decimal(b_reconstruction_);
+     std::cout << "b_value = " << b_value << std::endl;
+     std::cout << "logn = " << logn << std::endl;
+
+     std::cout << "R_share = " << R_share << std::endl;
+     R_share = binary_to_decimal(d);
+     std::cout << "R_share = " << R_share << std::endl;
+     uint64_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_)<< std::endl;
     #endif
 
-    return R_share;
+   return R_share;
 }
 
 
 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<socket_t>& socketsb, std::vector<socket_t>& sockets2, bool party)
+					               int64_t ** leaves, int64_t ** leafbits, std::vector<socket_t>& socketsb, std::vector<socket_t>& sockets2, bool party)
 {
 	
 	#ifdef DEBUG
@@ -246,7 +231,7 @@ void convert_shares(size_t i, __m128i ** output, int8_t ** flags, size_t n_threa
 	{
 		if(party)
 		{
-			output[i][j] = -output[i][j];
+			output[i][j] =  -output[i][j];
 			flags[i][j]  =  -flags[i][j]; 
 		}
 	}
@@ -267,53 +252,52 @@ void convert_shares(size_t i, __m128i ** output, int8_t ** flags, size_t n_threa
 		 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;
 
- FCWshare+=rb;
-	int64_t FCWshare_reconstruction;
- 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;
 
-	int64_t PM = pm + rb;
-	int64_t PM_recv;
+ 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)));
-	boost::asio::read(socketsb[i], boost::asio::buffer(&PM_recv, sizeof(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 = PM_recv;
+ P2_shareconversion.PM_recv = share_b_recv.PM;// PM_recv;
  P2_shareconversion.rb = rb;
- P2_shareconversion.FCWshare_reconstruction = FCWshare_reconstruction;
+ 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] * PM_recv) + (flags[i][j] * rb); 
- 
+		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);		
 
-		if(!party)
-		{	
-		 flags_[j] -= (flags[i][j] * FCWshare_reconstruction);		
-		}
-		if(party)
-		{ 
-		 flags_[j] -= (flags[i][j] * FCWshare_reconstruction);
-		}
 	
 		#ifdef DEBUG
 		int64_t flags_rec;
-		boost::asio::write(sb, boost::asio::buffer(&flags_[j], sizeof(flags_[j])));
-		boost::asio::read(sb, boost::asio::buffer(&flags_rec, sizeof(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)
@@ -322,30 +306,28 @@ void convert_shares(size_t i, __m128i ** output, int8_t ** flags, size_t n_threa
 		}
 		#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;
-            }
+    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
 	}
-
 	 // write_evalfull_outs_into_a_file(party, i, db_nitems, flags[i],  leaves[i], final_correction_word[i]); 
 }