void MinPolyMod(zz_pX& hh, const zz_pX& g, const zz_pXModulus& F, long m) { zz_pX h, h1; long n = F.n; if (m < 1 || m > n) Error("MinPoly: bad args"); /* probabilistically compute min-poly */ ProbMinPolyMod(h, g, F, m); if (deg(h) == m) { hh = h; return; } CompMod(h1, h, g, F); if (IsZero(h1)) { hh = h; return; } /* not completely successful...must iterate */ long i; zz_pX h2, h3; zz_pXMultiplier H1; vec_zz_p R(INIT_SIZE, n); for (;;) { R.SetLength(n); for (i = 0; i < n; i++) random(R[i]); build(H1, h1, F); UpdateMap(R, R, H1, F); DoMinPolyMod(h2, g, F, m-deg(h), R); mul(h, h, h2); if (deg(h) == m) { hh = h; return; } CompMod(h3, h2, g, F); MulMod(h1, h3, H1, F); if (IsZero(h1)) { hh = h; return; } } }
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; }