void rotate1D(DoubleCRT& d, long i, long amt, const vector< vector< DoubleCRT > > & maskTable) // rotate d in dimension i by amt { const FHEcontext& context = d.getContext(); const PAlgebra& al = context.zMstar; // const PAlgebraModTwo& al2 = context.modTwo; long ngens = al.numOfGens(); // long nslots = al.NSlots(); assert(i >= 0 && i < ngens); long ord = al.OrderOf(i); amt = amt % ord; if (amt < 0) amt += ord; if (amt == 0) return; if (al.SameOrd(i)) { // "native" rotation long val = PowerMod(al.ZmStarGen(i), amt, al.M()); d.automorph(val); } else { // more expensive "non-native" rotation assert(maskTable[i].size() > 0); long val = PowerMod(al.ZmStarGen(i), amt, al.M()); // long ival = InvMod(val, al.M()); long ival = PowerMod(al.ZmStarGen(i), amt-ord, al.M()); const DoubleCRT& m1 = maskTable[i].at(ord-amt); DoubleCRT d1(d); d1.Mul(m1, false); d -= d1; d.automorph(val); d1.automorph(ival); d += d1; } }