Exemplo n.º 1
0
def primePowerTest(n):
    """
    This program using Algo. 1.7.5 in Cohen's book judges whether
    n is of the form p**k with prime p or not.
    If it is True, then (p,k) will be returned,
    otherwise (n,0).
    """
    if n % 2 == 1:
        q = n
        while True:
            if not prime.primeq(q):
                a = 2
                while prime.spsp(n, a):
                    a += 1
                d = gcd.gcd(pow(a,q,q) - a, q)
                if d == 1 or d == q:
                    return (n, 0)
                else:
                    q = d
            else:
                p = q
                break
    else:
        p = 2

    k, q = arith1.vp(n, p)
    if q == 1:
        return (p, k)
    else:
        return (n, 0)
Exemplo n.º 2
0
def osada(target):
    """
    Return True if target is irreducible, False if reducible
    or None if undecidable.

    Osada's criterion is the following.  Let f = \sum a_i X^i be a
    monic integer coefficient polynomial whose constant term is a
    prime number p or -p.  Then, if one of the following conditions
    holds, f is irreducible.
    (1) p > 1 + \sum_{i=1}^{n-1} |ai|,
    (2) p >= 1 + \sum_{i=1}^{n-1} |ai| and f has no root with
        absolute value 1.

    Note that the second case is not implemented.
    """
    # precondition
    if target.leading_coefficient() != 1:
        return None
    if not prime.primeq(abs(target[0])):
        return None

    # the criterion
    degree = target.degree()
    rhs = 1 + sum(abs(c) for (d, c) in target if 0 < d < degree - 1)
    # (1)
    if abs(target[0]) > rhs:
        return True

    # undecided
    return None
Exemplo n.º 3
0
def primePowerTest(n):
    """
    This program using Algo. 1.7.5 in Cohen's book judges whether
    n is of the form p**k with prime p or not.
    If it is True, then (p,k) will be returned,
    otherwise (n,0).
    """
    if n & 1:
        q = n
        while True:
            if not prime.primeq(q):
                a = 2
                while prime.spsp(n, a):
                    a += 1
                d = gcd.gcd(pow(a,q,q) - a, q)
                if d == 1 or d == q:
                    return (n, 0)
                q = d
            else:
                p = q
                break
    else:
        p = 2

    k, q = arith1.vp(n, p)
    if q == 1:
        return (p, k)
    else:
        return (n, 0)
Exemplo n.º 4
0
def qs(n, s, f):
    """
    This is main function of QS
    Arguments are (composite_number, sieve_range, factorbase_size)
    You must input these 3 arguments.
    """
    a = time.time()
    Q = QS(n, s, f)
    _log.info("Sieve range is [ %d , %d ] , Factorbase size = %d , Max Factorbase %d" % (Q.move_range[0], Q.move_range[-1], len(Q.FB), Q.maxFB))
    Q.run_sieve()
    V = Elimination(Q.smooth)
    A = V.gaussian()
    _log.info("Found %d linearly dependent relations" % len(A))
    answerX_Y = []
    N_factors = []
    for i in A:
        B = V.history[i].keys()
        X = 1
        Y = 1
        for j in B:
            X *= Q.smooth[j][1][0]
            Y *= Q.smooth[j][1][1]
            Y = Y % Q.number
        X = sqrt_modn(X, Q.number)
        answerX_Y.append(X-Y)
    for k in answerX_Y:
        if k != 0:
            factor = gcd.gcd(k, Q.number)
            if factor not in N_factors and factor != 1 and \
               factor != Q.number and prime.primeq(factor) == 1:
                N_factors.append(factor)
    N_factors.sort()
    _log.info("Total time = %f sec" % (time.time()-a))
    _log.info(str(N_factors))
Exemplo n.º 5
0
 def testRegular(self):
     f = uniutil.polynomial(enumerate([12, 7, 1]), Z)
     r = zassenhaus.padic_factorization(f)
     self.assertTrue(isinstance(r, tuple))
     self.assertEqual(2, len(r))
     self.assertTrue(prime.primeq(r[0]))
     self.assertTrue(isinstance(r[1], list))
     self.assertEqual(2, len(r[1]))
