Ejemplo n.º 1
0
 def register(self, divisor, isprime=Unknown):
     """
     Register a divisor of the number, if the divisor is a true
     divisor of the number.  The number is divided by the divisor
     as many times as possible.
     """
     for base, index in self.factors:
         if base == divisor:
             if isprime and not self.primality[base]:
                 self.setPrimality(base, isprime)
             break
         common_divisor = gcd.gcd(base, divisor)
         if common_divisor == 1:
             continue
         # common_divisor > 1:
         if common_divisor == divisor:
             if isprime:
                 self.setPrimality(divisor, isprime)
             k, coprime = arith1.vp(base, common_divisor)
             while not gcd.coprime(common_divisor, coprime):
                 # try a smaller factor
                 common_divisor = gcd.gcd(common_divisor, coprime)
                 k, coprime = arith1.vp(base, common_divisor)
             if k:
                 if coprime > 1:
                     self.replace(base, [(common_divisor, k), (coprime, 1)])
                 else:
                     self.replace(base, [(common_divisor, k)])
         else:  # common_divisor properly divides divisor.
             self.register(common_divisor)
             self.register(divisor // common_divisor)
Ejemplo n.º 2
0
def rhomethod(n, **options):
    """
    Find a non-trivial factor of n using Pollard's rho algorithm.
    The implementation refers the explanation in C.Pomerance's book.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if not verbose:
        _silence()

    if n <= 3:
        return 1

    g = n
    while g == n:
        # x^2 + a is iterated. Starting value x = u.
        a = bigrandom.randrange(1, n - 2)
        u = v = bigrandom.randrange(0, n - 1)
        _log.info("%d %d" % (a, u))
        g = gcd.gcd((v**2 + v + a) % n - u, n)
        while g == 1:
            u = (u**2 + a) % n
            v = ((pow(v, 2, n) + a)**2 + a) % n
            g = gcd.gcd(v - u, n)
    if not verbose:
        _verbose()
    return g
Ejemplo n.º 3
0
def rhomethod(n, **options):
    """
    Find a non-trivial factor of n using Pollard's rho algorithm.
    The implementation refers the explanation in C.Pomerance's book.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if not verbose:
        _silence()

    if n <= 3:
        return 1

    g = n
    while g == n:
        a = bigrandom.randrange(1, n-2)
        u = v = bigrandom.randrange(0, n-1)
        _log.info("%d %d" % (a, u))
        g = gcd.gcd((v**2 + v + a) % n - u, n)
        while g == 1:
            u = (u**2 + a) % n
            v = ((pow(v, 2, n) + a)**2 + a) % n
            g = gcd.gcd(v - u, n)
    if not verbose:
        _verbose()
    return g
Ejemplo n.º 4
0
 def register(self, divisor, isprime=Unknown):
     """
     Register a divisor of the number, if the divisor is a true
     divisor of the number.  The number is divided by the divisor
     as many times as possible.
     """
     for base, index in self.factors:
         if base == divisor:
             if isprime and not self.primality[base]:
                 self.setPrimality(base, isprime)
             break
         common_divisor = gcd.gcd(base, divisor)
         if common_divisor == 1:
             continue
         # common_divisor > 1:
         if common_divisor == divisor:
             if isprime:
                 self.setPrimality(divisor, isprime)
             k, coprime = arith1.vp(base, common_divisor)
             while not gcd.coprime(common_divisor, coprime):
                 # try a smaller factor
                 common_divisor = gcd.gcd(common_divisor, coprime)
                 k, coprime = arith1.vp(base, common_divisor)
             if k:
                 if coprime > 1:
                     self.replace(base, [(common_divisor, k), (coprime, 1)])
                 else:
                     self.replace(base, [(common_divisor, k)])
         else: # common_divisor properly divides divisor.
             self.register(common_divisor)
             self.register(divisor // common_divisor)
Ejemplo n.º 5
0
def aks(n):
    """
    AKS ( Cyclotomic Congruence Test ) primality test for a natural number.
    
    Input: a natural number n ( n > 1 ).
    Output: n is prime => return True
            n is not prime => return False.
    """
    import nzmath.multiplicative as multiplicative

    if arith1.powerDetection(n)[1] != 1:  #Power Detection
        return False

    lg = math.log(n, 2)
    k = int(lg * lg)

    start = 3
    while 1:
        d = gcd.gcd(start, n)
        if 1 < d < n:
            return False
        x = n % start
        N = x
        for i in range(1, k + 1):
            if N == 1:
                break
            N = (N * x) % start
        if i == k:
            r = start
            break
        start += 1
    d = gcd.gcd(r, n)
    if 1 < d < n:
        return False
    if n <= r:
        return True

    e = multiplicative.euler(r)  #Cyclotomic Conguence
    e = math.sqrt(e)
    e = int(e * lg)
    for b in range(1, e + 1):
        f = array_poly.ArrayPolyMod([b, 1], n)
        total = array_poly.ArrayPolyMod([1], n)
        count = n
        while count > 0:
            if count & 1:
                total = total * f
                total = _aks_mod(total, r)
            f = f.power()
            f = _aks_mod(f, r)
            count = count >> 1
        total_poly = total.coefficients_to_dict()
        if total_poly != {0: b, n % r: 1}:
            return False
    return True
Ejemplo n.º 6
0
def pmom(n, **options):
    """
    This function tries to find a non-trivial factor of n using
    Algorithm 8.8.2 (p-1 first stage) of Cohen's book.
    In case of N = pow(2,i), this program will not terminate.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if not verbose:
        _silence()

    # initialize
    x = y = 2
    primes = []
    if 'B' in options:
        B = options['B']
    else:
        B = 10000

    for q in prime.generator():
        primes.append(q)
        if q > B:
            if gcd.gcd(x - 1, n) == 1:
                if not verbose:
                    _verbose()
                return 1
            x = y
            break
        q1 = q
        l = B // q
        while q1 <= l:
            q1 *= q
        x = pow(x, q1, n)
        if len(primes) >= 20:
            if gcd.gcd(x - 1, n) == 1:
                primes, y = [], x
            else:
                x = y
                break

    for q in primes:
        q1 = q
        while q1 <= B:
            x = pow(x, q, n)
            g = gcd.gcd(x - 1, n)
            if g != 1:
                if not verbose:
                    _verbose()
                if g == n:
                    return 1
                return g
            q1 *= q
Ejemplo n.º 7
0
def pmom(n, **options):
    """
    This function tries to find a non-trivial factor of n using
    Algorithm 8.8.2 (p-1 first stage) of Cohen's book.
    In case of N = pow(2,i), this program will not terminate.
    """
    # verbosity
    verbose = options.get('verbose', False)
    if not verbose:
        _silence()

    # initialize
    x , B = 2 , 10000001
    y = x
    primes = []

    for q in prime.generator():
        primes.append(q)
        if q > B:
            if gcd.gcd(x-1, n) == 1:
                if not verbose:
                    _verbose()
                return 1
            x = y
            break
        q1 = q
        l = B//q
        while q1 <= l:
            q1 *= q
        x = pow(x, q1, n)
        if len(primes) >= 20:
            if gcd.gcd(x-1, n) == 1:
                primes, y = [], x
            else:
                x = y
                break

    for q in primes:
        q1 = q
        while q1 <= B:
            x = pow(x, q, n)
            g = gcd.gcd(x-1, n)
            if g != 1:
                if not verbose:
                    _verbose()
                if g == n:
                    return 1
                return g
            q1 *= q
Ejemplo n.º 8
0
    def sub8(self, q, k, n, J):
        s = J.get(3, q)
        J3 = J.get(3, q)
        m = len(s)
        sx_z = {1: s}
        x = 3
        step = 2
        while m > x:
            z_4b = Zeta(m)
            i = x
            j = 1
            while i != 0:
                z_4b[j] = J3[i]
                i = (i + x) % m
                j += 1
            z_4b[0] = J3[0]
            sx_z[x] = z_4b
            s = pow(sx_z[x], x, n) * s
            step = 8 - step
            x += step

        s = pow(s, n // m, n)

        r = n % m
        step = 2
        x = 3
        while m > x:
            c = r * x
            if c > m:
                s = pow(sx_z[x], c // m, n) * s
            step = 8 - step
            x += step
        r = r & 7
        if r == 5 or r == 7:
            s = J.get(2, q).promote(m) * s
        s = +(s % n)

        if s.weight() == 1 and s.mass() == 1:
            if gcd.gcd(m, s.z.index(1)) == 1 and pow(q,
                                                     (n - 1) >> 1, n) == n - 1:
                self.done(2)
            return True
        elif s.weight() == 1 and s.mass() == n - 1:
            if gcd.gcd(m, s.z.index(n - 1)) == 1 and pow(q, (n - 1) >> 1,
                                                         n) == n - 1:
                self.done(2)
            return True
        return False
Ejemplo n.º 9
0
def dumas(target, p):
    """
    Return True if target is irreducible, False if reducible
    or None if undecidable.

    Dumas's criterion is the following.  Let f = \sum a_i X^i be a
    integer coefficient polynomial with degree n, and p be a prime
    number.  f is irreducible if
    (I) gcd(n, v(a_n) - v(a_0)) == 1
        (where v(m) denotes the number e that p**e divide m but
        p**(e+1) doesn't)
    (II) for any i (0 < i < n), (i, v(a_i)) is above the line connecting
        (0, v(a_0)) and (n, v(a_n)).
    This criterion includes Eisenstein's case.
    """
    segments = dict((d, arith1.vp(c, p=p)[0]) for (d, c) in target)
    # (I)
    degree = target.degree()
    if abs(gcd.gcd(degree, segments[degree] - segments[0])) != 1:
        return None
    # (II)
    #(segments[degree] - segments[0]) / degree * x + segment[0] < segments[x]
    slope = segments[degree] - segments[0]
    if all(slope * x <= degree * (v - segments[0])
           for x, v in segments.iteritems()):
        return True
    # the criterion doesn't work
    return None
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
 def change_base_module(self, other_base):
     """
     change base_module to other_base_module
     (i.e. represent with respect to base_module)
     """
     if self.base == other_base:
         return self
     n = self.number_field.degree
     if isinstance(other_base, list):
         other_base = matrix.FieldSquareMatrix(n,
             [vector.Vector(other_base[i]) for i in range(n)])
     else: # matrix repr
         other_base = other_base.copy()
     tr_base_mat, tr_base_denom = _toIntegerMatrix(
         other_base.inverse(self.base))
     denom = tr_base_denom * self.denominator
     mat_repr, numer = _toIntegerMatrix(
         tr_base_mat * self.mat_repr, 2)
     d = gcd.gcd(denom, numer)
     if d != 1:
         denom = ring.exact_division(denom, d)
         numer = ring.exact_division(numer, d)
     if numer != 1:
         mat_repr = numer * mat_repr
     return self.__class__([mat_repr, denom], self.number_field, other_base)
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
 def to_HNFRepresentation(self):
     """
     Transform self to the corresponding ideal as HNF representation
     """
     int_ring = self.number_field.integer_ring()
     n = self.number_field.degree
     polynomial = self.number_field.polynomial
     k = len(self.generator)
     # separate coeff and denom for generators and base
     gen_denom = reduce( gcd.lcm,
                         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     base_int, base_denom = _toIntegerMatrix(int_ring)
     
     base_alg = [BasicAlgNumber([base_int[j], 1], 
     polynomial) for j in range(1, n + 1)]
     repr_mat_list = []
     for gen in gen_list:
         for base in base_alg:
             new_gen = gen * base
             repr_mat_list.append(
                 vector.Vector([new_gen.coeff[j] for j in range(n)]))
     mat_repr = matrix.RingMatrix(n, n * k, repr_mat_list)
     new_mat_repr, numer = _toIntegerMatrix(mat_repr, 2)
     denom = gen_denom * base_denom
     denom_gcd = gcd.gcd(numer, denom)
     if denom_gcd != 1:
         denom = ring.exact_division(denom, denom_gcd)
         numer = ring.exact_division(numer, denom_gcd)
         if numer != 1:
             new_mat_repr = numer * new_mat_repr
     else:
         new_mat_repr = mat_repr
     return Ideal([new_mat_repr, denom], self.number_field)
Ejemplo n.º 14
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))
Ejemplo n.º 15
0
 def change_base_module(self, other_base):
     """
     change base_module to other_base_module
     (i.e. represent with respect to base_module)
     """
     if self.base == other_base:
         return self
     n = self.number_field.degree
     if isinstance(other_base, list):
         other_base = matrix.FieldSquareMatrix(n,
             [vector.Vector(other_base[i]) for i in range(n)])
     else: # matrix repr
         other_base = other_base.copy()
     tr_base_mat, tr_base_denom = _toIntegerMatrix(
         other_base.inverse(self.base))
     denom = tr_base_denom * self.denominator
     mat_repr, numer = _toIntegerMatrix(
         tr_base_mat * self.mat_repr, 2)
     d = gcd.gcd(denom, numer)
     if d != 1:
         denom = ring.exact_division(denom, d)
         numer = ring.exact_division(numer, d)
     if numer != 1:
         mat_repr = numer * mat_repr
     return self.__class__([mat_repr, denom], self.number_field, other_base)
Ejemplo n.º 16
0
 def to_HNFRepresentation(self):
     """
     Transform self to the corresponding ideal as HNF representation
     """
     int_ring = self.number_field.integer_ring()
     n = self.number_field.degree
     polynomial = self.number_field.polynomial
     k = len(self.generator)
     # separate coeff and denom for generators and base
     gen_denom = reduce( gcd.lcm,
                         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     base_int, base_denom = _toIntegerMatrix(int_ring)
     
     base_alg = [BasicAlgNumber([base_int[j], 1], 
     polynomial) for j in range(1, n + 1)]
     repr_mat_list = []
     for gen in gen_list:
         for base in base_alg:
             new_gen = gen * base
             repr_mat_list.append(
                 vector.Vector([new_gen.coeff[j] for j in range(n)]))
     mat_repr = matrix.RingMatrix(n, n * k, repr_mat_list)
     new_mat_repr, numer = _toIntegerMatrix(mat_repr, 2)
     denom = gen_denom * base_denom
     denom_gcd = gcd.gcd(numer, denom)
     if denom_gcd != 1:
         denom = ring.exact_division(denom, denom_gcd)
         numer = ring.exact_division(numer, denom_gcd)
         if numer != 1:
             new_mat_repr = numer * new_mat_repr
     else:
         new_mat_repr = mat_repr
     return Ideal([new_mat_repr, denom], self.number_field)
Ejemplo n.º 17
0
    def get_random_curve_with_point(cls, curve_type, n, bounds):
        """
        Return the curve with parameter C and a point Q on the curve,
        according to the curve_type, factorization target n and the
        bounds for stages.

        curve_type should be one of the module constants corresponding
        to parameters:
          S: Suyama's parameter selection strategy
          B: Bernstein's [2:1], [16,18,4,2]
          A1: Asuncion's [2:1], [4,14,1,1]
          A2: Asuncion's [2:1], [16,174,4,41]
          A3: Asuncion's [3:1], [9,48,1,2]
          A4: Asuncion's [3:1], [9,39,1,1]
          A5: Asuncion's [4:1], [16,84,1,1]
          N3: Nakamura's [2:1], [28,22,7,3]
          This is a class method.
        """
        bound = bounds.first
        if curve_type not in cls._CURVE_TYPES:
            raise ValueError("Input curve_type is wrong.")
        if curve_type == SUYAMA:
            t = n
            while _gcd.gcd(t, n) != 1:
                sigma = random.randrange(6, bound + 1)
                u, v = (sigma**2 - 5) % n, (4 * sigma) % n
                t = 4 * (u**3) * v
            d = _arith1.inverse(t, n)
            curve = cls((((u - v)**3 * (3 * u + v)) * d - 2) % n)
            start_point = Point(pow(u, 3, n), pow(v, 3, n))
        elif curve_type == BERNSTEIN:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((4 * d + 2) % n)
        elif curve_type == ASUNCION1:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((d + 1) % n)
        elif curve_type == ASUNCION2:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((4 * d + 41) % n)
        elif curve_type == ASUNCION3:
            d = random.randrange(1, bound + 1)
            start_point = Point(3, 1)
            curve = cls((d + 2) % n)
        elif curve_type == ASUNCION4:
            d = random.randrange(1, bound + 1)
            start_point = Point(3, 1)
            curve = cls((d + 1) % n)
        elif curve_type == ASUNCION5:
            d = random.randrange(1, bound + 1)
            start_point = Point(4, 1)
            curve = cls((d + 1) % n)
        elif curve_type == NAKAMURA3:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((7 * d + 3) % n)
        return curve, start_point
Ejemplo n.º 18
0
    def sub8(self, q, k, n, J):
        s = J.get(3, q)
        J3 = J.get(3, q)
        m = len(s)
        sx_z = {1:s}
        x = 3
        step = 2
        while m > x:
            z_4b = Zeta(m)
            i = x
            j = 1
            while i != 0:
                z_4b[j] = J3[i]
                i = (i + x) % m
                j += 1
            z_4b[0] = J3[0]
            sx_z[x] = z_4b
            s = pow(sx_z[x], x, n) * s
            step = 8 - step
            x += step

        s = pow(s, n//m, n)

        r = n % m
        step = 2
        x = 3
        while m > x:
            c = r*x
            if c > m:
                s = pow(sx_z[x], c//m, n) * s
            step = 8 - step
            x += step
        r = r % 8
        if r == 5 or r == 7:
            s = J.get(2, q).promote(m) * s
        s = +(s % n)

        if s.weight() == 1 and s.mass() == 1:
            if gcd.gcd(m, s.z.index(1)) == 1 and pow(q, (n-1)//2, n) == n-1:
                self.done(2)
            return True
        elif s.weight() == 1 and s.mass() == n-1:
            if gcd.gcd(m, s.z.index(n-1)) == 1 and pow(q, (n-1)//2, n) == n-1:
                self.done(2)
            return True
        return False
Ejemplo n.º 19
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
Ejemplo n.º 20
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
Ejemplo n.º 21
0
 def twoElementRepresentation(self):
     # refer to [Poh-Zas] 
     # Algorithm 4.7.10 and Exercise 29 in CCANT
     """
     Reduce the number of generator to only two elements
     Warning: If self is not a prime ideal, this method is not efficient
     """
     k = len(self.generator)
     gen_denom = reduce( gcd.lcm, 
         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     int_I = Ideal_with_generator(gen_list)
     R = 1
     norm_I = int_I.norm()
     l_I = int_I.smallest_rational()
     if l_I.denominator > 1:
         raise ValueError, "input an integral ideal"
     else:
         l_I = l_I.numerator
     while True:
         lmda = [R for i in range(k)]
         while lmda[0] > 0:
             alpha = lmda[0] * gen_list[0]
             for i in range(1, k):
                 alpha += lmda[i] * gen_list[i]
             if gcd.gcd(
               norm_I, ring.exact_division(
               alpha.norm(), norm_I)
               ) == 1 or gcd.gcd(
               norm_I, ring.exact_division(
               (alpha + l_I).norm(), norm_I)) == 1:
                 l_I_ori = BasicAlgNumber(
                     [[l_I] + [0] * (self.number_field.degree - 1),
                     gen_denom], self.number_field.polynomial)
                 alpha_ori = BasicAlgNumber([alpha.coeff, 
                     gen_denom], self.number_field.polynomial)
                 return Ideal_with_generator([l_I_ori, alpha_ori])
             for j in range(k)[::-1]:
                 if lmda[j] != -R:
                     lmda[j] -= 1
                     break
                 else:
                     lmda[j] = R
         R += 1
Ejemplo n.º 22
0
 def twoElementRepresentation(self):
     # refer to [Poh-Zas]
     # Algorithm 4.7.10 and Exercise 29 in CCANT
     """
     Reduce the number of generator to only two elements
     Warning: If self is not a prime ideal, this method is not efficient
     """
     k = len(self.generator)
     gen_denom = reduce(gcd.lcm,
                        (self.generator[j].denom for j in range(k)))
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     int_I = Ideal_with_generator(gen_list)
     R = 1
     norm_I = int_I.norm()
     l_I = int_I.smallest_rational()
     if l_I.denominator > 1:
         raise ValueError, "input an integral ideal"
     else:
         l_I = l_I.numerator
     while True:
         lmda = [R for i in range(k)]
         while lmda[0] > 0:
             alpha = lmda[0] * gen_list[0]
             for i in range(1, k):
                 alpha += lmda[i] * gen_list[i]
             if gcd.gcd(norm_I, ring.exact_division(
                     alpha.norm(), norm_I)) == 1 or gcd.gcd(
                         norm_I,
                         ring.exact_division(
                             (alpha + l_I).norm(), norm_I)) == 1:
                 l_I_ori = BasicAlgNumber(
                     [[l_I] + [0] *
                      (self.number_field.degree - 1), gen_denom],
                     self.number_field.polynomial)
                 alpha_ori = BasicAlgNumber([alpha.coeff, gen_denom],
                                            self.number_field.polynomial)
                 return Ideal_with_generator([l_I_ori, alpha_ori])
             for j in range(k)[::-1]:
                 if lmda[j] != -R:
                     lmda[j] -= 1
                     break
                 else:
                     lmda[j] = R
         R += 1
Ejemplo n.º 23
0
 def _simplify(self):
     """
     simplify self.denominator
     """
     mat_repr, numer = _toIntegerMatrix(self.mat_repr, 2)
     denom_gcd = gcd.gcd(numer, self.denominator)
     if denom_gcd != 1:
         self.denominator = ring.exact_division(self.denominator, denom_gcd)
         self.mat_repr = Submodule.fromMatrix(
             ring.exact_division(numer, denom_gcd) * mat_repr)
Ejemplo n.º 24
0
 def _simplify(self):
     """
     simplify self.denominator
     """
     mat_repr, numer = _toIntegerMatrix(self.mat_repr, 2)
     denom_gcd = gcd.gcd(numer, self.denominator)
     if denom_gcd != 1:
         self.denominator = ring.exact_division(self.denominator, denom_gcd)
         self.mat_repr = Submodule.fromMatrix(
             ring.exact_division(numer, denom_gcd) * mat_repr)
Ejemplo n.º 25
0
    def get_random_curve_with_point(cls, curve_type, n, bounds):
        """
        Return the curve with parameter C and a point Q on the curve,
        according to the curve_type, factorization target n and the
        bounds for stages.

        curve_type should be one of the module constants corresponding
        to parameters:
          S: Suyama's parameter selection strategy
          B: Bernstein's [2:1], [16,18,4,2]
          A1: Asuncion's [2:1], [4,14,1,1]
          A2: Asuncion's [2:1], [16,174,4,41]
          A3: Asuncion's [3:1], [9,48,1,2]
          A4: Asuncion's [3:1], [9,39,1,1]
          A5: Asuncion's [4:1], [16,84,1,1]

        This is a class method.
        """
        bound = bounds.first
        if curve_type not in cls._CURVE_TYPES:
            raise ValueError("Input curve_type is wrong.")
        if curve_type == SUYAMA:
            t = n
            while _gcd.gcd(t, n) != 1:
                sigma = random.randrange(6, bound + 1)
                u, v = (sigma**2 - 5) % n, (4*sigma) % n
                t = 4*(u**3)*v
            d = _arith1.inverse(t, n)
            curve = cls((((u - v)**3 * (3*u + v)) * d - 2) % n)
            start_point = Point(pow(u, 3, n), pow(v, 3, n))
        elif curve_type == BERNSTEIN:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((4*d + 2) % n)
        elif curve_type == ASUNCION1:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((d + 1) % n)
        elif curve_type == ASUNCION2:
            d = random.randrange(1, bound + 1)
            start_point = Point(2, 1)
            curve = cls((4*d + 41) % n)
        elif curve_type == ASUNCION3:
            d = random.randrange(1, bound + 1)
            start_point = Point(3, 1)
            curve = cls((d + 2) % n)
        elif curve_type == ASUNCION4:
            d = random.randrange(1, bound + 1)
            start_point = Point(3, 1)
            curve = cls((d + 1) % n)
        elif curve_type == ASUNCION5:
            d = random.randrange(1, bound + 1)
            start_point = Point(4, 1)
            curve = cls((d + 1) % n)
        return curve, start_point
Ejemplo n.º 26
0
def bigprimeq(z):
    """
    Giving up rigorous proof of primality, return True for a probable
    prime.
    """
    if int(z) != z:
        raise ValueError("non-integer for primeq()")
    elif z <= 1:
        return False
    elif gcd.gcd(z, PRIMONIAL_31) > 1:
        return (z in PRIMES_LE_31)
    return millerRabin(z)
Ejemplo n.º 27
0
def bigprimeq(z):
    """
    Giving up rigorous proof of primality, return True for a probable
    prime.
    """
    if int(z) != z:
        raise ValueError("non-integer for primeq()")
    elif z <= 1:
        return False
    elif gcd.gcd(z, 510510) > 1:
        return (z in (2, 3, 5, 7, 11, 13, 17))
    return millerRabin(z)
Ejemplo n.º 28
0
def _toIntegerMatrix(mat, option=0):
    """
    transform a (including integral) rational matrix to 
        some integral matrix as the following
    [option]
    0: return integral-matrix, denominator
       (mat = 1/denominator * integral-matrix)
    1: return integral-matrix, denominator, numerator
       (mat = numerator/denominator * reduced-int-matrix)
    2: return integral-matrix, numerator (assuming mat is integral)
       (mat = numerator * numerator-reduced-rational-matrix)
    """
    def getDenominator(ele):
        """
        get the denominator of ele
        """
        if rational.isIntegerObject(ele):
            return 1
        else: # rational
            return ele.denominator
    def getNumerator(ele):
        """
        get the numerator of ele
        """
        if rational.isIntegerObject(ele):
            return ele
        else: # rational
            return ele.numerator
    if isinstance(mat, vector.Vector):
        mat = mat.toMatrix(True)
    if option <= 1:
        denom = mat.reduce(
            lambda x, y: gcd.lcm(x, getDenominator(y)), 1)
        new_mat = mat.map(
            lambda x: getNumerator(x) * ring.exact_division(
            denom, getDenominator(x)))
        if option == 0:
            return Submodule.fromMatrix(new_mat), denom
    else:
        new_mat = mat
    numer = new_mat.reduce(
        lambda x, y: gcd.gcd(x, getNumerator(y)))
    if numer != 0:
        new_mat2 = new_mat.map(
            lambda x: ring.exact_division(getNumerator(x), numer))
    else:
        new_mat2 = new_mat
    if option == 1:
        return Submodule.fromMatrix(new_mat2), denom, numer
    else:
        return Submodule.fromMatrix(new_mat2), numer
Ejemplo n.º 29
0
def _toIntegerMatrix(mat, option=0):
    """
    transform a (including integral) rational matrix to 
        some integral matrix as the following
    [option]
    0: return integral-matrix, denominator
       (mat = 1/denominator * integral-matrix)
    1: return integral-matrix, denominator, numerator
       (mat = numerator/denominator * reduced-int-matrix)
    2: return integral-matrix, numerator (assuming mat is integral)
       (mat = numerator * numerator-reduced-rational-matrix)
    """
    def getDenominator(ele):
        """
        get the denominator of ele
        """
        if rational.isIntegerObject(ele):
            return 1
        else: # rational
            return ele.denominator
    def getNumerator(ele):
        """
        get the numerator of ele
        """
        if rational.isIntegerObject(ele):
            return ele
        else: # rational
            return ele.numerator
    if isinstance(mat, vector.Vector):
        mat = mat.toMatrix(True)
    if option <= 1:
        denom = mat.reduce(
            lambda x, y: gcd.lcm(x, getDenominator(y)), 1)
        new_mat = mat.map(
            lambda x: getNumerator(x) * ring.exact_division(
            denom, getDenominator(x)))
        if option == 0:
            return Submodule.fromMatrix(new_mat), denom
    else:
        new_mat = mat
    numer = new_mat.reduce(
        lambda x, y: gcd.gcd(x, getNumerator(y)))
    if numer != 0:
        new_mat2 = new_mat.map(
            lambda x: ring.exact_division(getNumerator(x), numer))
    else:
        new_mat2 = new_mat
    if option == 1:
        return Submodule.fromMatrix(new_mat2), denom, numer
    else:
        return Submodule.fromMatrix(new_mat2), numer
Ejemplo n.º 30
0
def stage1(n, bounds, C, Q):
    """
    ECM stage 1 for factoring n.
    The upper bound for primes to be tested is bounds.first.
    It uses curve C and starting point Q.
    """
    for p in _prime.generator_eratosthenes(bounds.first):
        q = p
        while q < bounds.first:
            Q = mul(Q, p, C, n)
            q *= p
    g = _gcd.gcd(Q.z, n)
    _log.debug("Stage 1: %d" % g)
    return g
Ejemplo n.º 31
0
def stage1(n, bounds, C, Q):
    """
    ECM stage 1 for factoring n.
    The upper bound for primes to be tested is bounds.first.
    It uses curve C and starting point Q.
    """
    for p in _prime.generator_eratosthenes(bounds.first):
        q = p
        while q < bounds.first:
            Q = mul(Q, p, C, n)
            q *= p
    g = _gcd.gcd(Q.z, n)
    _log.debug("Stage 1: %d" % g)
    return g
Ejemplo n.º 32
0
def stage2(n, bounds, C, Q):
    """
    ECM stage 2 for factoring n.
    The upper bounds for primes to be tested are stored in bounds.
    It uses curve C and starting point Q.
    """
    d1 = bounds.first + random.randrange(1, 16)
    d2 = 0
    while _gcd.gcd(d1, d2) != 1:
        d2 = random.randrange(2, d1//5 + 1) # We want to keep d2 small
    for i in range(1, bounds.second//d1):
        if _gcd.gcd(i, d2) != 1:
            continue
        for j in range(1, d1//2):
            if _gcd.gcd(j, d1) == 1:
                Q = mul(Q, i*d1 + j*d2, C, n)
                if i*d1 - j*d2 > bounds.first:
                    Q = mul(Q, i*d1 - j*d2, C, n)
        g = _gcd.gcd(Q.z, n)
        if 1 < g < n:
            _log.debug("Stage 2: %d" % g)
            return g
    _log.debug("Stage 2: %d" % g)
    return 1
Ejemplo n.º 33
0
def stage2(n, bounds, C, Q):
    """
    ECM stage 2 for factoring n.
    The upper bounds for primes to be tested are stored in bounds.
    It uses curve C and starting point Q.
    """
    d1 = bounds.first + random.randrange(1, 16)
    d2 = 0
    while _gcd.gcd(d1, d2) != 1:
        d2 = random.randrange(2, d1 // 5 + 1)  # We want to keep d2 small
    for i in range(1, bounds.second // d1):
        if _gcd.gcd(i, d2) != 1:
            continue
        for j in range(1, d1 // 2):
            if _gcd.gcd(j, d1) == 1:
                Q = mul(Q, i * d1 + j * d2, C, n)
                if i * d1 - j * d2 > bounds.first:
                    Q = mul(Q, i * d1 - j * d2, C, n)
        g = _gcd.gcd(Q.z, n)
        if 1 < g < n:
            _log.debug("Stage 2: %d" % g)
            return g
    _log.debug("Stage 2: %d" % g)
    return 1
Ejemplo n.º 34
0
def _isprime(n, pdivisors=None):
    """
    Return True iff n is prime.

    The check is done without APR.
    Assume that n is very small (less than 10**12) or
    prime factorization of n - 1 is known (prime divisors are passed to
    the optional argument pdivisors as a sequence).
    """
    if gcd.gcd(n, PRIMONIAL_31) > 1:
        return n in PRIMES_LE_31
    elif n < 10**12:
        # 1369 == 37**2
        # 1662803 is the only prime base in smallSpsp which has not checked
        return n < 1369 or n == 1662803 or smallSpsp(n)
    else:
        return full_euler(n, pdivisors)
Ejemplo n.º 35
0
 def subodd(self, p, q, n, J):
     """
     Return the sub result for odd key 'p'.
     If it is True, the status of 'p' is flipped to 'done'.
     """
     s = J.get(1, p, q)
     Jpq = J.get(1, p, q)
     m = s.size
     for x in range(2, m):
         if x % p == 0:
             continue
         sx = Zeta(m)
         i = x
         j = 1
         while i > 0:
             sx[j] = Jpq[i]
             i = (i + x) % m
             j += 1
         sx[0] = Jpq[0]
         sx = pow(sx, x, n)
         s = s*sx % n
     s = pow(s, n//m, n)
     r = n % m
     t = 1
     for x in range(1, m):
         if x % p == 0:
             continue
         c = (r*x) // m
         if c:
             tx = Zeta(m)
             i = x
             j = 1
             while i > 0:
                 tx[j] = Jpq[i]
                 i = (i + x) % m
                 j += 1
             tx[0] = Jpq[0]
             tx = pow(tx, c, n)
             t = t*tx % n
     s = +(t*s % n)
     if s.weight() == 1 and s.mass() == 1:
         for i in range(1, m):
             if gcd.gcd(m, s.z.index(1)) == 1:
                 self.done(p)
             return True
     return False
Ejemplo n.º 36
0
 def subodd(self, p, q, n, J):
     """
     Return the sub result for odd key 'p'.
     If it is True, the status of 'p' is flipped to 'done'.
     """
     s = J.get(1, p, q)
     Jpq = J.get(1, p, q)
     m = s.size
     for x in range(2, m):
         if x % p == 0:
             continue
         sx = Zeta(m)
         i = x
         j = 1
         while i > 0:
             sx[j] = Jpq[i]
             i = (i + x) % m
             j += 1
         sx[0] = Jpq[0]
         sx = pow(sx, x, n)
         s = s * sx % n
     s = pow(s, n // m, n)
     r = n % m
     t = 1
     for x in range(1, m):
         if x % p == 0:
             continue
         c = (r * x) // m
         if c:
             tx = Zeta(m)
             i = x
             j = 1
             while i > 0:
                 tx[j] = Jpq[i]
                 i = (i + x) % m
                 j += 1
             tx[0] = Jpq[0]
             tx = pow(tx, c, n)
             t = t * tx % n
     s = +(t * s % n)
     if s.weight() == 1 and s.mass() == 1:
         for i in range(1, m):
             if gcd.gcd(m, s.z.index(1)) == 1:
                 self.done(p)
             return True
     return False
Ejemplo n.º 37
0
 def __init__(self, valuelist, polynomial, precompute=False):
     if len(polynomial) != len(valuelist[0])+1:
         raise ValueError
     self.value = valuelist
     self.coeff = valuelist[0]
     self.denom = valuelist[1]
     self.degree = len(polynomial) - 1
     self.polynomial = polynomial
     self.field = NumberField(self.polynomial)
     Gcd = gcd.gcd_of_list(self.coeff)
     GCD = gcd.gcd(Gcd[0], self.denom) 
     if GCD != 1:
         self.coeff = [i//GCD for i in self.coeff]
         self.denom = self.denom//GCD
     if precompute:
         self.getConj()
         self.getApprox()
         self.getCharPoly()
Ejemplo n.º 38
0
 def __init__(self, valuelist, polynomial, precompute=False):
     if len(polynomial) != len(valuelist[0]) + 1:
         raise ValueError
     self.value = valuelist
     self.coeff = valuelist[0]
     self.denom = valuelist[1]
     self.degree = len(polynomial) - 1
     self.polynomial = polynomial
     self.field = NumberField(self.polynomial)
     Gcd = gcd.gcd_of_list(self.coeff)
     GCD = gcd.gcd(Gcd[0], self.denom)
     if GCD != 1:
         self.coeff = [i // GCD for i in self.coeff]
         self.denom = self.denom // GCD
     if precompute:
         self.getConj()
         self.getApprox()
         self.getCharPoly()
Ejemplo n.º 39
0
 def _scalar_mul(self, other):
     """
     return other * self, assuming other is a scalar
     (i.e. an element of self.number_field)
     """
     # use other is an element of higher or lower degree number field ?
     #if other.getRing() != self.number_field:
     #    raise NotImplementedError(
     #        "other is not a element of number field")
     if not isinstance(other, BasicAlgNumber):
         try:
             other = other.ch_basic()
         except:
             raise NotImplementedError(
                 "other is not an element of a number field")
     # represent other with respect to self.base
     other_repr, pseudo_other_denom = _toIntegerMatrix(
         self.base.inverse(vector.Vector(other.coeff)))
     other_repr = other_repr[1]
     # compute mul using self.base's multiplication
     base_mul = self._base_multiplication()
     n = self.number_field.degree
     mat_repr = []
     for k in range(1, self.mat_repr.column + 1):
         mat_repr_ele = vector.Vector([0] * n)
         for i1 in range(1, n + 1):
             for i2 in range(1, n + 1):
                 mat_repr_ele += self.mat_repr[
                     i1, k] * other_repr[i2] * _symmetric_element(
                         i1, i2, base_mul)
         mat_repr.append(mat_repr_ele)
     mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(mat_repr), mat_repr), 1)
     denom = self.denominator * pseudo_other_denom * other.denom * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * mat_repr
     else:
         mat_repr = mat_repr
     return self.__class__([mat_repr, denom], self.number_field, self.base)
Ejemplo n.º 40
0
 def _scalar_mul(self, other):
     """
     return other * self, assuming other is a scalar
     (i.e. an element of self.number_field)
     """
     # use other is an element of higher or lower degree number field ?
     #if other.getRing() != self.number_field:
     #    raise NotImplementedError(
     #        "other is not a element of number field")
     if not isinstance(other, BasicAlgNumber):
         try:
             other = other.ch_basic()
         except:
             raise NotImplementedError(
                 "other is not an element of a number field")
     # represent other with respect to self.base
     other_repr, pseudo_other_denom = _toIntegerMatrix(
         self.base.inverse(vector.Vector(other.coeff)))
     other_repr = other_repr[1]
     # compute mul using self.base's multiplication
     base_mul = self._base_multiplication()
     n = self.number_field.degree
     mat_repr = []
     for k in range(1, self.mat_repr.column +1):
         mat_repr_ele = vector.Vector([0] * n)
         for i1 in range(1, n + 1):
             for i2 in range(1, n + 1):
                 mat_repr_ele += self.mat_repr[i1, k] * other_repr[
                     i2] * _symmetric_element(i1, i2, base_mul)
         mat_repr.append(mat_repr_ele)
     mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(mat_repr), mat_repr), 1)
     denom = self.denominator * pseudo_other_denom * other.denom * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * mat_repr
     else:
         mat_repr = mat_repr
     return self.__class__([mat_repr, denom], self.number_field, self.base)
Ejemplo n.º 41
0
def mpqsfind(n, s=0, f=0, m=0, verbose=False):
    """
    This is main function of MPQS.
    Arguments are (composite_number, sieve_range, factorbase_size, multiplier)
    You must input composite_number at least.
    """
    # verbosity
    if verbose:
        _log.setLevel(logging.DEBUG)
        _log.debug("verbose")
    else:
        _log.setLevel(logging.NOTSET)

    starttime = time.time()
    M = MPQS(n, s, f, m)
    _log.info("Sieve range is [%d, %d]" % (M.move_range[0], M.move_range[-1]))
    _log.info("Factorbase size = %d, Max Factorbase %d" % (len(M.FB), M.maxFB))
    M.get_vector()
    N = M.number // M.multiplier
    V = Elimination(M.smooth)
    A = V.gaussian()
    _log.info("Found %d linearly dependent relations" % len(A))
    differences = []
    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 = arith1.floorsqrt(X) % M.number
        if X != Y:
            differences.append(X-Y)

    for diff in differences:
        divisor = gcd.gcd(diff, N)
        if 1 < divisor < N:
            _log.info("Total time = %f sec" % (time.time() - starttime))
            return divisor
Ejemplo n.º 42
0
def primeq(n):
    """
    A convenient function for primatilty test. It uses one of
    trialDivision, smallSpsp or apr depending on the size of n.
    """
    if int(n) != n:
        raise ValueError("non-integer for primeq()")
    if n <= 1:
        return False

    if gcd.gcd(n, PRIMONIAL_31) > 1:
        return n in PRIMES_LE_31
    if n < 2000000:
        return trialDivision(n)
    if not smallSpsp(n):
        return False
    if n < 10**12:
        return True
    if not GRH:
        return apr(n)
    else:
        return miller(n)
Ejemplo n.º 43
0
def primeq(n):
    """
    A convinient function for primatilty test. It uses one of
    trialDivision, smallSpsp or apr depending on the size of n.
    """
    if int(n) != n:
        raise ValueError("non-integer for primeq()")
    if n <= 1:
        return False

    if gcd.gcd(n, 510510) > 1:
        return (n in (2, 3, 5, 7, 11, 13, 17))
    if n < 2000000:
        return trialDivision(n)
    if not smallSpsp(n):
        return False
    if n < 10 ** 12:
        return True
    if not GRH:
        return apr(n)
    else:
        return miller(n)
Ejemplo n.º 44
0
def _kernel_of_qpow(omega, q, p, minpoly, n):
    """
    Return the kernel of q-th powering, which is a linear map over Fp.
    q is a power of p which exceeds n.

    (omega_j^q (mod theminpoly) = \sum a_i_j omega_i   a_i_j in Fp)
    """
    omega_poly = omega.get_polynomials()
    denom = omega.denominator
    theminpoly = minpoly.to_field_polynomial()
    field_p = finitefield.FinitePrimeField.getInstance(p)
    zero = field_p.zero
    qpow = matrix.zeroMatrix(n, n, field_p) # Fp matrix
    for j in range(n):
        a_j = [zero] * n
        omega_poly_j = uniutil.polynomial(enumerate(omega.basis[j]), Z)
        omega_j_qpow = pow(omega_poly_j, q, minpoly)
        redundancy = gcd.gcd(omega_j_qpow.content(), denom ** q)
        omega_j_qpow = omega_j_qpow.coefficients_map(lambda c: c // redundancy)
        essential = denom ** q // redundancy
        while omega_j_qpow:
            i = omega_j_qpow.degree()
            a_ji = int(omega_j_qpow[i] / (omega_poly[i][i] * essential))
            omega_j_qpow -= a_ji * (omega_poly[i] * essential)
            if omega_j_qpow.degree() < i:
                a_j[i] = field_p.createElement(a_ji)
            else:
                _log.debug("%s / %d" % (str(omega_j_qpow), essential))
                _log.debug("j = %d, a_ji = %s" % (j, a_ji))
                raise ValueError("omega is not a basis")
        qpow.setColumn(j + 1, a_j)

    result = qpow.kernel()
    if result is None:
        _log.debug("(_k_q): trivial kernel")
        return matrix.zeroMatrix(n, 1, field_p)
    else:
        return result
Ejemplo n.º 45
0
def _kernel_of_qpow(omega, q, p, minpoly, n):
    """
    Return the kernel of q-th powering, which is a linear map over Fp.
    q is a power of p which exceeds n.

    (omega_j^q (mod theminpoly) = \sum a_i_j omega_i   a_i_j in Fp)
    """
    omega_poly = omega.get_polynomials()
    denom = omega.denominator
    theminpoly = minpoly.to_field_polynomial()
    field_p = finitefield.FinitePrimeField.getInstance(p)
    zero = field_p.zero
    qpow = matrix.zeroMatrix(n, n, field_p) # Fp matrix
    for j in range(n):
        a_j = [zero] * n
        omega_poly_j = uniutil.polynomial(enumerate(omega.basis[j]), Z)
        omega_j_qpow = pow(omega_poly_j, q, minpoly)
        redundancy = gcd.gcd(omega_j_qpow.content(), denom ** q)
        omega_j_qpow = omega_j_qpow.coefficients_map(lambda c: c // redundancy)
        essential = denom ** q // redundancy
        while omega_j_qpow:
            i = omega_j_qpow.degree()
            a_ji = int(omega_j_qpow[i] / (omega_poly[i][i] * essential))
            omega_j_qpow -= a_ji * (omega_poly[i] * essential)
            if omega_j_qpow.degree() < i:
                a_j[i] = field_p.createElement(a_ji)
            else:
                _log.debug("%s / %d" % (str(omega_j_qpow), essential))
                _log.debug("j = %d, a_ji = %s" % (j, a_ji))
                raise ValueError("omega is not a basis")
        qpow.setColumn(j + 1, a_j)

    result = qpow.kernel()
    if result is None:
        _log.debug("(_k_q): trivial kernel")
        return matrix.zeroMatrix(n, 1, field_p)
    else:
        return result
Ejemplo n.º 46
0
 def _rational_mul(self, other):
     """
     return other * self, assuming other is a rational element
     """
     if rational.isIntegerObject(other):
         other_numerator = rational.Integer(other)
         other_denominator = rational.Integer(1)
     else:
         other_numerator = other.numerator
         other_denominator = other.denominator
     denom_gcd = gcd.gcd(self.denominator, other_numerator)
     if denom_gcd != 1:
         new_denominator = ring.exact_division(
             self.denominator, denom_gcd) * other_denominator
         multiply_num = other_numerator.exact_division(denom_gcd)
     else:
         new_denominator = self.denominator * other_denominator
         multiply_num = other_numerator
     new_module = self.__class__(
                      [self.mat_repr * multiply_num, new_denominator],
                      self.number_field, self.base, self.mat_repr.ishnf)
     new_module._simplify()
     return new_module
Ejemplo n.º 47
0
 def inverse(self):
     """
     Return the inverse ideal of self
     """
     # Algorithm 4.8.21 in CCANT
     field = self.number_field
     # step 1 (Note that det(T)T^-1=(adjugate matrix of T))
     T = Ideal._precompute_for_different(field)
     d = int(T.determinant())
     inv_different = Ideal([T.adjugateMatrix(), 1], field,
                           field.integer_ring())
     # step 2
     inv_I = self * inv_different # already base is taken for integer_ring
     inv_I.toHNF()
     # step 3
     inv_mat, denom = _toIntegerMatrix(
         (inv_I.mat_repr.transpose() * T).inverse(), 0)
     numer = d * inv_I.denominator
     gcd_denom = gcd.gcd(denom, numer)
     if gcd_denom != 1:
         denom = ring.exact_division(denom, gcd_denom)
         numer = ring.exact_division(numer, gcd_denom)
     return Ideal([numer * inv_mat, denom], field, field.integer_ring())
Ejemplo n.º 48
0
 def __mul__(self, other):
     if isinstance(other, BasicAlgNumber):
         d = self.denom*other.denom
         f = zpoly(self.polynomial)
         g = zpoly(self.coeff)
         h = zpoly(other.coeff)
         j = (g * h).pseudo_mod(f)
         jcoeff = [j[i] for i in range(self.degree)]
         return BasicAlgNumber([jcoeff, d], self.polynomial)
     elif isinstance(other, (int, long)):
         Coeff = [i*other for i in self.coeff] 
         return BasicAlgNumber([Coeff, self.denom], self.polynomial)
     elif isinstance(other, rational.Rational):
         GCD = gcd.gcd(other.numerator, self.denom)
         denom = self.denom * other.denominator
         mul = other.numerator
         if GCD != 1:
             denom //= GCD
             mul //= GCD
         Coeff = [self.coeff[j] * mul for j in range(self.degree)]
         return BasicAlgNumber([Coeff, denom], self.polynomial)
     else:
         return NotImplemented
Ejemplo n.º 49
0
 def inverse(self):
     """
     Return the inverse ideal of self
     """
     # Algorithm 4.8.21 in CCANT
     field = self.number_field
     # step 1 (Note that det(T)T^-1=(adjugate matrix of T))
     T = Ideal._precompute_for_different(field)
     d = int(T.determinant())
     inv_different = Ideal([T.adjugateMatrix(), 1], field,
                           field.integer_ring())
     # step 2
     inv_I = self * inv_different  # already base is taken for integer_ring
     inv_I.toHNF()
     # step 3
     inv_mat, denom = _toIntegerMatrix(
         (inv_I.mat_repr.transpose() * T).inverse(), 0)
     numer = d * inv_I.denominator
     gcd_denom = gcd.gcd(denom, numer)
     if gcd_denom != 1:
         denom = ring.exact_division(denom, gcd_denom)
         numer = ring.exact_division(numer, gcd_denom)
     return Ideal([numer * inv_mat, denom], field, field.integer_ring())
Ejemplo n.º 50
0
 def __mul__(self, other):
     if isinstance(other, BasicAlgNumber):
         d = self.denom * other.denom
         f = zpoly(self.polynomial)
         g = zpoly(self.coeff)
         h = zpoly(other.coeff)
         j = (g * h).pseudo_mod(f)
         jcoeff = [j[i] for i in range(self.degree)]
         return BasicAlgNumber([jcoeff, d], self.polynomial)
     elif isinstance(other, int):
         Coeff = [i * other for i in self.coeff]
         return BasicAlgNumber([Coeff, self.denom], self.polynomial)
     elif isinstance(other, rational.Rational):
         GCD = gcd.gcd(other.numerator, self.denom)
         denom = self.denom * other.denominator
         mul = other.numerator
         if GCD != 1:
             denom //= GCD
             mul //= GCD
         Coeff = [self.coeff[j] * mul for j in range(self.degree)]
         return BasicAlgNumber([Coeff, denom], self.polynomial)
     else:
         return NotImplemented
Ejemplo n.º 51
0
 def _rational_mul(self, other):
     """
     return other * self, assuming other is a rational element
     """
     if rational.isIntegerObject(other):
         other_numerator = rational.Integer(other)
         other_denominator = rational.Integer(1)
     else:
         other_numerator = other.numerator
         other_denominator = other.denominator
     denom_gcd = gcd.gcd(self.denominator, other_numerator)
     if denom_gcd != 1:
         new_denominator = ring.exact_division(
             self.denominator, denom_gcd) * other_denominator
         multiply_num = other_numerator.exact_division(denom_gcd)
     else:
         new_denominator = self.denominator * other_denominator
         multiply_num = other_numerator
     new_module = self.__class__(
         [self.mat_repr * multiply_num, new_denominator], self.number_field,
         self.base, self.mat_repr.ishnf)
     new_module._simplify()
     return new_module
Ejemplo n.º 52
0
 def _module_mul(self, other):
     """
     return self * other as the multiplication of modules
     """
     #if self.number_field != other.number_field:
     #    raise NotImplementedError
     if self.base != other.base:
         new_self = self.change_base_module(other.base)
     else:
         new_self = self.copy()
     base_mul = other._base_multiplication()
     n = self.number_field.degree
     new_mat_repr = []
     for k1 in range(1, new_self.mat_repr.column + 1):
         for k2 in range(1, other.mat_repr.column + 1):
             new_mat_repr_ele = vector.Vector([0] * n)
             for i1 in range(1, n + 1):
                 for i2 in range(1, n + 1):
                     new_mat_repr_ele += new_self.mat_repr[
                         i1, k1] * other.mat_repr[i2, k2
                         ] * _symmetric_element(i1, i2, base_mul)
             new_mat_repr.append(new_mat_repr_ele)
     new_mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(new_mat_repr), new_mat_repr), 1)
     denom = new_self.denominator * other.denominator * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * new_mat_repr
     else:
         mat_repr = new_mat_repr
     sol = self.__class__(
         [mat_repr, denom], self.number_field, other.base)
     sol.toHNF()
     return sol
Ejemplo n.º 53
0
    def represent_element(self, other):
        """
        represent other as a linear combination with generators of self
        if other not in self, return False
        Note that we do not assume self.mat_repr is HNF
        """
        #if other not in self.number_field:
        #    return False
        theta_repr = (self.base * self.mat_repr)
        theta_repr.toFieldMatrix()
        pseudo_vect_repr = theta_repr.inverseImage(
            vector.Vector(other.coeff))
        pseudo_vect_repr = pseudo_vect_repr[1]
        gcd_self_other = gcd.gcd(self.denominator, other.denom)
        multiply_numerator = self.denominator // gcd_self_other
        multiply_denominator = other.denom // gcd_self_other

        def getNumerator_and_Denominator(ele):
            """
            get the pair of numerator and denominator of ele
            """
            if rational.isIntegerObject(ele):
                return (ele, 1)
            else: # rational
                return (ele.numerator, ele.denominator)

        list_repr = []
        for j in range(1, len(pseudo_vect_repr) + 1):
            try:
                numer, denom = getNumerator_and_Denominator(
                    pseudo_vect_repr[j])
                list_repr_ele = ring.exact_division(
                    numer * multiply_numerator, denom * multiply_denominator)
                list_repr.append(list_repr_ele)
            except ValueError: # division is not exact
                return False
        return list_repr
Ejemplo n.º 54
0
    def represent_element(self, other):
        """
        represent other as a linear combination with generators of self
        if other not in self, return False
        Note that we do not assume self.mat_repr is HNF
        """
        #if other not in self.number_field:
        #    return False
        theta_repr = (self.base * self.mat_repr)
        theta_repr.toFieldMatrix()
        pseudo_vect_repr = theta_repr.inverseImage(
            vector.Vector(other.coeff))
        pseudo_vect_repr = pseudo_vect_repr[1]
        gcd_self_other = gcd.gcd(self.denominator, other.denom)
        multiply_numerator = self.denominator // gcd_self_other
        multiply_denominator = other.denom // gcd_self_other

        def getNumerator_and_Denominator(ele):
            """
            get the pair of numerator and denominator of ele
            """
            if rational.isIntegerObject(ele):
                return (ele, 1)
            else: # rational
                return (ele.numerator, ele.denominator)

        list_repr = []
        for j in range(1, len(pseudo_vect_repr) + 1):
            try:
                numer, denom = getNumerator_and_Denominator(
                    pseudo_vect_repr[j])
                list_repr_ele = ring.exact_division(
                    numer * multiply_numerator, denom * multiply_denominator)
                list_repr.append(list_repr_ele)
            except ValueError: # division is not exact
                return False
        return list_repr
Ejemplo n.º 55
0
 def _module_mul(self, other):
     """
     return self * other as the multiplication of modules
     """
     #if self.number_field != other.number_field:
     #    raise NotImplementedError
     if self.base != other.base:
         new_self = self.change_base_module(other.base)
     else:
         new_self = self.copy()
     base_mul = other._base_multiplication()
     n = self.number_field.degree
     new_mat_repr = []
     for k1 in range(1, new_self.mat_repr.column + 1):
         for k2 in range(1, other.mat_repr.column + 1):
             new_mat_repr_ele = vector.Vector([0] * n)
             for i1 in range(1, n + 1):
                 for i2 in range(1, n + 1):
                     new_mat_repr_ele += new_self.mat_repr[
                         i1, k1] * other.mat_repr[i2,
                                                  k2] * _symmetric_element(
                                                      i1, i2, base_mul)
             new_mat_repr.append(new_mat_repr_ele)
     new_mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(new_mat_repr), new_mat_repr), 1)
     denom = new_self.denominator * other.denominator * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * new_mat_repr
     else:
         mat_repr = new_mat_repr
     sol = self.__class__([mat_repr, denom], self.number_field, other.base)
     sol.toHNF()
     return sol
Ejemplo n.º 56
0
 def testGcd(self):
     self.assertEqual(1, gcd.gcd(1, 2))
     self.assertEqual(2, gcd.gcd(2, 4))
     self.assertEqual(10, gcd.gcd(0, 10))
     self.assertEqual(10, gcd.gcd(10, 0))
     self.assertEqual(1, gcd.gcd(13, 21))
Ejemplo n.º 57
0
def _isprime(n):
    if gcd.gcd(n, 510510) > 1:
        return (n in (2, 3, 5, 7, 11, 13, 17))
    return smallSpsp(n)
Ejemplo n.º 58
0
 def gcd(self, n, m):
     """
     Return the greatest common divisor of given 2 integers.
     """
     a, b = abs(n), abs(m)
     return Integer(gcd.gcd(a, b))
Ejemplo n.º 59
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
Ejemplo n.º 60
0
 def gcd(self, n, m):
     """
     Return the greatest common divisor of given 2 integers.
     """
     a, b = abs(n), abs(m)
     return Integer(gcd.gcd(a, b))