def reduce_p(f, p, output=True):
    f = process(f)
    if any(type(c) != int for c in f.coef) or f.coef[-1] % p == 0:
        return "cannot apply"
    F = Zn(p)
    g = polynom(f.coef, True, F)
    print(g)
    if f.deg() == 2 or f.deg() == 3:
        for i in range(0, p):
            if output:
                print("g(%s) = %s" %(F(i), g(F(i))))
            if g(F(i)) == 0:
                return "inconclusive"
        return "irreducible"
    else:
        for i in range(0, p):
            if output:
                print("g(%s) = %s" %(F(i), g(F(i))))
            if g(F(i)) == 0:
                return "inconclusive"
        for i in range(2, math.ceil((len(g.coef))/2)):
            for fn in itertools.product(*[[F(i) for i in range(0, p)] for q in range(0, i+1)]):
                if fn == tuple([F(0) for i in range(0, i+1)]) or fn[-1] == F(0):
                    continue
                h = polynom(list(fn), True, F)
                temp = divmod(g, h)
                if output:
                    print("%s = (%s)(%s) + (%s)" %(g, h, temp[0], temp[1]))
                if not temp[1]:
                    return "inconclusive"
        return "irreducible"
def generate_test_functions():
    from random import randint
    m = randint(10, 30)
    n = randint(2, m)
    f = polynom([randint(1, 10)] + [randint(-30, 30) for i in range(0, m)])
    g = polynom([randint(1, 10)] + [randint(-30, 30) for i in range(0, n)])
    return (f, g)
def karatsuba(a, b):
    if type(a) == int and type(b) == int:
        n = max(int_len(a), int_len(b))
        m = int(n/2)
        base = 10
        basem = base**m
        a1 = int(a/basem)
        a0 = a%basem
        b1 = int(b/basem)
        b0 = b%basem
        z2 = a1*b1
        z0 = a0*b0
        z1 = (a1 + a0)*(b1 + b0) - z2 - z0
        return z2*(base**(2*m)) + z1*basem + z0
    if type(a) == polynom and type(b) == polynom:
        if not len(a) or not len(b):
            return polynom(0)
        n = max(len(a), len(b))
        m = int(n/2)
        a1 = a >> m
        a0 = polynom(a.coef[0:m], True, a.ring)
        b1 = b >> m
        b0 = polynom(b.coef[0:m], True, b.ring) 
        z2 = a1*b1
        z0 = a0*b0
        z1 = (a1 + a0)*(b1 + b0) - z2 - z0
        return (z2 << 2*m) + (z1 << m) + z0
