Ejemplo n.º 1
0
void totalSums(const EncryptedArray& ea, Ctxt& ctxt)
{
  long n = ea.size();

  if (n == 1) return;

  Ctxt orig = ctxt;

  long k = NumBits(n);
  long e = 1;

  for (long i = k-2; i >= 0; i--) {
    Ctxt tmp1 = ctxt;
    ea.rotate(tmp1, e);
    ctxt += tmp1; // ctxt = ctxt + (ctxt >>> e)
    e = 2*e;

    if (bit(n, i)) {
      Ctxt tmp2 = orig;
      ea.rotate(tmp2, e);
      ctxt += tmp2; // ctxt = ctxt + (orig >>> e)
                    // NOTE: we could have also computed
                    // ctxt =  (ctxt >>> e) + orig, however,
                    // this would give us greater depth/noise
      e += 1;
    }
  }
}
Ejemplo n.º 2
0
void replicateAllOrig(const EncryptedArray& ea, const Ctxt& ctxt,
                      ReplicateHandler *handler, RepAux* repAuxPtr)
{
  long nSlots = ea.size();
  long n = GreatestPowerOfTwo(nSlots); // 2^n <= nSlots

  Ctxt ctxt1 = ctxt;

  if ((1L << n) < nSlots)
    SelectRange(ea, ctxt1, 0, 1L << n);

  RepAux repAux;
  if (repAuxPtr==NULL) repAuxPtr = &repAux;

  recursiveReplicate(ea, ctxt1, n, n, 0, 1L << n, 
                     *repAuxPtr, handler);

  if ((1L << n) < nSlots) {
    ctxt1 = ctxt;
    SelectRange(ea, ctxt1, 1L << n, nSlots);
    ea.rotate(ctxt1, -(1L << n));
    recursiveReplicate(ea, ctxt1, n, n, 1L << n, nSlots, *repAuxPtr, handler);
  }
    
}
Ejemplo n.º 3
0
void benchmark(const EncryptedArray   & ea,
               const FHEPubKey        & pk,
               const FHESecKey        & sk,
               const MDL::Matrix<long>& data)
{
    const long BATCH_SIZE = 5000;
    MDL::Timer encTimer, evalTimer;
    MDL::EncVector mu(pk), sigma(pk);

    for (long part = 0; part *BATCH_SIZE < data.rows(); part++) {
        long from  = std::min<long>(part * BATCH_SIZE, data.rows());
        long to    = std::min<long>(from + BATCH_SIZE, data.rows());
        encTimer.start();
        auto ctxts = encrypt(data, pk, ea, from, to);
        encTimer.end();
        evalTimer.start();

        auto sum = summation(ctxts);
        mu    += sum.first;
        sigma += sum.second;
        evalTimer.end();
    }
    evalTimer.start();
    auto mu_mu = mu.covariance(ea, data.cols());
    NTL::ZZX N;
    std::vector<long> n(ea.size(), data.rows());
    ea.encode(N, n);
    sigma.multByConstant(N);
    for (size_t col = 0; col < data.cols(); col++) {
        ea.rotate(mu_mu[col], col * data.cols());
        sigma -= mu_mu[col];
    }
    evalTimer.end();

    MDL::Vector<long> mat;
    sigma.unpack(mat, sk, ea, true);
    for (int i = 0; i < data.cols(); i++) {
        for (int j = 0; j < data.cols(); j++) {
            std::cout << mat[i * data.cols() + j] << " ";
        }
        std::cout << std::endl;
    }
    printf("Covariance of %zd data, enc %f, eval %f\n", data.rows(),
           encTimer.second(), evalTimer.second());
}
Ejemplo n.º 4
0
static
void recursiveReplicate(const EncryptedArray& ea, const Ctxt& ctxt, 
                        long n, long k, long pos, long limit,  
                        RepAux& repAux,
                        ReplicateHandler *handler)
{
  if (pos >= limit) return;

  if (replicateVerboseFlag) {
    // DEBUG code
    cerr << "check: " << k; CheckCtxt(ctxt, "");
  }

  long nSlots = ea.size();

  if (k == 0) {

    if ( (1L << n) >= nSlots) {
      handler->handle(ctxt);
      return;
    }

    // need to replicate to fill positions [ (1L << n) .. nSlots )
    if (repAux.tab(0).null()) {
      // need to generate mask
      ZZX mask;
      SelectRange(ea, mask, 0, nSlots - (1L << n));
      repAux.tab(0).set_ptr(new DoubleCRT(mask, ea.getContext()));
    }


    Ctxt ctxt_tmp = ctxt;
    ctxt_tmp.multByConstant(*repAux.tab(0));

    ea.rotate(ctxt_tmp, 1L << n);
    ctxt_tmp += ctxt;
    handler->handle(ctxt_tmp);
    return;
  }


  k--;

  Ctxt ctxt_masked = ctxt;

  { // artificial scope to miminize storage in
    // the recursion


    { // another artificial scope

      // mask should be at index k+1

      if (repAux.tab(k+1).null()) {
        // need to generate mask

        vector< long > maskArray;
        maskArray.resize(nSlots);
        for (long i = 0; i < (1L << n); i++)
          maskArray[i] = 1- bit(i, k); // the reverse of bit k of i
        for (long i = (1L << n); i < nSlots; i++)
          maskArray[i] = 0;

        ZZX mask;
        ea.encode(mask, maskArray);
        repAux.tab(k+1).set_ptr(new DoubleCRT(mask, ea.getContext()));
      }

      ctxt_masked.multByConstant(*repAux.tab(k+1));
    }

    Ctxt ctxt_left = ctxt_masked;
    ea.rotate(ctxt_left, 1L << k);
    ctxt_left += ctxt_masked;

    recursiveReplicate(ea, ctxt_left, n, k, pos, limit, repAux, handler);
  
  }
 
  pos += (1L << k);
  if (pos >= limit)
    return;

  Ctxt ctxt_right = ctxt;
  ctxt_right -= ctxt_masked; 
  ctxt_masked = ctxt_right; // reuse ctxt_masked as a temp
  ea.rotate(ctxt_masked, -(1L << k));
  ctxt_right += ctxt_masked;

  recursiveReplicate(ea, ctxt_right, n, k, pos, limit, repAux, handler);
}