def new_xgcd(p,q): if(q == 0): return p, parent.one(), parent.zero() aux_den,_,_ = xgcd(p.denominator(),q.denominator()) p *= aux_den; q *= aux_den if(p.denominator() == 1 and q.denominator() == 1): g,P,Q = xgcd(p.numerator(),q.numerator()) return g, aux_den*parent(P), aux_den*parent(Q) m,r = new_euclidean(p,q) if(self.is_zero(r)): return q, parent.zero(), parent.one() if(r.is_unit()): return parent.one(), aux_den*parent(1/r), aux_den*parent(-m/r) g, P, Q = new_xgcd(q,r) return (g, aux_den*Q, aux_den*(P-m*Q))
def set_peripheral_info(self): G = self.manifold.fundamental_group() phi = MapToFreeAbelianization(G) m, l = [phi(w)[0] for w in G.peripheral_curves()[0]] if m < 0: m, l = -m, -l self.m_abelian, self.l_abelian = m, l # Same as index of homological meridian in H_1(M)_free self.l_order = gcd(m, l) # We also want to be able to view things from a more homologically # natural point of view. hom_l = self.manifold.homological_longitude() if abs(hom_l[1]) == 1: hom_m = (1, 0) else: a, b = xgcd(*hom_l)[1:] hom_m = (b, -a) M = self.manifold.copy() M.set_peripheral_curves([hom_m, hom_l]) cusp = M.cusp_info(0).shape assert abs(1 + cusp) > 1 - 1e-10 and abs(1 - cusp) > 1 - 1e-10 self.hom_m = hom_m self.hom_l = hom_l self.hom_m_abelian = abs(self.m_abelian * hom_m[0] + self.l_abelian * hom_m[1]) self.change_trans_to_hom_framing = matrix([hom_m, hom_l]) # Moreover, we store two special copies of the meridian for # later use. self.special_meridians = meridians_fixing_infinity_and_zero( self.manifold)
def attack(n, e1, c1, e2, c2): """ Recovers the plaintext from two ciphertexts, encrypted using the same modulus and different public exponents. :param n: the common modulus :param e1: the first public exponent :param c1: the ciphertext of the first encryption :param e2: the second public exponent :param c2: the ciphertext of the second encryption :return: the plaintext """ _, u, v = xgcd(e1, e2) p1 = pow(c1, u, n) if u > 0 else pow(pow(c1, -1, n), -u, n) p2 = pow(c2, v, n) if v > 0 else pow(pow(c2, -1, n), -v, n) return p1 * p2 % n
def HJ_path(s1, s2): r""" Return the Hirzebruch-Jung path from s1 to s2. INPUT: - ``s1``, ``s2`` -- rational number such that `s_1 > s_2` OUTPUT: a list of pairs `(m_0, d_0),\ldots,(m_r,d_r)` such that .. MATH:: s_1 > \frac{m_1}{d_1} > \ldots > \frac{m_r}{d_r} = s_2 and .. MATH:: m_i d_{i+1} - m_{i+1} d_i = 1, \quad i=1,..,r-1. """ from sage.all import xgcd, ceil, floor assert s1 > s2, "s1 must be larger than s2" m1 = s1.numerator() d1 = s1.denominator() m2 = s2.numerator() d2 = s2.denominator() path = [(m1, d1)] while m1 / d1 > s2: _, x, y = xgcd(m1, d1) if d1 * m2 - m1 * d2 > 0: k = ceil((x * m2 + y * d2) / (d1 * m2 - m1 * d2)) else: k = floor((x * m2 + y * d2) / (d1 * m2 - m1 * d2)) m = -y - k * m1 d = x - k * d1 path.append((m, d)) m1, d1 = m, d # these test are for debugging only, and should be unnecessary by now assert path[0][0] / path[0][1] == s1, "first entry not correct: {}".format( path) assert path[-1][0] / path[-1][ 1] == s2, "last entry not correct: {}".format(path) assert all([ path[i][0] * path[i + 1][1] - path[i + 1][0] * path[i][1] == 1 for i in range(len(path) - 1) ]), "determinant condition wrong: {}".format(path) return path
def rsa_keys(): prime1, prime2 = gen_prime(), gen_prime() # or 65537 modulus = prime1 * prime2 phi = (prime1 - 1) * (prime2 - 1) # public_exponent = 65537 public_exponent = sympy.randprime(65537, phi) private_exponent = int(sage_all.xgcd(public_exponent, phi)[1]) # to decrypt public_key = [public_exponent, modulus] private_key = [private_exponent, modulus] json_key("public", public_key) json_key("private", private_key) # save_key("public", public_key) # save_key("private", private_key) return public_key, private_key
def bezout(q, m): r"""Returns :math:`u,v` such that :math:`uq+mv=1`. Parameters ---------- q,m : integer Two coprime integers with :math:`q > 0`. Returns ------- tuple of integers """ if q == 1: return (1, 0) g, u, v = xgcd(q, -m) return (u, v)
def bezout(q,m): r"""Returns :math:`u,v` such that :math:`uq+mv=1`. Parameters ---------- q,m : integer Two coprime integers with :math:`q > 0`. Returns ------- tuple of integers """ if q == 1: return (1,0) g,u,v = xgcd(q,-m) return (u,v)
def zero_lifted_holonomy(manifold, m, l, f): """ Given a closed manifold and any log of the holonomy of the meridian and longitude, adjust logs by multiplies of f pi i such that the peripheral curves goes to 0. """ CIF = m.parent() RIF = CIF.real_field() multiple_of_pi = RIF(f*pi) # (m_fill, l_fill) Dehn-filling m_fill, l_fill = [int(x) for x in manifold.cusp_info()[0]['filling']] # Compute what the peripheral curves goes to right now p_interval = (m_fill * m + l_fill * l).imag() / multiple_of_pi is_int, p = p_interval.is_int() if not is_int: raise Exception( "Expected multiple of %d * pi * i (increase precision?)" % f) if p == 0: # Nothing to do return m, l # Compute by what multiple of 2 pi i to adjust g, a, b = xgcd(m_fill, l_fill) m -= p * a * multiple_of_pi * sage.all.I l -= p * b * multiple_of_pi * sage.all.I # For sanity, double check that we compute it right. p_interval = (m_fill * m + l_fill * l).imag() / multiple_of_pi is_int, p = p_interval.is_int() if not is_int: raise Exception( "Expected multiple of %d * pi * i (increase precision?)" % f) if p != 0: # Nothing to do raise Exception("Expected 0") return m, l
############################################################################### # Math functions ############################################################################### set_seed(SEED + 101) X = [random.randint(-1000, 1000) for _ in range(20)] + [random.randint(-1000, 1_000_000_000) for _ in range(20)] Y = [random.randint(-1000, 1000) for _ in range(20)] + [random.randint(-1000, 1_000_000_000) for _ in range(20)] D = [0,]*len(X) S = [0,]*len(X) T = [0,]*len(X) for i in range(len(X)): x = X[i] y = Y[i] d, s, t = xgcd(x, y) D[i] = int(d) S[i] = int(s) T[i] = int(t) d = {"X": X, "Y": Y, "D": D, "S": S, "T": T} save_pickle(d, FOLDER, "egcd.pkl") set_seed(SEED + 102) X = [[random.randint(-1000, 1000) for _ in range(random.randint(2, 6))] for _ in range(20)] + [[random.randint(-1000, 1_000_000) for _ in range(random.randint(2, 6))] for _ in range(20)] Z = [0,]*len(X) for i in range(len(X)): x = X[i] z = lcm(x) Z[i] = int(z) d = {"X": X, "Z": Z} save_pickle(d, FOLDER, "lcm.pkl")
def make_luts(field, sub_folder, seed, sparse=False): global FIELD, RING print(f"Making LUTs for {field}") ############################################################################### # Finite field arithmetic ############################################################################### folder = os.path.join(PATH, "fields", "data", sub_folder) if os.path.exists(folder): shutil.rmtree(folder) os.mkdir(folder) FIELD = field RING = PolynomialRing(field, names="x") characteristic = int(field.characteristic()) order = int(field.order()) dtype = np.int64 if order <= np.iinfo(np.int64).max else object alpha = field.primitive_element() # assert field.gen() == field.multiplicative_generator() d = { "characteristic": int(field.characteristic()), "degree": int(field.degree()), "order": int(field.order()), "primitive_element": I(field.primitive_element()), "irreducible_poly": [int(c) for c in field.modulus().list()[::-1]] } save_json(d, folder, "properties.json", indent=True) set_seed(seed + 1) X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j]) + F(YY[i, j])) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "add.pkl") set_seed(seed + 2) X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j]) - F(YY[i, j])) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "subtract.pkl") set_seed(seed + 3) X, Y, XX, YY, ZZ = io_2d(0, order, 0, order, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j]) * F(YY[i, j])) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "multiply.pkl") set_seed(seed + 4) X, Y, XX, YY, ZZ = io_2d(0, order, -order - 2, order + 3, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j]) * YY[i, j]) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "scalar_multiply.pkl") set_seed(seed + 5) X, Y, XX, YY, ZZ = io_2d(0, order, 1, order, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j]) / F(YY[i, j])) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "divide.pkl") set_seed(seed + 6) X, Z = io_1d(0, order, sparse=sparse) for i in range(X.shape[0]): Z[i] = I(-F(X[i])) d = {"X": X, "Z": Z} save_pickle(d, folder, "additive_inverse.pkl") set_seed(seed + 7) X, Z = io_1d(1, order, sparse=sparse) for i in range(X.shape[0]): Z[i] = I(1 / F(X[i])) d = {"X": X, "Z": Z} save_pickle(d, folder, "multiplicative_inverse.pkl") set_seed(seed + 8) X, Y, XX, YY, ZZ = io_2d(1, order, -order - 2, order + 3, sparse=sparse) for i in range(ZZ.shape[0]): for j in range(ZZ.shape[1]): ZZ[i, j] = I(F(XX[i, j])**YY[i, j]) d = {"X": X, "Y": Y, "Z": ZZ} save_pickle(d, folder, "power.pkl") set_seed(seed + 9) X, Z = io_1d(1, order, sparse=sparse) for i in range(Z.shape[0]): try: Z[i] = I(field.fetch_int(X[i]).log(alpha)) except: Z[i] = I(log(F(X[i]), alpha)) d = {"X": X, "Z": Z} save_pickle(d, folder, "log.pkl") set_seed(seed + 10) X, Z = io_1d(0, order, sparse=sparse) for i in range(X.shape[0]): Z[i] = int(F(X[i]).additive_order()) d = {"X": X, "Z": Z} save_pickle(d, folder, "additive_order.pkl") set_seed(seed + 11) X, Z = io_1d(1, order, sparse=sparse) for i in range(X.shape[0]): Z[i] = int(F(X[i]).multiplicative_order()) d = {"X": X, "Z": Z} save_pickle(d, folder, "multiplicative_order.pkl") set_seed(seed + 12) X, _ = io_1d(0, order, sparse=sparse) Z = [] for i in range(len(X)): x = F(X[i]) p = x.charpoly() z = poly_to_list(p) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "characteristic_poly_element.pkl") set_seed(seed + 13) shapes = [(2, 2), (3, 3), (4, 4), (5, 5), (6, 6)] X = [] Z = [] for i in range(len(shapes)): x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) p = x.charpoly() z = poly_to_list(p) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "characteristic_poly_matrix.pkl") set_seed(seed + 14) X, _ = io_1d(0, order, sparse=sparse) Z = [] for i in range(len(X)): x = F(X[i]) p = x.minpoly() z = poly_to_list(p) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "minimal_poly_element.pkl") # set_seed(seed + 15) # shapes = [(2,2), (3,3), (4,4), (5,5), (6,6)] # X = [] # Z = [] # for i in range(len(shapes)): # x = randint_matrix(0, order, shapes[i]) # X.append(x) # x = matrix(FIELD, [[F(e) for e in row] for row in x]) # p = x.minpoly() # z = np.array([I(e) for e in p.list()[::-1]], dtype=dtype).tolist() # z = z if z != [] else [0] # Z.append(z) # d = {"X": X, "Z": Z} # save_pickle(d, folder, "minimal_poly_matrix.pkl") set_seed(seed + 16) X, Z = io_1d(0, order, sparse=sparse) for i in range(X.shape[0]): z = F(X[i]).trace() Z[i] = int(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "field_trace.pkl") set_seed(seed + 17) X, Z = io_1d(0, order, sparse=sparse) for i in range(X.shape[0]): z = F(X[i]).norm() Z[i] = int(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "field_norm.pkl") ############################################################################### # Linear algebra ############################################################################### set_seed(seed + 201) X_shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4)] Y_shapes = [(2, 2), (3, 3), (2, 4), (3, 3), (4, 5)] X = [] Y = [] Z = [] for i in range(len(shapes)): x = randint_matrix(0, order, X_shapes[i]) y = randint_matrix(0, order, Y_shapes[i]) X.append(x) Y.append(y) x = matrix(FIELD, [[F(e) for e in row] for row in x]) y = matrix(FIELD, [[F(e) for e in row] for row in y]) z = x * y z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "matrix_multiply.pkl") set_seed(seed + 202) shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4)] X = [] Z = [] for i in range(len(shapes)): x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = x.rref() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "row_reduce.pkl") set_seed(seed + 203) shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4), (4, 3), (4, 4), (4, 5), (5, 4), (5, 5), (5, 6), (6, 5), (6, 6)] X = [] L = [] U = [] for i in range(len(shapes)): while True: # Ensure X has a PLU decomposition with P = I, which means it has an LU decomposition x = randint_matrix(0, order, shapes[i]) x_orig = x.copy() x = matrix(FIELD, [[F(e) for e in row] for row in x]) p, l, u = x.LU() if p == matrix.identity(FIELD, shapes[i][0]): break X.append(x_orig) l = np.array([[I(e) for e in row] for row in l], dtype) u = np.array([[I(e) for e in row] for row in u], dtype) L.append(l) U.append(u) d = {"X": X, "L": L, "U": U} save_pickle(d, folder, "lu_decompose.pkl") set_seed(seed + 204) shapes = [(2, 2), (2, 3), (3, 2), (3, 3), (3, 4), (4, 3), (4, 4), (4, 5), (5, 4), (5, 5), (5, 6), (6, 5), (6, 6)] X = [] L = [] U = [] P = [] for i in range(len(shapes)): x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) p, l, u = x.LU() p = np.array([[I(e) for e in row] for row in p], dtype) l = np.array([[I(e) for e in row] for row in l], dtype) u = np.array([[I(e) for e in row] for row in u], dtype) P.append(p) L.append(l) U.append(u) d = {"X": X, "P": P, "L": L, "U": U} save_pickle(d, folder, "plu_decompose.pkl") set_seed(seed + 205) shapes = [(2, 2), (3, 3), (4, 4), (5, 5), (6, 6)] X = [] Z = [] for i in range(len(shapes)): while True: x = randint_matrix(0, order, shapes[i]) x_orig = x.copy() x = matrix(FIELD, [[F(e) for e in row] for row in x]) if x.rank() == shapes[i][0]: break X.append(x_orig) z = x.inverse() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "matrix_inverse.pkl") set_seed(seed + 206) shapes = [(2, 2), (2, 2), (2, 2), (3, 3), (3, 3), (3, 3), (4, 4), (4, 4), (4, 4), (5, 5), (5, 5), (5, 5), (6, 6), (6, 6), (6, 6)] X = [] Z = [] for i in range(len(shapes)): x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = I(x.determinant()) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "matrix_determinant.pkl") set_seed(seed + 207) shapes = [(2, 2), (2, 2), (2, 2), (3, 3), (3, 3), (3, 3), (4, 4), (4, 4), (4, 4), (5, 5), (5, 5), (5, 5), (6, 6), (6, 6), (6, 6)] X = [] Y = [] Z = [] for i in range(len(shapes)): while True: x = randint_matrix(0, order, shapes[i]) x_orig = x.copy() x = matrix(FIELD, [[F(e) for e in row] for row in x]) if x.rank() == shapes[i][0]: break X.append(x_orig) y = randint_matrix(0, order, shapes[i][1]) # 1-D vector Y.append(y) y = vector(FIELD, [F(e) for e in y]) z = x.solve_right(y) z = np.array([I(e) for e in z], dtype) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "matrix_solve.pkl") set_seed(seed + 208) shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)] X = [] Z = [] for i in range(len(shapes)): deg = shapes[i][1] # The degree of the vector space # Random matrix x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = x.row_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) # Reduce the row space by 1 by copying the 0th row to the jth row for j in range(1, shapes[i][0]): x = copy(x) x[j, :] = F(random.randint(0, order - 1)) * x[0, :] z = x.row_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) # Zero matrix x = copy(x) x[:] = F(0) z = x.row_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "row_space.pkl") set_seed(seed + 209) shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)] X = [] Z = [] for i in range(len(shapes)): deg = shapes[i][0] # The degree of the vector space # Random matrix x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = x.column_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) # Reduce the column space by 1 by copying the 0th column to the jth column for j in range(1, shapes[i][1]): x = copy(x) x[:, j] = F(random.randint(0, order - 1)) * x[:, 0] z = x.column_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) # Zero matrix x = copy(x) x[:] = F(0) z = x.column_space() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "column_space.pkl") set_seed(seed + 210) shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)] X = [] Z = [] for i in range(len(shapes)): deg = shapes[i][0] # The degree of the vector space # Random matrix x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = x.left_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) # Reduce the left null space by 1 by copying the 0th row to the jth row for j in range(1, shapes[i][0]): x = copy(x) x[j, :] = F(random.randint(0, order - 1)) * x[0, :] z = x.left_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) # Zero matrix x = copy(x) x[:] = F(0) z = x.left_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "left_null_space.pkl") set_seed(seed + 211) shapes = [(2, 2), (2, 3), (2, 4), (3, 2), (4, 2), (3, 3)] X = [] Z = [] for i in range(len(shapes)): deg = shapes[i][1] # The degree of the vector space # Random matrix x = randint_matrix(0, order, shapes[i]) X.append(x) x = matrix(FIELD, [[F(e) for e in row] for row in x]) z = x.right_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) # Reduce the null space by 1 by copying the 0th column to the jth column for j in range(1, shapes[i][1]): x = copy(x) x[:, j] = F(random.randint(0, order - 1)) * x[:, 0] z = x.right_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) # Zero matrix x = copy(x) x[:] = F(0) z = x.right_kernel() if z.dimension() == 0: z = randint_matrix(0, 1, (0, deg)) else: z = z.basis_matrix() z = np.array([[I(e) for e in row] for row in z], dtype) X.append(np.array([[I(e) for e in row] for row in x], dtype)) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "null_space.pkl") ############################################################################### # Polynomial arithmetic ############################################################################### folder = os.path.join(PATH, "polys", "data", sub_folder) if os.path.exists(folder): shutil.rmtree(folder) os.mkdir(folder) MIN_COEFFS = 1 MAX_COEFFS = 12 set_seed(seed + 101) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) y = list_to_poly(Y[i]) z = x + y z = poly_to_list(z) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "add.pkl") set_seed(seed + 102) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) y = list_to_poly(Y[i]) z = x - y z = poly_to_list(z) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "subtract.pkl") set_seed(seed + 103) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) y = list_to_poly(Y[i]) z = x * y z = poly_to_list(z) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "multiply.pkl") set_seed(seed + 104) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random.randint(1, 2 * characteristic) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) y = Y[i] z = x * y z = poly_to_list(z) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "scalar_multiply.pkl") set_seed(seed + 105) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] # Add some specific polynomial types X.append([0]), Y.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS)) # 0 / y X.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS // 2)), Y.append( random_coeffs(0, order, MAX_COEFFS // 2, MAX_COEFFS)) # x / y with x.degree < y.degree X.append(random_coeffs(0, order, 2, MAX_COEFFS)), Y.append( random_coeffs(0, order, 1, 2)) # x / y with y.degree = 0 Q = [] R = [] for i in range(len(X)): x = list_to_poly(X[i]) y = list_to_poly(Y[i]) q = x // y r = x % y q = poly_to_list(q) Q.append(q) r = poly_to_list(r) R.append(r) d = {"X": X, "Y": Y, "Q": Q, "R": R} save_pickle(d, folder, "divmod.pkl") set_seed(seed + 106) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(4)] X.append(random_coeffs(0, order, 1, 2)) Y = [0, 1, 2, 3] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) ZZ = [] for j in range(len(Y)): y = Y[j] z = x**y z = poly_to_list(z) ZZ.append(z) Z.append(ZZ) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "power.pkl") set_seed(seed + 107) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = arange(0, order, sparse=sparse) Z = np.array(np.zeros((len(X), len(Y))), dtype=dtype) for i in range(len(X)): for j in range(len(Y)): x = list_to_poly(X[i]) y = F(Y[j]) z = x(y) Z[i, j] = I(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "evaluate.pkl") set_seed(seed + 108) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [randint_matrix(0, order, (2, 2)) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) y = matrix(FIELD, [[F(e) for e in row] for row in Y[i]]) z = x(y) z = np.array([[I(e) for e in row] for row in z], dtype) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "evaluate_matrix.pkl") ############################################################################### # Polynomial arithmetic methods ############################################################################### set_seed(seed + 301) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) z = x.reverse() z = poly_to_list(z) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "reverse.pkl") set_seed(seed + 302) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] R = [] M = [] for i in range(len(X)): x = list_to_poly(X[i]) roots = x.roots() RR, MM = [], [] for root in roots: r = root[0] m = root[1] RR.append(I(r)) MM.append(int(m)) idxs = np.argsort(RR) # Sort by ascending roots RR = (np.array(RR, dtype=dtype)[idxs]).tolist() MM = (np.array(MM, dtype=dtype)[idxs]).tolist() R.append(RR) M.append(MM) d = {"X": X, "R": R, "M": M} save_pickle(d, folder, "roots.pkl") set_seed(seed + 303) X = [ random_coeffs(0, order, 2 * FIELD.degree(), 6 * FIELD.degree()) for i in range(20) ] Y = [ 1, ] * 10 + [random.randint(2, FIELD.degree() + 1) for i in range(10)] Z = [] for i in range(len(X)): x = list_to_poly(X[i]) z = x.derivative(Y[i]) z = poly_to_list(z) Z.append(z) d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "derivative.pkl") ############################################################################### # Polynomial arithmetic functions ############################################################################### set_seed(seed + 401) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] D = [] S = [] T = [] for i in range(len(X)): x = list_to_poly(X[i]) y = list_to_poly(Y[i]) d, s, t = xgcd(x, y) d = poly_to_list(d) s = poly_to_list(s) t = poly_to_list(t) D.append(d) S.append(s) T.append(t) d = {"X": X, "Y": Y, "D": D, "S": S, "T": T} save_pickle(d, folder, "egcd.pkl") set_seed(seed + 402) X = [] Z = [] for i in range(20): XX = [ random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(random.randint(2, 5)) ] X.append(XX) xx = [list_to_poly(XXi) for XXi in XX] z = lcm(xx) z = poly_to_list(z) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "lcm.pkl") set_seed(seed + 403) X = [] Z = [] for i in range(20): XX = [ random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(random.randint(2, 5)) ] X.append(XX) xx = [list_to_poly(XXi) for XXi in XX] z = prod(xx) z = poly_to_list(z) Z.append(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "prod.pkl") set_seed(seed + 404) X = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] E = [random.randint(2, 10) for i in range(20)] M = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)] Z = [] for i in range(20): x = list_to_poly(X[i]) e = E[i] m = list_to_poly(M[i]) z = (x**e) % m z = poly_to_list(z) Z.append(z) d = {"X": X, "E": E, "M": M, "Z": Z} save_pickle(d, folder, "modular_power.pkl") set_seed(seed + 405) X = [ 0, ] * 20 # The remainder Y = [ 0, ] * 20 # The modulus Z = [ 0, ] * 20 # The solution for i in range(20): n = random.randint(2, 4) # The number of polynomials x, y = [], [] for j in range(n): d = random.randint(3, 5) x.append(random_coeffs(0, order, d, d + 1)) y.append(random_coeffs( 0, order, d + 1, d + 2)) # Ensure modulus degree is greater than remainder degree X[i] = x Y[i] = y try: x = [list_to_poly(xx) for xx in x] y = [list_to_poly(yy) for yy in y] z = crt(x, y) Z[i] = poly_to_list(z) except: Z[i] = None d = {"X": X, "Y": Y, "Z": Z} save_pickle(d, folder, "crt.pkl") ############################################################################### # Special polynomials ############################################################################### set_seed(seed + 501) X = [random_coeffs(0, order, 1, 6) for _ in range(20)] Z = [ False, ] * len(X) for i in range(len(X)): if random.choice(["one", "other"]) == "one": X[i][0] = 1 x = list_to_poly(X[i]) z = x.is_monic() Z[i] = bool(z) d = {"X": X, "Z": Z} save_pickle(d, folder, "is_monic.pkl") set_seed(seed + 502) IS = [] IS_NOT = [] if order <= 2**16: while len(IS) < 10: x = random_coeffs(0, order, 1, 6) f = list_to_poly(x) if f.is_irreducible(): IS.append(x) while len(IS_NOT) < 10: x = random_coeffs(0, order, 1, 6) f = list_to_poly(x) if not f.is_irreducible(): IS_NOT.append(x) d = {"IS": IS, "IS_NOT": IS_NOT} save_pickle(d, folder, "is_irreducible.pkl") set_seed(seed + 503) IS = [] IS_NOT = [] if order <= 2**16: while len(IS) < 10: x = random_coeffs(0, order, 1, 6) f = list_to_poly(x) # f = f / f.coefficients()[-1] # Make monic # assert f.is_monic() if f.degree() == 1 and f.coefficients(sparse=False)[0] == 0: continue # For some reason `is_primitive()` crashes on f(x) = a*x if not f.is_irreducible(): continue # Want to find an irreducible polynomial that is also primitive if f.is_primitive(): IS.append(x) while len(IS_NOT) < 10: x = random_coeffs(0, order, 1, 6) f = list_to_poly(x) # f = f / f.coefficients()[-1] # Make monic # assert f.is_monic() if f.degree() == 1 and f.coefficients(sparse=False)[0] == 0: continue # For some reason `is_primitive()` crashes on f(x) = a*x if not f.is_irreducible(): continue # Want to find an irreducible polynomial that is not primitive if not f.is_primitive(): IS_NOT.append(x) d = {"IS": IS, "IS_NOT": IS_NOT} save_pickle(d, folder, "is_primitive.pkl") set_seed(seed + 504) if order <= 2**16: X = [random_coeffs(0, order, 1, 6) for _ in range(20)] Z = [ False, ] * len(X) for i in range(len(X)): x = list_to_poly(X[i]) z = x.is_squarefree() Z[i] = bool(z) else: X = [] Z = [] d = {"X": X, "Z": Z} save_pickle(d, folder, "is_square_free.pkl")