예제 #1
0
파일: EvalMap.cpp 프로젝트: shaih/HElib
ThinEvalMap::ThinEvalMap(const EncryptedArray& _ea, 
                 bool minimal,
                 const Vec<long>& mvec, 
                 bool _invert,
                 bool build_cache)

  : ea(_ea), invert(_invert)
{
  const FHEcontext& context = ea.getContext();
  const PAlgebra& zMStar = ea.getPAlgebra();
  
  long p = zMStar.getP();
  long d = zMStar.getOrdP();

  // FIXME: we should check that ea was initilized with 
  // G == factors[0], but this is a slight pain to check
  // currently

  // NOTE: this code is derived from a more general setting, and
  // could certainly be greatly simplified

  nfactors = mvec.length();
  //OLD: assert(nfactors > 0);
  helib::assertTrue(nfactors > 0, "Invalid argument: mvec must have positive length");

  for (long i = 0; i < nfactors; i++) {
    for (long j = i+1; j < nfactors; j++) {
      helib::assertEq(GCD(mvec[i], mvec[j]), 1l, "Invalid argument: mvec must have pairwise-disjoint entries");
    }
  }

  long m = computeProd(mvec);
  //OLD: assert(m == long(zMStar.getM()));
  helib::assertEq(m, (long)zMStar.getM(), "Invalid argument: mvec's product does not match ea's m");

  Vec<long> phivec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)  phivec[i] = phi_N(mvec[i]);
  long phim = computeProd(phivec);

  Vec<long> dprodvec(INIT_SIZE, nfactors+1);
  dprodvec[nfactors] = 1;
  
  for (long i = nfactors-1; i >= 0; i--)
    dprodvec[i] = dprodvec[i+1] *
      multOrd(PowerMod(p % mvec[i], dprodvec[i+1], mvec[i]), mvec[i]);

  Vec<long> dvec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    dvec[i] = dprodvec[i] / dprodvec[i+1];

  long nslots = phim/d;
  //OLD: assert(d == dprodvec[0]);
  helib::assertEq(d, dprodvec[0], "d must match the first entry of dprodvec");
  //OLD: assert(nslots == long(zMStar.getNSlots()));
  helib::assertEq(nslots, (long)zMStar.getNSlots(), "Invalid argument: mismatch of number of slots");

  long inertPrefix = 0;
  for (long i = 0; i < nfactors && dvec[i] == 1; i++) {
    inertPrefix++;
  }

  if (inertPrefix != nfactors-1)
    throw helib::LogicError("ThinEvalMap: case not handled: bad inertPrefix");

  Vec< Vec<long> > local_reps(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    init_representatives(local_reps[i], i, mvec, zMStar);

  Vec<long> crtvec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++) 
    crtvec[i] = (m/mvec[i]) * InvMod((m/mvec[i]) % mvec[i], mvec[i]);

  Vec<long> redphivec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    redphivec[i] = phivec[i]/dvec[i];

  CubeSignature redphisig(redphivec);

  Vec< shared_ptr<CubeSignature> > sig_sequence;
  sig_sequence.SetLength(nfactors+1);
  sig_sequence[nfactors] = shared_ptr<CubeSignature>(new CubeSignature(phivec));

  Vec<long> reduced_phivec = phivec;

  for (long dim = nfactors-1; dim >= 0; dim--) {
    reduced_phivec[dim] /= dvec[dim];
    sig_sequence[dim] = 
      shared_ptr<CubeSignature>(new CubeSignature(reduced_phivec));
  }

  matvec.SetLength(nfactors);

  if (invert) {
     long dim = nfactors - 1;
     unique_ptr<MatMul1D> mat1_data;
     mat1_data.reset(buildThinStep1Matrix(ea, sig_sequence[dim],
		     local_reps[dim], dim, m/mvec[dim]));
     matvec[dim].reset(new MatMul1DExec(*mat1_data, minimal));
  }
  else {
     long dim = nfactors - 1;
     unique_ptr<MatMul1D> mat1_data;
     mat1_data.reset(buildThinStep2Matrix(ea, sig_sequence[dim],
		     local_reps[dim], dim, m/mvec[dim], invert, /*inflate=*/true));
     matvec[dim].reset(new MatMul1DExec(*mat1_data, minimal));
  }

  for (long dim=nfactors-2; dim>=0; --dim) {
    unique_ptr<MatMul1D> mat_data;

    mat_data.reset(buildThinStep2Matrix(ea, sig_sequence[dim], local_reps[dim],
				       dim, m/mvec[dim], invert));
    matvec[dim].reset(new MatMul1DExec(*mat_data, minimal));
  }

  if (build_cache) upgrade();
}
예제 #2
0
EvalMap::EvalMap(const EncryptedArray& _ea, const Vec<long>& mvec, bool _invert,
                 bool normal_basis)

  : ea(_ea), invert(_invert)
{
  const FHEcontext& context = ea.getContext();
  const PAlgebra& zMStar = context.zMStar;
  
  long p = zMStar.getP();
  long d = zMStar.getOrdP();

  // FIXME: we should check that ea was initilized with 
  // G == factors[0], but this is a slight pain to check
  // currently

  // NOTE: this code is derived from a more general setting, and
  // could certainly be greatly simplified

  nfactors = mvec.length();
  assert(nfactors > 0);

  for (long i = 0; i < nfactors; i++)
    for (long j = i+1; j < nfactors; j++)
      assert(GCD(mvec[i], mvec[j]) == 1);

  long m = computeProd(mvec);
  assert(m == long(zMStar.getM()));

  Vec<long> phivec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)  phivec[i] = phi_N(mvec[i]);
  long phim = computeProd(phivec);

  Vec<long> dprodvec(INIT_SIZE, nfactors+1);
  dprodvec[nfactors] = 1;
  
  for (long i = nfactors-1; i >= 0; i--)
    dprodvec[i] = dprodvec[i+1] *
      multOrd(PowerMod(p % mvec[i], dprodvec[i+1], mvec[i]), mvec[i]);

  Vec<long> dvec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    dvec[i] = dprodvec[i] / dprodvec[i+1];

  long nslots = phim/d;
  assert(d == dprodvec[0]);
  assert(nslots == long(zMStar.getNSlots()));

  long inertPrefix = 0;
  for (long i = 0; i < nfactors && dvec[i] == 1; i++) {
    inertPrefix++;
  }

  if (inertPrefix != nfactors-1)
    Error("EvalMap: case not handled: bad inertPrefix");

  Vec< Vec<long> > local_reps(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    init_representatives(local_reps[i], i, mvec, zMStar);

  Vec<long> crtvec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++) 
    crtvec[i] = (m/mvec[i]) * InvMod((m/mvec[i]) % mvec[i], mvec[i]);

  Vec<long> redphivec(INIT_SIZE, nfactors);
  for (long i = 0; i < nfactors; i++)
    redphivec[i] = phivec[i]/dvec[i];

  CubeSignature redphisig(redphivec);

  Vec< shared_ptr<CubeSignature> > sig_sequence;
  sig_sequence.SetLength(nfactors+1);
  sig_sequence[nfactors] = shared_ptr<CubeSignature>(new CubeSignature(phivec));

  Vec<long> reduced_phivec = phivec;

  for (long dim = nfactors-1; dim >= 0; dim--) {
    reduced_phivec[dim] /= dvec[dim];
    sig_sequence[dim] = 
      shared_ptr<CubeSignature>(new CubeSignature(reduced_phivec));
  }

  long dim = nfactors - 1;
  mat1.reset(buildStep1Matrix(ea, sig_sequence[dim],
       	          local_reps[dim], dim, m/mvec[dim], invert, normal_basis));

  matvec.SetLength(nfactors-1);
  for (dim=nfactors-2; dim>=0; --dim) {
    matvec[dim].reset(buildStep2Matrix(ea, sig_sequence[dim], local_reps[dim],
				       dim, m/mvec[dim], invert));
  }
}