Exemplo n.º 1
0
def ecpp(n, era=None):
    """
    Algorithm 27 (Atkin-Morain ECPP)
    Input : a natural number n
    Output : If n is prime, retrun True. Else, return False
    """
    _log.info('n = %d' % n)
    disc_and_order_info = _ecpp_find_disc(n, era)
    if not disc_and_order_info:
        return False
    # disc, m = k*q, era
    disc, m, k, q, era = disc_and_order_info
    # non(quadratic|cubic) residue
    g = quasi_primitive(n, disc == -3)

    try:
        # find param corresponding to order m
        for param in param_gen(disc, n, g):
            E = Elliptic(param, n)
            P = E.choose_point()
            if E.mul(m, P) == [0]:
                break
        # find a point [k]P is not the unit.
        U = E.mul(k, P)
        while U == [0]:
            P = E.choose_point()
            U = E.mul(k, P)
        # compute [q]([k]P)
        V = E.mul(q, U)
    except ZeroDivisionError:
        return False
    if V == [0]:
        if q > 1000000000:
            return ecpp(q, era)
        elif prime.trialDivision(q):
            return True
        else:
            return False
    else:
        return False
Exemplo n.º 2
0
def ecpp(n, era=None):
    """
    Algorithm 27 (Atkin-Morain ECPP)
    Input : a natural number n
    Output : If n is prime, retrun True. Else, return False
    """
    _log.info("n = %d" % n)
    disc_and_order_info = _ecpp_find_disc(n, era)
    if not disc_and_order_info:
        return False
    # disc, m = k*q, era
    disc, m, k, q, era = disc_and_order_info
    # non(quadratic|cubic) residue
    g = quasi_primitive(n, disc == -3)

    try:
        # find param corresponding to order m
        for param in param_gen(disc, n, g):
            E = Elliptic(param, n)
            P = E.choose_point()
            if E.mul(m, P) == [0]:
                break
        # find a point [k]P is not the unit.
        U = E.mul(k, P)
        while U == [0]:
            P = E.choose_point()
            U = E.mul(k, P)
        # compute [q]([k]P)
        V = E.mul(q, U)
    except ZeroDivisionError:
        return False
    if V == [0]:
        if q > 1000000000:
            return ecpp(q, era)
        elif prime.trialDivision(q):
            return True
        else:
            return False
    else:
        return False
Exemplo n.º 3
0
 def testTrialDivision(self):
     self.assertTrue(prime.trialDivision(3))
     self.assertTrue(prime.trialDivision(23))
     self.assertFalse(prime.trialDivision(7 * 13))
     self.assertTrue(prime.trialDivision(97))
     self.assertFalse(prime.trialDivision(11 * 13))
Exemplo n.º 4
0
def atkin_morain(n):
    """
    Atkin-Morain ECPP Algorithm.
    Args:
        n: Probable Prime

    Returns:
        Certificate of primality, or False.
    """
    if n < arbitrary_bound:
        if prime.trialDivision(n):
            return [n]
        else:
            return False

    d = 0
    m_found = False
    while m_found is False:
        try:
            d, ms = choose_discriminant(n, d)
        except ValueError:
            return False
        for m in ms:
            factors = factor_orders(m, n)
            if factors is not None:
                k, q = factors

                params = curve_parameters(d, n)
                try:
                    # Test to see if the order of the curve is really m
                    a, b = params.pop()
                    ec = EllipticCurve(a, b, n)
                    while not test_order(ec, m):
                        a, b = params.pop()
                        ec = EllipticCurve(a, b, n)
                    #print n, a, b

                    m_found = True
                    break
                except IndexError:
                    pass

        # if no proper m can be found. Go back to choose_discriminant()
    '''
    If this step fails need to return false.
    '''



    try:
    # operate on point
        while True:
            P = choose_point(ec)
            U = ec.mul(k, P) # U = [m/q]P
            if U != 0:
                break
        V = ec.mul(q, U)
    except (ZeroDivisionError, ValueError):
        return False

    if V != 0:
        return False
    else:
        if q > arbitrary_bound:
            cert = atkin_morain(q)
            if cert:
                cert.insert(0, (q, m, a, b))
            return cert
        else:
            if prime.trialDivision(q):
                return [q]
            else:
                return False