Пример #1
0
// 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));
}
Пример #2
0
// A counterpart of tableLookup. The input is an encrypted table T[]
// and an array of encrypted bits I[], holding the binary representation
// of an index i into T.  This function increments by one the entry T[i].
void tableWriteIn(const CtPtrs& table, const CtPtrs& idx,
                  std::vector<zzX>* unpackSlotEncoding)
{
  FHE_TIMER_START;
  const Ctxt* ct = table.ptr2nonNull(); // find some non-null Ctxt
  long size = lsize(table);
  if (size==0) return;
  std::vector<Ctxt> products(size, Ctxt(ZeroCtxtLike, *ct));  
  CtPtrs_vectorCt pWrap(products); // A wrapper

  // Compute all products of ecnrypted bits =: b_i
  computeAllProducts(pWrap, idx, unpackSlotEncoding);

  // incrememnt each entry of T[i] by products[i]
  NTL_EXEC_RANGE(lsize(table), first, last)
  for(long i=first; i<last; i++)
    *table[i] += products[i];
  NTL_EXEC_RANGE_END
}