void PAlgebraModDerived<type>::decodePlaintext( vector<RX>& alphas, const RX& ptxt, const MappingData<type>& mappingData) const { long nSlots = zMStar.getNSlots(); if (isDryRun()) { alphas.assign(nSlots, RX::zero()); return; } // First decompose p into CRT components vector<RX> CRTcomps(nSlots); // allocate space for CRT component CRT_decompose(CRTcomps, ptxt); // CRTcomps[i] = p mod facors[i] if (mappingData.degG==1) { alphas = CRTcomps; return; } alphas.resize(nSlots); REBak bak; bak.save(); mappingData.contextForG.restore(); for (long i=0; i<nSlots; i++) { REX te; conv(te, CRTcomps[i]); // lift i'th CRT componnet to mod G(X) te %= mappingData.rmaps[i]; // reduce CRTcomps[i](Y) mod Qi(Y), over (Z_2[X]/G(X)) // the free term (no Y component) should be our answer (as a poly(X)) alphas[i] = rep(ConstTerm(te)); } }
template<> void PAlgebraModTmpl<zz_pX,vec_zz_pX,zz_pXModulus>::decodePlaintext( vector<zz_pX>& alphas, const zz_pX& ptxt, const zz_pX &G, const vector<zz_pX>& maps) const { unsigned nSlots = zmStar.NSlots(); if (nSlots==0 || maps.size()!= nSlots ||deg(G)<1|| zmStar.OrdTwo()%deg(G)!=0){ alphas.resize(0); return; } // First decompose p into CRT componsnt vector<zz_pX> CRTcomps(nSlots); // allocate space for CRT component CRT_decompoe(CRTcomps, ptxt); // CRTcomps[i] = p mod facors[i] // Next convert each entry in CRTcomps[] back to base-G representation // (this is roughly the inverse of the embedInSlots operation) // maps contains all the base-G ==> base-Fi maps // SHAI: The code below is supposed to be Nigel's code, borrowed partly // from the constructor Algebra::Algebra(...) and partly from the // function AElement::to_type(2). I don't really unerstand that code, // so hopefully nothing was lost in translation alphas.resize(nSlots); zz_pE::init(G); // the extension field R[X]/G(X) for (unsigned i=0; i<nSlots; i++) { // We need to lift Fi from R[Y] to (R[X]/G(X))[Y] zz_pEX Qi; conv(Qi,(zz_pX&)factors[i]); vec_zz_pEX FRts=SFCanZass(Qi); // factor Fi over Z_2[X]/G(X) // need to choose the right factor, the one that gives us back X int j; for (j=0; j<FRts.length(); j++) { // lift maps[i] to (R[X]/G(X))[Y] and reduce mod j'th factor of Fi zz_pEX GRti = to_zz_pEX((zz_pX&)maps[i]); GRti %= FRts[j]; if (IsX(rep(coeff(GRti,0)))) { // is GRti == X? Qi = FRts[j]; // If so, we found the right factor break; } // If this does not happen then move to the next factor of Fi } zz_pEX te; conv(te,CRTcomps[i]); // lift i'th CRT componnet to mod G(X) te %= Qi; // reduce CRTcomps[i](Y) mod Qi(Y), over (Z_2[X]/G(X)) // the free term (no Y component) should be our answer (as a poly(X)) alphas[i] = rep(coeff(te,0)); } }