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
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
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))
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