Beispiel #1
0
def dup_zz_hensel_lift(p, f, f_list, l, K):
    """
    Multifactor Hensel lifting in `Z[x]`.

    Given a prime `p`, polynomial `f` over `Z[x]` such that `lc(f)`
    is a unit modulo `p`, monic pair-wise coprime polynomials `f_i`
    over `Z[x]` satisfying::

        f = lc(f) f_1 ... f_r (mod p)

    and a positive integer `l`, returns a list of monic polynomials
    `F_1`, `F_2`, ..., `F_r` satisfying::

       f = lc(f) F_1 ... F_r (mod p**l)

       F_i = f_i (mod p), i = 1..r

    References
    ==========

    1. [Gathen99]_

    """
    r = len(f_list)
    lc = dup_LC(f, K)

    if r == 1:
        F = dup_mul_ground(f, K.gcdex(lc, p**l)[0], K)
        return [dup_trunc(F, p**l, K)]

    m = p
    k = r // 2
    d = int(_ceil(_log(l, 2)))

    g = gf_from_int_poly([lc], p)

    for f_i in f_list[:k]:
        g = gf_mul(g, gf_from_int_poly(f_i, p), p, K)

    h = gf_from_int_poly(f_list[k], p)

    for f_i in f_list[k + 1:]:
        h = gf_mul(h, gf_from_int_poly(f_i, p), p, K)

    s, t, _ = gf_gcdex(g, h, p, K)

    g = gf_to_int_poly(g, p)
    h = gf_to_int_poly(h, p)
    s = gf_to_int_poly(s, p)
    t = gf_to_int_poly(t, p)

    for _ in range(1, d + 1):
        (g, h, s, t), m = dup_zz_hensel_step(m, f, g, h, s, t, K), m**2

    return dup_zz_hensel_lift(p, g, f_list[:k], l, K) \
         + dup_zz_hensel_lift(p, h, f_list[k:], l, K)
Beispiel #2
0
def dup_zz_hensel_lift(p, f, f_list, l, K):
    """
    Multifactor Hensel lifting in `Z[x]`.

    Given a prime `p`, polynomial `f` over `Z[x]` such that `lc(f)`
    is a unit modulo `p`, monic pair-wise coprime polynomials `f_i`
    over `Z[x]` satisfying::

        f = lc(f) f_1 ... f_r (mod p)

    and a positive integer `l`, returns a list of monic polynomials
    `F_1`, `F_2`, ..., `F_r` satisfying::

       f = lc(f) F_1 ... F_r (mod p**l)

       F_i = f_i (mod p), i = 1..r

    References
    ==========

    1. [Gathen99]_

    """
    r = len(f_list)
    lc = dup_LC(f, K)

    if r == 1:
        F = dup_mul_ground(f, K.gcdex(lc, p**l)[0], K)
        return [ dup_trunc(F, p**l, K) ]

    m = p
    k = r // 2
    d = int(_ceil(_log(l, 2)))

    g = gf_from_int_poly([lc], p)

    for f_i in f_list[:k]:
        g = gf_mul(g, gf_from_int_poly(f_i, p), p, K)

    h = gf_from_int_poly(f_list[k], p)

    for f_i in f_list[k + 1:]:
        h = gf_mul(h, gf_from_int_poly(f_i, p), p, K)

    s, t, _ = gf_gcdex(g, h, p, K)

    g = gf_to_int_poly(g, p)
    h = gf_to_int_poly(h, p)
    s = gf_to_int_poly(s, p)
    t = gf_to_int_poly(t, p)

    for _ in range(1, d + 1):
        (g, h, s, t), m = dup_zz_hensel_step(m, f, g, h, s, t, K), m**2

    return dup_zz_hensel_lift(p, g, f_list[:k], l, K) \
        + dup_zz_hensel_lift(p, h, f_list[k:], l, K)
