コード例 #1
0
ファイル: recryption.cpp プロジェクト: lbathen/HElib
// The main method
void ThinRecryptData::init(const FHEcontext& context, const Vec<long>& mvec_,
		       long t, bool consFlag, bool build_cache_, bool minimal)
{
  if (alMod != NULL) { // were we called for a second time?
    cerr << "@Warning: multiple calls to ThinRecryptData::init\n";
    return;
  }
  assert(computeProd(mvec_) == (long)context.zMStar.getM()); // sanity check

  // Record the arguments to this function
  mvec = mvec_;
  conservative = consFlag;
  build_cache = build_cache_;

  if (t <= 0) t = defSkHwt+1; // recryption key Hwt
  hwt = t;
  long p = context.zMStar.getP();
  long phim = context.zMStar.getPhiM();
  long r = context.alMod.getR();
  long p2r = context.alMod.getPPowR();
  double logp = log((double)p);

  double noise = p2r * sqrt((t+1)*phim/3.0);
  double gamma = 2*(t+noise)/((t+1)*p2r); // ratio between numerators

  long logT = ceil(log((double)(t+2))/logp); // ceil(log_p(t+2))
  double rho = (t+1)/pow(p,logT);

  if (!conservative) {   // try alpha, e with this "aggresive" setting
    setAlphaE(alpha, e, rho, gamma, noise, logp, p2r, t);
    ePrime = e -r +1 -logT;

    // If e is too large, try again with rho/p instead of rho
    long bound = (1L << (context.bitsPerLevel-1)); // halfSizePrime/2
    if (pow(p,e) > bound) { // try the conservative setting instead
      cerr << "* p^e="<<pow(p,e)<<" is too big (bound="<<bound<<")\n";
      conservative = true;
    }
  }
  if (conservative) { // set alpha, e with a "conservative" rho/p
    setAlphaE(alpha, e, rho/p, gamma, noise, logp, p2r, t);
    ePrime = e -r -logT;
  }

  // Compute highest key-Hamming-weight that still works (not more than 256)
  double qOver4 = (pow(p,e)+1)/4;
  for (t-=10; qOver4>=lowerBound2(p,r,ePrime,t,alpha)
	 &&  qOver4>=lowerBound1(p,r,ePrime,t,alpha,noise) && t<257; t++);
  skHwt = t-1;

  // First part of Bootstrapping works wrt plaintext space p^{r'}
  alMod = new PAlgebraMod(context.zMStar, e-ePrime+r);
  ea = new EncryptedArray(context, *alMod);
         // Polynomial defaults to F0, PAlgebraMod explicitly given

  coeffToSlot = new ThinEvalMap(*ea, minimal, mvec, true, build_cache);
  slotToCoeff = new ThinEvalMap(*context.ea, minimal, mvec, false, build_cache);
}
コード例 #2
0
ファイル: recryption.cpp プロジェクト: fionser/HElib
// The main method
void RecryptData::init(const FHEcontext& context, const Vec<long>& mvec_,
		       long t, bool consFlag, bool build_cache_, bool minimal)
{
  if (alMod != NULL) { // were we called for a second time?
    cerr << "@Warning: multiple calls to RecryptData::init\n";
    return;
  }
  assert(computeProd(mvec_) == (long)context.zMStar.getM()); // sanity check

  // Record the arguments to this function
  mvec = mvec_;
  conservative = consFlag;
  build_cache = build_cache_;

  if (t <= 0) t = defSkHwt+1; // recryption key Hwt
  hwt = t;
  long p = context.zMStar.getP();
  long phim = context.zMStar.getPhiM();
  long r = context.alMod.getR();
  long p2r = context.alMod.getPPowR();
  double logp = log((double)p);

  double noise = p2r * sqrt((t+1)*phim/3.0);
  double gamma = 2*(t+noise)/((t+1)*p2r); // ratio between numerators

  long logT = ceil(log((double)(t+2))/logp); // ceil(log_p(t+2))
  double rho = (t+1)/pow(p,logT);

  if (!conservative) {   // try alpha, e with this "aggresive" setting
    setAlphaE(alpha, e, rho, gamma, noise, logp, p2r, t);
    ePrime = e -r +1 -logT;

    // If e is too large, try again with rho/p instead of rho
    long bound = (1L << (context.bitsPerLevel-1)); // halfSizePrime/2
    if (pow(p,e) > bound) { // try the conservative setting instead
      cerr << "* p^e="<<pow(p,e)<<" is too big (bound="<<bound<<")\n";
      conservative = true;
    }
  }
  if (conservative) { // set alpha, e with a "conservative" rho/p
    setAlphaE(alpha, e, rho/p, gamma, noise, logp, p2r, t);
    ePrime = e -r -logT;
  }

  // Compute highest key-Hamming-weight that still works (not more than 256)
  double qOver4 = (pow(p,e)+1)/4;
  for (t-=10; qOver4>=lowerBound2(p,r,ePrime,t,alpha)
	 &&  qOver4>=lowerBound1(p,r,ePrime,t,alpha,noise) && t<257; t++);
  skHwt = t-1;

  // First part of Bootstrapping works wrt plaintext space p^{r'}
  alMod = new PAlgebraMod(context.zMStar, e-ePrime+r);
  ea = new EncryptedArray(context, *alMod);
         // Polynomial defaults to F0, PAlgebraMod explicitly given


  p2dConv = new PowerfulDCRT(context, mvec);

  // Initialize the linear polynomial for unpacking the slots
  zz_pBak bak; bak.save(); ea->getAlMod().restoreContext();
  long nslots = ea->size();
  long d = ea->getDegree();

  const Mat<zz_p>& CBi=ea->getDerived(PA_zz_p()).getNormalBasisMatrixInverse();

  vector<ZZX> LM;
  LM.resize(d);
  for (long i = 0; i < d; i++) // prepare the linear polynomial
    LM[i] = rep(CBi[i][0]);

  vector<ZZX> C; 
  ea->buildLinPolyCoeffs(C, LM); // "build" the linear polynomial

  unpackSlotEncoding.resize(d);  // encode the coefficients

  for (long j = 0; j < d; j++) {
    vector<ZZX> v(nslots);
    for (long k = 0; k < nslots; k++) v[k] = C[j];
    ea->encode(unpackSlotEncoding[j], v);
  }
  firstMap = new EvalMap(*ea, minimal, mvec, true, build_cache);
  secondMap = new EvalMap(*context.ea, minimal, mvec, false, build_cache);
}