Exemplo n.º 1
0
def find_special_state(poly_list, P_matrix, states):
    """Calculate the special state for each state, given the P matrix.
    Return format: (c, d) where T^c a^i_d = special_state for each i.
    """
    n = P_matrix.rows
    special_s = zeros(1, n)
    special_s[0] = 1
    special_s *= P_matrix.inv_mod(2)
    special_state = []
    runsum = 0
    for p in poly_list:
        special_state.append(special_s[runsum:runsum + degree(p)])
        runsum += degree(p)
    special_param = []
    for i, p in enumerate(poly_list):
        t = len(states[i]) - 1
        e = (2**degree(p) - 1) / t
        found = False
        for j, state in enumerate(states[i]):
            cur_state = state[:]
            for k in range(e):
                if cur_state == special_state[i]:
                    special_param.append({"shift": k, "state": j})
                    found = True
                    break
                cur_state = LFSR_from_poly(p, cur_state)
            if found:
                break
    return special_param
Exemplo n.º 2
0
def get_poly_list(list_):
    """Return a list of polynomials and the sum of their degrees."""
    f = Poly(1, modulus=2)
    sum_degree = 0
    poly_list = []
    found_reduc = False
    found_const = False
    found_dup = False
    for bin_str in list_:
        polynum = int(bin_str, 2)
        p = poly_from_num(polynum)
        if not p.is_irreducible():
            found_reduc = True
        elif p == Poly(1, modulus=2):
            found_const = True
        elif p in poly_list:
            found_dup = True
        else:
            f *= p
            poly_list.append(p)
            sum_degree += int(degree(p))
    if found_reduc:
        print "WARNING: At least one input was reducible."
    if found_const:
        print "WARNING: At least one input was a constant polynomial."
    if found_dup:
        print "WARNING: Multiple entries found."
    return (f, sorted(poly_list, key=lambda x: int(degree(x))), sum_degree)
Exemplo n.º 3
0
def find_pairs(p, poly_state, shift, state):
    """Find all pairs between states of a given polynomial such that
    T^l a_j + T^-m a_k = special_state."""
    special_state = list(poly_state[state])
    for i in range(shift):
        special_state = LFSR_from_poly(p, special_state)
    t = len(poly_state) - 1
    e = (2**degree(p) - 1) / t
    pairs_list = {}
    for j in range(t + 1):
        state_j = poly_state[j]
        for k in range(j, t + 1):
            ctr = 0
            for l in range(e):
                temp = [(state_j[i] + special_state[i]) % 2
                        for i in range(degree(p))]
                for m in range(e):
                    if temp == poly_state[k]:
                        if (j, k) in pairs_list:
                            pairs_list[(j, k)].append((l, -m % e))
                            if j != k:
                                pairs_list[(k, j)].append((-m % e, l))
                        else:
                            pairs_list[(j, k)] = [(l, -m % e)]
                            if j != k:
                                pairs_list[(k, j)] = [(-m % e, l)]
                        ctr += 1
                        break
                    else:
                        temp = LFSR_from_poly(p, temp)
                state_j = LFSR_from_poly(p, state_j)
    return pairs_list
Exemplo n.º 4
0
def pair_generator(poly_list, lists):
    """Generate all combination of pairs as given from find_pairs."""
    if poly_list:
        pairs = lists[0]
        t = max([key[0] for key in pairs])
        e = (2**degree(poly_list[0]) - 1) / t
        for pair in pairs:
            state_1 = pair[0]
            state_2 = pair[1]
            for shift_pair in pairs[pair]:
                next_list = pair_generator(poly_list[1:], lists[1:])
                ord_1 = e if state_1 != t else 1
                ord_2 = e if state_2 != t else 1
                cur_param = {
                    "order_1": ord_1,
                    "order_2": ord_2,
                    "shift_pair_1": shift_pair[0],
                    "shift_pair_2": shift_pair[1],
                    "state_1": state_1,
                    "state_2": state_2
                }
                for next_pair in next_list:
                    yield [cur_param] + next_pair
    else:
        yield []
Exemplo n.º 5
0
def get_P_matrix(poly_list):
    """Return the P matrix as specified in the paper."""
    n = sum([int(degree(p)) for p in poly_list])
    P_matrix = zeros(n)
    runsum = 0
    for p in poly_list:
        deg_p = int(degree(p))
        for i in range(deg_p):
            P_matrix[runsum + i, i] = 1
            cur_state = [0] * deg_p
            cur_state[i] = 1
            for j in range(deg_p, n):
                cur_state = LFSR_from_poly(p, cur_state)
                P_matrix[runsum + i, j] = cur_state[-1]
        runsum += deg_p
    return P_matrix
Exemplo n.º 6
0
def _get_base_matrix(p, q, t):
    """Return the basis-conversion matrix between the roots of two
    polynomials."""
    n = int(degree(p))
    M = zeros(n)
    M[0, 0] = 1
    q_trimmed = q - Poly(LT(q), modulus=2)
    cur_poly = Poly(to_list([t]), modulus=2)
    div_poly = Poly(to_list([n]), modulus=2)
    for i in range(1, n):
        while degree(cur_poly) >= n:
            cur_poly = quo(cur_poly, div_poly) * q_trimmed + rem(
                cur_poly, div_poly)
        for j in range(len(cur_poly.all_coeffs())):
            M[i, j] = cur_poly.all_coeffs()[-j - 1]
        cur_poly = cur_poly * Poly(to_list([t]), modulus=2)
    return M.inv_mod(2)