Beispiel #4
0
 def ExpandKey(self):
     result = self.keys[0]
     temp = result[-1]
     for i in range(4):
         if i % 4 == 0:
             temp = self.ShiftRows(['', temp])[1]
             temp = self.SubBytes([temp])[0]
             if self.Rcon == False:
                 self.Rcon = polynom('1')
             else:
                 self.Rcon *= polynom('10')
             if self.Rcon()[1] >= 0x80:
                 self.Rcon += polynom(bin(0x11b)[2:])
             tmp = int(self.Rcon()[2], 16) ^ int(temp[0], 16)
             temp = [hex(tmp)[2:]] + temp[1:]
         tmp1 = []
         for j in range(4):
             tmp2 = hex(int(temp[j], 16) ^ int(result[i][j], 16))[2:]
             tmp1 += ["0" * ((2 - len(tmp2)) % 2) + tmp2]
         result += [tmp1]
         temp = tmp1
     keys = []
     for i in range(len(result) // 4):
         keys += [result[4 * i:4 * (i + 1)]]
     return keys
Beispiel #5
0
 def AddRoundKey(self, mat):
     result = mat[:]
     key = self.TransposeMat(self.keys[0])
     for i in range(len(mat)):
         for j in range(len(mat[i])):
             tmp = (polynom(bin(int(result[i][j], 16))[2:]) +
                    polynom(bin(int(key[i][j], 16))[2:]))()[2]
             result[i][j] = "0" * ((2 - len(tmp)) % 2) + tmp
     self.keys = self.ExpandKey()
     self.keys = self.keys[1:]
     return mat
Beispiel #6
0
 def mix(self, line):
     if len(line) != 4:
         return False
     result = []
     mat = [['02', '03', '01', '01'], ['01', '02', '03', '01'],
            ['01', '01', '02', '03'], ['03', '01', '01', '02']]
     for i in range(4):
         tmp = polynom('0')
         for j in range(4):
             tmp += polynom(bin(int(mat[i][j]))[2:]) * polynom(
                 bin(int(line[j], 16))[2:])
         result += ["0" * ((2 - len(tmp()[2])) % 2) + tmp()[2]]
     return result
def divp(a, b):
    if a.deg() < b.deg():
        raise Exception("a has to have degree greater than or equal to b's.")
    if a.ring != b.ring:
        raise Exception("a and b have to be polynomials over the same ring.")
    print("$a(x) =", a, "$")
    print("$b(x) =", b, "$")
    l_num = max([abs(coef) for coef in a.coef + b.coef])
    l = floor(log(abs(l_num))) + 1
    #print("$l$ is the number of digits in $", l_num, "$, which is ", l)
    q = []
    ap = a
    c = b.coef[-1]
    m = ap.deg()
    n = b.deg()
    powers = [1, c]
    for i in range(2, m-n+1):
        powers.append(powers[-1]*c)
    loop_num = 1
    while m >= n:
        ap_norm = max([abs(coef) for coef in ap.coef])
        l_ap = floor(log(abs(ap_norm))) + 1
        #print("At the beginning of the %sth iteration through the loop, $\\norm[\\infty]{a^\\prime} =" %(loop_num), ap_norm, "$, with number of digits $", l_ap, "$ and it is", l_ap <= loop_num*l, "that $L(\\norm[\\infty]{a^\\prime})$ is $\O(il)$")
        #print("Also, $a^\\prime =", ap, "$")
        #print("And so far, $q =", polynom(q, ring=a.ring), "$")
        d = ap.coef[-1]*powers[m-n]
        #print("So $d =", d, "$")
        q.append(d)
        ap = c*ap - ap.coef[-1]*(b << m-n) # This is b * x^{m-n}, I implemented multiplying by x^n as polynom << n.
        for i in range(1, min(m - ap.deg() - 1, m - n) + 1):
            q.append(0)
            ap = c*ap
        m = ap.deg()
        loop_num += 1
    q = polynom(q, ring=a.ring)
    r = ap
    #print("Finally, we are left with $q =", q, "$ and $r =", r, "$")
    return (q, r)
def mod_gcd2(a, b):
    if a.ring != int or b.ring != int:
        return "Nope"
    print("Step (1)")
    cont_a = gcd(*a.coef)
    cont_b = gcd(*b.coef)
    a = a / cont_a
    b = b / cont_b
    cont_gcd = gcd(cont_a, cont_b)
    print(cont_gcd)
    d = gcd(a.coef[-1], b.coef[-1])
    M = LandauMignotte(a, b)
    print("d =", d)
    print("M =", M)
    primes = sieve_eratosthenes(int(M+1))
    prime_index = 0
    while True:
        print("Step (2)")
        while (a.coef[-1] % primes[prime_index] == 0 and b.coef[-1] % primes[prime_index] == 0):
            prime_index += 1
        p = primes[prime_index]
        prime_index += 1
        c_p = gcd(a.change_ring(Zn(p)), b.change_ring(Zn(p)))
        c_p = c_p*~c_p.coef[-1]
        g_p = (d % p)*c_p
        print("with p =", p, "g_p =", g_p)
        while True:
            print("Step (3)")
            if g_p.deg() == 0:
                return polynom([1])
            P = p
            g = g_p
            print("P =", P, "and g =", g)
            print("Step (4)")
            while P <= M:
                print("P =", P)
                while (a.coef[-1] % primes[prime_index] == 0 or b.coef[-1] % primes[prime_index] == 0):
                    prime_index += 1
                p = primes[prime_index]
                prime_index += 1
                c_p = gcd(a.change_ring(Zn(p)), b.change_ring(Zn(p)))
                c_p = c_p*~c_p.coef[-1]
                g_p = (d % p)*c_p
                print("with p =", p, "g_p =", g_p)
                if g_p.deg() < g.deg():
                    print("New g_p has lower degree than the previous one.")
                    break
                if g_p.deg() == g.deg():
                    print("Degrees match when p =", p)
                    g = polynom([CRA2(g.coef[i], g_p.coef[i], P, p) for i in range(0, len(g.coef))], True)
                    P *= p
                    print("g =", g)
            else:
                print("P =", P, "> M =", M, "so time to test for completion with g =", g)
                if any(coef > M for coef in g.coef):
                    print("Positive coefficients are too large - we must have negative coefficients.")
                    coefs = []
                    for coef in g.coef:
                        if coef > M:
                            coefs.append(coef - P)
                        else:
                            coefs.append(coef)
                    alt_g = polynom(coefs, True)
                    if gcd(*alt_g.coef) != 1:
                        alt_g = alt_g/gcd(*alt_g.coef)
                        print("Primitive part =", alt_g)
                    if not a % alt_g and not b % alt_g:
                        return cont_gcd*alt_g
                else:
                    if gcd(*g.coef) != 1:
                        g = g/gcd(*g.coef)
                        print("Primitive part =", g)
                    if not a % g and not b % g:
                        return cont_gcd*g
                break