// Add/subtract a ciphertext part to a ciphertext. // With negative=true we subtract, otherwise we add. void Ctxt::addPart(const DoubleCRT& part, const SKHandle& handle, bool matchPrimeSet, bool negative) { FHE_TIMER_START; assert (&part.getContext() == &context); if (parts.size()==0) { // inserting 1st part primeSet = part.getIndexSet(); parts.push_back(CtxtPart(part,handle)); if (negative) parts.back().Negate(); // not thread-safe?? } else { // adding to a ciphertext with existing parts if (!(part.getIndexSet() <= primeSet)) { // add to the the prime-set of *this, if needed (this is expensive) if (matchPrimeSet) { IndexSet setDiff = part.getIndexSet() / primeSet; // set minus for (size_t i=0; i<parts.size(); i++) parts[i].addPrimes(setDiff); primeSet.insert(setDiff); } else // this should never happen throw std::logic_error("part has too many primes and matchPrimeSet==false"); } DoubleCRT tmp(context, IndexSet::emptySet()); const DoubleCRT* ptr = ∂ // mod-UP the part if needed IndexSet s = primeSet / part.getIndexSet(); if (!empty(s)) { // if need to mod-UP, do it on a temporary copy tmp = part; tmp.addPrimesAndScale(s); ptr = &tmp; } long j = getPartIndexByHandle(handle); if (j>=0) { // found a matching part, add them up if (negative) parts[j] -= *ptr; else parts[j] += *ptr; } else { // no mathing part found, just append this part parts.push_back(CtxtPart(*ptr,handle)); if (negative) parts.back().Negate(); // not thread-safe?? } } }
// Dummy encryption, this procedure just encodes the plaintext in a Ctxt object void Ctxt::DummyEncrypt(const ZZX& ptxt, double size) { if (size < 0.0) { size = ((double) context.zMStar.getPhiM()) * ptxtSpace*ptxtSpace /12.0; } noiseVar = size; primeSet = context.ctxtPrimes; // A single part, with the plaintext as data and handle pointing to 1 long f = rem(context.productOfPrimes(context.ctxtPrimes),ptxtSpace); if (f == 1) { // scale by constant DoubleCRT dcrt(ptxt, context, primeSet); parts.assign(1, CtxtPart(dcrt)); } else { ZZX tmp; MulMod(tmp, ptxt, f, ptxtSpace, /*positive=*/false); DoubleCRT dcrt(tmp, context, primeSet); parts.assign(1, CtxtPart(dcrt)); } }