Exemplo n.º 6
0
def ecm(n, curve_type=A1, incs=3, trials=20, **options):
    """
    Find a factor of n with Elliptic Curve Method.
    An unsuccessful factorization returns 1.

    There are a few optional arguments.

    By 'curve_type', the function choose a family of curves.
    Please use a module constant to specify the curve_type.

    The second optional argument 'incs' specifies the number of times
    for changing bounds.  The function repeats factorization trials
    several times changing curves with a fixed bounds.

    The last optional argument 'trials' can control how quickly move
    on to the next higher bounds.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if verbose:
        _log.setLevel(logging.DEBUG)
        _log.debug("verbose")
    else:
        _log.setLevel(logging.NOTSET)

    # trivial checks
    if _prime.primeq(n):
        _log.info("%d is prime!" % n)
        return n
    if _gcd.gcd(n, 6) != 1:
        _log.info("%d is not coprime to 6!" % n)
        if n % 2 == 0:
            return 2
        if n % 3 == 0:
            return 3

    # main loop
    bounds = Bounds(n)
    for inc in range(incs):
        _log.info("bounds increment %d times" % inc)
        _log.debug("Bounds B1, B2 = %s" % (bounds, ))
        for trial in range(trials):
            _log.info("Trial #: %d" % (trial + 1))
            curve, point = Curve.get_random_curve_with_point(
                curve_type, n, bounds)
            _log.debug("Curve param: %d" % curve.c)
            g = stage1(n, bounds, curve, point)
            if 1 < g < n:
                return g
            g = stage2(n, bounds, curve, point)
            if 1 < g < n:
                return g
        bounds.increment()
    _log.info("ECM 2 step test failed!")

    if not verbose:
        _log.setLevel(logging.DEBUG)
    return 1
Exemplo n.º 7
0
def ecm(n, curve_type=A1, incs=3, trials=20, **options):
    """
    Find a factor of n with Elliptic Curve Method.
    An unsuccessful factorization returns 1.

    There are a few optional arguments.

    By 'curve_type', the function choose a family of curves.
    Please use a module constant to specify the curve_type.

    The second optional argument 'incs' specifies the number of times
    for changing bounds.  The function repeats factorization trials
    several times changing curves with a fixed bounds.

    The last optional argument 'trials' can control how quickly move
    on to the next higher bounds.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if verbose:
        _log.setLevel(logging.DEBUG)
        _log.debug("verbose")
    else:
        _log.setLevel(logging.NOTSET)

    # trivial checks
    if _prime.primeq(n):
        _log.info("%d is prime!" % n)
        return n
    if _gcd.gcd(n, 6) != 1: 
        _log.info("%d is not coprime to 6!" % n)
        if n % 2 == 0:
            return 2
        if n % 3 == 0:
            return 3

    # main loop
    bounds = Bounds(n)
    for inc in range(incs):
        _log.info("bounds increment %d times" % inc)
        _log.debug("Bounds B1, B2 = %s" % (bounds,))
        for trial in range(trials):
            _log.info("Trial #: %d" % (trial + 1))
            curve, point = Curve.get_random_curve_with_point(curve_type, n, bounds)
            _log.debug("Curve param: %d" % curve.c)
            g = stage1(n, bounds, curve, point)
            if 1 < g < n:
                return g
            g = stage2(n, bounds, curve, point)
            if 1 < g < n:
                return g
        bounds.increment()
    _log.info("ECM 2 step test failed!")

    if not verbose:
        _log.setLevel(logging.DEBUG)
    return 1
Exemplo n.º 8
0
    def __init__(self, representative, modulus, modulus_is_prime=True):
        if not modulus_is_prime and not prime.primeq(abs(modulus)):
            raise ValueError("modulus must be a prime.")

        FiniteFieldElement.__init__(self)
        intresidue.IntegerResidueClass.__init__(self, representative, modulus)

        # ring
        self.ring = None
Exemplo n.º 9
0
    def __init__(self, representative, modulus, modulus_is_prime=True):
        if not modulus_is_prime and not prime.primeq(abs(modulus)):
            raise ValueError("modulus must be a prime.")

        FiniteFieldElement.__init__(self)
        intresidue.IntegerResidueClass.__init__(self, representative, modulus)

        # ring
        self.ring = None
Exemplo n.º 10
0
 def isfield(self):
     """
     isfield returns True if the modulus is prime, False if not.
     Since a finite domain is a field, other ring property tests
     are merely aliases of isfield.
     """
     if None == self.properties.isfield():
         if prime.primeq(self.m):
             self.properties.setIsfield(True)
         else:
             self.properties.setIsdomain(False)
     return self.properties.isfield()
Exemplo n.º 11
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
Exemplo n.º 12
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
Exemplo n.º 13
0
 def isfield(self):
     """
     isfield returns True if the modulus is prime, False if not.
     Since a finite domain is a field, other ring property tests
     are merely aliases of isfield.
     """
     if None == self.properties.isfield():
         if prime.primeq(self.m):
             self.properties.setIsfield(True)
         else:
             self.properties.setIsdomain(False)
     return self.properties.isfield()
