// Return in poly a polynomial with X^i encoded in all the slots static void x2iInSlots(ZZX& poly, long i, vector<ZZX>& xVec, const EncryptedArray& ea) { xVec.resize(ea.size()); ZZX x2i = ZZX(i,1); for (long j=0; j<(long)xVec.size(); j++) xVec[j] = x2i; ea.encode(poly, xVec); }
// return a degree-d irreducible polynomial mod p ZZX makeIrredPoly(long p, long d) { assert(d >= 1); assert(ProbPrime(p)); if (d == 1) return ZZX(1, 1); // the monomial X zz_pBak bak; bak.save(); zz_p::init(p); return to_ZZX(BuildIrred_zz_pX(d)); }
void mapPowerfulToPoly(ZZX& poly, const Vec<long>& pow, const Vec<long>& divVec, long m, const ZZX& phimX) { long k = pow.length(); assert(divVec.length() == k); long j = 0; for (long i = 0; i < k; i++) j += pow[i] * divVec[i]; j %= m; ZZX f = ZZX(j, 1); poly = f % phimX; }
/** * @brief Extract coefficients from ciphertext polynomial * @param coeffs extracted coefficients * @param ctxt ciphertext * @param n extract "n" lowest degree coefficients */ void extractCoeffs(EncryptedArray& ea, vector<Ctxt>& coeffs, Ctxt& ctxt, long n) { long d = ea.getDegree(); if (d < n) n = d; coeffs.clear(); vector<Ctxt> conj; for (int coeff = 0; coeff < n; ++coeff) { vector<ZZX> LM(d); LM[coeff] = ZZX(0, 1); // "building" the linearized-polynomial coefficients vector<ZZX> C(d); ea.buildLinPolyCoeffs(C, LM); coeffs.push_back(ctxt); applyLinPoly1(ea, coeffs[coeff], C, conj); } }
void mapPowerfulToPoly(ZZX& poly, const Vec<long>& pow, const Vec<long>& divVec, long m, const ZZX& phimX) { long k = pow.length(); //OLD: assert(divVec.length() == k); helib::assertEq(divVec.length(), k, "pow and divVec have different sizes"); long j = 0; for (long i = 0; i < k; i++) j += pow[i] * divVec[i]; j %= m; ZZX f = ZZX(j, 1); poly = f % phimX; }
int main() { string * tmp_ptr; long LLL, DDD, KKK ; long m; long ccc; FHEcontext * context_ptr; FHESecKey * fhekey_ptr; EncryptedArray * ea_ptr; LLL = 682; DDD=12; KKK=80; /* pair<long, long> m_c = get_m_c(LLL, DDD, KKK); m = m_c.first; ccc = m_c.second; */ m = 15709; ccc = 3; context_ptr = new FHEcontext(m, 2, 1); buildModChain(*context_ptr, DDD, ccc); fhekey_ptr = new FHESecKey(*context_ptr); fhekey_ptr->clear(); fhekey_ptr->GenSecKey(64,2); addSome1DMatrices(*fhekey_ptr); const FHEPubKey & pub_key = *fhekey_ptr; ZZX G; G = ZZX(1,1); ea_ptr = new EncryptedArray(*context_ptr, G); // Test I/O, write context and public key, then try to read them back cout << "KEY\n"; cout <<"L= " <<LLL<< " D= " << DDD<< " K= " << KKK << endl<< flush; { stringstream s1; writeContextBase(s1, *context_ptr); s1 << *context_ptr; string s2 = s1.str(); cout << s2 << endl; // output context also to external cout // Read back context from input stream (s3) unsigned long m1, p1, r1; stringstream s3(s2); readContextBase(s3, m1, p1, r1); FHEcontext c1(m1, p1, r1); s3 >> c1; assert(c1 == *context_ptr); } { stringstream s1; s1 << pub_key; string s2 = s1.str(); cout << s2 <<"\nENDKEY" << endl; // output public key also to external cout // Read back cpublic key from input stream (s3) stringstream s3(s2); FHEPubKey pk1(*context_ptr); s3 >> pk1; assert(pk1 == pub_key); } }
void TestIt(long R, long p, long r, long d, long c, long k, long w, long L, long m) { cerr << "\n\n******** TestIt: R=" << R << ", p=" << p << ", r=" << r << ", d=" << d << ", c=" << c << ", k=" << k << ", w=" << w << ", L=" << L << ", m=" << m << endl; FHEcontext context(m, p, r); buildModChain(context, L, c); // context.lazy = false; if (context.lazy) cerr << "LAZY REDUCTIONS\n"; else cerr << "NON-LAZY REDUCTIONS\n"; context.zMStar.printout(); cerr << endl; #ifdef DEBUG cerr << context << endl; #endif FHESecKey secretKey(context); const FHEPubKey& publicKey = secretKey; secretKey.GenSecKey(w); // A Hamming-weight-w secret key ZZX G; if (d == 0) { G = context.alMod.getFactorsOverZZ()[0]; d = deg(G); } else G = makeIrredPoly(p, d); cerr << "G = " << G << "\n"; cerr << "generating key-switching matrices... "; addSome1DMatrices(secretKey); // compute key-switching matrices that we need addFrbMatrices(secretKey); // compute key-switching matrices that we need cerr << "done\n"; cerr << "computing masks and tables for rotation..."; EncryptedArray ea(context, G); cerr << "done\n"; long nslots = ea.size(); // L selects even coefficients vector<ZZX> LM(d); for (long j = 0; j < d; j++) if (j % 2 == 0) LM[j] = ZZX(j, 1); vector<ZZX> C; ea.buildLinPolyCoeffs(C, LM); PlaintextArray p0(ea); p0.random(); Ctxt c0(publicKey); ea.encrypt(c0, publicKey, p0); Ctxt res(c0); applyLinPoly1(ea, res, C); PlaintextArray pp0(ea); ea.decrypt(res, secretKey, pp0); p0.print(cout); cout << "\n"; pp0.print(cout); cout << "\n"; }