void addTheseMatrices(FHESecKey& sKey, const std::set<long>& automVals, long keyID) { std::set<long>::iterator it; for (it=automVals.begin(); it!=automVals.end(); ++it) { long k = *it; sKey.GenKeySWmatrix(1, k, keyID, keyID); } sKey.setKeySwitchMap(); // re-compute the key-switching map }
void addMinimal1DMatrices(FHESecKey& sKey, long keyID) { const FHEcontext &context = sKey.getContext(); // key-switching matrices for the automorphisms for (long i: range(context.zMStar.numOfGens())) { addMinimal1Dmats4dim(sKey, i, keyID); } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// Generate all Frobenius matrices of the form s(X^{p^i})->s(X) void addSomeFrbMatrices(FHESecKey& sKey, long bound, long keyID) { const FHEcontext &context = sKey.getContext(); if (bound >= LONG(context.zMStar.getOrdP())) add1Dmats4dim(sKey, -1, keyID); else // For generators of large order, add only some of the powers addSome1Dmats4dim(sKey, -1, bound, keyID); sKey.setKeySwitchMap(); // re-compute the key-switching map }
// generate only matrices of the form s(X^{g^i})->s(X), but not all of them. // For a generator g whose order is larger than bound, generate only enough // matrices for the giant-step/baby-step procedures (2*sqrt(ord(g))of them). void addSome1DMatrices(FHESecKey& sKey, long bound, long keyID) { const FHEcontext &context = sKey.getContext(); long m = context.zMStar.getM(); // key-switching matrices for the automorphisms for (long i = 0; i < (long)context.zMStar.numOfGens(); i++) { // For generators of small order, add all the powers if (bound >= (long)context.zMStar.OrderOf(i)) for (long j = 1; j < (long)context.zMStar.OrderOf(i); j++) { long val = PowerMod(context.zMStar.ZmStarGen(i), j, m); // val = g^j // From s(X^val) to s(X) sKey.GenKeySWmatrix(1, val, keyID, keyID); if (!context.zMStar.SameOrd(i)) // also from s(X^{1/val}) to s(X) sKey.GenKeySWmatrix(1, InvMod(val,m), keyID, keyID); } else { // For generators of large order, add only some of the powers long num = SqrRoot(context.zMStar.OrderOf(i)); // floor(ord^{1/2}) if (num*num < (long) context.zMStar.OrderOf(i)) num++; // ceil(ord^{1/2}) // VJS: the above two lines replaces the following inexact calculation // with an exact calculation // long num = ceil(sqrt((double)context.zMStar.OrderOf(i))); for (long j=1; j <= num; j++) { // Add matrices for g^j and g^{j*num} long val1 = PowerMod(context.zMStar.ZmStarGen(i), j, m); // g^j long val2 = PowerMod(context.zMStar.ZmStarGen(i),num*j,m);// g^{j*num} if (j < num) { sKey.GenKeySWmatrix(1, val1, keyID, keyID); sKey.GenKeySWmatrix(1, val2, keyID, keyID); } if (!context.zMStar.SameOrd(i)) { // sKey.GenKeySWmatrix(1, InvMod(val1,m), keyID, keyID); sKey.GenKeySWmatrix(1, InvMod(val2,m), keyID, keyID); } } // VJS: experimantal feature...because the replication code // uses rotations by -1, -2, -4, -8, we add a few // of these as well...only the small ones are important, // and we only need them if SameOrd(i)... // Note: we do indeed get a nontrivial speed-up if (context.zMStar.SameOrd(i)) { for (long k = 1; k <= num; k = 2*k) { long j = context.zMStar.OrderOf(i) - k; long val = PowerMod(context.zMStar.ZmStarGen(i), j, m); // val = g^j sKey.GenKeySWmatrix(1, val, keyID, keyID); } } } } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// Generate all Frobenius matrices of the form s(X^{2^i})->s(X) void addFrbMatrices(FHESecKey& sKey, long keyID) { const FHEcontext &context = sKey.getContext(); long m = context.zMStar.getM(); for (long j = 1; j < (long)context.zMStar.getOrdP(); j++) { long val = PowerMod(context.zMStar.getP(), j, m); // val = p^j mod m sKey.GenKeySWmatrix(1, val, keyID, keyID); } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// A maximalistic approach: generate matrices s(X^e)->s(X) for all e \in Zm* void addAllMatrices(FHESecKey& sKey, long keyID) { const FHEcontext &context = sKey.getContext(); long m = context.zMStar.getM(); // key-switching matrices for the automorphisms for (long i = 0; i < m; i++) { if (!context.zMStar.inZmStar(i)) continue; sKey.GenKeySWmatrix(1, i, keyID, keyID); } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// generate only matrices of the form s(X^{g^i})->s(X), but not all of them. // For a generator g whose order is larger than bound, generate only enough // matrices for the giant-step/baby-step procedures (2*sqrt(ord(g))of them). void addSome1DMatrices(FHESecKey& sKey, long bound, long keyID) { const FHEcontext &context = sKey.getContext(); // key-switching matrices for the automorphisms for (long i: range(context.zMStar.numOfGens())) { // For generators of small order, add all the powers if (bound >= context.zMStar.OrderOf(i)) add1Dmats4dim(sKey, i, keyID); else // For generators of large order, add only some of the powers addSome1Dmats4dim(sKey, i, bound, keyID); } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// generate all matrices of the form s(X^{g^i})->s(X) for generators g of // Zm* /<2> and i<ord(g). If g has different orders in Zm* and Zm* /<2> // then generate also matrices of the form s(X^{g^{-i}})->s(X) void add1DMatrices(FHESecKey& sKey, long keyID) { const FHEcontext &context = sKey.getContext(); long m = context.zMStar.getM(); // key-switching matrices for the automorphisms for (long i = 0; i < (long)context.zMStar.numOfGens(); i++) { for (long j = 1; j < (long)context.zMStar.OrderOf(i); j++) { long val = PowerMod(context.zMStar.ZmStarGen(i), j, m); // val = g^j // From s(X^val) to s(X) sKey.GenKeySWmatrix(1, val, keyID, keyID); if (!context.zMStar.SameOrd(i)) // also from s(X^{1/val}) to s(X) sKey.GenKeySWmatrix(1, InvMod(val,m), keyID, keyID); } } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// Generate all key-switching matrices for a given permutation network void addMatrices4Network(FHESecKey& sKey, const PermNetwork& net, long keyID) { const FHEcontext &context = sKey.getContext(); long m = context.zMStar.getM(); for (long i=0; i<net.depth(); i++) { long e = net.getLayer(i).getE(); long gIdx = net.getLayer(i).getGenIdx(); long g = context.zMStar.ZmStarGen(gIdx); long g2e = PowerMod(g, e, m); // g^e mod m const Vec<long>&shamts = net.getLayer(i).getShifts(); for (long j=0; j<shamts.length(); j++) { if (shamts[j]==0) continue; long val = PowerMod(g2e, shamts[j], m); sKey.GenKeySWmatrix(1, val, keyID, keyID); } } sKey.setKeySwitchMap(); // re-compute the key-switching map }
// Generate all Frobenius matrices of the form s(X^{p^i})->s(X) void addMinimalFrbMatrices(FHESecKey& sKey, long keyID) { addMinimal1Dmats4dim(sKey, -1, keyID); sKey.setKeySwitchMap(); // re-compute the key-switching map }