github.com/jiajun1992/watercarver@v0.0.0-20191031150618-dfc2b17c0c4a/StadiumForWaterCarver/src/Prover_toom.cpp (about)

     1  /*
     2   * Prover_toom.cpp
     3   *
     4   *  Created on: 24.04.2011
     5   *      Author: stephaniebayer
     6   */
     7  
     8  #include "Prover_toom.h"
     9  #include <vector>
    10  #include "Cipher_elg.h"
    11  #include "G_q.h"
    12  #include "Mod_p.h"
    13  #include "ElGammal.h"
    14  #include "multi_expo.h"
    15  #include "func_pro.h"
    16  #include <fstream>
    17  #include <time.h>
    18  #include <sstream>
    19  #include <pthread.h>
    20  #include "FakeZZ.h"
    21  #include <chrono>
    22  NTL_CLIENT
    23  
    24  //extern G_q G;
    25  extern G_q H;
    26  //extern ElGammal El;
    27  extern long mu;
    28  extern long mu_h;
    29  
    30  //OpenMP config
    31  extern bool parallel;
    32  extern int num_threads;
    33  
    34  //extern long m_r;
    35  
    36  using namespace std::chrono;
    37  
    38  Prover_toom::Prover_toom(long &m_r_) : m_r(m_r_)
    39  {
    40  	// TODO remove containing stack -- this is never called
    41  }
    42  
    43  Prover_toom::Prover_toom(long &mr, vector<vector<Cipher_elg> *> *Cin,
    44  						 vector<vector<ZZ> *> *Rin, vector<vector<vector<long> *> *> *piin,
    45  						 vector<long> num, int m_in, int n_in, ElGammal *elgammal) : m_r(mr),
    46  																					 elgammal_(elgammal), ped_(n_in)
    47  {
    48  
    49  	// set the dimensions of the row and columns according to the user input
    50  	m = m_in;			  //number of rows
    51  	n = n_in;			  //number of columns
    52  	C = Cin;			  //sets the reencrypted chipertexts to the input
    53  	R = Rin;			  //sets the random elements to the input
    54  	pi = piin;			  // sets the permutation to the input
    55  	omega_mulex = num[3]; //windowsize for sliding-window technique
    56  	omega_sw = num[4];	//windowsize for multi-expo technique
    57  	omega_LL = num[7];	//windowsize for multi-expo technique
    58  
    59  	ped_.set_omega(omega_mulex, omega_LL, omega_sw);
    60  	//Creates the matrices A
    61  	A = new vector<vector<ZZ> *>(m);
    62  	func_pro::set_A(A, pi, m, n);
    63  
    64  	//Allocate the storage needed for the vectors
    65  	chal_x6 = new vector<ZZ>(2 * m);	 //x6, x6^2, ... challenges from round 6
    66  	chal_y6 = new vector<ZZ>(n);		 //y6, y6^2, ... challenges form round 6
    67  	chal_x8 = new vector<ZZ>(2 * m + 1); //x8, x8^2, ... challenges from round 8
    68  
    69  	//Allocate the storage needed for the vectors
    70  	c_A = new vector<Mod_p>(m + 1); //commitments to the rows in A
    71  	r_A = new vector<ZZ>(m + 1);	//random elements used for the commitments
    72  
    73  	D = new vector<vector<ZZ> *>(m + 1);   //vector containing in the first row random values and in all others y*A(ij) + B(ij)-z
    74  	D_h = new vector<vector<ZZ> *>(m);	 //Vector of the Hadamare products of the rows in D
    75  	D_s = new vector<vector<ZZ> *>(m + 1); //Shifted rows of D_h
    76  	d = new vector<ZZ>(n);				   //containing random elements to proof product of D_hm
    77  	Delta = new vector<ZZ>(n);			   //containing random elements to proof product of D_hm
    78  	d_h = new vector<ZZ>(n);			   // vector containing the last row of D-h
    79  
    80  	r_D_h = new vector<ZZ>(m);						 //random elements for commitments to D_h
    81  	c_D_h = new vector<Mod_p>(m + 2);				 //commitments to the rows in D_h
    82  	C_small = new vector<vector<Cipher_elg> *>(m_r); //matrix of reduced ciphertexts
    83  
    84  	B = new vector<vector<ZZ> *>(m);				   //matrix of permuted exponents, exponents are x2^i, i=1, ..N
    85  	basis_B = new vector<vector<vector<long> *> *>(m); //basis for the multi-expo, containing the Bij
    86  	B_small = new vector<vector<ZZ> *>(m_r);		   //matrix of reduced exponents
    87  	B_0 = new vector<ZZ>(n);						   //vector containing random exponents
    88  	basis_B0 = new vector<vector<long> *>(n);		   //basis for multi-expo, containing  the B0j
    89  	r_B = new vector<ZZ>(m);						   //random elements used to commit to B
    90  	r_B_small = new vector<ZZ>(m_r);				   //random elements for commitments to B_small
    91  	c_B = new vector<Mod_p>(m);						   //vector of commitments to rows in T
    92  
    93  	C_c = new vector<Cipher_elg>(mu_h); //Ciphertexts to prove correctness of reduction
    94  	c_a_c = new vector<Mod_p>(mu_h);	//vector containing the commitments to value used for the reencryption of E_c
    95  	a_c = new vector<ZZ>(mu_h);			//vector containing the values used for reecnrcyption
    96  	r_c = new vector<ZZ>(mu_h);			//random elements used to commit to a_c
    97  	rho_c = new vector<ZZ>(mu_h);		//random elements used in the reencryption
    98  
    99  	a = new vector<ZZ>(2 * mu);			//elements used for reencryption in round 5
   100  	r_a = new vector<ZZ>(2 * mu);		//random elements to commit to elements in a
   101  	c_a = new vector<Mod_p>(2 * mu);	//commitments to elements a
   102  	E = new vector<Cipher_elg>(2 * mu); //vector of the products of the diogonals of Y^T generated in round 9
   103  	rho_a = new vector<ZZ>(2 * mu);		//contains random elements used for the reencryption in 9
   104  
   105  	Dl = new vector<ZZ>(2 * m + 1);		 //bilinear_map(Y_pi, U, chal_t)
   106  	r_Dl = new vector<ZZ>(2 * m + 1);	//random elements to commit to the C_ls
   107  	c_Dl = new vector<Mod_p>(2 * m + 1); //commitments to the C_ls
   108  
   109  	d_bar = new vector<ZZ>(n);	 // chal_x8*D_h(m-1) +d
   110  	Delta_bar = new vector<ZZ>(n); //chal_x8*d_h+Delta
   111  	D_h_bar = new vector<ZZ>(n);   //sum over the rows in D_h
   112  
   113  	B_bar = new vector<ZZ>(n);   // sum over the rows in B multiplied by chal^i
   114  	A_bar = new vector<ZZ>(n);   //sum over the rows in A times the challenges
   115  	D_s_bar = new vector<ZZ>(n); // sum over the rows in D_s times the challenges
   116  }
   117  
   118  //Destructor deletes all pointers and frees the storage
   119  Prover_toom::~Prover_toom()
   120  {
   121  	delete chal_x6;
   122  	delete chal_y6;
   123  	delete chal_x8;
   124  	delete c_A;
   125  	delete r_A;
   126  
   127  	Functions::delete_vector(D);
   128  	Functions::delete_vector(D_h);
   129  	Functions::delete_vector(D_s);
   130  	delete d;
   131  	delete Delta;
   132  	delete d_h;
   133  
   134  	delete r_D_h;
   135  	delete c_D_h;
   136  	if (B != NULL)
   137  		Functions::delete_vector(B);
   138  	if (basis_B != NULL)
   139  		Functions::delete_vector(basis_B);
   140  	delete B_0;
   141  	if (basis_B0 != NULL)
   142  		Functions::delete_vector(basis_B0);
   143  	delete r_B;
   144  	delete r_B_small;
   145  	delete c_B;
   146  	delete a;
   147  	delete r_a;
   148  	delete c_a;
   149  	delete rho_a;
   150  
   151  	delete Dl;
   152  	delete r_Dl;
   153  	delete c_Dl;
   154  
   155  	delete D_h_bar;
   156  	delete d_bar;
   157  	delete Delta_bar;
   158  	delete B_bar;
   159  	delete A_bar;
   160  	delete D_s_bar;
   161  
   162  	delete C_c;
   163  	delete c_a_c; //vector containing the commitments to value used for the reencryption of E_low_up
   164  	delete a_c;   //vector containing the exponents
   165  	delete r_c;
   166  	delete rho_c;
   167  	delete E;
   168  }
   169  
   170  string Prover_toom::get_public_vector()
   171  {
   172  	return ped_.get_public_vector();
   173  }
   174  
   175  //round_1 picks random elements and commits to the rows of A
   176  string Prover_toom::round_1()
   177  {
   178  	long i;
   179  	//calculates commitments to rows of A
   180  	Functions::commit_op(A, r_A, c_A, ped_);
   181  
   182  	//ofstream ost(name.c_str());
   183  	stringstream out_stream;
   184  	for (i = 0; i < m; i++)
   185  	{
   186  		out_stream << c_A->at(i) << " ";
   187  	}
   188  	return out_stream.str();
   189  }
   190  
   191  //round_3, permuted the exponents in s,  picks random elements and commits to values
   192  string Prover_toom::round_3(const string &input)
   193  {
   194  	long i;
   195  	ZZ x2;
   196  	vector<vector<ZZ> *> *chal_x2 = new vector<vector<ZZ> *>(m);
   197  
   198  	stringstream ist(input);
   199  	ist >> x2;
   200  
   201  	//creates a matrix with entries x2,..., x2^N
   202  	func_pro::set_x2(chal_x2, x2, m, n);
   203  
   204  	//permutes chal_x2 according pi to create B
   205  	func_pro::set_B_op(B, basis_B, chal_x2, pi, omega_mulex);
   206  
   207  	//commits to the rows in B
   208  	Functions::commit_op(B, r_B, c_B, ped_);
   209  
   210  	//write data in the file name
   211  	stringstream out_stream;
   212  	for (i = 0; i < m; i++)
   213  	{
   214  		out_stream << c_B->at(i) << " ";
   215  	}
   216  
   217  	Functions::delete_vector(chal_x2);
   218  	return out_stream.str();
   219  }
   220  
   221  //round_5a calculates D and the commitments to the vectors chal_z, D_h
   222  void Prover_toom::round_5a()
   223  {
   224  	long i;
   225  	vector<ZZ> *r = new vector<ZZ>(n);
   226  	vector<ZZ> *v_z = new vector<ZZ>(n); //row containing the challenge alpha
   227  	ZZ ord = H.get_ord();
   228  	time_t rawtime;
   229  	time(&rawtime);
   230  	//calculate for each value in the first m rows in D: y* A_ij + A_ij -z
   231  	func_pro::set_D(D, A, B, chal_z4, chal_y4);
   232  	//Set the matrix D_h as the Hadamard product of the rows in D
   233  	func_pro::set_D_h(D_h, D);
   234  	const ZZ one = to_ZZ(1);
   235  	{
   236  //PARALLELIZE
   237  #pragma omp parallel for num_threads(num_threads) if (parallel)
   238  		for (i = 0; i < n; i++)
   239  		{
   240  			v_z->at(i) = chal_z4; //fills the vector alpha with the challenge alpha
   241  			NegateMod(r->at(i), one, ord);
   242  		}
   243  	}
   244  	//Sets the additional row in D to contain -1
   245  	D->at(m) = r;
   246  	//random number to commit to last row in A
   247  	r_A->at(m) = 0;
   248  
   249  	//calculate commitment to alpha
   250  	Functions::commit_op(v_z, r_z, c_z, ped_);
   251  	//calculate commitment to the rows in D_h
   252  	Functions::commit_op(D_h, r_D_h, c_D_h, ped_);
   253  	delete v_z;
   254  }
   255  
   256  void Prover_toom::round_5b()
   257  {
   258  	func_pro::set_Rb(B, R, R_b);
   259  	commit_ac();
   260  	calculate_Cc(C, basis_B);
   261  }
   262  
   263  string Prover_toom::round_5(const string &input)
   264  {
   265  	long i;
   266  
   267  	//reads the values out of the file
   268  	stringstream ist(input);
   269  	ist >> chal_z4;
   270  	ist >> chal_y4;
   271  	round_5a();
   272  	int i1 = 0;
   273  	while (i1 < 10000000)
   274  	{
   275  		i1++;
   276  	}
   277  	round_5b();
   278  
   279  	stringstream ost;
   280  	//writes the commitments in the file
   281  	ost << c_z << "\n";
   282  	for (i = 0; i < m; i++)
   283  	{
   284  		ost << c_D_h->at(i) << " ";
   285  	}
   286  	ost << "\n";
   287  
   288  	for (i = 0; i < mu_h; i++)
   289  	{
   290  		ost << C_c->at(i) << " ";
   291  	}
   292  	ost << "\n";
   293  	for (i = 0; i < mu_h; i++)
   294  	{
   295  		ost << c_a_c->at(i) << " ";
   296  	}
   297  	return ost.str();
   298  }
   299  
   300  string Prover_toom::round_5_red(const string &input)
   301  {
   302  	long i;
   303  
   304  	stringstream ist(input);
   305  	ist >> chal_z4;
   306  	ist >> chal_y4;
   307  
   308  	func_pro::set_Rb(B, R, R_b);
   309  	commit_ac();
   310  	calculate_Cc(C, basis_B);
   311  
   312  	//cout << "round_5_red before loop1" << endl;
   313  	stringstream ost;
   314  	for (i = 0; i < mu_h; i++)
   315  	{
   316  		ost << C_c->at(i) << " ";
   317  	}
   318  	ost << "\n";
   319  	//cout << "round_5_red after loop1" << endl;
   320  	for (i = 0; i < mu_h; i++)
   321  	{
   322  		ost << c_a_c->at(i) << " ";
   323  	}
   324  	//cout << "round_5_red after loop2" << endl;
   325  	return ost.str();
   326  }
   327  
   328  string Prover_toom::round_5_red1(const string &input)
   329  {
   330  	long i;
   331  	stringstream ist(input);
   332  	x = new vector<ZZ>(mu_h);
   333  
   334  	//reads challenges x
   335  	for (i = 0; i < mu_h; i++)
   336  	{
   337  		ist >> x->at(i);
   338  	}
   339  
   340  	//Call of round 5a
   341  	//cout << "round_5b before" << endl;
   342  	round_5a();
   343  	//cout << "round_5b after" << endl;
   344  	//calculate F_c and Z_c for the first reduction
   345  	calculate_ac_bar(x);
   346  	calculate_r_ac_bar(x);
   347  
   348  	//reduction from m rows to m_r rows
   349  	auto tstart = high_resolution_clock::now();
   350  	reduce_C(C, B, r_B, x, 4 * m_r);
   351  	auto tstop = high_resolution_clock::now();
   352  	time_di = time_di + duration<double>(tstop - tstart).count();
   353  
   354  	set_Rb1(x);
   355  	commit_ac();
   356  	calculate_Cc(C_small, B_small);
   357  
   358  	delete x;
   359  
   360  	stringstream ost;
   361  	//writes the commitments in the file
   362  	ost << c_z << "\n";
   363  	for (i = 0; i < m; i++)
   364  	{
   365  		ost << c_D_h->at(i) << " ";
   366  	}
   367  	ost << "\n";
   368  	for (i = 0; i < mu_h; i++)
   369  	{
   370  		ost << C_c->at(i) << " ";
   371  	}
   372  	ost << "\n";
   373  	for (i = 0; i < mu_h; i++)
   374  	{
   375  		ost << c_a_c->at(i) << " ";
   376  	}
   377  	ost << a_c_bar << endl;
   378  	ost << r_ac_bar << endl;
   379  	//cout << "round_5b after111" << endl;
   380  	return ost.str();
   381  }
   382  
   383  void Prover_toom::round_7a()
   384  {
   385  
   386  	//Set the rows in D_s as D_s(i) = chal_t_1^i+1*D_h(i) for i<m-1 and D_s(m-1) = sum(chal_x6^i+1 * D_s(i+1) and set last row of D_s to random values and also D(0)
   387  	func_pro::set_D_s(D_s, D_h, D, chal_x6, r_Dl_bar);
   388  
   389  	//calculate the values Dls as Dl(l) = sum(D(i)*D_s->at(i)*chal_y6) for j=n+i-l and commits to the values
   390  	func_pro::commit_Dl_op(c_Dl, Dl, r_Dl, D, D_s, chal_y6, ped_);
   391  
   392  	//commitments to D(0) and D_s(m)
   393  	Functions::commit_op(D->at(0), r_D0, c_D0, ped_);
   394  
   395  	Functions::commit_op(D_s->at(m), r_Dm, c_Dm, ped_);
   396  
   397  	//commitments to prove that the product over the elements in D_h->at(m) is the desired product of n *y + x2n -z
   398  	func_pro::commit_d_op(d, r_d, c_d, ped_);
   399  
   400  	func_pro::commit_Delta_op(Delta, d, r_Delta, c_Delta, ped_);
   401  
   402  	func_pro::commit_d_h_op(D_h, d_h, d, Delta, r_d_h, c_d_h, ped_);
   403  }
   404  
   405  void Prover_toom::round_7b()
   406  {
   407  	calculate_ac_bar(chal_x6);
   408  	calculate_r_ac_bar(chal_x6);
   409  }
   410  
   411  void Prover_toom::round_7c()
   412  {
   413  	vector<Cipher_elg> *e = 0;
   414  
   415  	auto tstart = high_resolution_clock::now();
   416  	reduce_C(C, B, r_B, chal_x6, m_r);
   417  	set_Rb1(chal_x6);
   418  	auto tstop = high_resolution_clock::now();
   419  	//cout << "7c: reduce_C " << duration<double>(tstop - tstart).count() << endl;
   420  	time_di = time_di + duration<double>(tstop - tstart).count();
   421  
   422  	tstart = high_resolution_clock::now();
   423  	func_pro::commit_a_op(a, r_a, c_a, ped_);
   424  	tstop = high_resolution_clock::now();
   425  	//cout << "7c: commit_a " << duration<double>(tstop - tstart).count() << endl;
   426  	func_pro::commit_B0_op(B_0, basis_B0, r_B0, c_B0, omega_mulex, ped_);
   427  
   428  	tstart = high_resolution_clock::now();
   429  	e = calculate_e();
   430  	tstop = high_resolution_clock::now();
   431  	//cout << "7c: e " << duration<double>(tstop - tstart).count() << endl;
   432  	time_di = time_di + duration<double>(tstop - tstart).count();
   433  	//cout<<"To calculate the di's took "<<time_di<<" sec."<<endl;
   434  
   435  	calculate_E(e);
   436  
   437  	delete e;
   438  	Functions::delete_vector(C_small);
   439  }
   440  
   441  void Prover_toom::round_7c_red()
   442  {
   443  	vector<Cipher_elg> *e = 0;
   444  	vector<vector<Cipher_elg> *> *C_small_temp = 0;
   445  	vector<vector<ZZ> *> *B_small_temp = 0;
   446  	vector<ZZ> *r_B_small_temp = 0;
   447  	//cout << "round_7c_red 0" << endl;
   448  	//auto tstart= high_resolution_clock::now();
   449  	C_small_temp = copy_C();
   450  	B_small_temp = copy_B();
   451  	r_B_small_temp = copy_r_B();
   452  
   453  	C_small = new vector<vector<Cipher_elg> *>(m_r);
   454  	B_small = new vector<vector<ZZ> *>(m_r);
   455  	r_B_small = new vector<ZZ>(m_r);
   456  	reduce_C(C_small_temp, B_small_temp, r_B_small_temp, chal_x6, m_r);
   457  	set_Rb1(chal_x6);
   458  	//cout << "round_7c_red 1" << endl;
   459  	//auto tstop = high_resolution_clock::now();
   460  	//time_di = time_di+ duration<double>(tstop-tstart).count();
   461  	//cout << "round_7c_red 2" << endl;
   462  	func_pro::commit_a_op(a, r_a, c_a, ped_);
   463  	func_pro::commit_B0_op(B_0, basis_B0, r_B0, c_B0, omega_mulex, ped_);
   464  	//cout << "round_7c_red 3" << endl;
   465  	//tstart = high_resolution_clock::now();
   466  	e = calculate_e();
   467  	//cout << "round_7c_red 4" << endl;
   468  	//tstop = high_resolution_clock::now();
   469  	//time_di = time_di+duration<double>(tstop-tstart).count();
   470  	//cout<<"To calculate the di's took "<<time_di<<" sec."<<endl;
   471  	//cout << "round_7c_red 5" << endl;
   472  	calculate_E(e);
   473  	Functions::delete_vector(C_small);
   474  	Functions::delete_vector(C_small_temp);
   475  	Functions::delete_vector(B_small_temp);
   476  	delete r_B_small_temp;
   477  	delete e;
   478  }
   479  
   480  string Prover_toom::round_7(const string &input)
   481  {
   482  	long i, l;
   483  	//reads the values out of the file
   484  	stringstream ist(input);
   485  	//reads the vector t_1
   486  	l = 2 * m;
   487  	for (i = 0; i < l; i++)
   488  	{
   489  		ist >> chal_x6->at(i);
   490  	}
   491  	//reads the vector t
   492  	for (i = 0; i < n; i++)
   493  	{
   494  		ist >> chal_y6->at(i);
   495  	}
   496  
   497  	round_7a();
   498  	round_7b();
   499  	round_7c();
   500  
   501  	//Set name of the output file and open stream
   502  
   503  	stringstream ost;
   504  	for (i = 0; i <= l; i++)
   505  	{
   506  		ost << c_Dl->at(i) << " ";
   507  	}
   508  	ost << "\n";
   509  	ost << c_D0 << "\n";
   510  	ost << c_Dm << "\n";
   511  	ost << c_d << "\n";
   512  	ost << c_Delta << "\n";
   513  	ost << c_d_h << "\n";
   514  	ost << a_c_bar << "\n";
   515  	ost << r_ac_bar << "\n";
   516  	for (i = 0; i < 8; i++)
   517  	{
   518  		ost << E->at(i) << " ";
   519  	}
   520  	ost << "\n";
   521  	ost << c_B0 << "\n";
   522  	for (i = 0; i < 8; i++)
   523  	{
   524  		ost << c_a->at(i) << " ";
   525  	}
   526  	ost << "\n";
   527  
   528  	return ost.str();
   529  }
   530  
   531  string Prover_toom::round_7_red(const string &input)
   532  {
   533  	long i, l;
   534  	//reads the values out of the file
   535  	stringstream ist(input);
   536  	//reads the vector t_1
   537  	l = 2 * m; //Todo: l should be m or 2m?
   538  	for (i = 0; i < l; i++)
   539  	{
   540  		ist >> chal_x6->at(i);
   541  	}
   542  	//reads the vector t
   543  	for (i = 0; i < n; i++)
   544  	{
   545  		ist >> chal_y6->at(i);
   546  	}
   547  	//cout << "round_7_red 7a " << endl;
   548  	round_7a();
   549  	//cout << "round_7_red 7b " << endl;
   550  	round_7b();
   551  	//cout << "round_7_red 7c_red " << endl;
   552  	round_7c_red();
   553  	//cout << "round_7_red 7c finish " << endl;
   554  
   555  	stringstream ost;
   556  	for (i = 0; i <= l; i++)
   557  	{
   558  		ost << c_Dl->at(i) << " ";
   559  	}
   560  	ost << "\n";
   561  	ost << c_D0 << "\n";
   562  	ost << c_Dm << "\n";
   563  	ost << c_d << "\n";
   564  	ost << c_Delta << "\n";
   565  	ost << c_d_h << "\n";
   566  
   567  	ost << a_c_bar << "\n";
   568  	ost << r_ac_bar << "\n";
   569  	for (i = 0; i < 8; i++)
   570  	{
   571  		ost << E->at(i) << " ";
   572  	}
   573  	ost << "\n";
   574  	ost << c_B0 << "\n";
   575  	for (i = 0; i < 8; i++)
   576  	{
   577  		ost << c_a->at(i) << " ";
   578  	}
   579  	ost << "\n";
   580  	return ost.str();
   581  }
   582  
   583  void Prover_toom::round_9a()
   584  {
   585  
   586  	//Calculate D_h_bar = sum(chal^i*D_h(row(i)))
   587  	func_pro::calculate_D_h_bar(D_h_bar, D_h, chal_x8);
   588  
   589  	//calculate r_Dh_bar = sum(chal^i*r_Dh_bar(i)), opening to prove correctness of D_h
   590  	func_pro::calculate_r_Dh_bar(r_D_h, chal_x8, r_Dh_bar);
   591  
   592  	//calculate d_bar, r_d_bar, Delta_bar, r_Delta_bar, openings to prove product over elements in D_h->at(m-1)
   593  	func_pro::calculate_dbar_rdbar(D_h, chal_x8, d_bar, d, r_D_h, r_d, r_d_bar);
   594  	func_pro::calculate_Deltabar_rDeltabar(d_h, chal_x8, Delta_bar, Delta, r_d_h, r_Delta, r_Delta_bar);
   595  }
   596  
   597  void Prover_toom::round_9b()
   598  {
   599  
   600  	//A_bar and r_A_bar, openings to prove permutation in D
   601  	func_pro::calculate_A_bar(D, A_bar, chal_x8);
   602  	func_pro::calculate_r_A_bar(r_D0, r_A, r_B, chal_x8, r_z, chal_y4, r_A_bar);
   603  
   604  	//D_s_bar and r_Ds_bar, openings to prove correctness of D_s
   605  	func_pro::calculate_D_s_bar(D_s, D_s_bar, chal_x8);
   606  	func_pro::calculate_r_Ds_bar(r_D_h, chal_x6, chal_x8, r_Ds_bar, r_Dm);
   607  
   608  	//sum of the random values used to commit to the Dl's, to prover correctness of them
   609  	func_pro::calculate_r_Dl_bar(r_Dl, chal_x8, r_Dl_bar);
   610  }
   611  
   612  void Prover_toom::round_9c()
   613  {
   614  	//calculate B_bar
   615  	func_pro::calculate_B_bar(B_0, B_small, chal_x8, B_bar);
   616  	Functions::delete_vector(B_small);
   617  
   618  	//calculate r_B_bar
   619  	func_pro::calculate_r_B_bar(r_B_small, chal_x8, r_B0, r_B_bar);
   620  
   621  	//calculate a_bar
   622  	func_pro::calculate_a_bar(a, chal_x8, a_bar);
   623  
   624  	//calculate r_a_bar
   625  	func_pro::calculate_r_a_bar(r_a, chal_x8, r_a_bar);
   626  
   627  	//calculate rho_a_bar
   628  	func_pro::calculate_rho_a_bar(rho_a, chal_x8, rho_bar);
   629  }
   630  
   631  string Prover_toom::round_9(const string &input)
   632  {
   633  	long i;
   634  	long l = chal_x8->size();
   635  
   636  	//reads the values out of the file
   637  	stringstream ist(input);
   638  
   639  	//reads the vector e
   640  	for (i = 0; i < l; i++)
   641  	{
   642  		ist >> chal_x8->at(i);
   643  	}
   644  
   645  	round_9a();
   646  	round_9b();
   647  	round_9c();
   648  
   649  	//Set name of the output file and open stream
   650  	stringstream ost;
   651  
   652  	for (i = 0; i < n; i++)
   653  	{
   654  		ost << D_h_bar->at(i) << " ";
   655  	}
   656  	ost << "\n";
   657  
   658  	ost << r_Dh_bar;
   659  	ost << "\n";
   660  
   661  	for (i = 0; i < n; i++)
   662  	{
   663  		ost << d_bar->at(i) << " ";
   664  	}
   665  	ost << "\n";
   666  	ost << r_d_bar << "\n";
   667  	for (i = 0; i < n; i++)
   668  	{
   669  		ost << Delta_bar->at(i) << " ";
   670  	}
   671  	ost << "\n";
   672  	ost << r_Delta_bar << "\n";
   673  
   674  	for (i = 0; i < n; i++)
   675  	{
   676  		ost << A_bar->at(i) << " ";
   677  	}
   678  	ost << "\n";
   679  	ost << r_A_bar << "\n";
   680  	for (i = 0; i < n; i++)
   681  	{
   682  		ost << D_s_bar->at(i) << " ";
   683  	}
   684  	ost << "\n";
   685  	ost << r_Ds_bar << "\n";
   686  	ost << r_Dl_bar << "\n";
   687  	for (i = 0; i < n; i++)
   688  	{
   689  		ost << B_bar->at(i) << " ";
   690  	}
   691  	ost << "\n";
   692  
   693  	ost << r_B_bar;
   694  	ost << "\n";
   695  
   696  	ost << a_bar;
   697  	ost << "\n";
   698  
   699  	ost << r_a_bar;
   700  	ost << "\n";
   701  
   702  	ost << rho_bar;
   703  	ost << "\n";
   704  
   705  	return ost.str();
   706  }
   707  
   708  void Prover_toom::commit_ac()
   709  {
   710  	long i;
   711  	ZZ ord = H.get_ord();
   712  	//does not need parallelization
   713  	for (i = 0; i < mu_h; i++)
   714  	{
   715  		a_c->at(i) = RandomBnd(ord);
   716  		r_c->at(i) = RandomBnd(ord);
   717  		rho_c->at(i) = RandomBnd(ord);
   718  	}
   719  	a_c->at(mu - 1) = to_ZZ(0);
   720  	r_c->at(mu - 1) = to_ZZ(0);
   721  	NegateMod(rho_c->at(mu - 1), R_b, ord);
   722  
   723  	for (i = 0; i < mu_h; i++)
   724  	{
   725  		c_a_c->at(i) = ped_.commit_sw(a_c->at(i), r_c->at(i));
   726  	}
   727  }
   728  
   729  void Prover_toom::calculate_Cc(vector<vector<Cipher_elg> *> *C, vector<vector<vector<long> *> *> *B)
   730  {
   731  	long i, j, l, k;
   732  	ZZ mod = H.get_mod();
   733  	CurvePoint gen = H.get_gen().get_val();
   734  	Cipher_elg temp, temp_1;
   735  	CurvePoint t_1;
   736  	high_resolution_clock::time_point t1, t2;
   737  
   738  	//cout << "mu " << mu << endl;
   739  	//cout << "mu_h " << mu_h << endl;
   740  	//cout << "m_r " << m_r << endl;
   741  	//cout << "omega_mulex " << omega_mulex << endl;
   742  
   743  	const Cipher_elg one_enced(curve_zeropoint(), mod);
   744  	//int count = 0;
   745  	t1 = high_resolution_clock::now();
   746  	for (k = 0; k < mu_h; k++)
   747  	{
   748  		temp = one_enced;
   749  		{
   750  			for (i = 0; i < mu; i++)
   751  			{
   752  				j = k + 1 - mu + i;
   753  				if ((j >= 0) & (j < mu))
   754  				{
   755  //PARALLELIZE
   756  #pragma omp parallel for num_threads(num_threads) if (parallel)
   757  					for (l = 0; l < m_r; l++)
   758  					{
   759  						Cipher_elg c;
   760  						multi_expo::expo_mult(c, C->at(4 * l + i), B->at(4 * l + j), omega_mulex);
   761  #pragma omp critical(Cc1)
   762  						{
   763  							Cipher_elg::mult(temp, temp, c);
   764  						}
   765  					}
   766  				}
   767  			}
   768  		}
   769  		PowerMod(t_1, gen, a_c->at(k), mod);
   770  		temp_1 = elgammal_->encrypt(t_1, rho_c->at(k));
   771  		Cipher_elg::mult(C_c->at(k), temp, temp_1);
   772  	}
   773  	t2 = high_resolution_clock::now();
   774  	//duration<double> par1 = duration_cast<duration<double>>(t2-t1);
   775  	//cout << "Calculate_Cc par 1 " << par1.count() << endl;
   776  }
   777  
   778  void Prover_toom::calculate_Cc(vector<vector<Cipher_elg> *> *C, vector<vector<ZZ> *> *B)
   779  {
   780  	long i, j, l, k;
   781  	ZZ mod = H.get_mod();
   782  	CurvePoint gen = H.get_gen().get_val();
   783  	Cipher_elg temp, temp_1;
   784  	CurvePoint t_1;
   785  	high_resolution_clock::time_point t1, t2;
   786  
   787  	t1 = high_resolution_clock::now();
   788  	for (k = 0; k < mu_h; k++)
   789  	{
   790  		temp = Cipher_elg(curve_zeropoint(), mod);
   791  		{
   792  			for (i = 0; i < mu; i++)
   793  			{
   794  				j = k + 1 - mu + i;
   795  				if ((j >= 0) & (j < mu))
   796  				{
   797  //PARALLELIZE
   798  #pragma omp parallel for private(temp_1) num_threads(num_threads) if (parallel)
   799  					for (l = 0; l < m_r; l++)
   800  					{
   801  						multi_expo::expo_mult(temp_1, C->at(4 * l + i), B->at(4 * l + j), omega_mulex);
   802  #pragma omp critical(Cc2)
   803  						{
   804  							Cipher_elg::mult(temp, temp, temp_1);
   805  						}
   806  					}
   807  				}
   808  			}
   809  		}
   810  		PowerMod(t_1, gen, a_c->at(k), mod);
   811  		temp_1 = elgammal_->encrypt(t_1, rho_c->at(k));
   812  		Cipher_elg::mult(C_c->at(k), temp, temp_1);
   813  	}
   814  	t2 = high_resolution_clock::now();
   815  	//duration<double> par1 = duration_cast<duration<double>>(t2-t1);
   816  	//cout << "Calculate_Cc par 2 " << par1.count() << endl;
   817  }
   818  
   819  void Prover_toom::calculate_ac_bar(vector<ZZ> *x)
   820  {
   821  	long i;
   822  	ZZ temp;
   823  	ZZ ord = H.get_ord();
   824  	//does not need parallelization
   825  	a_c_bar = a_c->at(0);
   826  	for (i = 1; i < mu_h; i++)
   827  	{
   828  		MulMod(temp, a_c->at(i), x->at(i - 1), ord);
   829  		AddMod(a_c_bar, a_c_bar, temp, ord);
   830  	}
   831  }
   832  
   833  void Prover_toom::calculate_r_ac_bar(vector<ZZ> *x)
   834  {
   835  	long i;
   836  	ZZ temp;
   837  	ZZ ord = H.get_ord();
   838  	//does not need parallelization
   839  	r_ac_bar = r_c->at(0);
   840  	for (i = 1; i < mu_h; i++)
   841  	{
   842  		MulMod(temp, r_c->at(i), x->at(i - 1), ord);
   843  		AddMod(r_ac_bar, r_ac_bar, temp, ord);
   844  	}
   845  }
   846  
   847  static void __do_reduce_C_external(vector<vector<Cipher_elg> *> *C, vector<vector<ZZ> *> *B, vector<ZZ> *r_B, vector<vector<Cipher_elg> *> *C_small, vector<vector<ZZ> *> *B_small, vector<ZZ> *r_B_small, vector<ZZ> *x_temp, ZZ &ord, int omega_LL, long i, int n)
   848  {
   849  	ZZ temp, temp_1;
   850  	vector<Cipher_elg> *row_C;
   851  	vector<ZZ> *row_B;
   852  
   853  	row_C = new vector<Cipher_elg>(n);
   854  	row_B = new vector<ZZ>(n);
   855  	{
   856  //PARALLELIZE
   857  #pragma omp parallel for num_threads(num_threads) if (parallel)
   858  		for (long j = 0; j < n; j++)
   859  		{
   860  			ZZ temp, temp_1;
   861  			multi_expo::multi_expo_LL(row_C->at(j), C->at(4 * i)->at(j), C->at(4 * i + 1)->at(j), C->at(4 * i + 2)->at(j), C->at(4 * i + 3)->at(j), x_temp, omega_LL);
   862  			temp = B->at(4 * i)->at(j);
   863  			MulMod(temp_1, B->at(4 * i + 1)->at(j), x_temp->at(2), ord);
   864  			AddMod(temp, temp, temp_1, ord);
   865  			MulMod(temp_1, B->at(4 * i + 2)->at(j), x_temp->at(1), ord);
   866  			AddMod(temp, temp, temp_1, ord);
   867  			MulMod(temp_1, B->at(4 * i + 3)->at(j), x_temp->at(0), ord);
   868  			AddMod(temp, temp, temp_1, ord);
   869  			row_B->at(j) = temp;
   870  		}
   871  	}
   872  	C_small->at(i) = row_C;
   873  	B_small->at(i) = row_B;
   874  	temp = r_B->at(4 * i);
   875  	MulMod(temp_1, r_B->at(4 * i + 1), x_temp->at(2), ord);
   876  	AddMod(temp, temp, temp_1, ord);
   877  	MulMod(temp_1, r_B->at(4 * i + 2), x_temp->at(1), ord);
   878  	AddMod(temp, temp, temp_1, ord);
   879  	MulMod(temp_1, r_B->at(4 * i + 3), x_temp->at(0), ord);
   880  	AddMod(temp, temp, temp_1, ord);
   881  	r_B_small->at(i) = temp;
   882  }
   883  
   884  void Prover_toom::reduce_C(vector<vector<Cipher_elg> *> *C, vector<vector<ZZ> *> *B, vector<ZZ> *r_B, vector<ZZ> *x, long length)
   885  {
   886  	ZZ ord = H.get_ord();
   887  	vector<ZZ> *x_temp = new vector<ZZ>(4);
   888  
   889  	auto tstart = high_resolution_clock::now();
   890  	x_temp->at(3) = 1;
   891  	x_temp->at(2) = x->at(0);
   892  	x_temp->at(1) = x->at(1);
   893  	x_temp->at(0) = x->at(2);
   894  
   895  	{
   896  		for (long i = 0; i < length; i++)
   897  		{
   898  			__do_reduce_C_external(C, B, r_B, C_small, B_small, r_B_small, x_temp, ord, omega_LL, i, n);
   899  		}
   900  	}
   901  	auto tstop = high_resolution_clock::now();
   902  	time_di = time_di + duration<double>(tstop - tstart).count();
   903  	delete x_temp;
   904  }
   905  
   906  void Prover_toom::set_Rb1(vector<ZZ> *x)
   907  {
   908  	long i;
   909  	ZZ temp;
   910  	ZZ ord = H.get_ord();
   911  	//does not need parallelization
   912  	R_b = rho_c->at(0);
   913  	for (i = 1; i < mu_h; i++)
   914  	{
   915  		MulMod(temp, rho_c->at(i), x->at(i - 1), ord);
   916  		AddMod(R_b, R_b, temp, ord);
   917  	}
   918  }
   919  
   920  vector<Cipher_elg> *Prover_toom::calculate_e()
   921  {
   922  	long k, l;
   923  	Cipher_elg temp;
   924  	vector<Cipher_elg> *dt = 0;
   925  	//cout << "calculate_e, m = " << m << endl;
   926  	vector<Cipher_elg> *e = new vector<Cipher_elg>(2 * m); // should here be changed?
   927  														   //high_resolution_clock::time_point t1, t2;
   928  	//cout << "calculate_e 0, c_small size = " << C_small->size() << endl;
   929  	dt = toom4_pow(C_small, B_small);
   930  	//cout << "calculate_e 1" << endl;
   931  //PARALLELIZE
   932  //t1 = high_resolution_clock::now();
   933  #pragma omp parallel for private(temp) num_threads(num_threads) if (parallel)
   934  	for (k = 0; k < mu; k++)
   935  	{
   936  		if (k == 0)
   937  		{
   938  			multi_expo::expo_mult(e->at(0), C_small->at(mu - 1), basis_B0, omega_mulex);
   939  		}
   940  		else
   941  		{
   942  			multi_expo::expo_mult(temp, C_small->at(mu - k - 1), basis_B0, omega_mulex);
   943  			Cipher_elg::mult(e->at(k), temp, dt->at(2 * mu - k - 1));
   944  		}
   945  	}
   946  	//cout << "calculate_e 2" << endl;
   947  	//t2 = high_resolution_clock::now();
   948  	l = 2 * mu;
   949  #pragma omp parallel for num_threads(num_threads) if (parallel)
   950  	for (k = mu; k < l; k++)
   951  	{
   952  		e->at(k) = dt->at(2 * mu - k - 1);
   953  	}
   954  	//cout << "calculate_e 3" << endl;
   955  	//duration<double> par1 = duration_cast<duration<double>>(t2-t1);
   956  	//cout << "Calculate_e par 1 " << par1.count() << endl;
   957  
   958  	delete dt;
   959  	return e;
   960  }
   961  
   962  void Prover_toom::calculate_E(vector<Cipher_elg> *e)
   963  {
   964  	long i, l;
   965  	Mod_p t;
   966  	Mod_p gen = H.get_gen();
   967  	ZZ ord = H.get_ord();
   968  	//does not need parallelism
   969  	l = 2 * mu;
   970  	for (i = 0; i < l; i++)
   971  	{
   972  		rho_a->at(i) = RandomBnd(ord);
   973  	}
   974  	rho_a->at(mu) = R_b;
   975  	for (i = 0; i < l; i++)
   976  	{
   977  		t = gen.expo(a->at(i));
   978  		E->at(i) = elgammal_->encrypt(t, rho_a->at(i)) * e->at(i);
   979  	}
   980  }
   981  
   982  vector<vector<Cipher_elg> *> *Prover_toom::copy_C()
   983  {
   984  	long i, j, l;
   985  	vector<Cipher_elg> *row_C;
   986  	l = mu * m_r;
   987  	vector<vector<Cipher_elg> *> *C_small_temp = new vector<vector<Cipher_elg> *>(l);
   988  
   989  	for (i = 0; i < l; i++)
   990  	{
   991  		row_C = new vector<Cipher_elg>(n);
   992  		for (j = 0; j < n; j++)
   993  		{
   994  			row_C->at(j) = C_small->at(i)->at(j);
   995  		}
   996  		C_small_temp->at(i) = row_C;
   997  		delete C_small->at(i);
   998  		C_small->at(i) = 0;
   999  	}
  1000  	//cout << "copy_C, c_small_temp.size = " << (*C_small_temp).size() << endl;
  1001  	delete C_small;
  1002  	C_small = 0;
  1003  	//cout << "copy_C, c_small_temp.size = " << (*C_small_temp).size() << endl;
  1004  	return C_small_temp;
  1005  }
  1006  
  1007  vector<vector<ZZ> *> *Prover_toom::copy_B()
  1008  {
  1009  	long i, j;
  1010  	long l = mu * m_r;
  1011  	vector<vector<ZZ> *> *B_small_temp = new vector<vector<ZZ> *>(l);
  1012  	vector<ZZ> *row_B;
  1013  
  1014  	for (i = 0; i < l; i++)
  1015  	{
  1016  		row_B = new vector<ZZ>(n);
  1017  		for (j = 0; j < n; j++)
  1018  		{
  1019  			row_B->at(j) = B_small->at(i)->at(j);
  1020  		}
  1021  		B_small_temp->at(i) = row_B;
  1022  		delete B_small->at(i);
  1023  		B_small->at(i) = 0;
  1024  	}
  1025  	delete B_small;
  1026  
  1027  	return B_small_temp;
  1028  }
  1029  
  1030  vector<ZZ> *Prover_toom::copy_r_B()
  1031  {
  1032  	long i;
  1033  	long l = mu * m_r;
  1034  	vector<ZZ> *r_B_small_temp = new vector<ZZ>(l);
  1035  	for (i = 0; i < l; i++)
  1036  	{
  1037  		r_B_small_temp->at(i) = r_B_small->at(i);
  1038  	}
  1039  	delete r_B_small;
  1040  	r_B_small = 0;
  1041  
  1042  	return r_B_small_temp;
  1043  }
  1044  
  1045  vector<vector<ZZ> *> *Prover_toom::evulation(vector<vector<ZZ> *> *p)
  1046  {
  1047  	vector<vector<ZZ> *> *ret;
  1048  	vector<ZZ> *row;
  1049  	ZZ p0, p1, p2, p3, ord, temp, temp_1;
  1050  	long l, i;
  1051  	//cout << "evulation, 0" << endl;
  1052  	l = p->at(0)->size();
  1053  	//cout << "evulation, l = " << l << endl;
  1054  	ord = H.get_ord();
  1055  	ret = new vector<vector<ZZ> *>(l);
  1056  	//does not need parallelization
  1057  	for (i = 0; i < l; i++)
  1058  	{
  1059  		row = new vector<ZZ>(7);
  1060  		AddMod(p0, p->at(2)->at(i), p->at(0)->at(i), ord);
  1061  		AddMod(p1, p->at(3)->at(i), p->at(1)->at(i), ord);
  1062  		MulMod(temp, p->at(2)->at(i), 2, ord);
  1063  		MulMod(temp_1, p->at(0)->at(i), 8, ord);
  1064  		AddMod(p2, temp, temp_1, ord);
  1065  		MulMod(temp, p->at(1)->at(i), 4, ord);
  1066  		AddMod(p3, p->at(3)->at(i), temp, ord);
  1067  
  1068  		row->at(0) = p->at(3)->at(i);
  1069  		MulMod(temp_1, p->at(1)->at(i), 2, ord);
  1070  		AddMod(temp, temp_1, p->at(0)->at(i), ord);
  1071  		MulMod(temp_1, p->at(2)->at(i), 4, ord);
  1072  		AddMod(temp, temp, temp_1, ord);
  1073  		MulMod(temp_1, p->at(3)->at(i), 8, ord);
  1074  		AddMod(row->at(1), temp, temp_1, ord);
  1075  		AddMod(row->at(2), p0, p1, ord);
  1076  		SubMod(row->at(3), p0, p1, ord);
  1077  		AddMod(row->at(4), p2, p3, ord);
  1078  		SubMod(row->at(5), p2, p3, ord);
  1079  		row->at(6) = p->at(0)->at(i);
  1080  		ret->at(i) = row;
  1081  	}
  1082  	//cout << "evulation, ret" << endl;
  1083  	return ret;
  1084  }
  1085  
  1086  vector<vector<vector<CurvePoint> *> *> *Prover_toom::evulation_pow(vector<vector<Cipher_elg> *> *p)
  1087  {
  1088  	vector<vector<vector<CurvePoint> *> *> *ret;
  1089  	vector<vector<CurvePoint> *> *ret_u;
  1090  	//vector<vector<CurvePoint>* >* ret_v;
  1091  	vector<CurvePoint> *row_u;
  1092  	//vector<CurvePoint>* row_v;
  1093  	CurvePoint p0_u, p1_u, p2_u, p3_u, temp_u, temp_1_u;
  1094  	//CurvePoint p0_v,p1_v,p2_v,p3_v,temp_v, temp_1_v;
  1095  	ZZ mod = H.get_mod();
  1096  	long l, i;
  1097  	l = p->at(0)->size();
  1098  	//cout << "evulation_pow, l =" << l << ", p.size = " << p->size() << endl;
  1099  	ret = new vector<vector<vector<CurvePoint> *> *>(1);
  1100  	ret_u = new vector<vector<CurvePoint> *>(l);
  1101  	//ret_v = new vector<vector<CurvePoint>*>(l);
  1102  	//does not need parallelization
  1103  	for (i = 0; i < l; i++)
  1104  	{
  1105  		row_u = new vector<CurvePoint>(7);
  1106  		//	row_v = new vector<CurvePoint>(7);
  1107  		MulMod(p0_u, p->at(1)->at(i).get_u(), p->at(3)->at(i).get_u(), mod);
  1108  		//	MulMod(p0_v,p->at(1)->at(i).get_v(), p->at(3)->at(i).get_v(),mod);
  1109  		MulMod(p1_u, p->at(0)->at(i).get_u(), p->at(2)->at(i).get_u(), mod);
  1110  		//	MulMod(p1_v ,p->at(0) ->at(i).get_v(), p->at(2)->at(i).get_v(), mod);
  1111  		PowerMod(temp_u, p->at(1)->at(i).get_u(), 2, mod);
  1112  		//	PowerMod(temp_v, p->at(1)->at(i).get_v(), 2,mod);
  1113  		PowerMod(temp_1_u, p->at(3)->at(i).get_u(), 8, mod);
  1114  		//	PowerMod(temp_1_v, p->at(3)->at(i).get_v(), 8,mod);
  1115  		MulMod(p2_u, temp_u, temp_1_u, mod);
  1116  		//	MulMod(p2_v ,temp_v , temp_1_v,mod);
  1117  		PowerMod(temp_u, p->at(2)->at(i).get_u(), 4, mod);
  1118  		//	PowerMod(temp_v, p->at(2)->at(i).get_v(), 4, mod);
  1119  		MulMod(p3_u, p->at(0)->at(i).get_u(), temp_u, mod);
  1120  		//	MulMod(p3_v ,p->at(0)->at(i).get_v() , temp_v,mod);
  1121  
  1122  		row_u->at(0) = p->at(0)->at(i).get_u();
  1123  		PowerMod(temp_u, p->at(2)->at(i).get_u(), 2, mod);
  1124  		MulMod(temp_u, temp_u, p->at(3)->at(i).get_u(), mod);
  1125  		PowerMod(temp_1_u, p->at(1)->at(i).get_u(), 4, mod);
  1126  		MulMod(temp_u, temp_u, temp_1_u, mod);
  1127  		PowerMod(temp_1_u, p->at(0)->at(i).get_u(), 8, mod);
  1128  		MulMod(row_u->at(1), temp_u, temp_1_u, mod);
  1129  		MulMod(row_u->at(2), p0_u, p1_u, mod);
  1130  		InvMod(temp_u, p1_u, mod);
  1131  		MulMod(row_u->at(3), p0_u, temp_u, mod);
  1132  		MulMod(row_u->at(4), p2_u, p3_u, mod);
  1133  		InvMod(temp_u, p3_u, mod);
  1134  		MulMod(row_u->at(5), p2_u, temp_u, mod);
  1135  		row_u->at(6) = p->at(3)->at(i).get_u();
  1136  
  1137  		//	row_v->at(0) = p->at(0)->at(i).get_v();
  1138  		//	PowerMod(temp_v, p->at(2)->at(i).get_v(), 2,mod);
  1139  		//	MulMod(temp_v,temp_v , p->at(3)->at(i).get_v(), mod);
  1140  		//	PowerMod(temp_1_v, p->at(1)->at(i).get_v(), 4,mod);
  1141  		//	MulMod(temp_v,temp_v,temp_1_v,mod);
  1142  		//	PowerMod(temp_1_v, p->at(0)->at(i).get_v(), 8, mod);
  1143  		// MulMod(row_v->at(1), temp_v,temp_1_v,mod);
  1144  		// MulMod(row_v->at(2) , p0_v,p1_v,mod);
  1145  		// InvMod(temp_v, p1_v, mod);
  1146  		// MulMod(row_v->at(3) , p0_v,temp_v,mod);
  1147  		// MulMod(row_v ->at(4) , p2_v,p3_v,mod);
  1148  		// InvMod(temp_v, p3_v, mod);
  1149  		// MulMod(row_v ->at(5),p2_v,temp_v,mod);
  1150  		// row_v->at(6) = p->at(3)->at(i).get_v();
  1151  
  1152  		ret_u->at(i) = row_u;
  1153  		//	ret_v->at(i) = row_v;
  1154  	}
  1155  	//cout << "evulation_pow 0" << endl;
  1156  
  1157  	ret->at(0) = ret_u;
  1158  	//ret->at(1) = ret_v;
  1159  	return ret;
  1160  }
  1161  
  1162  vector<vector<vector<CurvePoint> *> *> *Prover_toom::point_pow(vector<vector<vector<CurvePoint> *> *> *points_p, vector<vector<ZZ> *> *points_q)
  1163  {
  1164  	long i, l;
  1165  	vector<vector<vector<CurvePoint> *> *> *ret;
  1166  	vector<vector<CurvePoint> *> *ret_u;
  1167  	//vector<vector<CurvePoint>*>* ret_v;
  1168  	//vector<ZZ>* row_u;
  1169  	//vector<ZZ>* row_v;
  1170  	ZZ mod = H.get_mod();
  1171  	l = points_p->at(0)->size();
  1172  
  1173  	high_resolution_clock::time_point t1, t2, t3, t4;
  1174  
  1175  	ret = new vector<vector<vector<CurvePoint> *> *>(1);
  1176  	ret_u = new vector<vector<CurvePoint> *>(l);
  1177  	//ret_v = new vector<vector<CurvePoint>*>(l);
  1178  
  1179  	for (long j = 0; j < l; j++)
  1180  	{
  1181  		ret_u->at(j) = new vector<CurvePoint>(7);
  1182  		//	ret_v->at(j) = new vector<CurvePoint>(7);
  1183  	}
  1184  
  1185  	{
  1186  //PARALLELIZE
  1187  #pragma omp parallel for collapse(2) num_threads(num_threads) if (parallel)
  1188  		for (long j = 0; j < l; j++)
  1189  		{
  1190  			for (i = 0; i < 7; i++)
  1191  			{
  1192  				PowerMod(ret_u->at(j)->at(i), points_p->at(0)->at(j)->at(i), points_q->at(j)->at(i), mod);
  1193  				//            PowerMod(ret_v->at(j)->at(i), points_p->at(1)->at(j)->at(i), points_q->at(j)->at(i),mod);
  1194  			}
  1195  		}
  1196  	}
  1197  
  1198  	ret->at(0) = ret_u;
  1199  	//ret->at(1) = ret_v;
  1200  	for (i = 0; i < l; i++)
  1201  	{
  1202  		delete points_p->at(0)->at(i);
  1203  		points_p->at(0)->at(i) = 0;
  1204  		//	delete points_p->at(1)->at(i);
  1205  		//	points_p->at(1)->at(i)=0;
  1206  	}
  1207  	delete points_p->at(0);
  1208  	//delete points_p->at(1);
  1209  	delete points_p;
  1210  	for (i = 0; i < l; i++)
  1211  	{
  1212  		delete points_q->at(i);
  1213  		points_q->at(i) = 0;
  1214  	}
  1215  	delete points_q;
  1216  
  1217  	return ret;
  1218  }
  1219  
  1220  vector<vector<CurvePoint> *> *Prover_toom::mult_points(vector<vector<vector<CurvePoint> *> *> *points)
  1221  {
  1222  	long i, l, j;
  1223  	vector<vector<CurvePoint> *> *ret = new vector<vector<CurvePoint> *>(1);
  1224  	vector<CurvePoint> *ret_u = new vector<CurvePoint>(7);
  1225  	//vector<CurvePoint>* ret_v = new vector<CurvePoint>(7);
  1226  	l = points->at(0)->size();
  1227  	CurvePoint temp_u; //, temp_v
  1228  	ZZ mod = H.get_mod();
  1229  	//does not need parallelization
  1230  	for (i = 0; i < 7; i++)
  1231  	{
  1232  		temp_u = curve_zeropoint();
  1233  		//	temp_v = curve_zeropoint();
  1234  		for (j = 0; j < l; j++)
  1235  		{
  1236  			MulMod(temp_u, temp_u, points->at(0)->at(j)->at(i), mod);
  1237  			//		MulMod(temp_v, temp_v, points->at(1)->at(j)->at(i),mod);
  1238  		}
  1239  		ret_u->at(i) = temp_u;
  1240  		//	ret_v->at(i) = temp_v;
  1241  	}
  1242  	for (i = 0; i < l; i++)
  1243  	{
  1244  		delete points->at(0)->at(i);
  1245  		points->at(0)->at(i) = 0;
  1246  		//	delete points->at(1)->at(i);
  1247  		//	points->at(1)->at(i) = 0;
  1248  	}
  1249  	delete points->at(0);
  1250  	points->at(0) = 0;
  1251  	//	delete points->at(1);
  1252  	//	points->at(1) =0;
  1253  	delete points;
  1254  	ret->at(0) = ret_u;
  1255  	//	ret->at(1) = ret_v;
  1256  	return ret;
  1257  }
  1258  
  1259  vector<CurvePoint> *Prover_toom::interpolation_pow(vector<CurvePoint> *points)
  1260  {
  1261  	vector<CurvePoint> *ret = new vector<CurvePoint>(7);
  1262  	CurvePoint r1, r2, r3, r4, r5, r6, r7, temp_pt;
  1263  	ZZ temp_zz;
  1264  	ZZ ord = H.get_ord();
  1265  	ZZ mod = H.get_mod();
  1266  
  1267  	r1 = points->at(0);
  1268  	r2 = points->at(1);
  1269  	r3 = points->at(2);
  1270  	r4 = points->at(3);
  1271  	r5 = points->at(4);
  1272  	r6 = points->at(5);
  1273  	r7 = points->at(6);
  1274  
  1275  	MulMod(r2, r2, r5, mod);
  1276  	InvMod(temp_pt, r5, mod);
  1277  	MulMod(r6, r6, temp_pt, mod);
  1278  	InvMod(temp_pt, r3, mod);
  1279  	MulMod(r4, r4, temp_pt, mod);
  1280  	InvMod(temp_pt, r1, mod);
  1281  	MulMod(r5, r5, temp_pt, mod);
  1282  	PowerMod(temp_pt, r7, 64, mod);
  1283  	InvMod(temp_pt, temp_pt, mod);
  1284  	MulMod(r5, r5, temp_pt, mod);
  1285  	InvMod(temp_zz, to_ZZ(2), ord);
  1286  	PowerMod(r4, r4, temp_zz, mod);
  1287  	MulMod(r3, r3, r4, mod);
  1288  	PowerMod(temp_pt, r5, 2, mod);
  1289  	MulMod(r5, temp_pt, r6, mod);
  1290  
  1291  	PowerMod(temp_pt, r3, 65, mod);
  1292  	InvMod(temp_pt, temp_pt, mod);
  1293  	MulMod(r2, r2, temp_pt, mod);
  1294  	InvMod(r4, r4, mod);
  1295  	InvMod(r6, r6, mod);
  1296  	InvMod(temp_pt, r7, mod);
  1297  	MulMod(r3, r3, temp_pt, mod);
  1298  	InvMod(temp_pt, r1, mod);
  1299  	MulMod(r3, r3, temp_pt, mod);
  1300  	PowerMod(temp_pt, r3, 45, mod);
  1301  	MulMod(r2, r2, temp_pt, mod);
  1302  	PowerMod(temp_pt, r3, 8, mod);
  1303  	InvMod(temp_pt, temp_pt, mod);
  1304  	MulMod(r5, r5, temp_pt, mod);
  1305  
  1306  	InvMod(temp_zz, to_ZZ(24), ord);
  1307  	PowerMod(r5, r5, temp_zz, mod);
  1308  	InvMod(temp_pt, r2, mod);
  1309  	MulMod(r6, r6, temp_pt, mod);
  1310  	PowerMod(temp_pt, r4, 16, mod);
  1311  	InvMod(temp_pt, temp_pt, mod);
  1312  	MulMod(r2, r2, temp_pt, mod);
  1313  	InvMod(temp_zz, to_ZZ(18), ord);
  1314  	PowerMod(r2, r2, temp_zz, mod);
  1315  	InvMod(temp_pt, r5, mod);
  1316  	MulMod(r3, r3, temp_pt, mod);
  1317  	InvMod(temp_pt, r2, mod);
  1318  	MulMod(r4, r4, temp_pt, mod);
  1319  	PowerMod(temp_pt, r2, 30, mod);
  1320  	MulMod(r6, r6, temp_pt, mod);
  1321  	InvMod(temp_zz, to_ZZ(60), ord);
  1322  	PowerMod(r6, r6, temp_zz, mod);
  1323  	InvMod(temp_pt, r6, mod);
  1324  	MulMod(r2, r2, temp_pt, mod);
  1325  
  1326  	ret->at(0) = r1;
  1327  	ret->at(1) = r2;
  1328  	ret->at(2) = r3;
  1329  	ret->at(3) = r4;
  1330  	ret->at(4) = r5;
  1331  	ret->at(5) = r6;
  1332  	ret->at(6) = r7;
  1333  
  1334  	return ret;
  1335  }
  1336  
  1337  // p is a list of points, q is a list of scalars
  1338  vector<Cipher_elg> *Prover_toom::toom4_pow(vector<vector<Cipher_elg> *> *p, vector<vector<ZZ> *> *q)
  1339  {
  1340  	vector<vector<vector<CurvePoint> *> *> *points_p;
  1341  	vector<vector<ZZ> *> *points_q;
  1342  	vector<vector<vector<CurvePoint> *> *> *points_temp;
  1343  	vector<vector<CurvePoint> *> *points;
  1344  	vector<CurvePoint> *ret_u;
  1345  	//vector<CurvePoint>* ret_v;
  1346  	vector<Cipher_elg> *ret = new vector<Cipher_elg>(7);
  1347  	long i, l;
  1348  	ZZ mod = H.get_mod();
  1349  	//auto begin= high_resolution_clock::now();
  1350  	//cout << "toom4_pow, 0 " << endl;
  1351  	points_p = evulation_pow(p);
  1352  	//cout << "toom4_pow, 0 " << endl;
  1353  	points_q = evulation(q);
  1354  	//cout << "toom4_pow, 1 " << endl;
  1355  	points_temp = point_pow(points_p, points_q);
  1356  	//cout << "toom4_pow, 2 " << endl;
  1357  	//auto tstart= high_resolution_clock::now();
  1358  	//cout << "toom4, begin: " << duration<double>(tstart - begin).count() << endl;
  1359  	points = mult_points(points_temp);
  1360  	//cout << "toom4_pow, 3 " << endl;
  1361  	ret_u = interpolation_pow(points->at(0));
  1362  	//cout << "toom4_pow, 4 " << endl;
  1363  	//auto tstart2= high_resolution_clock::now();
  1364  	//cout << "interpolation1 time " << duration<double>(tstart2 - tstart).count() << endl;
  1365  	//ret_v = interpolation_pow(points->at(1));
  1366  	//auto end= high_resolution_clock::now();
  1367  	//cout << "interpolation2 time " << duration<double>(end - tstart2).count() << endl;
  1368  	l = points->size();
  1369  	//cout << "toom4_pow, l = " << l << endl;
  1370  	for (i = 0; i < l; i++)
  1371  	{
  1372  		delete points->at(i);
  1373  		points->at(i) = 0;
  1374  	}
  1375  	delete points;
  1376  	//cout << "toom4_pow, 0 " << endl;
  1377  	for (i = 0; i < 7; i++)
  1378  	{
  1379  		ret->at(i) = Cipher_elg(ret_u->at(i), mod);
  1380  	}
  1381  	delete ret_u;
  1382  	return ret;
  1383  }