def recursion(k, fcoeff, re): gcd = [1] if k > 1: gcd = quot_remain_p(ZZ.map(recursion((k - 2), fcoeff, re)), ZZ.map(recursion((k - 1), fcoeff, re)), p, ZZ)[1] elif any(re) == False: gcd = fcoeff else: if k == 0: gcd = re else: gcd = quot_remain_p(ZZ.map(fcoeff), ZZ.map(re), p, ZZ)[1] return [item % p for item in gcd]
def x_powermod(k, fcoeff, a1): # this function genrates x^(2^k) mod function f(x) if (k > 0): p1 = np.poly1d(x_powermod((k - 1), fcoeff, a1)) ** 2 result = quot_remain_p(ZZ.map(p1.coeffs), ZZ.map(fcoeff), p, ZZ)[1] else: result = a1 return [item % p for item in result]
def mod_xp(position, fcoeff, a1): # mod_xp(p) is x^p mod f(x) # multiply elements one by one result = np.poly1d(1) for x in position: result = np.poly1d((result * np.poly1d(x_powermod(x, fcoeff, a1)) ).coeffs % p) result = quot_remain_p(ZZ.map(np.poly1d(result).coeffs), ZZ.map(fcoeff), p, ZZ)[1] return result
def roots_f(startP, g_x, resss): if np.poly1d(g_x).order == 1: resss.append(monic(g_x)) return resss else: r = GCD(startP, P, Y, g_x) if np.poly1d(r).order < np.poly1d(g_x).order and np.poly1d(r).order != 0: resss.append(monic(r)) g_x = quot_remain_p(ZZ.map(g_x), ZZ.map(np.poly1d(monic(r))), p, ZZ)[0] return roots_f(startP, g_x, resss) else: startP = rand_startP() return roots_f(startP, g_x, resss)