def factor_orders(m, n): """ m = kq Args: m: for factorizations n: the integer for prime proving. Used to compute bound Returns: """ k = 1 q = m bound = (floorpowerroot(n, 4) + 1) ** 2 for p in small_primes: ''' Check again. ''' # if q becomes too small, fails anyway if q <= bound: break # if p is over the bound, and p is a factor of q. A solution is found. if p > bound and q % p == 0: k *= q/p q = p break # When q is > bound. Try to factorize through small primes. while q % p == 0: q = q/p k *= p if q <= bound or k == 1: return None if not prime.millerRabin(q): return None return k, q
def _ecpp_find_disc(n, era=None): """ Return (disc, m, k, q, era) where: - disc: appropriate discriminant for ecpp - m: one of possible orders for disc - k: smooth part of m - q: rough part of m which is greater than (n^(1/4) + 1)^2 - era: list of small primes """ up = (arith1.floorpowerroot(n, 4) + 1)**2 for disc in disc_gen(n): legendre = arith1.legendre(disc, n) if legendre == 0: return False elif legendre == -1: continue # legendre == 1: try: u, v = cornacchiamodify(disc, n) except ValueError: continue for m in (f(n, u, v) for f in orders.get(disc, default_orders)): k, q, era = _factor_order(m, up, era) if k: return disc, m, k, q, era else: # no usable discriminat found return False
def _ecpp_find_disc(n, era=None): """ Return (disc, m, k, q, era) where: - disc: appropriate discriminant for ecpp - m: one of possible orders for disc - k: smooth part of m - q: rough part of m which is greater than (n^(1/4) + 1)^2 - era: list of small primes """ up = (arith1.floorpowerroot(n, 4) + 1) ** 2 for disc in disc_gen(n): legendre = arith1.legendre(disc, n) if legendre == 0: return False elif legendre == -1: continue # legendre == 1: try: u, v = cornacchiamodify(disc, n) except ValueError: continue for m in (f(n, u, v) for f in orders.get(disc, default_orders)): k, q, era = _factor_order(m, up, era) if k: return disc, m, k, q, era else: # no usable discriminat found return False
def class_number_bsgs(disc): """ Return the class number with the given discriminant. """ if disc & 3 not in (0, 1): raise ValueError("a discriminant must be 0 or 1 mod 4") if disc >= 0: raise ValueError("a discriminant must be negative") lx = max(arith1.floorpowerroot(abs(disc), 5), 500 * (math.log(abs(disc)))**2) uprbd = int(class_formula(disc, int(lx)) * 3 / 2) lwrbd = (uprbd >> 1) + 1 bounds = [lwrbd, uprbd] # get the unit element = RetNext(disc) ut = element.unit() # append the unit to subset of G sossp = ClassGroup(disc, 0, []) sogsp = ClassGroup(disc, 0, []) sossp.insttree(ut) sogsp.insttree(ut) h = 1 # order finished = False while not finished: mstp1 = bounds[1] - bounds[0] if mstp1 <= 1: q = 1 else: q = arith1.floorsqrt(mstp1) if misc.primePowerTest(mstp1)[1] != 2: q += 1 # get next element nt = element.retnext() # x is the set of elements of G x = [ut, nt**h] if q > 2: x.extend([0] * (q - 2)) # compute small steps if x[1] == ut: # compute the order of nt n = trorder(h, sossp, sogsp, nt, disc) else: n = trbabysp(q, x, bounds, sossp, sogsp, ut, h, nt, disc) # finished? finished, h, sossp, sogsp = isfinished_trbsgs(lwrbd, bounds, h, n, sossp, sogsp, nt, disc) return h
def isPrime(self): """ determine whether self is prime ideal or not """ if not self.isIntegral(): return False size = self.number_field.degree nrm = self.norm() p = arith1.floorpowerroot(nrm, size) if p**size != nrm or not prime.primeq(p): return False return None #undefined
def isPrime(self): """ determine whether self is prime ideal or not """ if not self.isIntegral(): return False size = self.number_field.degree nrm = self.norm() p = arith1.floorpowerroot(nrm, size) if p ** size != nrm or not prime.primeq(p): return False return None #undefined
def class_number_bsgs(disc): """ Return the class number with the given discriminant. """ if disc % 4 not in (0, 1): raise ValueError("a discriminant must be 0 or 1 mod 4") if disc >= 0: raise ValueError("a discriminant must be negative") lx = max(arith1.floorpowerroot(abs(disc), 5), 500 * (math.log(abs(disc)))**2) uprbd = int(class_formula(disc, int(lx)) * 3 / 2) lwrbd = uprbd // 2 + 1 bounds = [lwrbd, uprbd] # get the unit element = RetNext(disc) ut = element.unit() # append the unit to subset of G sossp = ClassGroup(disc, 0, []) sogsp = ClassGroup(disc, 0, []) sossp.insttree(ut) sogsp.insttree(ut) h = 1 # order finished = False while not finished: mstp1 = bounds[1] - bounds[0] if mstp1 <= 1: q = 1 else: q = arith1.floorsqrt(mstp1) if misc.primePowerTest(mstp1)[1] != 2: q += 1 # get next element nt = element.retnext() # x is the set of elements of G x = [ut, nt ** h] if q > 2: x.extend([0] * (q - 2)) # compute small steps if x[1] == ut: # compute the order of nt n = trorder(h, sossp, sogsp, nt, disc) else: n = trbabysp(q, x, bounds, sossp, sogsp, ut, h, nt, disc) # finished? finished, h, sossp, sogsp = isfinished_trbsgs(lwrbd, bounds, h, n, sossp, sogsp, nt, disc) return h
def sqrPDF(f): """ Return the square of the given quadratic form 'f'. """ # compute disc and etc D = disc(f) sogsp = arith1.floorpowerroot(int(abs(D / 4)), 4) (u, v, d_1) = euclid_exd(f[1], f[0]) la = f[0] // d_1 lb = f[1] // d_1 lc = (-f[2] * u) % la c_1 = la - lc if c_1 < lc: lc = -c_1 # partial reduction v_2, v_3, z, d, v = parteucl(la, lc, sogsp) if z == 0: g = (lb * v_3 + f[2]) // d a_2 = d**2 c_2 = v_3 ** 2 b_2 = f[1] + (d + v_3)**2 - a_2 - c_2 c_2 = c_2 + g * d_1 return reducePDF((a_2, b_2, c_2)) e = (f[2] * v + lb * d) // la g = (e * v_2 - lb) // v b_2 = e * v_2 + v * g if d_1 > 1: b_2 = d_1 * b_2 v = d_1 * v v_2 = d_1 * v_2 a_2 = d ** 2 c_2 = v_3 ** 2 b_2 = b_2 + (d + v_3) ** 2 - a_2 - c_2 a_2 = a_2 + e * v c_2 = c_2 + g * v_2 return reducePDF((a_2, b_2, c_2))
def sqrPDF(f): """ Return the square of the given quadratic form 'f'. """ # compute disc and etc D = disc(f) sogsp = arith1.floorpowerroot(int(abs(D / 4)), 4) (u, v, d_1) = euclid_exd(f[1], f[0]) la = f[0] // d_1 lb = f[1] // d_1 lc = (-f[2] * u) % la c_1 = la - lc if c_1 < lc: lc = -c_1 # partial reduction v_2, v_3, z, d, v = parteucl(la, lc, sogsp) if z == 0: g = (lb * v_3 + f[2]) // d a_2 = d**2 c_2 = v_3**2 b_2 = f[1] + (d + v_3)**2 - a_2 - c_2 c_2 = c_2 + g * d_1 return reducePDF((a_2, b_2, c_2)) e = (f[2] * v + lb * d) // la g = (e * v_2 - lb) // v b_2 = e * v_2 + v * g if d_1 > 1: b_2 = d_1 * b_2 v = d_1 * v v_2 = d_1 * v_2 a_2 = d**2 c_2 = v_3**2 b_2 = b_2 + (d + v_3)**2 - a_2 - c_2 a_2 = a_2 + e * v c_2 = c_2 + g * v_2 return reducePDF((a_2, b_2, c_2))
def testFloorpowerroot(self): self.assertEqual(0, arith1.floorpowerroot(0, 1)) self.assertEqual(0, arith1.floorpowerroot(0, 4)) self.assertEqual(0, arith1.floorpowerroot(0, 7)) self.assertEqual(1, arith1.floorpowerroot(1, 2)) self.assertEqual(1, arith1.floorpowerroot(1, 6)) self.assertEqual(1, arith1.floorpowerroot(1, 9)) self.assertEqual(1, arith1.floorpowerroot(2, 3)) self.assertEqual(1, arith1.floorpowerroot(2, 7)) self.assertEqual(2, arith1.floorpowerroot(8, 3)) self.assertEqual(2, arith1.floorpowerroot(128, 7)) self.assertEqual((5, 5), arith1.floorpowerroot(5, 1, True)) self.assertEqual((5, 25), arith1.floorpowerroot(27, 2, True)) self.assertEqual((0, 0), arith1.floorpowerroot(0, 7, True)) self.assertEqual((3, 243), arith1.floorpowerroot(245, 5, True)) self.assertEqual((-3, -243), arith1.floorpowerroot(-245, 5, True)) for j in range(3, 100, 10): k = 5**j self.assertEqual(4, arith1.floorpowerroot(k - 1, j)) self.assertEqual(5, arith1.floorpowerroot(k, j)) self.assertEqual(5, arith1.floorpowerroot(k + 1, j)) self.assertEqual(arith1.floorpowerroot(400000000000000000000, 4), arith1.floorsqrt(20000000000))