def get_H(m_val, t_val, k_vec, g_vec): support = [] g_a = [] k_poly = sympy.Poly(k_vec, alpha, domain='FF(2)') # Store the support of the code into a list for i in range(pow(2, m_val)): if i == 0: # Calculate g(0) a_poly = sympy.reduced(sympy.Poly(sympy.Poly(g_vec, x, domain='FF(2)').eval(0), alpha, domain='FF(2)').args[0], [k_poly])[1].set_modulus(2) else: # Calculate g(a^(i-1)) a_poly = sympy.reduced(sympy.Poly(g_vec, alpha**(i-1), domain='FF(2)').args[0], [k_poly])[1].set_modulus(2) if not a_poly.is_zero: # Only store if it is not zero if i == 0: support.append(sympy.reduced(0, [k_poly])[1].set_modulus(2)) else: support.append(sympy.reduced(alpha**(i-1), [k_poly])[1].set_modulus(2)) g_a.append(a_poly) if args.vv: print('\nSupport:\n', support, '\n\ng(a_n):\n', g_a) col = [] # Store the inverses of g(a) for element in g_a: inverse = sympy.invert(element, k_poly) col.append(inverse) if args.vv: print('\nInverses:\n', col) # Form the Parity check matrix poly_H = [] for i in range(t_val): poly_H_row = [] for j in range(len(support)): top = sympy.Poly.pow(support[j], i) product = sympy.reduced(sympy.Poly.mul(top, col[j]), [k_poly])[1].set_modulus(2) poly_H_row.append(product) poly_H.append(poly_H_row) bin_H = sympy.zeros(t_val * m_val, len(support)) # Turn the parity check matrix into a binary matrix for i in range(t_val): for j in range(len(support)): current_poly = poly_H[i][j].all_coeffs() current_len = len(current_poly) for k in range(current_len): try: bin_H[(i*(m_val))+k,j] = current_poly[current_len-k-1] except: sympy.pprint(bin_H) print('i =', i, ', j =', j, ', k =', k) exit() bin_H, pivot = bin_H.rref(iszerofunc=lambda x: x % 2==0) bin_H = bin_H.applyfunc(lambda x: mod(x,2)) bin_H = fixup_H(bin_H, pivot) return(bin_H)
def create_matrix(equations, coeffs): A = zeros(len(equations)) i = 0; j = 0 for j in range(0, len(coeffs)): c = coeffs[j] for i in range(0, len(equations)): e = equations[i] d, _ = reduced(e, [c]) A[i,j] = d[0] return A
def create_matrix(equations, coeffs): A = zeros(len(equations)) i = 0 j = 0 for j in range(0, len(coeffs)): c = coeffs[j] for i in range(0, len(equations)): e = equations[i] d, _ = reduced(e, [c]) A[i, j] = d[0] return A
def reduce_open_equations(self): # Reduce open equations red_op_eqs = [] for op_eq in self.op_eqs: _, r = sp.reduced(op_eq, self.eqs, self.X_vars) if self.X_vars else 0, op_eq if r == 0: self.op_eqs = [ to_poly(0, self.X_vars) ] return if not is_nonzero_constant(r): red_op_eqs.append(r) self.op_eqs = red_op_eqs
def search_routine(function, initial_node, extensions, num_initial_Y_assigned=1, num_initial_Y_variates=lambda x: len(x[0].free_symbols), groebner_routine=lambda f, G: reduced(f, G, *G.gens)): """ This routine searches through a tree hierachy of comp representations. function: the function you want to compute """ # search def search(H, n, m): """ H: array of polys n: number of Y variates already assigned m: number of Y variates """ # the groebner_routine *reduced* computes the remainder # compute the remainder wrt to a Groebner basis (GB) # GB uses lex monomial ordering here, with y's ordered higher than x's # this will cause the y's to be eliminated first _, rem = groebner_routine( function, groebner(H, *range_var('y', range(1, m+1, 1)))) if rem == 0: # return this yield [n, m] + [str_poly(h) for h in H] + ["rem: "+str_poly(rem)] # if extensions are no more possible if n == m: return # idea: next expression should be chosen to move the groebner basis # remainder to zero # TODO: of course would be more efficient to update the groebner basis # rather than recomputing from scratch each time try: for h, nn, mm in extensions(H, n, m, rem=rem): # h : new constraint to be enforced # nn : update of number of Y variates assigned # mm : update of number of Y variates in total for g in search(H + [h], nn, mm): # recurse into search yield g except TypeError as e: print e pass # for loop will barf if extensions return None # return return search(initial_node, num_initial_Y_assigned, num_initial_Y_variates(initial_node))
# Program 10b: Polynomial Reduce. See Example 4. from sympy import reduced from sympy.abc import x, y, z f = x**4 + y**4 + z**4 p = reduced(f, [x**2+y, z**2*y-1, y-z**2]) print(p) q = reduced(f, [y - z**2, z**2 * y - 1, x**2 + y]) print(q)
def routine(functions, B): for f in functions: a, rem = reduced(f, B, *B.gens) if rem != 0: return _, rem return _, Poly(0, *B.gens)
def schoof(self): """ schoof's algorithm for counting the number of points on an elliptic curve over F_p The goal is to compute the trace of the frobenious endomorphism t. Then p + 1 + t is the order of the group. Computing t is done by computing t mod l_1,l_2,...,l_s for a sufficient number of primes l_1,l_2,...,l_s such that their product is greater than 4*sqrt(p). Then use the chinese remainder theorem to recover t. let q_li and t_li be q and t mod l_i for i= 1,...,s. Then the equation (x**2p,y**2p) + q_li(x,y) = t_l(x**p,y**p) mod l_i is used to calculate the t_li's. """ a, b, p = self.a, self.b, self.p x, y = sp.symbols('x,y') list_of_primes = list_of_congruences = [] # Build list of odd primes satisfying condition's above i = 3 product = 2 while product < 4 * math.sqrt(p): if is_probable_prime(i): list_of_primes.append(i) product *= i i += 2 # Special case to determine t mod 2. if roots_in_F_q(p, f): list_of_congruences.append((2, 1)) else: list_of_congruences.append((2, 0)) # alias E.dpoly() f = E.dpoly # Build list of congruences for l in list_of_primes: p_l = p % l x_pl, y_pl = x - f(pl - 1) * f(pl + 1) / f(pl)**2, f( 2 * pl) / f(pl)**4 # We skip the case that (x**2p,y**2p) == +- q_pl(x,y) if (x**(2 * p), y**(2 * p)) == (x_pl, y_pl): continue elif (x**(2 * p), y**(2 * p)) == (-x_pl, -y_pl): continue # Calculate (x',y') = (x**2p,y**2p) + q_pl(x,y) mod phi_l x_prime, y_prime = self.symbolic_add((x**(2 * p), y**(2 * p)), (x_pl, y_pl)) x_prime, y_prime = sp.reduced(x_prime, f(pl)), sp.reduced(y_prime, f(pl)) # Look for t_l such that (x',y') = t_l(x**p,y**p) mod phi(l) for t_l in xrange(1, (l - 1) / 2): found_tl = False x_tl, y_tl = self.symbolic_scalar(t_l, (x**p, y**p)) if sp.reduced(x_prime - x_tl, f(pl)) == 0: found_tl = True if sp.reduced((y_prime - y_tl) / y, f(pl)) == 0: list_of_congruences.append((l, t_l)) else: list_of_congruences.append((l, -t_l)) return chinese_remainder_theorem(list_of_congruences)