// recrypt all ctxt at level < belowLvl void packedRecrypt(const CtPtrs& array, const std::vector<zzX>& unpackConsts, const EncryptedArray& ea, long belowLvl) { std::vector<Ctxt*> v; for (long i=0; i<array.size(); i++) if ( array.isSet(i) && !array[i]->isEmpty() && array[i]->findBaseLevel()<belowLvl ) v.push_back(array[i]); packedRecrypt(CtPtrs_vectorPt(v), unpackConsts, ea); }
void packedRecrypt(const CtPtrMat& m, const std::vector<zzX>& unpackConsts, const EncryptedArray& ea, long belowLvl) { std::vector<Ctxt*> v; for (long i=0; i<m.size(); i++) for (long j=0; j<m[i].size(); j++) if ( m[i].isSet(j) && !m[i][j]->isEmpty() && m[i][j]->findBaseLevel()<belowLvl ) v.push_back(m[i][j]); packedRecrypt(CtPtrs_vectorPt(v), unpackConsts, ea); }
// For an n-size array, compute the 2^n products // products[j] = \prod_{i s.t. j_i=1} array[i] // \times \prod_{i s.t. j_i=0}(a-array[i]) void computeAllProducts(/*Output*/CtPtrs& products, /*Index*/const CtPtrs& array, std::vector<zzX>* unpackSlotEncoding) { FHE_TIMER_START; long nBits = array.size(); if (lsize(products)>0) { long nBits2 = NTL::NumBits(lsize(products)-1); // ceil(log_2(size)) if (nBits>nBits2) nBits=nBits2; // ignore extra bits in 'array' } if (nBits<1) return; // do nothing assert(nBits <= 16); // Output cannot be bigger than 2^16 if (lsize(products)==0) // try to set the output size products.resize(1L << nBits, &array); for (long i=0; i<lsize(products); i++) products[i]->clear(); // Check that we have enough levels, try to bootstrap otherwise assert(array.ptr2nonNull() != nullptr); long bpl = array.ptr2nonNull()->getContext().BPL(); if (findMinBitCapacity(array) < (NTL::NumBits(nBits)+1)*bpl) { const Ctxt* ct = array.ptr2nonNull(); // find some non-null Ctxt assert(unpackSlotEncoding!=nullptr); assert(ct!=nullptr); assert(ct->getPubKey().isBootstrappable()); packedRecrypt(array, *unpackSlotEncoding, *(ct->getContext().ea), /*belowLevel=*/nBits +3); } if (findMinBitCapacity(array) < (NTL::NumBits(nBits)+1)*bpl) throw std::logic_error("not enough levels for table lookup"); // Call the recursive function that copmutes the products recursiveProducts(products, CtPtrs_slice(array,0,nBits)); }