void SingleCRT::toPoly(ZZX& poly, const IndexSet& s) const { IndexSet s1 = map.getIndexSet() & s; if (card(s1) == 0) { clear(poly); return; } ZZ p = to_ZZ(context.ithPrime(s1.first())); // the first modulus poly = map[s1.first()]; // Get poly modulo the first prime vec_ZZ& vp = poly.rep; // ensure that coeficient vector is of size phi(m) with entries in [-p/2,p/2] long phim = context.zMstar.phiM(); long vpLength = vp.length(); if (vpLength<phim) { // just in case of leading zeros in poly vp.SetLength(phim); for (long j=vpLength; j<phim; j++) vp[j]=0; } ZZ p_over_2 = p/2; for (long j=0; j<phim; j++) if (vp[j] > p_over_2) vp[j] -= p; // do incremental integer CRT for other levels for (long i = s1.next(s1.first()); i <= s1.last(); i = s1.next(i)) { long q = context.ithPrime(i); // the next modulus // CRT the coefficient vectors of poly and current intVecCRT(vp, p, map[i].rep, q); // defined in the module NumbTh p *= q; // update the modulus } poly.normalize(); // need to call this after we work on the coeffs }
// If the IndexSet is omitted, default to all the primes in the chain void PowerfulDCRT::ZZXtoPowerful(Vec<ZZ>& out, const ZZX& poly, IndexSet set) const { if (empty(set)) set = IndexSet(0, pConvVec.length()-1); zz_pBak bak; bak.save(); // backup NTL's current modulus ZZ product = conv<ZZ>(1L); for (long i = set.first(); i <= set.last(); i = set.next(i)) { pConvVec[i].restoreModulus(); long newPrime = zz_p::modulus(); zz_pX oneRowPoly; conv(oneRowPoly, poly); // reduce mod p and convert to zz_pX HyperCube<zz_p> oneRowPwrfl(indexes.shortSig); pConvVec[i].polyToPowerful(oneRowPwrfl, oneRowPoly); if (i == set.first()) // just copy conv(out, oneRowPwrfl.getData()); else // CRT intVecCRT(out, product, oneRowPwrfl.getData(), newPrime); // in NumbTh product *= newPrime; } }
void PowerfulDCRT::dcrtToPowerful(Vec<ZZ>& out, const DoubleCRT& dcrt) const { const IndexSet& set = dcrt.getIndexSet(); if (empty(set)) { // sanity check clear(out); return; } zz_pBak bak; bak.save(); // backup NTL's current modulus ZZ product = conv<ZZ>(1L); for (long i = set.first(); i <= set.last(); i = set.next(i)) { pConvVec[i].restoreModulus(); zz_pX oneRowPoly; long newPrime = dcrt.getOneRow(oneRowPoly,i); HyperCube<zz_p> oneRowPwrfl(indexes.shortSig); pConvVec[i].polyToPowerful(oneRowPwrfl, oneRowPoly); if (i == set.first()) // just copy conv(out, oneRowPwrfl.getData()); else // CRT intVecCRT(out, product, oneRowPwrfl.getData(), newPrime); // in NumbTh product *= newPrime; } }