Beispiel #3
0
def test_gf_gcdex():
    assert gf_gcdex([], [], 11, ZZ) == ([1], [], [])
    assert gf_gcdex([2], [], 11, ZZ) == ([6], [], [1])
    assert gf_gcdex([], [2], 11, ZZ) == ([], [6], [1])
    assert gf_gcdex([2], [2], 11, ZZ) == ([], [6], [1])

    assert gf_gcdex([], [3,0], 11, ZZ) == ([], [4], [1,0])
    assert gf_gcdex([3,0], [], 11, ZZ) == ([4], [], [1,0])

    assert gf_gcdex([3,0], [3,0], 11, ZZ) == ([], [4], [1,0])

    assert gf_gcdex([1,8,7], [1,7,1,7], 11, ZZ) == ([5,6], [6], [1,7])
def inverse(f):
    # Fast inverse method
    global phid
    global q
    p = ZZ.map(f)
    mod = ZZ.map(phid)
    s, t, g = gf_gcdex(p, mod, q, ZZ)
    if len(g) == 1 and g[0] == 1:
        return s
    else:
        return [-1]
Beispiel #5
0
def find_inv(poly, mod, constant = -a):
    xN_minus_a = np.zeros(N+1)
    xN_minus_a[0] = 1
    xN_minus_a[-1] = constant

    f_poly = ZZ.map(poly)
    x_mod = ZZ.map(xN_minus_a)
    s, t, g = gf_gcdex(f_poly, x_mod, mod, ZZ)

    # Recall that s*f + t*g = h. 
    # If g = 1, then s is the inverse of f mod t (= x^n-a)
    if len(g) == 1 and g[0] == 1:
        return trunc_polynomial(s)
    return trunc_polynomial(0)
Beispiel #6
0
def dup_zz_diophantine(F, m, p, K):
    """Wang/EEZ: Solve univariate Diophantine equations. """
    if len(F) == 2:
        a, b = F

        f = gf_from_int_poly(a, p)
        g = gf_from_int_poly(b, p)

        s, t, G = gf_gcdex(g, f, p, K)

        s = gf_lshift(s, m, K)
        t = gf_lshift(t, m, K)

        q, s = gf_div(s, f, p, K)

        t = gf_add_mul(t, q, g, p, K)

        s = gf_to_int_poly(s, p)
        t = gf_to_int_poly(t, p)

        result = [s, t]
    else:
        G = [F[-1]]

        for f in reversed(F[1:-1]):
            G.insert(0, dup_mul(f, G[0], K))

        S, T = [], [[1]]

        for f, g in zip(F, G):
            t, s = dmp_zz_diophantine([g, f], T[-1], [], 0, p, 1, K)
            T.append(t)
            S.append(s)

        result, S = [], S + [T[-1]]

        for s, f in zip(S, F):
            s = gf_from_int_poly(s, p)
            f = gf_from_int_poly(f, p)

            r = gf_rem(gf_lshift(s, m, K), f, p, K)
            s = gf_to_int_poly(r, p)

            result.append(s)

    return result
Beispiel #7
0
def dup_zz_diophantine(F, m, p, K):
    """Wang/EEZ: Solve univariate Diophantine equations. """
    if len(F) == 2:
        a, b = F

        f = gf_from_int_poly(a, p)
        g = gf_from_int_poly(b, p)

        s, t, G = gf_gcdex(g, f, p, K)

        s = gf_lshift(s, m, K)
        t = gf_lshift(t, m, K)

        q, s = gf_div(s, f, p, K)

        t = gf_add_mul(t, q, g, p, K)

        s = gf_to_int_poly(s, p)
        t = gf_to_int_poly(t, p)

        result = [s, t]
    else:
        G = [F[-1]]

        for f in reversed(F[1:-1]):
            G.insert(0, dup_mul(f, G[0], K))

        S, T = [], [[1]]

        for f, g in zip(F, G):
            t, s = dmp_zz_diophantine([g, f], T[-1], [], 0, p, 1, K)
            T.append(t)
            S.append(s)

        result, S = [], S + [T[-1]]

        for s, f in zip(S, F):
            s = gf_from_int_poly(s, p)
            f = gf_from_int_poly(f, p)

            r = gf_rem(gf_lshift(s, m, K), f, p, K)
            s = gf_to_int_poly(r, p)

            result.append(s)

    return result
