예제 #1
0
def miller(P, Q, n, denominator=False):
    # return the miller loop f_{P, n}(Q) for an even embedded degree curve
    if Q.is_zero():
        raise ValueError("Q must be nonzero.")
    n = ZZ(n)
    if n.is_zero():
        raise ValueError("n must be nonzero.")
    n_is_negative = False
    if n < 0:
        n = n.abs()
        n_is_negative = True
    t_num, t_den = 1, 1
    V = P
    S = 2 * V  # V=P is in affine coordinates
    nbin = n.bits()
    i = n.nbits() - 2
    while i > -1:
        [S, [ell_num, ell_den]] = eval_line(V, V, Q)
        t_num = (t_num**2) * ell_num
        if denominator:
            [R, [vee_num, vee_den]] = eval_line(S, -S, Q)
            t_den = (t_den**2) * ell_den * vee_num
            t_num *= vee_den
        V = S
        if nbin[i] == 1:
            [S, [ell_num, ell_den]] = eval_line(V, P, Q)
            t_num = t_num * ell_num
            if denominator:
                [R, [vee_num, vee_den]] = eval_line(S, -S, Q)
                t_den *= ell_den * vee_num
                t_num *= vee_den
            V = S
        i = i - 1
    if not (denominator):
        t_den = 1
    if n_is_negative:
        t_num, t_den = t_den, t_num
        S = -S
    return [S, [t_num, t_den]]
예제 #2
0
def decompose(P, f, g=None, target=None):
    """
    Compute a polynomial Q of degree target such that compose(Q, f,
    g).  Assumes deg f >= deg g. The result is returned as a list of
    coefficients.
    """

    def dec(P, f, g, invf, invg):
        a = f.parent()(0)
        if P.degree() >= f.degree() + g.degree():
            a, P = P.quo_rem(f)

        return a + (P * invf) % g, (P * invg) % f

    if g is None:
        g = f.parent()(1)
    if target is None:
        target = ZZ(P.degree() // f.degree())
    n, a, b = 0, 1, 1
    moduli = []
    for bit in reversed(target.bits()):
        if bit:
            n1, a1, b1 = n + 1, a * f, b * g
        else:
            n1, a1, b1 = n, a, b
        moduli.append((n1, a1, b1))
        n, a, b = n + n1, a * a1, b * b1

    res = {0: P}
    for n, a, b in reversed(moduli):
        newres = {}
        _, inva, invb = a.xgcd(b)
        for i, p in res.iteritems():
            p0, p1 = dec(p, a, b, inva, invb)
            newres[i + n] = p0 + newres.get(i + n, 0)
            newres[i] = p1 + newres.get(i, 0)
        res = newres

    return [res[i] for i in range(len(res))]
예제 #3
0
def decompose(P, f, g=None, target=None):
    """
    Compute a polynomial Q of degree target such that compose(Q, f,
    g).  Assumes deg f >= deg g. The result is returned as a list of
    coefficients.
    """
    def dec(P, f, g, invf, invg):
        a = f.parent()(0)
        if P.degree() >= f.degree() + g.degree():
            a, P = P.quo_rem(f)

        return a + (P * invf) % g, (P * invg) % f

    if g is None:
        g = f.parent()(1)
    if target is None:
        target = ZZ(P.degree() // f.degree())
    n, a, b = 0, 1, 1
    moduli = []
    for bit in reversed(target.bits()):
        if bit:
            n1, a1, b1 = n + 1, a * f, b * g
        else:
            n1, a1, b1 = n, a, b
        moduli.append((n1, a1, b1))
        n, a, b = n + n1, a * a1, b * b1

    res = {0: P}
    for n, a, b in reversed(moduli):
        newres = {}
        _, inva, invb = a.xgcd(b)
        for i, p in res.iteritems():
            p0, p1 = dec(p, a, b, inva, invb)
            newres[i + n] = p0 + newres.get(i + n, 0)
            newres[i] = p1 + newres.get(i, 0)
        res = newres

    return [res[i] for i in range(len(res))]