Exemplo n.º 14
0
    def make_poly(self):
        """
        Make coefficients of f(x)= ax^2+b*x+c
        """
        T = time.time()
        if self.d_list == []:
            d = int(math.sqrt((math.sqrt(self.number)/(math.sqrt(2)*self.Srange))))
            if d%2 == 0:
                if (d+1)%4 == 1: #case d=0 mod4
                    d += 3
                else:
                    d += 1       #case d=2 mod4
            elif d%4 == 1:       #case d=1 mod4
                d += 2
                                 #case d=3 mod4
        else:
            d = self.d_list[-1]

        while d in self.d_list or not prime.primeq(d) or \
              arith1.legendre(self.number,d) != 1 or d in self.FB:
            d += 4
        a = d**2
        h_0 = pow(self.number, (d-3)//4, d)
        h_1 = (h_0*self.number) % d
        h_2 = ((arith1.inverse(2,d)*h_0*(self.number - h_1**2))/d) % d
        b = (h_1 + h_2*d) % a
        if b%2 == 0:
            b = b - a

        self.d_list.append(d)
        self.a_list.append(a)
        self.b_list.append(b)

        # Get solution of  F(x) = 0 (mod p^i)
        solution = []
        i = 0
        for s in self.Nsqrt:
            k = 0
            p_solution = []
            ppow = 1
            while k < len(s):
                ppow *= self.FB[i+2]
                a_inverse = arith1.inverse(2*self.a_list[-1], ppow)
                x_1 = ((-b + s[k][0])*a_inverse) % ppow
                x_2 = ((-b + s[k][1])*a_inverse) % ppow
                p_solution.append([x_1, x_2])
                k += 1
            i += 1
            solution.append(p_solution)
        self.solution = solution
        self.coefficienttime += time.time() - T
Exemplo n.º 15
0
 def testPrimeqComposite(self):
     self.assertFalse(prime.primeq(1))
     self.assertFalse(prime.primeq(2**2))
     self.assertFalse(prime.primeq(2 * 7))
     self.assertFalse(prime.primeq(3 * 5))
     self.assertFalse(prime.primeq(11 * 31))
     self.assertFalse(
         prime.primeq(1111111111111111111 * 11111111111111111111111))
Exemplo n.º 16
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
Exemplo n.º 17
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
Exemplo n.º 18
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
Exemplo n.º 19
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
Exemplo n.º 20
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
Exemplo n.º 21
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
Exemplo n.º 22
0
 def testPrimeqPrime(self):
     self.assertTrue(prime.primeq(2))
     self.assertTrue(prime.primeq(3))
     self.assertTrue(prime.primeq(23))
     self.assertTrue(prime.primeq(1662803))
     self.assertTrue(prime.primeq(1111111111111111111))
Exemplo n.º 23
0
    def __init__(self, n, sieverange=0, factorbase=0, multiplier=0):
        self.number = n
        _log.info("The number is %d MPQS starting" % n)

        if prime.primeq(self.number):
            raise ValueError("This number is Prime Number")
        for i in [2,3,5,7,11,13]:
            if n % i == 0:
                raise ValueError("This number is divided by %d" % i)

        self.sievingtime = 0
        self.coefficienttime = 0
        self.d_list = []
        self.a_list = []
        self.b_list = []

        #Decide prameters for each digits
        self.digit = arith1.log(self.number, 10) + 1

        if sieverange != 0:
            self.Srange = sieverange
            if factorbase != 0:
                self.FBN = factorbase
            elif self.digit < 9:
                self.FBN = parameters_for_mpqs[0][1]
            else:
                self.FBN = parameters_for_mpqs[self.digit-9][1]
        elif factorbase != 0:
            self.FBN = factorbase
            if self.digit < 9:
                self.Srange = parameters_for_mpqs[0][0]
            else:
                self.Srange = parameters_for_mpqs[self.digit-9][0]
        elif self.digit < 9:
            self.Srange = parameters_for_mpqs[0][0]
            self.FBN = parameters_for_mpqs[0][1]
        elif self.digit > 53:
            self.Srange = parameters_for_mpqs[44][0]
            self.FBN = parameters_for_mpqs[44][1]
        else:
            self.Srange = parameters_for_mpqs[self.digit-9][0]
            self.FBN = parameters_for_mpqs[self.digit-9][1]

        self.move_range = range(-self.Srange, self.Srange+1)

        # Decide k such that k*n = 1 (mod4) and k*n has many factor base
        if multiplier == 0:
            self.sqrt_state = []
            for i in [3,5,7,11,13]:
                s = arith1.legendre(self.number, i)
                self.sqrt_state.append(s)
            index8 = (self.number % 8) // 2
            j = 0
            while self.sqrt_state != prime_8[index8][j][1]:
                j += 1
            k = prime_8[index8][j][0]
        else:
            if n % 4 == 1:
                k = 1
            else:
                if multiplier == 1:
                    raise ValueError("This number is 3 mod 4 ")
                else:
                    k = multiplier
        self.number = k*self.number
        self.multiplier = k

        _log.info("%d - digits Number" % self.digit)
        _log.info("Multiplier is %d" % self.multiplier)

        # Table of (log p) , p in FB
        i = 0
        k = 0
        factor_base = [-1]
        FB_log = [0]
        while k < self.FBN:
            ii = primes_table[i]
            if arith1.legendre(self.number,ii) == 1:
                factor_base.append(ii)
                FB_log.append(primes_log_table[i])
                k += 1
            i += 1

        self.FB = factor_base
        self.FB_log = FB_log
        self.maxFB = factor_base[-1]

        # Solve x^2 = n (mod p^e)
        N_sqrt_list = []
        for i in self.FB:
            if i != 2 and i != -1:
                e = int(math.log(2*self.Srange, i))
                N_sqrt_modp = sqroot_power(self.number, i, e)
                N_sqrt_list.append(N_sqrt_modp)
        self.Nsqrt = N_sqrt_list
Exemplo n.º 24
0
def mpqs(n, s=0, f=0, m=0):
    """
    This is main function of MPQS.
    Arguments are (composite_number, sieve_range, factorbase_size, multiplier)
    You must input composite_number at least.
    """
    T = time.time()
    M = MPQS(n, s, f, m)
    _log.info("Sieve range is [ %d , %d ] , Factorbase size = %d , Max Factorbase %d" % (M.move_range[0], M.move_range[-1], len(M.FB), M.maxFB))
    M.get_vector()
    N = M.number // M.multiplier
    V = Elimination(M.smooth)
    A = V.gaussian()
    _log.info("Found %d linerly dependent relations" % len(A))
    answerX_Y = []
    N_prime_factors = []
    N_factors = []
    output = []
    for i in A:
        B = V.history[i].keys()
        X = 1
        Y = 1
        for j in B:
            X *= M.smooth[j][1][0]
            Y *= M.smooth[j][1][1]
            Y = Y % M.number
        X = sqrt_modn(X, M.number)
        if X != Y:
            answerX_Y.append(X-Y)
    NN = 1
    for k in answerX_Y:
        factor = gcd.gcd(k, N)
        if factor not in N_factors and factor != 1 and factor != N \
               and factor not in N_prime_factors:
            if prime.primeq(factor):
                NN = NN*factor
                N_prime_factors.append(factor)
            else:
                N_factors.append(factor)

    _log.info("Total time = %f sec" % (time.time() - T))

    if NN == N:
        _log.debug("Factored completely!")
        N_prime_factors.sort()
        for p in N_prime_factors:
            N = N // p
            i = arith1.vp(N, p, 1)[0]
            output.append((p, i))
        return output
    elif NN != 1:
        f = N // NN
        if prime.primeq(f):
            N_prime_factors.append(f)
            _log.debug("Factored completely !")
            N_prime_factors.sort()
            for p in N_prime_factors:
                N = N // p
                i = arith1.vp(N, p, 1)[0]
                output.append((p, i))
            return output

    for F in N_factors:
        for FF in N_factors:
            if F != FF:
                Q = gcd.gcd(F, FF)
                if prime.primeq(Q) and Q not in N_prime_factors:
                    N_prime_factors.append(Q)
                    NN = NN*Q

    N_prime_factors.sort()
    for P in N_prime_factors:
        i, N = arith1.vp(N, P)
        output.append((P, i))

    if  N == 1:
        _log.debug("Factored completely!! ")
        return output

    for F in N_factors:
        g = gcd.gcd(N, F)
        if prime.primeq(g):
            N_prime_factors.append(g)
            N = N // g
            i = arith1.vp(N, g, 1)[0]
            output.append((g, i))
    if N == 1:
        _log.debug("Factored completely !! ")
        return output
    elif prime.primeq(N):
        output.append((N, 1))
        _log.debug("Factored completely!!! ")
        return output
    else:
        N_factors.sort()
        _log.error("Sorry, not factored completely")
        return output, N_factors