예제 #1
0
 def testExactDivision(self):
     fortyfive = misc.FactoredInteger(45)
     self.assertEqual(45, int(fortyfive))
     fifteen = fortyfive.exact_division(3)
     self.assertEqual(15, int(fifteen))
     five = fortyfive // 9
     self.assertEqual(5, int(five))
     five = fortyfive.exact_division(misc.FactoredInteger(9, {3: 2}))
     self.assertEqual(5, int(five))
예제 #2
0
 def testSquarefreePart(self):
     fifteen = misc.FactoredInteger(15)
     self.assertEqual(15, fifteen.squarefree_part())
     self.assertTrue(
         isinstance(fifteen.squarefree_part(True), misc.FactoredInteger))
     self.assertEqual(15, fifteen.squarefree_part(True).integer)
     self.assertEqual({3: 1, 5: 1}, fifteen.squarefree_part(True).factors)
     factored45 = misc.FactoredInteger(45, {3: 2, 5: 1})
     self.assertEqual({5: 1}, factored45.squarefree_part(True).factors)
예제 #3
0
def trorder(n, sossp, sogsp, nt, disc):
    """
    Compute the order.

    n: int
    nt: element
    """
    factor_n = misc.FactoredInteger(n)
    while True:
        c_s1 = ClassGroup(disc, 0, [])
        lstp_ls = sossp.retel()
        sogsptp = sogsp.retel()
        for p, e in factor_n:
            # initialize c_s1
            base = nt**(int(factor_n) // p)
            for ttp_ls in lstp_ls:
                c_s1.insttree(base * ttp_ls)
            # search in c_s1
            for tmp_ell in sogsptp:
                rete = c_s1.search(tmp_ell)
                if rete != False:
                    factor_n //= p
                    break
            else:
                continue
            break
        else:
            return int(factor_n)
예제 #4
0
def ordercv(n, sossp, sogsp, nt, disc, classnum, tmp_ss, tmp_gs):
    """
    n: int
    """
    factor_n = misc.FactoredInteger(n)
    while True:
        c_s1 = ClassGroup(disc, classnum, [])  # a subset of G
        lstp_ls = sossp.retel()
        sogsptp = sogsp.retel()
        for p, e in factor_n:
            base = nt**(int(factor_n) // p)
            for ttp_ls in lstp_ls:
                tmp_c_s1 = base * ttp_ls
                tmp_c_s1.s_parent = ttp_ls
                c_s1.insttree(tmp_c_s1)
            for tmp_ell in sogsptp:
                rete = c_s1.search(tmp_ell)
                if rete != False:
                    factor_n //= p
                    tmp_ss = rete.s_parent
                    tmp_gs = tmp_ell
                    break
            else:
                continue
            break
        else:
            break
    return int(factor_n), tmp_ss, tmp_gs
예제 #5
0
    def _primitive_polynomial(char, degree):
        """
        Return a primitive polynomial of self.degree.

        REF: Lidl & Niederreiter, Introduction to finite fields and
             their applications.
        """
        cardinality = char**degree
        basefield = FinitePrimeField.getInstance(char)
        const = basefield.primitive_element()
        if degree & 1:
            const = -const
        cand = uniutil.polynomial({0: const, degree: basefield.one}, basefield)
        maxorder = factor_misc.FactoredInteger((cardinality - 1) // (char - 1))
        var = uniutil.polynomial({1: basefield.one}, basefield)
        while not (cand.isirreducible() and all(
                pow(var,
                    int(maxorder) // p, cand).degree() > 0
                for p in maxorder.prime_divisors())):
            # randomly modify the polynomial
            deg = bigrandom.randrange(1, degree)
            coeff = basefield.random_element(1, char)
            cand += uniutil.polynomial({deg: coeff}, basefield)
        _log.debug(cand.order.format(cand))
        return cand
예제 #6
0
 def testIsDivisibleBy(self):
     factored45 = misc.FactoredInteger(45, {3: 2, 5: 1})
     self.assertFalse(factored45.is_divisible_by(2))
     self.assertTrue(factored45.is_divisible_by(3))
     self.assertTrue(factored45.is_divisible_by(5))
     self.assertFalse(factored45.is_divisible_by(7))
     self.assertTrue(factored45.is_divisible_by(9))
     self.assertTrue(factored45.is_divisible_by(15))
예제 #7
0
def viafactor(n):
    """
    Test whether n is squarefree or not.

    It is obvious that if one knows the prime factorization of the number,
    he/she can tell whether the number is squarefree or not.
    """
    for p, e in factor_misc.FactoredInteger(n):
        if e >= 2:
            return False
    return True
예제 #8
0
def sigma(m, n):
    """
    Return the sum of m-th powers of the factors of n.
    """
    if n == 1:
        return 1
    if prime.primeq(n):
        return 1 + n**m
    s = 1
    for p, e in factor_misc.FactoredInteger(n):
        t = 1
        for i in range(1, e + 1):
            t += (p**i)**m
        s *= t
    return s
예제 #9
0
 def primitive_element(self):
     """
     Return a primitive element of the field, i.e., a generator of
     the multiplicative group.
     """
     fullorder = card(self) - 1
     if self._orderfactor is None:
         self._orderfactor = factor_misc.FactoredInteger(fullorder)
     for i in bigrange.range(self.char, card(self)):
         g = self.createElement(i)
         for p in self._orderfactor.prime_divisors():
             if g**(fullorder // p) == self.one:
                 break
         else:
             return g
예제 #10
0
 def order(self):
     """
     Find and return the order of the element in the multiplicative
     group of F_p.
     """
     if self.n == 0:
         raise ValueError("zero is not in the group.")
     if not hasattr(self, "orderfactor"):
         self.orderfactor = factor_misc.FactoredInteger(self.m - 1)
     o = 1
     for p, e in self.orderfactor:
         b = self**(int(self.orderfactor) // (p**e))
         while b.n != 1:
             o = o * p
             b = b**p
     return o
예제 #11
0
 def order(self, elem):
     """
     Find and return the order of the element in the multiplicative
     group of the field.
     """
     if not elem:
         raise ValueError("zero is not in the multiplicative group.")
     if self._orderfactor is None:
         self._orderfactor = factor_misc.FactoredInteger(card(self) - 1)
     o = 1
     for p, e in self._orderfactor:
         b = elem**(int(self._orderfactor) // (p**e))
         while b != self.one:
             o = o * p
             b = b**p
     return o
예제 #12
0
 def order(self):
     """
     Compute order using grouporder factorization.
     """
     clas = self.set.entity
     if hasattr(clas, "zero") and self.entity == clas.zero:
         return 1
     ordfact = factor_misc.FactoredInteger(self.set.grouporder())
     identity = self.set.identity()
     k = 1
     for p, e in ordfact:
         b = self.ope2(int(ordfact) // (p**e))
         while b != identity:
             k = k * p
             b = b.ope2(p)
     return k
예제 #13
0
def euler(n):
    """
    Euler totient function.
    It returns the number of relatively prime numbers to n smaller than n.
    """
    if n == 1:
        return 1
    if prime.primeq(n):
        return n - 1
    t = 1
    for p, e in factor_misc.FactoredInteger(n):
        if e > 1:
            t *= pow(p, e - 1) * (p - 1)
        else:
            t *= p - 1
    return t
예제 #14
0
def moebius(n):
    """
    Moebius function.
    It returns:
      -1  if n has odd distinct prime factors,
       1  if n has even distinct prime factors, or
       0  if n has a squared prime factor.
    """
    if n == 1:
        return 1
    if prime.primeq(n):
        return -1
    m = 1
    for p, e in factor_misc.FactoredInteger(n):
        if e > 1:
            return 0
        m = -m
    return m
예제 #15
0
def SilverPohligHellman(target, base, p):
    """
    Silver-Pohlig-Hellman method of DLP for finite prime fields.

    x, the discrete log of target, can be determined for each prime
    power factor of p - 1 (passed through factored_order):
      x = \sum s_j p_i**j mod p_i**e (0 <= s_j < p_i)

    Lidl, Niederreiter, 'Intro. to finite fields and their
    appl.' (revised ed) pp.356 (1994) CUP.
    """
    log_mod_factor = {}
    order = p - 1
    factored_order = factor_misc.FactoredInteger(order)
    base_inverse = arith1.inverse(base, p)
    for p_i, e in factored_order:
        log_mod_factor[p_i] = 0
        smallorder = order
        modtarget = target
        primitive_root_of_unity = pow(base, order // p_i, p)
        p_i_power = 1
        for j in range(e):
            smallorder //= p_i
            targetpow = pow(modtarget, smallorder, p)
            if targetpow == 1:
                s_j = 0
            else:
                root_of_unity = primitive_root_of_unity
                for k in range(1, p_i):
                    if targetpow == root_of_unity:
                        s_j = k
                        break
                    root_of_unity = root_of_unity * primitive_root_of_unity % p
                log_mod_factor[p_i] += s_j * p_i_power
            modtarget = modtarget * pow(base_inverse, s_j * p_i_power, p) % p
            p_i_power *= p_i
        if p_i < p_i_power:
            log_mod_factor[p_i_power] = log_mod_factor[p_i]
            del log_mod_factor[p_i]

    if len(log_mod_factor) == 1:
        return list(log_mod_factor.values())[0]
    return arith1.CRT([(r, p) for (p, r) in list(log_mod_factor.items())])
예제 #16
0
def _prepare_squarefactors(disc):
    """
    Return a list of square factors of disc (=discriminant).

    PRECOND: d is integer
    """
    squarefactors = []
    if disc < 0:
        fund_disc, absd = -1, -disc
    else:
        fund_disc, absd = 1, disc
    v2, absd = arith1.vp(absd, 2)
    if squarefree.trivial_test_ternary(absd):
        fund_disc *= absd
    else:
        for p, e in factor_misc.FactoredInteger(absd):
            if e > 1:
                squareness, oddity = divmod(e, 2)
                squarefactors.append((p, squareness))
                if oddity:
                    fund_disc *= p
            else:
                fund_disc *= p
    if fund_disc & 3 == 1:
        if v2 & 1:
            squareness, oddity = divmod(v2, 2)
            squarefactors.append((2, squareness))
            if oddity:
                fund_disc *= 2
        else:
            squarefactors.append((2, v2 >> 1))
    else: # fund_disc & 3 == 3
        assert v2 >= 2
        fund_disc *= 4
        if v2 > 2:
            squarefactors.append((2, (v2 - 2) >> 1))
    return squarefactors
예제 #17
0
 def testDivisors(self):
     fifteen = misc.FactoredInteger(15)
     self.assertEqual([1, 3, 5, 15], fifteen.divisors())
예제 #18
0
 def testEquality(self):
     fifteen = misc.FactoredInteger(15)
     self.assertEqual(15, fifteen)
     self.assertEqual(misc.FactoredInteger(15), fifteen)
     self.assertNotEqual(misc.FactoredInteger(16), fifteen)
예제 #19
0
 def testPrimeDivisors(self):
     fifteen = misc.FactoredInteger(15)
     self.assertEqual([3, 5], fifteen.prime_divisors())
예제 #20
0
 def testProperDivisors(self):
     fortyfive = misc.FactoredInteger(45)
     self.assertEqual([3, 5, 9, 15], fortyfive.proper_divisors())
예제 #21
0
 def testInitFactored(self):
     factored45 = misc.FactoredInteger(45, {3: 2, 5: 1})
     self.assertEqual(45, factored45.integer)
     self.assertEqual({3: 2, 5: 1}, factored45.factors)