Exemplo n.º 7
0
def get_associate_poly(poly_list):
    """Return the associated primitive polynomial of a list of
    polynomials."""
    associates = []
    max_degree = max([int(degree(p)) for p in poly_list])
    for i in range(1, max_degree + 1):
        poly_sublist = [p for p in poly_list if int(degree(p)) == i]
        if poly_sublist:
            primitive_poly = generate_primitive(i)
            m_seq = []
            for p in primitive_poly:
                seq = [1] * (2**i - 1)
                state = [1] * i
                for j in range(i, 2**i - 1):
                    state = LFSR_from_poly(p, state)
                    seq[j] = state[-1]
                m_seq.append(seq)
        for p in poly_sublist:
            if check_primitive(p):
                associates.append({"poly": p, "t": 1})
            else:
                for j in divisors(2**i - 1, proper=True)[1:]:
                    found_associate = False
                    if totient(2**i - 1) / totient(
                        (2**i - 1) / j) <= len(primitive_poly):
                        decimated_seq = map(lambda x: decimate(x, j), m_seq)
                        while len(decimated_seq[0]) < 2 * i:
                            for seq in decimated_seq:
                                seq += seq[:min(len(seq), 2 * i - len(seq))]
                        for idx, seq in enumerate(decimated_seq):
                            state = seq[:i]
                            cur_seq = state * 2
                            for k in range(i, 2 * i):
                                state = LFSR_from_poly(p, state)
                                cur_seq[k] = state[-1]
                            if cur_seq == seq[:2 * i]:
                                associates.append({
                                    "poly": primitive_poly[idx],
                                    "t": j
                                })
                                found_associate = True
                                break
                        if found_associate:
                            break
    return associates
Exemplo n.º 8
0
def LFSR_from_poly(char_poly, state):
    """Return the next state given the characteristic polynomial of a
    LFSR and a state."""
    deg_p = int(degree(char_poly))
    LFSR = zeros(deg_p, 1)
    for i in range(deg_p):
        LFSR[i] = int(char_poly.all_coeffs()[-i - 1])
    next_state = state[:] + [(Matrix(1, deg_p, state) * LFSR)[0] % 2]
    return next_state[1:]
Exemplo n.º 9
0
def check_primitive(p):
    """Check if a polynomial is primitive in F_2[X]."""
    if not p.is_irreducible():
        return False
    deg_p = int(degree(p))
    for i in [j for j in divisors(2**deg_p - 1, proper=True) if j > deg_p]:
        q = Poly(to_list([0, i]), modulus=2)
        if rem(q, p, modulus=2).is_zero():
            return False
    return True
Exemplo n.º 10
0
def _get_state(M, p, t):
    """Return the states of a polynomial, given its basis conversion
    matrix."""
    deg_p = int(degree(p))
    state = [1] * (t * deg_p)
    new_p = p - Poly(LT(p), modulus=2)
    cur_poly = Poly(1, modulus=2)
    div_poly = Poly(LT(p), modulus=2)
    for i in range(1, t * deg_p):
        cur_poly *= Poly([0, 1], modulus=2)
        if degree(cur_poly) == deg_p:
            cur_poly = quo(cur_poly, div_poly) * new_p + rem(
                cur_poly, div_poly)
        coeff = zeros(1, deg_p)
        for j in range(len(cur_poly.all_coeffs())):
            coeff[j] = int(cur_poly.all_coeffs()[-j - 1])
        coeff = (coeff * M).applyfunc(lambda x: x % 2)
        state[i] = coeff[0]
    v = []
    for i in range(t):
        v.append(state[i::t])
    v.append([0] * deg_p)
    return v
Exemplo n.º 11
0
def _get_associate_poly(poly_list):
    """Return the associated primitive polynomial of a list of
    polynomials."""
    associates = []
    max_degree = max([int(degree(p)) for p in poly_list])
    for i in range(1, max_degree + 1):
        poly_sublist = [p for p in poly_list if int(degree(p)) == i]
        if poly_sublist:
            primitive_poly = generate_primitive(i)
        for p in poly_sublist:
            if check_primitive(p):
                associates.append({"poly": p, "t": 1})
            else:
                for q in primitive_poly:
                    found_associate = False
                    for j in divisors(2**i - 1, proper=True):
                        if rem(p(Poly(to_list([j]), modulus=2)), q).is_zero():
                            associates.append({"poly": q, "t": j})
                            found_associate = True
                            break
                    if found_associate:
                        break
    return associates
Exemplo n.º 12
0
def get_cycle(p, states, t):
    """Return the distinct cycles of LFSR with a given characteristic
    polynomial."""
    n = degree(p)
    e = (2**n - 1) / t
    cycles = []
    for state in states:
        if e <= n:
            cur_cycle = state[0:e]
        else:
            cur_cycle = [0] * e
            cur_cycle[0:n] = state
            temp_state = state
            for i in range(n, e):
                temp_state = LFSR_from_poly(p, temp_state)
                cur_cycle[i] = temp_state[-1]
        cycles.append(cur_cycle)
    return cycles
Exemplo n.º 13
0
def get_state(q, t):
    deg = degree(q)
    seq = [1] * (2**deg - 1)
    state = [1] * deg
    for i in range(deg, 2**deg - 1):
        state = LFSR_from_poly(q, state)
        seq[i] = state[-1]

    states = []
    for i in range(t):
        state = decimate(seq, t, i)
        while len(state) < deg:
            state += state
        states.append(state[:deg])

    states.append([0] * deg)

    return states