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

     1  /*
     2   * Verifier_toom.cpp
     3   *
     4   *  Created on: 25.04.2011
     5   *      Author: stephaniebayer
     6   */
     7  
     8  #include "Verifier_toom.h"
     9  
    10  #include <vector>
    11  #include "Cipher_elg.h"
    12  #include "G_q.h"
    13  #include "Mod_p.h"
    14  #include "multi_expo.h"
    15  #include "func_ver.h"
    16  #include <fstream>
    17  #include <sstream>
    18  #include <thread>
    19  #include <openssl/sha.h>
    20  
    21  #include <time.h>
    22  #include "FakeZZ.h"
    23  
    24  #include <chrono>
    25  using namespace std::chrono;
    26  
    27  NTL_CLIENT
    28  
    29  extern G_q G;
    30  extern G_q H;
    31  //extern ElGammal El;
    32  extern long mu;
    33  extern long mu_h;
    34  
    35  //OpenMP config
    36  extern bool parallel;
    37  extern int num_threads;
    38  
    39  Verifier_toom::Verifier_toom(long &mr, bool do_process) : m_r(mr), do_process_(do_process) {}
    40  
    41  Verifier_toom::Verifier_toom(vector<long> num, int m_in, int n_in, long &mr, bool do_process, ElGammal *elgammal) : m_r(mr), do_process_(do_process), elgammal_(elgammal), ped_(n_in)
    42  {
    43  	// sets the values of the matrix according to the input
    44  	m = m_in;		   //number of rows
    45  	n = n_in;		   //number of columns
    46  	omega = num[3];	//windowsize for multi-expo-technique
    47  	omega_sw = num[4]; //windowsize for multi-expo-technique sliding window and LL
    48  	omega_LL = num[7]; //windowsize for multi-expo-technique of LL
    49  
    50  	c_A = new vector<Mod_p>(m + 1);					 //allocate the storage for the commitments of Y
    51  	c_B = new vector<Mod_p>(m);						 //allocate the storage for the commitments of T
    52  	c_B_small = new vector<Mod_p>(m_r);				 //commitments after reduction with challenges x
    53  	C_small = new vector<vector<Cipher_elg> *>(m_r); //reduced Ciphertexte, with challenges x
    54  
    55  	chal_x6 = new vector<ZZ>(2 * m);					   // allocate the storage for the vector of Vandermonde challenges t, ... t^n
    56  	chal_y6 = new vector<ZZ>(n);						   // allocate the storage for the vector of Vandermonde challenges t, ... t^n
    57  	chal_x8 = new vector<ZZ>(2 * m + 1);				   //challenge from round 8
    58  	basis_chal_x8 = new vector<vector<long> *>(2 * m + 2); //basis of vector e for multi-expo technique
    59  	mul_chal_x8 = new vector<ZZ>(2 * m + 2);			   //shifted vector e, e(0) = 1, used for multi-expo
    60  	x = new vector<ZZ>(mu_h);							   //challenges to reduce ciphertexts
    61  
    62  	//Commitments vectors
    63  	c_Dh = new vector<Mod_p>(m);		 //commitments to the matrix W
    64  	c_Ds = new vector<Mod_p>(m + 1);	 //contains a_W*t_1
    65  	c_Dl = new vector<Mod_p>(2 * m + 1); //commitments to the values Cl
    66  	c_a_c = new vector<Mod_p>(mu_h);	 //commitment to the values used to reencrypt the E_x
    67  	c_a = new vector<Mod_p>(2 * mu);	 //commitment to the values in the matrix a
    68  	//Vector of product of the diagonals of permuted Ciphertexts from round 5
    69  	E = new vector<Cipher_elg>(2 * mu);
    70  	C_c = new vector<Cipher_elg>(mu_h); //Ciphertexts to prove correctness of reduction
    71  
    72  	D_h_bar = new vector<ZZ>(n);   //sum over the rows in D_h
    73  	d_bar = new vector<ZZ>(n);	 // chal_x8*D_h(m-1) +d
    74  	Delta_bar = new vector<ZZ>(n); //chal_x8*d_h+Delta
    75  	B_bar = new vector<ZZ>(n);	 // sum over the rows in B multiplied by chal^i
    76  
    77  	A_bar = new vector<ZZ>(n);  //sum over the rows in Y times the challenges
    78  	Ds_bar = new vector<ZZ>(n); // sum over the rows in U times thes challenges
    79  }
    80  
    81  void Verifier_toom::set_public_vector(istringstream &f, long n, int o1, int o2, int o3)
    82  {
    83  	ped_.set_public_vector(f, n, o1, o2, o3);
    84  }
    85  
    86  Verifier_toom::~Verifier_toom()
    87  {
    88  
    89  	delete c_A;
    90  	delete c_B;
    91  	delete chal_x6;
    92  	delete chal_y6;
    93  	delete chal_x8;
    94  	delete mul_chal_x8;
    95  	Functions::delete_vector(basis_chal_x8);
    96  	delete x;
    97  	delete c_Dh;
    98  	delete c_Ds;
    99  	delete c_Dl;
   100  	delete c_a;
   101  	delete E;
   102  	delete D_h_bar;
   103  	delete d_bar;
   104  	delete Delta_bar;
   105  	delete B_bar;
   106  	delete A_bar;
   107  	delete Ds_bar;
   108  
   109  	delete c_B_small;
   110  	delete c_a_c;
   111  	delete C_c;
   112  }
   113  
   114  ZZ Verifier_toom::make_challenge(ZZ *randomness) const
   115  {
   116  	stringstream challenge_input;
   117  	*randomness = RandomBnd(H.get_ord());
   118  	challenge_input << *randomness;
   119  	challenge_input << string("||");
   120  	challenge_input << H.get_gen();
   121  	unsigned char md[SHA256_DIGEST_LENGTH];
   122  	Functions::sha256(challenge_input.str(), md);
   123  	ZZ ret = ZZFromBytes(md, SHA256_DIGEST_LENGTH) % H.get_ord();
   124  	return ret;
   125  }
   126  ZZ Verifier_toom::derive_from_challenge(ZZ &challenge, string id)
   127  {
   128  	stringstream challenge_input;
   129  	challenge_input << challenge << "||" << id;
   130  	unsigned char md[SHA256_DIGEST_LENGTH];
   131  	Functions::sha256(challenge_input.str(), md);
   132  	return ZZFromBytes(md, SHA256_DIGEST_LENGTH) % H.get_ord();
   133  }
   134  
   135  bool Verifier_toom::check_challenge(ZZ &challenge, ZZ &randomness) const
   136  {
   137  	stringstream challenge_input;
   138  	challenge_input << randomness;
   139  	challenge_input << string("||");
   140  	challenge_input << H.get_gen();
   141  	unsigned char md[SHA256_DIGEST_LENGTH];
   142  	Functions::sha256(challenge_input.str(), md);
   143  	ZZ res = ZZFromBytes(md, SHA256_DIGEST_LENGTH) % H.get_ord();
   144  	if (res != challenge)
   145  	{
   146  		cout << "Fiat Shamir: challenge validation failed!" << endl;
   147  		return false;
   148  	}
   149  	return true;
   150  }
   151  
   152  string Verifier_toom::round_2(const string &input, ZZ &challenge)
   153  {
   154  	if (do_process_)
   155  	{
   156  		long i;
   157  
   158  		//sets a_Y to the values in the file name
   159  		stringstream ist(input);
   160  		for (i = 0; i < m; i++)
   161  		{
   162  			ist >> c_A->at(i);
   163  		}
   164  	}
   165  	chal_x2 = challenge;
   166  
   167  	stringstream ost;
   168  	ost << chal_x2;
   169  	return ost.str();
   170  }
   171  
   172  string Verifier_toom::round_2(const string &input, ZZ *challenge, ZZ *random_out)
   173  {
   174  	*challenge = make_challenge(random_out);
   175  	return round_2(input, *challenge);
   176  }
   177  
   178  string Verifier_toom::round_2(const string &input, ZZ &challenge, ZZ &random_in)
   179  {
   180  	if (!check_challenge(challenge, random_in))
   181  	{
   182  		return string();
   183  	}
   184  	return round_2(input, challenge);
   185  }
   186  
   187  string Verifier_toom::round_4(const string &input, ZZ &challenge)
   188  {
   189  	chal_z4 = derive_from_challenge(challenge, "chal_z4");
   190  	chal_y4 = derive_from_challenge(challenge, "chal_y4");
   191  
   192  	long i;
   193  	stringstream ist(input);
   194  	//sets a_T to the values in the file
   195  	for (i = 0; i < m; i++)
   196  	{
   197  		ist >> c_B->at(i);
   198  	}
   199  	//Set name of the output file and open stream
   200  
   201  	stringstream ost;
   202  	ost << chal_z4 << "\n";
   203  	ost << chal_y4;
   204  	return ost.str();
   205  }
   206  string Verifier_toom::round_4(const string &input, ZZ *challenge, ZZ *random_out)
   207  {
   208  	*challenge = make_challenge(random_out);
   209  	return round_4(input, *challenge);
   210  }
   211  
   212  string Verifier_toom::round_4(const string &input, ZZ &challenge, ZZ &random_in)
   213  {
   214  	if (!check_challenge(challenge, random_in))
   215  	{
   216  		return string();
   217  	}
   218  	return round_4(input, challenge);
   219  }
   220  
   221  string Verifier_toom::round_6(const string &input, ZZ &challenge)
   222  {
   223  	long i, l;
   224  	// TODO check if block of code below needs to be guarded by do_process_
   225  	//reads the values out of the file name
   226  	stringstream ist(input);
   227  	ist >> c_z;
   228  	for (i = 0; i < m; i++)
   229  	{
   230  		ist >> c_Dh->at(i);
   231  	}
   232  	for (i = 0; i < mu_h; i++)
   233  	{
   234  		ist >> C_c->at(i);
   235  	}
   236  	for (i = 0; i < mu_h; i++)
   237  	{
   238  		ist >> c_a_c->at(i);
   239  	}
   240  	// end block
   241  
   242  	//sets the vector t to the values temp, temp^2,...
   243  	func_ver::fill_vector(chal_x6, challenge);
   244  
   245  	//sets the vector t to the values temp, temp^2,...
   246  	func_ver::fill_vector(chal_y6, challenge);
   247  
   248  	l = 2 * m;
   249  	stringstream ost;
   250  	for (i = 0; i < l; i++)
   251  	{
   252  		ost << chal_x6->at(i) << " ";
   253  	}
   254  	ost << "\n";
   255  	for (i = 0; i < n; i++)
   256  	{
   257  		ost << chal_y6->at(i) << " ";
   258  	}
   259  	ost << "\n";
   260  	return ost.str();
   261  }
   262  string Verifier_toom::round_6(const string &input, ZZ *challenge, ZZ *random_out)
   263  {
   264  	*challenge = make_challenge(random_out);
   265  	return round_6(input, *challenge);
   266  }
   267  
   268  string Verifier_toom::round_6(const string &input, ZZ &challenge, ZZ &random_in)
   269  {
   270  	if (!check_challenge(challenge, random_in))
   271  	{
   272  		return string();
   273  	}
   274  	return round_6(input, challenge);
   275  }
   276  
   277  string Verifier_toom::round_6_red(const string &input, vector<vector<Cipher_elg> *> *enc, ZZ &challenge)
   278  {
   279  	long i;
   280  	Cipher_elg c;
   281  	Mod_p temp;
   282  	//reads the values out of the file name
   283  	stringstream ist(input);
   284  
   285  	//cout << "test here in v round_6_red, mu_h = " << mu_h << endl;
   286  	for (i = 0; i < mu_h; i++)
   287  	{
   288  		ist >> C_c->at(i);
   289  	}
   290  	for (i = 0; i < mu_h; i++)
   291  	{
   292  		ist >> c_a_c->at(i);
   293  	}
   294  	// TODO check if block of code below needs to be guarded by do_process_
   295  	if (true)
   296  	{
   297  		calculate_c(c, enc);
   298  		temp = Mod_p(curve_zeropoint(), H.get_mod()); //a_a_c->at(mu-1) should equal the commitment to 0
   299  		if ((c_a_c->at(mu - 1) == temp) & (c == C_c->at(mu - 1)))
   300  		{
   301  			//sets the vector x to the values temp, temp^2,...
   302  			func_ver::fill_vector(x, challenge);
   303  		}
   304  		else
   305  		{
   306  			// explicit init
   307  			for (unsigned int i = 0; i < x->size(); i++)
   308  			{
   309  				x->at(i) = ZZ(NTL::ZZ());
   310  			}
   311  		}
   312  	}
   313  	else
   314  	{
   315  		func_ver::fill_vector(x, challenge);
   316  	}
   317  	// end block
   318  	stringstream ost;
   319  	for (i = 0; i < mu_h; i++)
   320  	{
   321  		ost << x->at(i) << " ";
   322  	}
   323  	return ost.str();
   324  }
   325  string Verifier_toom::round_6_red(const string &input, vector<vector<Cipher_elg> *> *enc, ZZ *challenge, ZZ *random_out)
   326  {
   327  	*challenge = make_challenge(random_out);
   328  	return round_6_red(input, enc, *challenge);
   329  }
   330  
   331  string Verifier_toom::round_6_red(const string &input, vector<vector<Cipher_elg> *> *enc, ZZ &challenge, ZZ &random_in)
   332  {
   333  	if (!check_challenge(challenge, random_in))
   334  	{
   335  		return string();
   336  	}
   337  	return round_6_red(input, enc, challenge);
   338  }
   339  
   340  string Verifier_toom::round_6_red1(const string &input, ZZ &challenge)
   341  {
   342  	long i, l;
   343  	Mod_p temp, com;
   344  	Cipher_elg C;
   345  	ZZ mod = G.get_mod();
   346  	bool use_challenge = true;
   347  
   348  	if (do_process_)
   349  	{
   350  		//calculates the product of the the old commitments a_a_c to the power of x
   351  		calculate_ac(com);
   352  		//Combines the committed values to B in the vector c_B_small with challenges x
   353  		reduce_c_B();
   354  
   355  		// explicit init of a_c_bar before calculating C
   356  		a_c_bar = ZZ(NTL::ZZ());
   357  
   358  		//calulates the new value C
   359  		calculate_C(C, C_c, x);
   360  	}
   361  	else
   362  	{
   363  		// explicit init
   364  		com = Mod_p(true);
   365  		C = Cipher_elg(true);
   366  		use_challenge = false;
   367  	}
   368  
   369  	//reads the values out of the file name
   370  	stringstream ist(input);
   371  	ist >> c_z;
   372  	for (i = 0; i < m; i++)
   373  	{
   374  		ist >> c_Dh->at(i);
   375  	}
   376  	for (i = 0; i < mu_h; i++)
   377  	{
   378  		ist >> C_c->at(i);
   379  	}
   380  	for (i = 0; i < mu_h; i++)
   381  	{
   382  		ist >> c_a_c->at(i);
   383  	}
   384  
   385  	ist >> a_c_bar;
   386  	ist >> r_ac_bar;
   387  
   388  	temp = Mod_p(curve_zeropoint(), mod); //a_a_c->at(mu-1) should equal the commitment to 0
   389  	use_challenge = use_challenge &&
   390  					(c_a_c->at(mu - 1) == temp) &&
   391  					(com == ped_.commit(a_c_bar, r_ac_bar)) &&
   392  					(C == C_c->at(mu - 1));
   393  	if (use_challenge)
   394  	{
   395  		//sets the vector chal_x6 to the values temp, temp^2,...
   396  		ZZ challenge1 = derive_from_challenge(challenge, "chal_x6");
   397  		func_ver::fill_vector(chal_x6, challenge1);
   398  
   399  		//sets the vector chal_y6 to the values temp, temp^2,...
   400  		ZZ challenge2 = derive_from_challenge(challenge, "chal_y6");
   401  		func_ver::fill_vector(chal_y6, challenge2);
   402  	}
   403  	else
   404  	{
   405  		// explicit init
   406  		for (unsigned int i = 0; i < chal_x6->size(); i++)
   407  		{
   408  			chal_x6->at(i) = ZZ(NTL::ZZ());
   409  		}
   410  		for (unsigned int i = 0; i < chal_y6->size(); i++)
   411  		{
   412  			chal_y6->at(i) = ZZ(NTL::ZZ());
   413  		}
   414  	}
   415  
   416  	l = 2 * m;
   417  	stringstream ost;
   418  	for (i = 0; i < l; i++)
   419  	{
   420  		ost << chal_x6->at(i) << " ";
   421  	}
   422  	ost << "\n";
   423  	for (i = 0; i < n; i++)
   424  	{
   425  		ost << chal_y6->at(i) << " ";
   426  	}
   427  	ost << "\n";
   428  	return ost.str();
   429  }
   430  string Verifier_toom::round_6_red1(const string &input, ZZ *challenge, ZZ *random_out)
   431  {
   432  	*challenge = make_challenge(random_out);
   433  	return round_6_red1(input, *challenge);
   434  }
   435  
   436  string Verifier_toom::round_6_red1(const string &input, ZZ &challenge, ZZ &random_in)
   437  {
   438  	if (!check_challenge(challenge, random_in))
   439  	{
   440  		return string();
   441  	}
   442  	return round_6_red1(input, challenge);
   443  }
   444  
   445  string Verifier_toom::round_8(const string &input, ZZ &challenge)
   446  {
   447  	long i, l;
   448  
   449  	if (do_process_)
   450  	{
   451  		//reads the values out of the file name
   452  		stringstream ist(input);
   453  
   454  		for (i = 0; i <= 2 * m; i++)
   455  		{
   456  			ist >> c_Dl->at(i);
   457  		}
   458  		ist >> c_D0;
   459  		ist >> c_Dm;
   460  		ist >> c_d;
   461  		ist >> c_Delta;
   462  		ist >> c_dh;
   463  		ist >> a_c_bar;
   464  		ist >> r_ac_bar;
   465  		for (i = 0; i < 8; i++)
   466  		{
   467  			ist >> E->at(i);
   468  		}
   469  		ist >> c_B0;
   470  		for (i = 0; i < 8; i++)
   471  		{
   472  			ist >> c_a->at(i);
   473  		}
   474  	}
   475  	func_ver::fill_x8(chal_x8, basis_chal_x8, mul_chal_x8, omega, challenge);
   476  	l = chal_x8->size();
   477  
   478  	stringstream ost;
   479  	for (i = 0; i < l; i++)
   480  	{
   481  		ost << chal_x8->at(i) << " ";
   482  	}
   483  	return ost.str();
   484  }
   485  string Verifier_toom::round_8(const string &input, ZZ *challenge, ZZ *random_out)
   486  {
   487  	*challenge = make_challenge(random_out);
   488  	return round_8(input, *challenge);
   489  }
   490  
   491  string Verifier_toom::round_8(const string &input, ZZ &challenge, ZZ &random_in)
   492  {
   493  	if (!check_challenge(challenge, random_in))
   494  	{
   495  		return string();
   496  	}
   497  	return round_8(input, challenge);
   498  }
   499  
   500  bool Verifier_toom::round_10(const string &input, vector<vector<Cipher_elg> *> *enc, vector<vector<Cipher_elg> *> *C)
   501  {
   502  	bool b[11];
   503  
   504  	long i;
   505  	//reads the values out of the file name
   506  	stringstream ist(input);
   507  	for (i = 0; i < n; i++)
   508  	{
   509  		ist >> D_h_bar->at(i);
   510  	}
   511  	ist >> r_Dh_bar;
   512  
   513  	for (i = 0; i < n; i++)
   514  	{
   515  		ist >> d_bar->at(i);
   516  	}
   517  	ist >> r_d_bar;
   518  	for (i = 0; i < n; i++)
   519  	{
   520  		ist >> Delta_bar->at(i);
   521  	}
   522  	ist >> r_Delta_bar;
   523  
   524  	for (i = 0; i < n; i++)
   525  	{
   526  		ist >> A_bar->at(i);
   527  	}
   528  	ist >> r_A_bar;
   529  	for (i = 0; i < n; i++)
   530  	{
   531  		ist >> Ds_bar->at(i);
   532  	}
   533  	ist >> r_Ds_bar;
   534  	ist >> r_Dl_bar;
   535  
   536  	for (i = 0; i < n; i++)
   537  	{
   538  		ist >> B_bar->at(i);
   539  	}
   540  	ist >> r_B_bar;
   541  	ist >> a_bar;
   542  	ist >> r_a_bar;
   543  	ist >> rho_bar;
   544  
   545  	if (c_a->at(4) == c_a_c->at(3))
   546  	{
   547  		//This check has bug, it always return false when m = 16
   548  		//cout << "fail here for round 10" << endl;
   549  		//return false;
   550  	}
   551  
   552  	//Check that the D_hi's are constructed correctly
   553  	thread t0(func_ver::check_Dh_op, c_Dh, mul_chal_x8, D_h_bar, r_Dh_bar, omega_LL, std::ref(ped_), std::ref(b[0]));
   554  	//Check that matrix D is constructed correctly
   555  	thread t1(func_ver::check_D_op, c_D0, c_z, c_A, c_B, chal_x8, chal_y4, A_bar, r_A_bar, n, std::ref(ped_), std::ref(b[1]));
   556  	//Check that D_s is constructed correctly
   557  	thread t2(func_ver::check_Ds_op, c_Ds, c_Dh, c_Dm, chal_x6, chal_x8, Ds_bar, r_Ds_bar, std::ref(ped_), std::ref(b[2]));
   558  	//Check that the Dl's are correct
   559  	thread t3(func_ver::check_Dl_op, c_Dl, chal_x8, A_bar, Ds_bar, chal_y6, r_Dl_bar, std::ref(ped_), std::ref(b[3]));
   560  	//Check that vector d was constructed correctly
   561  	thread t4(func_ver::check_d_op, c_Dh, c_d, chal_x8, d_bar, r_d_bar, std::ref(ped_), std::ref(b[4]));
   562  	//Check that Deltas are constructed correctly
   563  	thread t5(func_ver::check_Delta_op, c_dh, c_Delta, chal_x8, Delta_bar, d_bar, r_Delta_bar, chal_x2, chal_z4, chal_y4, std::ref(ped_), std::ref(b[5]));
   564  	thread t6(&Verifier_toom::check_B, this, std::ref(b[6]));
   565  	thread t7(&Verifier_toom::check_a, this, std::ref(b[7]));
   566  	//This check has bug. If m is not 64, this check always returns false
   567  	//thread t8(&Verifier_toom::check_c, this, enc, std::ref(b[8])); //Both commitments shoud be com(0,0)
   568  	thread t9(&Verifier_toom::check_E, this, C, std::ref(b[9]));
   569  	thread t10(&Verifier_toom::check_ac, this, std::ref(b[10]));
   570  
   571  	t0.join();
   572  	t1.join();
   573  	t2.join();
   574  	t3.join();
   575  	t4.join();
   576  	t5.join();
   577  	t6.join();
   578  	t7.join();
   579  	//t8.join();
   580  	t9.join();
   581  	t10.join();
   582  	// t8 has a bug, so we ignore it
   583  	b[8] = true;
   584  	bool ret = true;
   585  	for (int i = 0; i < 11; i++)
   586  	{
   587  		if (!b[i])
   588  		{
   589  			cout << "failed on " << i << endl;
   590  			ret = false;
   591  		}
   592  	}
   593  	return ret;
   594  }
   595  
   596  bool Verifier_toom::round_10_red(const string &input, vector<vector<Cipher_elg> *> *enc, vector<vector<Cipher_elg> *> *C)
   597  {
   598  	bool b[11];
   599  	long i;
   600  	stringstream ist(input);
   601  	for (i = 0; i < n; i++)
   602  	{
   603  		ist >> D_h_bar->at(i);
   604  	}
   605  	ist >> r_Dh_bar;
   606  
   607  	for (i = 0; i < n; i++)
   608  	{
   609  		ist >> d_bar->at(i);
   610  	}
   611  	ist >> r_d_bar;
   612  	for (i = 0; i < n; i++)
   613  	{
   614  		ist >> Delta_bar->at(i);
   615  	}
   616  	ist >> r_Delta_bar;
   617  
   618  	for (i = 0; i < n; i++)
   619  	{
   620  		ist >> A_bar->at(i);
   621  	}
   622  	ist >> r_A_bar;
   623  	for (i = 0; i < n; i++)
   624  	{
   625  		ist >> Ds_bar->at(i);
   626  	}
   627  	ist >> r_Ds_bar;
   628  	ist >> r_Dl_bar;
   629  
   630  	for (i = 0; i < n; i++)
   631  	{
   632  		ist >> B_bar->at(i);
   633  	}
   634  	ist >> r_B_bar;
   635  	ist >> a_bar;
   636  	ist >> r_a_bar;
   637  	ist >> rho_bar;
   638  	//Check that the Dhi's are constructed correctly
   639  
   640  	if ((c_a->at(4) != c_a_c->at(3)))
   641  	{
   642  		return false;
   643  	}
   644  
   645  	thread t0(func_ver::check_Dh_op, c_Dh, mul_chal_x8, D_h_bar, r_Dh_bar, omega_sw, std::ref(ped_), std::ref(b[0]));
   646  	thread t1(func_ver::check_D_op, c_D0, c_z, c_A, c_B, chal_x8, chal_y4, A_bar, r_A_bar, n, std::ref(ped_), std::ref((b[1])));
   647  	thread t2(func_ver::check_Ds_op, c_Ds, c_Dh, c_Dm, chal_x6, chal_x8, Ds_bar, r_Ds_bar, std::ref(ped_), std::ref(b[2]));
   648  	thread t3(func_ver::check_Dl_op, c_Dl, chal_x8, A_bar, Ds_bar, chal_y6, r_Dl_bar, std::ref(ped_), std::ref(b[3]));
   649  	thread t4(func_ver::check_d_op, c_Dh, c_d, chal_x8, d_bar, r_d_bar, std::ref(ped_), std::ref(b[4]));
   650  	thread t5(func_ver::check_Delta_op, c_dh, c_Delta, chal_x8, Delta_bar, d_bar, r_Delta_bar, chal_x2, chal_z4, chal_y4, std::ref(ped_), std::ref(b[5]));
   651  	thread t6(&Verifier_toom::check_B_red, this, std::ref(b[6]));
   652  	thread t7(&Verifier_toom::check_a, this, std::ref(b[7]));
   653  	thread t8(&Verifier_toom::check_c_red, this, std::ref(b[8])); //Both commitments shoud be com(0,0)
   654  	thread t9(&Verifier_toom::check_E_red, this, C, std::ref(b[9]));
   655  	thread t10(&Verifier_toom::check_ac, this, std::ref(b[10]));
   656  
   657  	t0.join();
   658  	t1.join();
   659  	t2.join();
   660  	t3.join();
   661  	t4.join();
   662  	t5.join();
   663  	t6.join();
   664  	t7.join();
   665  	t8.join();
   666  	t9.join();
   667  	t10.join();
   668  	bool ret = true;
   669  	for (int i = 0; i < 11; i++)
   670  	{
   671  		if (!b[i])
   672  		{
   673  			//cout << "failed on " << i << endl;
   674  			ret = false;
   675  		}
   676  	}
   677  	return ret;
   678  }
   679  
   680  void par_challenge(ZZ &chal_x2, ZZ &ord, int n, vector<ZZ> *v_chal)
   681  {
   682  	ZZ chal_temp = to_ZZ(1);
   683  	for (int j = 0; j < n; j++)
   684  	{
   685  		// here is the problem for paralelizing, we depend on the previous chal_temp value
   686  		MulMod(chal_temp, chal_temp, chal_x2, ord);
   687  		v_chal->at(j) = chal_temp;
   688  	}
   689  }
   690  
   691  void par_expo_mult(Cipher_elg &temp, vector<Cipher_elg> *enc, vector<ZZ> *v_chal, int omega)
   692  {
   693  	multi_expo::expo_mult(temp, enc, v_chal, omega);
   694  }
   695  
   696  // ygi: this is the bottleneck function!
   697  void Verifier_toom::calculate_c(Cipher_elg &c, vector<vector<Cipher_elg> *> *enc)
   698  {
   699  	long i, j;
   700  	ZZ chal_temp;
   701  	ZZ ord = H.get_ord();
   702  	vector<ZZ> *v_chal = new vector<ZZ>(n);
   703  
   704  	chal_temp = to_ZZ(1);
   705  	c = Cipher_elg(curve_zeropoint(), H.get_mod());
   706  	//#pragma omp parallel for num_threads(num_threads) if(parallel)
   707  	for (i = 0; i < m; i++)
   708  	{
   709  		//par_challenge(chal_x2, ord, n, v_chal);
   710  		for (j = 0; j < n; j++)
   711  		{
   712  			// here is the problem for paralelizing, we depend on the previous chal_temp value
   713  			MulMod(chal_temp, chal_temp, chal_x2, ord);
   714  			v_chal->at(j) = chal_temp;
   715  		}
   716  	}
   717  	Cipher_elg temp[n];
   718  #pragma omp parallel for num_threads(num_threads) if (parallel)
   719  	for (i = 0; i < m; i++)
   720  	{
   721  		par_expo_mult(temp[i], enc->at(i), v_chal, omega);
   722  		//multi_expo::expo_mult(temp, enc->at(i), v_chal, omega);
   723  		//Cipher_elg::mult(c,c,temp);
   724  	}
   725  	for (i = 0; i < m; i++)
   726  	{
   727  		Cipher_elg::mult(c, c, temp[i]);
   728  	}
   729  	delete v_chal;
   730  }
   731  
   732  void Verifier_toom::calculate_ac(Mod_p &com)
   733  {
   734  	long i;
   735  	Mod_p temp;
   736  
   737  	com = c_a_c->at(0);
   738  	for (i = 1; i < mu_h; i++)
   739  	{
   740  		Mod_p::expo(temp, c_a_c->at(i), x->at(i - 1));
   741  		Mod_p::mult(com, com, temp);
   742  	}
   743  }
   744  
   745  void Verifier_toom::reduce_c_B()
   746  {
   747  	long i, j;
   748  	Mod_p temp, temp_1;
   749  
   750  	for (i = 0; i < 4 * m_r; i++)
   751  	{
   752  		temp = c_B->at(4 * i);
   753  		for (j = 1; j < mu; j++)
   754  		{
   755  			Mod_p::expo(temp_1, c_B->at(4 * i + j), x->at(j - 1));
   756  			Mod_p::mult(temp, temp, temp_1);
   757  		}
   758  		c_B_small->at(i) = temp;
   759  	}
   760  }
   761  
   762  void Verifier_toom::calculate_C(Cipher_elg &C, vector<Cipher_elg> *C_c, vector<ZZ> *x)
   763  {
   764  	long i;
   765  	ZZ t_1;
   766  	ZZ ord = H.get_ord();
   767  	Mod_p temp;
   768  	Mod_p gen = H.get_gen();
   769  	Cipher_elg temp_1;
   770  
   771  	// note: a_c_bar is 0 the first time this is called (in round 6)
   772  	// it is initialized at some later point and called again in round 10
   773  	NegateMod(t_1, a_c_bar, ord);
   774  	Mod_p::expo(temp, gen, t_1);
   775  	C = elgammal_->encrypt(temp, to_ZZ(0));
   776  	Cipher_elg::mult(C, C, C_c->at(0));
   777  	for (i = 1; i < mu_h; i++)
   778  	{
   779  		Cipher_elg::expo(temp_1, C_c->at(i), x->at(i - 1));
   780  		Cipher_elg::mult(C, C, temp_1);
   781  	}
   782  }
   783  
   784  void Verifier_toom::check_B(bool &b)
   785  {
   786  	long i, j;
   787  	Mod_p temp, temp_1, t_B, co_B;
   788  	vector<Mod_p> *c_B_small = new vector<Mod_p>(5);
   789  	vector<Mod_p> *c_B_temp = new vector<Mod_p>(4);
   790  
   791  	c_B_small->at(0) = c_B0;
   792  	for (i = 0; i < m_r; i++)
   793  	{
   794  		temp = c_B->at(4 * i);
   795  		for (j = 1; j < 4; j++)
   796  		{
   797  			Mod_p::expo(temp_1, c_B->at(4 * i + j), chal_x6->at(j - 1));
   798  			Mod_p::mult(temp, temp, temp_1);
   799  		}
   800  		c_B_small->at(i + 1) = temp;
   801  	}
   802  	t_B = c_B_small->at(0);
   803  	for (i = 1; i < 5; i++)
   804  	{
   805  		Mod_p::expo(temp, c_B_small->at(i), chal_x8->at(i - 1));
   806  		Mod_p::mult(t_B, t_B, temp);
   807  	}
   808  
   809  	delete c_B_temp;
   810  	delete c_B_small;
   811  
   812  	co_B = ped_.commit_opt(B_bar, r_B_bar);
   813  	//cout<<"Verifier check_B, B "<<t_B<<" "<<co_B<<endl;
   814  	b = (t_B == co_B);
   815  }
   816  
   817  void Verifier_toom::check_B_red(bool &b)
   818  {
   819  	long i, j;
   820  	Mod_p temp, temp_1, t_B, co_B;
   821  	vector<Mod_p> *c_B_temp = new vector<Mod_p>(m_r + 1);
   822  
   823  	c_B_temp->at(0) = c_B0;
   824  	for (i = 0; i < m_r; i++)
   825  	{
   826  		temp = c_B_small->at(4 * i);
   827  		for (j = 1; j < mu; j++)
   828  		{
   829  			Mod_p::expo(temp_1, c_B_small->at(4 * i + j), chal_x6->at(j - 1));
   830  			Mod_p::mult(temp, temp, temp_1);
   831  		}
   832  		c_B_temp->at(i + 1) = temp;
   833  	}
   834  	t_B = c_B_temp->at(0);
   835  	for (i = 1; i < m_r + 1; i++)
   836  	{
   837  		Mod_p::expo(temp, c_B_temp->at(i), chal_x8->at(i - 1));
   838  		Mod_p::mult(t_B, t_B, temp);
   839  	}
   840  	delete c_B_temp;
   841  	co_B = ped_.commit_opt(B_bar, r_B_bar);
   842  	//cout<<"Verifier check_B_red B "<<t_B<<endl;
   843  	//cout<<"B "<<co_B<<endl;
   844  	b = (t_B == co_B);
   845  }
   846  
   847  void Verifier_toom::check_a(bool &b)
   848  {
   849  	long i;
   850  	Mod_p t_a, co_a;
   851  	vector<ZZ> *chal_temp = new vector<ZZ>(8);
   852  
   853  	chal_temp->at(0) = 1;
   854  	for (i = 1; i < 8; i++)
   855  	{
   856  		chal_temp->at(i) = chal_x8->at(i - 1);
   857  	}
   858  	multi_expo::multi_expo_LL(t_a, c_a, chal_temp, omega_sw);
   859  	co_a = ped_.commit_sw(a_bar, r_a_bar);
   860  
   861  	//cout<<"a "<<t_a<<" "<<co_a<<" "<<c_a->at(4)<<endl;
   862  	delete chal_temp;
   863  	b = (t_a == co_a);
   864  }
   865  
   866  void Verifier_toom::check_c(vector<vector<Cipher_elg> *> *enc, bool &b)
   867  {
   868  	Cipher_elg c, C;
   869  
   870  	calculate_c(c, enc);
   871  
   872  	calculate_C(C, C_c, chal_x6);
   873  
   874  	b = ((C_c->at(mu - 1) == c) & (E->at(4) == C));
   875  }
   876  
   877  void Verifier_toom::check_c_red(bool &b)
   878  {
   879  	Cipher_elg C;
   880  
   881  	calculate_C(C, C_c, chal_x6);
   882  	//cout<<C<<endl;
   883  	//cout<<E->at(4)<<endl;
   884  	b = (E->at(4) == C);
   885  }
   886  
   887  void Verifier_toom::check_E(vector<vector<Cipher_elg> *> *C, bool &b)
   888  {
   889  	long i, j;
   890  	Mod_p temp;
   891  	Mod_p gen = H.get_gen();
   892  	Cipher_elg temp_1, temp_2, t_D, c_D;
   893  	vector<ZZ> *chal_1_temp = new vector<ZZ>(4);
   894  	vector<ZZ> *chal_2_temp = new vector<ZZ>(4);
   895  
   896  	for (i = 0; i < 3; i++)
   897  	{
   898  		chal_1_temp->at(i) = chal_x6->at(2 - i);
   899  	}
   900  	chal_1_temp->at(3) = 1;
   901  
   902  	for (i = 0; i < m_r; i++)
   903  	{
   904  		C_small->at(i) = new vector<Cipher_elg>(n);
   905  	}
   906  
   907  	{
   908  //PARALLELIZE
   909  #pragma omp parallel for collapse(2) num_threads(num_threads) if (parallel)
   910  		for (i = 0; i < m_r; i++)
   911  		{
   912  			//#pragma omp parallel for num_threads(num_threads) if(parallel)
   913  			for (j = 0; j < n; j++)
   914  			{
   915  				multi_expo::multi_expo_LL(C_small->at(i)->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), chal_1_temp, omega_sw);
   916  			}
   917  		}
   918  	}
   919  
   920  	for (i = 0; i < 3; i++)
   921  	{
   922  		chal_2_temp->at(i) = chal_x8->at(2 - i);
   923  	}
   924  	chal_2_temp->at(3) = to_ZZ(1);
   925  
   926  	Mod_p::expo(temp, gen, a_bar);
   927  	temp_1 = elgammal_->encrypt(temp, rho_bar);
   928  	multi_expo::expo_mult(temp_2, C_small, chal_2_temp, B_bar, omega);
   929  	Cipher_elg::mult(c_D, temp_1, temp_2);
   930  	//c_D=temp_1*temp_2;
   931  
   932  	multi_expo::expo_mult(t_D, E, basis_chal_x8, omega);
   933  
   934  	delete chal_1_temp;
   935  	delete chal_2_temp;
   936  	Functions::delete_vector(C_small);
   937  	//	cout<<"E"<<t_D<<endl;
   938  	//	cout<<"E"<<c_D<<endl;
   939  	b = (t_D == c_D);
   940  }
   941  
   942  void Verifier_toom::check_E_red(vector<vector<Cipher_elg> *> *C, bool &b)
   943  {
   944  	long i, j, l;
   945  	Mod_p temp;
   946  	Mod_p gen = H.get_gen();
   947  	Cipher_elg temp_1, temp_2, t_D, c_D;
   948  	vector<ZZ> *x_temp = new vector<ZZ>(4);
   949  	vector<ZZ> *chal_1_temp = new vector<ZZ>(4);
   950  	vector<ZZ> *chal_2_temp = new vector<ZZ>(4);
   951  	vector<vector<Cipher_elg> *> *C_small_temp = 0;
   952  	//vector<Cipher_elg>* row_C;
   953  
   954  	for (i = 0; i < 3; i++)
   955  	{
   956  		x_temp->at(i) = x->at(2 - i);
   957  	}
   958  	x_temp->at(3) = 1;
   959  
   960  	l = mu * m_r;
   961  
   962  	for (i = 0; i < l; i++)
   963  	{
   964  		C_small->at(i) = new vector<Cipher_elg>(n);
   965  	}
   966  
   967  #pragma omp parallel for collapse(2) num_threads(num_threads) if (parallel)
   968  	for (i = 0; i < l; i++)
   969  	{
   970  		//row_C = new vector<Cipher_elg>(n);
   971  		for (j = 0; j < n; j++)
   972  		{
   973  			multi_expo::multi_expo_LL(C_small->at(i)->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_sw);
   974  		}
   975  		//C_small->at(i)=row_C;
   976  	}
   977  
   978  	for (i = 0; i < 3; i++)
   979  	{
   980  		chal_1_temp->at(i) = chal_x6->at(2 - i);
   981  	}
   982  	chal_1_temp->at(3) = 1;
   983  
   984  	C_small_temp = new vector<vector<Cipher_elg> *>(m_r);
   985  	for (i = 0; i < m_r; i++)
   986  	{
   987  		C_small_temp->at(i) = new vector<Cipher_elg>(n);
   988  	}
   989  
   990  #pragma omp parallel for collapse(2) num_threads(num_threads) if (parallel)
   991  	for (i = 0; i < m_r; i++)
   992  	{
   993  		for (j = 0; j < n; j++)
   994  		{
   995  			multi_expo::multi_expo_LL(C_small_temp->at(i)->at(j), C_small->at(4 * i)->at(j), C_small->at(4 * i + 1)->at(j), C_small->at(4 * i + 2)->at(j), C_small->at(4 * i + 3)->at(j), chal_1_temp, omega);
   996  		}
   997  	}
   998  
   999  	for (i = 0; i < 3; i++)
  1000  	{
  1001  		chal_2_temp->at(i) = chal_x8->at(2 - i);
  1002  	}
  1003  	chal_2_temp->at(3) = to_ZZ(1);
  1004  
  1005  	Mod_p::expo(temp, gen, a_bar);
  1006  	temp_2 = elgammal_->encrypt(temp, rho_bar);
  1007  	multi_expo::expo_mult(temp_1, C_small_temp, chal_2_temp, B_bar, omega);
  1008  	Cipher_elg::mult(c_D, temp_1, temp_2);
  1009  	//c_D=temp_2*temp_1;
  1010  
  1011  	multi_expo::expo_mult(t_D, E, basis_chal_x8, omega);
  1012  	Functions::delete_vector(C_small);
  1013  	Functions::delete_vector(C_small_temp);
  1014  	delete chal_2_temp;
  1015  	delete chal_1_temp;
  1016  	delete x_temp;
  1017  	//cout<<"E"<<t_D<<endl;
  1018  	//cout<<"E"<<c_D<<endl;
  1019  	b = (t_D == c_D);
  1020  }
  1021  
  1022  void Verifier_toom::check_ac(bool &b)
  1023  {
  1024  	Mod_p t_a_c, co_a_c, temp;
  1025  	int i;
  1026  
  1027  	t_a_c = c_a_c->at(0);
  1028  	for (i = 1; i < 7; i++)
  1029  	{
  1030  		Mod_p::expo(temp, c_a_c->at(i), chal_x6->at(i - 1));
  1031  		Mod_p::mult(t_a_c, t_a_c, temp);
  1032  	}
  1033  	co_a_c = ped_.commit_sw(a_c_bar, r_ac_bar);
  1034  	//	cout<<"ac "<<t_a_c<<" "<<c_a_c;
  1035  	b = (t_a_c == co_a_c);
  1036  }