Esempio n. 1
0
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)
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
 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
Esempio n. 5
0
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))
Esempio n. 6
0
# 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)
Esempio n. 7
0
 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)
Esempio n. 8
0
    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)