void berlekamp(vec_pair_ZZ_pX_long& factors, const ZZ_pX& f, long verbose) { double t; vec_pair_ZZ_pX_long sfd; vec_ZZ_pX x; if (!IsOne(LeadCoeff(f))) Error("berlekamp: bad args"); if (verbose) { cerr << "square-free decomposition..."; t = GetTime(); } SquareFreeDecomp(sfd, f); if (verbose) cerr << (GetTime()-t) << "\n"; factors.SetLength(0); long i, j; for (i = 0; i < sfd.length(); i++) { if (verbose) { cerr << "factoring multiplicity " << sfd[i].b << ", deg = " << deg(sfd[i].a) << "\n"; } SFBerlekamp(x, sfd[i].a, verbose); for (j = 0; j < x.length(); j++) append(factors, cons(x[j], sfd[i].b)); } }
// return an array such that alphas[i] \in R[X]/G(X) represent the // same element as rt = (p mod Ft) \in R[X]/Ft(X) where t=T[i]. // If the optional map pointer is non-NULL, then (*map)[i] contains // the output of mapToFt(...G,T[i]). template<> void PAlgebraModTmpl<GF2X,vec_GF2X,GF2XModulus>::decodePlaintext( vector<GF2X>& alphas, const GF2X& ptxt, const GF2X &G, const vector<GF2X>& 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<GF2X> 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); GF2E::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] GF2EX Qi; conv(Qi,(GF2X&)factors[i]); vec_GF2EX FRts=SFBerlekamp(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 GF2EX GRti = to_GF2EX((GF2X&)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 } GF2EX 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)); } }