void PAlgebraModDerived<type>::embedInSlots(RX& H, const vector<RX>& alphas, const MappingData<type>& mappingData) const { long nSlots = zMStar.getNSlots(); assert(lsize(alphas) == nSlots); for (long i = 0; i < nSlots; i++) assert(deg(alphas[i]) < mappingData.degG); vector<RX> crt(nSlots); // alloate space for CRT components // The i'th CRT component is (H mod F_t) = alphas[i](maps[i]) mod F_t, // where with t=T[i]. if (IsX(mappingData.G)) { // special case...no need for CompMod, which is // is not optimized for zero for (long i=0; i<nSlots; i++) // crt[i] = alpha(maps[i]) mod Ft crt[i] = ConstTerm(alphas[i]); } else { // general case... for (long i=0; i<nSlots; i++) // crt[i] = alpha(maps[i]) mod Ft CompMod(crt[i], alphas[i], mappingData.maps[i], factors[i]); } CRT_reconstruct(H,crt); // interpolate to get p }
long ProbIrredTest(const ZZ_pEX& f, long iter) { long n = deg(f); if (n <= 0) return 0; if (n == 1) return 1; ZZ_pEXModulus F; build(F, f); ZZ_pEX b, r, s; FrobeniusMap(b, F); long all_zero = 1; long i; for (i = 0; i < iter; i++) { random(r, n); TraceMap(s, r, n, F, b); all_zero = all_zero && IsZero(s); if (deg(s) > 0) return 0; } if (!all_zero || (n & 1)) return 1; PowerCompose(s, b, n/2, F); return !IsX(s); }
void PAlgebraModDerived<type>::embedInAllSlots(RX& H, const RX& alpha, const MappingData<type>& mappingData) const { if (isDryRun()) { H = RX::zero(); return; } FHE_TIMER_START; long nSlots = zMStar.getNSlots(); vector<RX> crt(nSlots); // alloate space for CRT components // The i'th CRT component is (H mod F_t) = alpha(maps[i]) mod F_t, // where with t=T[i]. if (IsX(mappingData.G) || deg(alpha) <= 0) { // special case...no need for CompMod, which is // is not optimized for this case for (long i=0; i<nSlots; i++) // crt[i] = alpha(maps[i]) mod Ft crt[i] = ConstTerm(alpha); } else { // general case... for (long i=0; i<nSlots; i++) // crt[i] = alpha(maps[i]) mod Ft CompMod(crt[i], alpha, mappingData.maps[i], factors[i]); } CRT_reconstruct(H,crt); // interpolate to get H FHE_TIMER_STOP; }
long BaseCase(const ZZ_pEX& h, long q, long a, const ZZ_pEXModulus& F) { long b, e; ZZ_pEX lh(INIT_SIZE, F.n); lh = h; b = 1; e = 0; while (e < a-1 && !IsX(lh)) { e++; b *= q; PowerCompose(lh, lh, q, F); } if (!IsX(lh)) b *= q; return b; }
long ComputeDegree(const ZZ_pX& h, const ZZ_pXModulus& F) // f = F.f is assumed to be an "equal degree" polynomial // h = X^p mod f // the common degree of the irreducible factors of f is computed { if (F.n == 1 || IsX(h)) return 1; FacVec fvec; FactorInt(fvec, F.n); return RecComputeDegree(fvec.length()-1, h, F, fvec); }
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)); } }
long RecComputeDegree(long u, const ZZ_pEX& h, const ZZ_pEXModulus& F, FacVec& fvec) { if (IsX(h)) return 1; if (fvec[u].link == -1) return BaseCase(h, fvec[u].q, fvec[u].a, F); ZZ_pEX h1, h2; long q1, q2, r1, r2; q1 = fvec[fvec[u].link].val; q2 = fvec[fvec[u].link+1].val; TandemPowerCompose(h1, h2, h, q1, q2, F); r1 = RecComputeDegree(fvec[u].link, h2, F, fvec); r2 = RecComputeDegree(fvec[u].link+1, h1, F, fvec); return r1*r2; }
void PAlgebraModDerived<type>::embedInSlots(RX& H, const vector<RX>& alphas, const MappingData<type>& mappingData) const { if (isDryRun()) { H = RX::zero(); return; } FHE_TIMER_START; long nSlots = zMStar.getNSlots(); assert(lsize(alphas) == nSlots); for (long i = 0; i < nSlots; i++) assert(deg(alphas[i]) < mappingData.degG); vector<RX> crt(nSlots); // alloate space for CRT components // The i'th CRT component is (H mod F_t) = alphas[i](maps[i]) mod F_t, // where with t=T[i]. if (IsX(mappingData.G)) { // special case...no need for CompMod, which is // is not optimized for this case for (long i=0; i<nSlots; i++) // crt[i] = alpha(maps[i]) mod Ft crt[i] = ConstTerm(alphas[i]); } else { // general case...still try to avoid CompMod when possible, // which is the common case for encoding masks for (long i=0; i<nSlots; i++) { // crt[i] = alpha(maps[i]) mod Ft if (deg(alphas[i]) <= 0) crt[i] = alphas[i]; else CompMod(crt[i], alphas[i], mappingData.maps[i], factors[i]); } } CRT_reconstruct(H,crt); // interpolate to get p FHE_TIMER_STOP; }
long ProbComputeDegree(const ZZ_pX& h, const ZZ_pXModulus& F) { if (F.n == 1 || IsX(h)) return 1; long n = F.n; ZZ_pX P1, P2, P3; random(P1, n); TraceMap(P2, P1, n, F, h); ProbMinPolyMod(P3, P2, F, n/2); long r = deg(P3); if (r <= 0 || n % r != 0) return 0; else return n/r; }
void PowerCompose(ZZ_pEX& y, const ZZ_pEX& h, long q, const ZZ_pEXModulus& F) { if (q < 0) LogicError("PowerCompose: bad args"); ZZ_pEX z(INIT_SIZE, F.n); long sw; z = h; SetX(y); while (q) { sw = 0; if (q > 1) sw = 2; if (q & 1) { if (IsX(y)) y = z; else sw = sw | 1; } switch (sw) { case 0: break; case 1: CompMod(y, y, z, F); break; case 2: CompMod(z, z, z, F); break; case 3: Comp2Mod(y, z, y, z, z, F); break; } q = q >> 1; } }
/////////////////////////////////////////////////////////////////////////// // PURPOSE: // Returns true if f fully factors into distinct roots // (i.e., if f is a product of distinct monic degree-1 polynomials // times possibly a constant) // and false otherwise. // If f is zero, returns false. // // ALGORITHM: // Let m=GF2E::degree() (i.e., the field is GF(2^m)). // The check is accomplished by checking if f divides X^{2^m} - X, // or equivalently if X^{2^m}-X is 0 mod f. // X^{2^m} - X has 2^m distinct roots -- namely, // every element of the field is a root. Hence, f divides it if and only // if f has all its roots and they are all distinct. // // RUNNING TIME: // Depends on NTL's implementation of FrobeniusMap, but for inputs of degree // e that is relatively small compared m, should take e^{\log_2 3} m // operations in GF(2^m). Note that \log_2 3 is about 1.585. static bool CheckIfDistinctRoots(const GF2EX & f) { if (IsZero(f)) return false; // We hanlde degree 0 and degree 1 case separately, so that later // we can assume X mod f is the same as X if (deg(f) == 0 || deg(f) == 1) return true; GF2EXModulus F; // F is the same as f, just more efficient modular operations build(F, f); GF2EX h; FrobeniusMap (h, F); // h = X^{2^m} mod F // If X^{2^m} - X = 0 mod F, then X^{2^m} mod F // should be just X (because degree of F > 1) return (IsX(h)); }
static long RecIrredTest(long u, const ZZ_pEX& h, const ZZ_pEXModulus& F, const FacVec& fvec) { long q1, q2; ZZ_pEX h1, h2; if (IsX(h)) return 0; if (fvec[u].link == -1) { return IrredBaseCase(h, fvec[u].q, fvec[u].a, F); } q1 = fvec[fvec[u].link].val; q2 = fvec[fvec[u].link+1].val; TandemPowerCompose(h1, h2, h, q1, q2, F); return RecIrredTest(fvec[u].link, h2, F, fvec) && RecIrredTest(fvec[u].link+1, h1, F, fvec); }
long DetIrredTest(const ZZ_pEX& f) { if (deg(f) <= 0) return 0; if (deg(f) == 1) return 1; ZZ_pEXModulus F; build(F, f); ZZ_pEX h; FrobeniusMap(h, F); ZZ_pEX s; PowerCompose(s, h, F.n, F); if (!IsX(s)) return 0; FacVec fvec; FactorInt(fvec, F.n); return RecIrredTest(fvec.length()-1, h, F, fvec); }
long ProbIrredTest(const ZZ_pX& f, long iter) { long n = deg(f); if (n <= 0) return 0; if (n == 1) return 1; const ZZ& p = ZZ_p::modulus(); ZZ_pXModulus F; build(F, f); ZZ_pX b, r, s; PowerXMod(b, p, F); long i; for (i = 0; i < iter; i++) { random(r, n); TraceMap(s, r, n, F, b); if (deg(s) > 0) return 0; } if (p >= n) return 1; long pp; conv(pp, p); if (n % pp != 0) return 1; PowerCompose(s, b, n/pp, F); return !IsX(s); }
static CYTHON_INLINE int ZZX_is_x(struct ZZX* x) { return IsX(*x); }
void PAlgebraModDerived<type>::mapToSlots(MappingData<type>& mappingData, const RX& G) const { assert(deg(G) > 0 && zMStar.getOrdP() % deg(G) == 0); assert(LeadCoeff(G) == 1); mappingData.G = G; mappingData.degG = deg(mappingData.G); long nSlots = zMStar.getNSlots(); long m = zMStar.getM(); mappingData.maps.resize(nSlots); mapToF1(mappingData.maps[0],mappingData.G); // mapping from base-G to base-F1 for (long i=1; i<nSlots; i++) mapToFt(mappingData.maps[i], mappingData.G, zMStar.ith_rep(i), &(mappingData.maps[0])); REBak bak; bak.save(); RE::init(mappingData.G); mappingData.contextForG.save(); if (deg(mappingData.G)==1) return; mappingData.rmaps.resize(nSlots); if (G == factors[0]) { // an important special case for (long i = 0; i < nSlots; i++) { long t = zMStar.ith_rep(i); long tInv = InvMod(t, m); RX ct_rep; PowerXMod(ct_rep, tInv, G); RE ct; conv(ct, ct_rep); REX Qi; SetCoeff(Qi, 1, 1); SetCoeff(Qi, 0, -ct); mappingData.rmaps[i] = Qi; } } else { // the general case: currently only works when r == 1 assert(r == 1); vec_REX FRts; for (long i=0; i<nSlots; i++) { // We need to lift Fi from R[Y] to (R[X]/G(X))[Y] REX Qi; long t, tInv=0; if (i == 0) { conv(Qi,factors[i]); FRts=EDF(Qi, FrobeniusMap(Qi), deg(Qi)/deg(G)); // factor Fi over GF(p)[X]/G(X) } else { t = zMStar.ith_rep(i); tInv = InvMod(t, m); } // need to choose the right factor, the one that gives us back X long 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 REX FRtsj; if (i == 0) FRtsj = FRts[j]; else { REX X2tInv = PowerXMod(tInv, FRts[j]); IrredPolyMod(FRtsj, X2tInv, FRts[j]); } // FRtsj is the jth factor of factors[i] over the extension field. // For j > 0, we save some time by computing it from the jth factor // of factors[0] via a minimal polynomial computation. REX GRti; conv(GRti, mappingData.maps[i]); GRti %= FRtsj; if (IsX(rep(ConstTerm(GRti)))) { // is GRti == X? Qi = FRtsj; // If so, we found the right factor break; } // If this does not happen then move to the next factor of Fi } assert(j < FRts.length()); mappingData.rmaps[i] = Qi; } } }
/**************** * Handle geometry requests from children. ****************/ XtGeometryResult _XmGMHandleGeometryManager(Widget parent, Widget w, XtWidgetGeometry * request, XtWidgetGeometry * reply, #if NeedWidePrototypes int margin_width, int margin_height, #else Dimension margin_width, Dimension margin_height, #endif /* NeedWidePrototypes */ int resize_policy, int allow_overlap) { /* Policy: Yes if margin is non null requests inside the margin or negative are a priori almosted (or denied if the resizepolicy does not authorize it). That's the only case where almost is returned, no management of a limit position or size is done */ XtWidgetGeometry localReply ; Dimension width, height, borderWidth ; Position x, y ; XtGeometryResult returnCode = XtGeometryNo ; Boolean geoFlag = False, queryonly = False ; XmManagerWidget manager = (XmManagerWidget) parent ; localReply = *request ; localReply.request_mode = CWX|CWY|CWWidth|CWHeight|CWBorderWidth ; if(!IsX(request)) localReply.x = XtX(w) ; if(!IsY(request)) localReply.y = XtY(w) ; if(!IsWidth(request)) localReply.width = XtWidth(w) ; if(!IsHeight(request)) localReply.height = XtHeight(w) ; if(!IsBorder(request)) localReply.border_width = XtBorderWidth(w) ; /* check for x less than margin width */ if(IsX(request) && (margin_width != 0) && (request->x < (int)margin_width)) { localReply.x = (Position) margin_width ; returnCode = XtGeometryAlmost ; } /* check for y less than margin height */ if(IsY(request) && (margin_height != 0) && (request->y < (int)margin_height)) { localReply.y = (Position) margin_height ; returnCode = XtGeometryAlmost ; } /* Save current size and set to new size */ x = XtX(w) ; y = XtY(w) ; width = XtWidth(w) ; height = XtHeight(w) ; borderWidth = XtBorderWidth(w) ; XtX(w) = localReply.x ; XtY(w) = localReply.y ; XtWidth(w) = localReply.width ; XtHeight(w) = localReply.height ; XtBorderWidth(w) = localReply.border_width ; if(!allow_overlap && _XmGMOverlap (manager, w)) { returnCode = XtGeometryNo ; } else { /* if we already know that we are not gonna change anything */ if ((returnCode == XtGeometryAlmost) || IsQueryOnly(request)) queryonly = True ; /* see if the new layout is OK */ geoFlag = _XmGMDoLayout(manager, margin_width, margin_height, resize_policy, queryonly) ; /* if we cannot adapt the new size but the child is still inside go for it */ if(!geoFlag && ((localReply.x + localReply.width + (localReply.border_width << 1)) <= (XtWidth(manager) - margin_width)) && ((localReply.y + localReply.height + (localReply.border_width << 1)) <= (XtHeight(manager) - margin_height))) geoFlag = True ; if (geoFlag) { if (returnCode != XtGeometryAlmost) returnCode = XtGeometryYes ; } else returnCode = XtGeometryNo ; if (returnCode == XtGeometryAlmost){ if (reply) *reply = localReply ; else returnCode = XtGeometryNo ; } } if ((returnCode != XtGeometryYes) || queryonly) { /* Can't oblige, so restore previous values. */ XtX(w) = x ; XtY(w) = y ; XtWidth(w) = width ; XtHeight(w) = height ; XtBorderWidth(w) = borderWidth ; } return returnCode ; }
void TandemPowerCompose(ZZ_pEX& y1, ZZ_pEX& y2, const ZZ_pEX& h, long q1, long q2, const ZZ_pEXModulus& F) { ZZ_pEX z(INIT_SIZE, F.n); long sw; z = h; SetX(y1); SetX(y2); while (q1 || q2) { sw = 0; if (q1 > 1 || q2 > 1) sw = 4; if (q1 & 1) { if (IsX(y1)) y1 = z; else sw = sw | 2; } if (q2 & 1) { if (IsX(y2)) y2 = z; else sw = sw | 1; } switch (sw) { case 0: break; case 1: CompMod(y2, y2, z, F); break; case 2: CompMod(y1, y1, z, F); break; case 3: Comp2Mod(y1, y2, y1, y2, z, F); break; case 4: CompMod(z, z, z, F); break; case 5: Comp2Mod(z, y2, z, y2, z, F); break; case 6: Comp2Mod(z, y1, z, y1, z, F); break; case 7: Comp3Mod(z, y1, y2, z, y1, y2, z, F); break; } q1 = q1 >> 1; q2 = q2 >> 1; } }