ZZX myCRT::DecodeMessage(ZZX &mes){ ZZ t; ZZX res; ZZ_pX mess_p, tm; mess_p = to_ZZ_pX(mes); for(int i=0; i<size; i++){ tm = mess_p%factors[i]; t = rep(coeff(tm,0)); t=t%to_ZZ("2"); SetCoeff(res, i, t); } return res; }
void myCRT::ComputeFactors(int f_degree, int f_size){ factors.SetLength(f_size); int s = 1<<f_degree; ZZ_pX list[s]; for(int i=0; i<s; i++) list[i] = to_ZZ_pX(num2ZZX(i+s)); int j=0; ZZ_pX t1 = modulus; ZZ_pX comp, remin, quo; SetCoeff(comp, 0, 0); for(int i=0; i<s; i++){ DivRem(quo, remin, t1, list[i]); if(remin == comp){ t1 = quo; factors[j] = list[i]; j++; } } size = factors.length(); }
//Comparison protocol based on "" bool COM(bool disp, long long seed, unsigned p, FHEcontext &context) { ZZ seedZZ; seedZZ = seed; srand48(seed); SetSeed(seedZZ); FHESISecKey secretKey(context); const FHESIPubKey &publicKey(secretKey); long phim = context.zMstar.phiM(); ZZ_pX ptxt1Poly, ptxt2Poly, sum, sumMult, prod, prod2, sumQuad; Plaintext resSum, resSumMult, resProd, resProdSwitch, resProd2, resSumQuad; //gen plaintext ptxt1Poly.rep.SetLength(phim); ptxt2Poly.rep.SetLength(phim); for (long i=0; i < phim; i++) { ptxt1Poly.rep[i] = RandomBnd(p); ptxt2Poly.rep[i] = RandomBnd(p); } //printpoly(ptxt1Poly, phim); ptxt1Poly.normalize(); ptxt2Poly.normalize(); #ifdef DEBUG cout<<"phim:"<<phim<<endl; cout<<"p1:"<<endl; printpoly(ptxt1Poly, phim); cout<<"p2:"<<endl; printpoly(ptxt2Poly, phim); #endif //plaintext operation sum = ptxt1Poly + ptxt2Poly; sumMult = ptxt2Poly * 7; prod = ptxt1Poly * ptxt2Poly; prod2 = prod * prod; sumQuad = prod2 * prod2 * 9; //\sum_((xy)^4) #ifdef DEBUG cout<<"sum:"<<endl; printpoly(sum, phim); cout<<"prod2:"<<endl; printpoly(prod2, phim); #endif rem(prod, prod, to_ZZ_pX(context.zMstar.PhimX())); rem(prod2, prod2, to_ZZ_pX(context.zMstar.PhimX())); rem(sumQuad, sumQuad, to_ZZ_pX(context.zMstar.PhimX())); //encryption start = std::clock(); Plaintext ptxt1(context, ptxt1Poly), ptxt2(context, ptxt2Poly); duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC; duration = duration/2; cout<<"Encryption:"<< duration <<'\n'; Ciphertext ctxt1(publicKey), ctxt2(publicKey); publicKey.Encrypt(ctxt1, ptxt1); publicKey.Encrypt(ctxt2, ptxt2); Ciphertext cSum = ctxt1; cSum += ctxt2; Ciphertext cSumMult = ctxt2; start = std::clock(); for (int i = 1; i < 7; i++) { cSumMult += ctxt2; } duration = ( std::clock() - start ) / (double) (CLOCKS_PER_SEC); duration = duration/6; cout<<"Addition:"<< duration <<'\n'; Ciphertext cProd = ctxt1; cProd *= ctxt2; secretKey.Decrypt(resSum, cSum); secretKey.Decrypt(resSumMult, cSumMult); KeySwitchSI keySwitch(secretKey); keySwitch.ApplyKeySwitch(cProd); secretKey.Decrypt(resProd, cProd); cProd *= cProd; Ciphertext tmp = cProd; Ciphertext cSumQuad = cProd; keySwitch.ApplyKeySwitch(cProd); secretKey.Decrypt(resProd2, cProd); for (int i = 0; i < 8; i++) { cSumQuad += tmp; } keySwitch.ApplyKeySwitch(cSumQuad); //apply key switch after summing all prod start = std::clock(); cSumQuad *= cProd; duration = ( std::clock() - start ) / (double) (CLOCKS_PER_SEC); cout<<"HMult without key switch:"<< duration <<'\n'; keySwitch.ApplyKeySwitch(cSumQuad); duration = ( std::clock() - start ) / (double) (CLOCKS_PER_SEC); cout<<"HMult with key switch:"<< duration <<'\n'; start = std::clock(); secretKey.Decrypt(resSumQuad, cSumQuad); duration = ( std::clock() - start ) / (double) (CLOCKS_PER_SEC); cout<<"Decryption:"<< duration <<'\n'; //comparison bool success = ((resSum.message == sum) && (resSumMult.message == sumMult) && (resProd.message == prod) && (resProd2.message == prod2) && (resSumQuad == sumQuad)); if (disp || !success) { cout << "Seed: " << seed << endl << endl; if (resSum.message != sum) { cout << "Add failed." << endl; } if (resSumMult.message != sumMult) { cout << "Adding multiple times failed." << endl; } if (resProd.message != prod) { cout << "Multiply failed." << endl; } if (resProd2.message != prod2) { cout << "Squaring failed." << endl; } if (resSumQuad.message != sumQuad) { cout << "Sum and quad failed." << endl; } } if (disp || !success) { cout << "Test " << (success ? "SUCCEEDED" : "FAILED") << endl; } return success; }
void myCRT::SetModulus(ZZX &m){ modulus = to_ZZ_pX(m); }