Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #7
0
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
Beispiel #8
0
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))
Beispiel #9
0
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))
Beispiel #10
0
 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))