bool test(accelerator_view &rv) { int data[] = {0, 0, 0, 0}; vector<int> Flags(data, data + sizeof(data) / sizeof(int)); extent<1> eflags(sizeof(data) / sizeof(int)); array<int, 1> aFlag(eflags, Flags.begin(), rv); const int size = 100; vector<int> A(size); vector<c> G(size); vector<c> G2(size); for(int i = 0; i < size; i++) { A[i] = INIT_VALUE; G[i].i = G[i].d = G[i].ui = G[i].f = i; G2[i].i = G2[i].d = G2[i].ui = G2[i].f = i; } extent<1> e(size); extent<2> eG(10, 10); array<int, 1> aA(e, A.begin(), rv); array<c, 2> aG(eG, G.begin(), rv); array<c, 2> aG2(eG, G2.begin(), rv); parallel_for_each(aA.get_extent(), [&](index<1>idx) __GPU { c *p = NULL; if (aFlag[0] == 0) p = &aG[0][0]; else p = &aG2[0][0]; double di = 0; for (int i = 0; i < 100; i++) { if (!Equal((*p).i, (int)i) || !Equal((*p).d, di) || !Equal((*p).ui, (unsigned __int32)i) || !Equal((*p).f, (float)i)) { aA[idx] = 1; } p++; di++; } });
int main() { // Timer auto start = std::chrono::steady_clock::now(); auto end = std::chrono::steady_clock::now(); std::cout << "Timings:" << std::endl; // Precomputation in the clear ECPrecomputation<FV::mess_t> precomputation; // Point G and variable for G+G ECPoint<FV::mess_t> G(G_x, G_y, G_z, G_t), GpG; // Compute 4G = (G+G)+(G+G) with 2 EC additions start = std::chrono::steady_clock::now(); ec_addition(GpG, G, G, precomputation); ec_addition(GpG, GpG, GpG, precomputation); end = std::chrono::steady_clock::now(); std::cout << "\tEC Addition in clear: \t\t" << get_time_us(start, end, 2) << " us" << std::endl; FV::mess_t result_x = GpG.X + FV::params::plaintextModulus<mpz_class>::value(); FV::mess_t result_y = GpG.Y + FV::params::plaintextModulus<mpz_class>::value(); // Multiply by the inverse of Z FV::mess_t iZ = GpG.Z.invert(); GpG.X *= iZ; GpG.Y *= iZ; /** * Let's do it homomorphically */ // Keygen start = std::chrono::steady_clock::now(); FV::sk_t secret_key; end = std::chrono::steady_clock::now(); std::cout << "\tSecret key generation: \t\t" << get_time_us(start, end, 1) << " us" << std::endl; start = std::chrono::steady_clock::now(); FV::evk_t evaluation_key(secret_key, 32); end = std::chrono::steady_clock::now(); std::cout << "\tEvaluation key generation: \t" << get_time_us(start, end, 1) << " us" << std::endl; start = std::chrono::steady_clock::now(); FV::pk_t public_key(secret_key, evaluation_key); end = std::chrono::steady_clock::now(); std::cout << "\tPublic key generation: \t\t" << get_time_us(start, end, 1) << " us" << std::endl; // Precomputation ECPrecomputation<FV::ciphertext_t> precomputation_encrypted; // Point G and variable for G+G FV::ciphertext_t eG_x, eG_y, eG_z, eG_t; FV::mess_t mG_x(G_x), mG_y(G_y), mG_z(G_z), mG_t(G_t); start = std::chrono::steady_clock::now(); FV::encrypt(eG_x, public_key, mG_x); FV::encrypt(eG_y, public_key, mG_y); FV::encrypt(eG_z, public_key, mG_z); FV::encrypt(eG_t, public_key, mG_t); end = std::chrono::steady_clock::now(); std::cout << "\tPoint Encryption: \t\t" << get_time_us(start, end, 1) << " us" << std::endl; ECPoint<FV::ciphertext_t> eG(eG_x, eG_y, eG_z, eG_t), eGpG; // Compute 4G = (G+G)+(G+G) with 2 EC additions start = std::chrono::steady_clock::now(); ec_addition<FV::ciphertext_t>(eGpG, eG, eG, precomputation_encrypted); ec_addition<FV::ciphertext_t>(eGpG, eGpG, eGpG, precomputation_encrypted); end = std::chrono::steady_clock::now(); std::cout << "\tHomom. EC Addition: \t\t" << get_time_us(start, end, 2) / 1000 << " ms" << std::endl; start = std::chrono::steady_clock::now(); FV::decrypt(mG_x, secret_key, public_key, eGpG.X); FV::decrypt(mG_y, secret_key, public_key, eGpG.Y); FV::decrypt(mG_z, secret_key, public_key, eGpG.Z); FV::decrypt(mG_t, secret_key, public_key, eGpG.T); end = std::chrono::steady_clock::now(); std::cout << "\tEC Point Decryption: \t\t" << get_time_us(start, end, 1) << " us" << std::endl; // Noise unsigned noise_x = noise(mG_x, secret_key, public_key, eGpG.X); std::cout << "noise in ciphertext: \t" << noise_x << "/" << public_key.noise_max << std::endl; // Multiply by the inverse of Z FV::mess_t invZ = mG_z.invert(); mG_x *= invZ; mG_y *= invZ; // Results std::cout << "4*G (clear): \t\t(" << GpG.X << "," << GpG.Y << ")" << std::endl; std::cout << "4*G (enc.): \t\t(" << mG_x << "," << mG_y << ")" << std::endl; return 0; }