def PolyInverseModOverQ(f: Poly, r: int): #r=2, предполагаем f0[0] = 1 f = f.trim() if (r < 1): raise ValueError #f = modPoly(f, zn) f0 = f.coef[0] if (f0 != Fraction(1, 1)): f0 = 1 / f0 if (f0 == Fraction(0, 1)): return None g = Poly(f0) l = int(math.ceil(math.log2(r))) for k in range(1, l + 1): g = (2 * g - f * (g**2)) g = g.truncate(2**k) return g
def PolyInverseModOverZn(f: Poly, r: int, zn: int): #r=2, mod zn r = log2 if (r < 1) or (zn < 1): raise ValueError #f = modPoly(f, zn) f0 = f.coef[0] if (not (f0 == 1)): g = Poly(inverse(f0, zn)) else: g = Poly(f0) if (g.coef[0] == None or zn == 1): return None l = int(math.ceil(math.log2(r))) for k in range(1, l + 1): g = (2 * g - f * (g**2)) g = g.truncate(2**k) g = modPoly(g, zn) return g