def test_gf_euclidean():
    assert gf_gcd([], [], 11, ZZ) == []
    assert gf_gcd([2], [], 11, ZZ) == [1]
    assert gf_gcd([], [2], 11, ZZ) == [1]
    assert gf_gcd([2], [2], 11, ZZ) == [1]

    assert gf_gcd([], [1, 0], 11, ZZ) == [1, 0]
    assert gf_gcd([1, 0], [], 11, ZZ) == [1, 0]

    assert gf_gcd([3, 0], [3, 0], 11, ZZ) == [1, 0]

    assert gf_gcd([1, 8, 7], [1, 7, 1, 7], 11, ZZ) == [1, 7]

    assert gf_gcdex([], [], 11, ZZ) == ([1], [], [])
    assert gf_gcdex([2], [], 11, ZZ) == ([6], [], [1])
    assert gf_gcdex([], [2], 11, ZZ) == ([], [6], [1])
    assert gf_gcdex([2], [2], 11, ZZ) == ([], [6], [1])

    assert gf_gcdex([], [3, 0], 11, ZZ) == ([], [4], [1, 0])
    assert gf_gcdex([3, 0], [], 11, ZZ) == ([4], [], [1, 0])

    assert gf_gcdex([3, 0], [3, 0], 11, ZZ) == ([], [4], [1, 0])

    assert gf_gcdex([1, 8, 7], [1, 7, 1, 7], 11, ZZ) == ([5, 6], [6], [1, 7])
def test_gf_euclidean():
    assert gf_gcd([], [], 11, ZZ) == []
    assert gf_gcd([2], [], 11, ZZ) == [1]
    assert gf_gcd([], [2], 11, ZZ) == [1]
    assert gf_gcd([2], [2], 11, ZZ) == [1]

    assert gf_gcd([], [1,0], 11, ZZ) == [1,0]
    assert gf_gcd([1,0], [], 11, ZZ) == [1,0]

    assert gf_gcd([3,0], [3,0], 11, ZZ) == [1,0]

    assert gf_gcd([1,8,7], [1,7,1,7], 11, ZZ) == [1,7]

    assert gf_gcdex([], [], 11, ZZ) == ([1], [], [])
    assert gf_gcdex([2], [], 11, ZZ) == ([6], [], [1])
    assert gf_gcdex([], [2], 11, ZZ) == ([], [6], [1])
    assert gf_gcdex([2], [2], 11, ZZ) == ([], [6], [1])

    assert gf_gcdex([], [3,0], 11, ZZ) == ([], [4], [1,0])
    assert gf_gcdex([3,0], [], 11, ZZ) == ([4], [], [1,0])

    assert gf_gcdex([3,0], [3,0], 11, ZZ) == ([], [4], [1,0])

    assert gf_gcdex([1,8,7], [1,7,1,7], 11, ZZ) == ([5,6], [6], [1,7])
Beispiel #10
0
 def inv(self, x):
     s, t, h = gf_gcdex(x, self.reducing, self.p, ZZ)
     return s
def gf_inv(p1,p2,m):
    res = gf_gcdex(gf_strip(p2), p1, m, ZZ)
    if res[2] != [1]:
        print("Nie ma odwrotnego")
    return res[0]
def gf_inv(a):  # irriducible polynomial
    # mod = 0x18f57 => x^16 + x^15 + x^11 + x^10 + x^9 + x^8 + x^6 + x^4 + x^2 + x^1 + 1 Polynome irreductible
    mod = [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1]
    a = hextolist(a)
    s, t, g = gf_gcdex(ZZ.map(gf_strip(a)), ZZ.map(mod), 2, ZZ)
    return listtohex(s)
Beispiel #13
0
 def inv(self, x: list) -> list:
     s, t, h = gf_gcdex(x, self.reducing, self.p, ZZ)
     return s