in pir_server.cpp [375:410]
inline void PIRServer::decompose_to_plaintexts_ptr(const Ciphertext &encrypted, Plaintext *plain_ptr, int logt) {
vector<Plaintext> result;
auto coeff_count = params_.poly_modulus_degree();
auto coeff_mod_count = params_.coeff_modulus().size();
auto encrypted_count = encrypted.size();
uint64_t t1 = 1 << logt; // t1 <= t.
uint64_t t1minusone = t1 -1;
// A triple for loop. Going over polys, moduli, and decomposed index.
for (int i = 0; i < encrypted_count; i++) {
const uint64_t *encrypted_pointer = encrypted.data(i);
for (int j = 0; j < coeff_mod_count; j++) {
// populate one poly at a time.
// create a polynomial to store the current decomposition value
// which will be copied into the array to populate it at the current
// index.
double logqj = log2(params_.coeff_modulus()[j].value());
//int expansion_ratio = ceil(logqj + exponent - 1) / exponent;
int expansion_ratio = ceil(logqj / logt);
// cout << "local expansion ratio = " << expansion_ratio << endl;
uint64_t curexp = 0;
for (int k = 0; k < expansion_ratio; k++) {
// Decompose here
for (int m = 0; m < coeff_count; m++) {
plain_ptr[i * coeff_mod_count * expansion_ratio
+ j * expansion_ratio + k][m] =
(*(encrypted_pointer + m + (j * coeff_count)) >> curexp) & t1minusone;
}
curexp += logt;
}
}
}
}