예제 #1
0
파일: find.py 프로젝트: nickspoon/part-ii
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
예제 #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
예제 #3
0
 def testRange(self):
     for i in range(10000):
         start = random.randrange(-5000, 1)**3
         stop = random.randrange(1, 5000)**3
         step = random.randrange(1, 200)
         d = bigrandom.randrange(start, stop, step)
         self.assertEqual(0, (d - start) % step)
         self.assertTrue(start <= d < stop)
         d = bigrandom.randrange(start**2, -stop**2, -step)
         self.assertEqual(0, (d - start**2) % step)
         self.assertTrue(start**2 >= d > -stop**2)
예제 #4
0
 def _random_irriducible(char, degree):
     """
     Return randomly chosen irreducible polynomial of self.degree.
     """
     cardinality = char ** degree
     basefield = FinitePrimeField.getInstance(char)
     seed = bigrandom.randrange(1, char) + cardinality
     cand = uniutil.FiniteFieldPolynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
     while cand.degree() < degree or not cand.isirreducible():
         seed = bigrandom.randrange(1, cardinality) + cardinality
         cand = uniutil.FiniteFieldPolynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
     _log.debug(cand.order.format(cand))
     return cand
예제 #5
0
 def choose_point(self):
     """
     Choose point on E_{a,b}(Z_n)
     Algorithm 27 (Atkin-morain ECPP) Step5
     """
     n, f = self.modulus, self.f
     x = bigrandom.randrange(n)
     Q = f(x)
     while arith1.legendre(Q, n) == -1:
         x = bigrandom.randrange(n)
         Q = f(x)
     y = arith1.modsqrt(Q, n)
     return [intresidue.IntegerResidueClass(t, n) for t in (x, y)]
예제 #6
0
파일: ecpp.py 프로젝트: nickspoon/part-ii
 def choose_point(self):
     """
     Choose point on E_{a,b}(Z_n)
     Algorithm 27 (Atkin-morain ECPP) Step5
     """
     n, f = self.modulus, self.f
     x = bigrandom.randrange(n)
     Q = f(x)
     while arith1.legendre(Q, n) == -1:
         x = bigrandom.randrange(n)
         Q = f(x)
     y = arith1.modsqrt(Q, n)
     return [intresidue.IntegerResidueClass(t, n) for t in (x, y)]
예제 #7
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
예제 #8
0
 def _random_irriducible(char, degree):
     """
     Return randomly chosen irreducible polynomial of self.degree.
     """
     cardinality = char**degree
     basefield = FinitePrimeField.getInstance(char)
     seed = bigrandom.randrange(1, char) + cardinality
     cand = uniutil.FiniteFieldPolynomial(enumerate(
         arith1.expand(seed, cardinality)),
                                          coeffring=basefield)
     while cand.degree() < degree or not cand.isirreducible():
         seed = bigrandom.randrange(1, cardinality) + cardinality
         cand = uniutil.FiniteFieldPolynomial(enumerate(
             arith1.expand(seed, cardinality)),
                                              coeffring=basefield)
     _log.debug(cand.order.format(cand))
     return cand
예제 #9
0
 def __init__(self, characteristic, n_or_modulus):
     """
     FiniteExtendedField(p, n_or_modulus) creates a finite field.
     characteristic must be prime. n_or_modulus can be:
       1) an integer greater than 1, or
       2) a polynomial in a polynomial ring of F_p with degree
          greater than 1.
     """
     FiniteField.__init__(self, characteristic)
     self.basefield = FinitePrimeField.getInstance(self.char)
     if isinstance(n_or_modulus, int):
         if n_or_modulus <= 1:
             raise ValueError("degree of extension must be > 1.")
         self.degree = n_or_modulus
         # randomly chosen irreducible polynomial
         top = FinitePrimeFieldPolynomial({self.degree: 1},
                                          coeffring=self.basefield)
         seed = bigrandom.randrange(1, self.char)
         cand = FinitePrimeFieldPolynomial(enumerate(
             arith1.expand(seed, self.char)),
                                           coeffring=self.basefield) + top
         while cand.degree() < self.degree or not cand.isirreducible():
             seed = bigrandom.randrange(1, self.char**self.degree)
             cand = FinitePrimeFieldPolynomial(
                 enumerate(arith1.expand(seed, self.char)),
                 coeffring=self.basefield) + top
         self.modulus = cand
     elif isinstance(n_or_modulus, FinitePrimeFieldPolynomial):
         if isinstance(n_or_modulus.getCoefficientRing(), FinitePrimeField):
             if n_or_modulus.degree() > 1 and n_or_modulus.isirreducible():
                 self.degree = n_or_modulus.degree()
                 self.modulus = n_or_modulus
             else:
                 raise ValueError(
                     "modulus must be of degree greater than 1.")
         else:
             raise TypeError("modulus must be F_p polynomial.")
     else:
         raise TypeError("degree or modulus must be supplied.")
     self.registerModuleAction(rational.theIntegerRing, self._int_mul)
     self.registerModuleAction(FinitePrimeField.getInstance(self.char),
                               self._fp_mul)
예제 #10
0
    def testUniform(self):
        trial_times = 100000
        error_range = 0.03 

        dist = {}
        for i in range(5, 100, 10):
            dist[i] = 0
        for i in range(trial_times):
            rnd = bigrandom.randrange(5, 100, 10)
            dist[rnd] += 1
        for i in range(5, 100, 10):
            self.assertTrue(abs(0.1 - dist[i]/float(trial_times)) < error_range)

        dist = {}
        for i in range(trial_times):
            rnd = bigrandom.randrange(-1, 255)
            dist[rnd] = dist.get(rnd, 0) + 1
        distkeys = dist.keys()
        distkeys.sort()
        self.assertEqual(distkeys, range(-1, 255))
예제 #11
0
def rand_probable_prime(minimum, maximum, times=20):
    """
    Return a random probable prime in range(minimum, maximum)
    """
    p = next_probable_prime(bigrandom.randrange(minimum, maximum), times)
    if p < maximum:
        return p

    # in very rare case or n is too small case,
    # search continues from the lower bound.
    return next_probable_prime(minimum, times)
예제 #12
0
def millerRabin(n, times=20):
    """
    Miller-Rabin pseudo-primality test.  Optional second argument
    times (default to 20) is the number of repetition.  The error
    probability is at most 4**(-times).
    """
    s, t = arith1.vp(n - 1, 2)
    for _ in range(times):
        b = bigrandom.randrange(2, n - 1)
        if not spsp(n, b, s, t):
            return False
    return True
예제 #13
0
파일: prime.py 프로젝트: nickspoon/part-ii
def millerRabin(n, times=20):
    """
    Miller-Rabin pseudo-primality test.  Optional second argument
    times (default to 20) is the number of repetition.  The error
    probability is at most 4**(-times).
    """
    s, t = arith1.vp(n - 1, 2)
    for _ in range(times):
        b = bigrandom.randrange(2, n-1)
        if not spsp(n, b, s, t):
            return False
    return True
예제 #14
0
def randomele(disc, unit):
    """
    Return a reduced random form with the given discriminant and the given unit.
    Also random element is not unit.
    """
    limit = int(math.sqrt(-disc / 3))
    while True:
        a = bigrandom.randrange(1, limit + 1)
        ind = 0
        while ind < 2 * a:
            b = bigrandom.randrange(a)
            if bigrandom.randrange(2):
                b = -b
            tp = disc - b**2
            if tp % (-4 * a) == 0:
                c = tp // (-4 * a)
                if gcd.gcd_of_list([a, b, c])[0] != 1:
                    continue
                red = reducePDF((a, b, c))
                if red != unit:
                    return ReducedQuadraticForm(red, unit)
            ind += 1
예제 #15
0
파일: quad.py 프로젝트: nickspoon/part-ii
def randomele(disc, unit):
    """
    Return a reduced random form with the given discriminant and the given unit.
    Also random element is not unit.
    """
    limit = int(math.sqrt(-disc / 3))
    while True:
        a = bigrandom.randrange(1, limit + 1)
        ind = 0
        while ind < 2*a:
            b = bigrandom.randrange(a)
            if bigrandom.randrange(2):
                b = -b
            tp = disc - b**2
            if tp % (-4 * a) == 0:
                c = tp // (-4 * a)
                if gcd.gcd_of_list([a, b, c])[0] != 1:
                    continue
                red = reducePDF((a, b, c))
                if red != unit:
                    return ReducedQuadraticForm(red, unit)
            ind += 1
예제 #16
0
def root_Fp(g, p, flag=True):
    """
    Return a root over F_p of nonzero polynomial g.
    p must be prime.
    If flag = False, return a root randomly
    """
    if isinstance(g, list):
        if not isinstance(g[0], tuple):
            g = zip(range(len(g)), g)
    Fp = finitefield.FinitePrimeField(p)
    g = uniutil.FinitePrimeFieldPolynomial(g, Fp)
    h = uniutil.FinitePrimeFieldPolynomial({1: -1, p: 1}, Fp)
    g = g.gcd(h)
    deg_g = g.degree()
    if g[0] == 0:
        deg_g = deg_g - 1
        g = g.shift_degree_to(deg_g)
    while True:
        if deg_g == 0:
            return None
        if deg_g == 1:
            return (-g[0] / g[1]).toInteger()
        elif deg_g == 2:
            d = g[1] * g[1] - 4 * g[0]
            e = arith1.modsqrt(d.toInteger(), p)
            return ((-g[1] - e) / (2 * g[2])).toInteger()
        deg_h = 0
        x = uniutil.FinitePrimeFieldPolynomial({0: -1, (p - 1) >> 1: 1}, Fp)
        if flag:
            a = 0
            while deg_h == 0 or deg_h == deg_g:
                b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp)
                v = g(b)
                h = x.gcd(v)
                a = a + 1
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0: a - 1, 1: 1}, Fp)
        else:
            while deg_h == 0 or deg_h == deg_g:
                a = bigrandom.randrange(p)
                b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp)
                v = g(b)
                h = x.gcd(v)
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0: a, 1: 1}, Fp)
        g = h(b)
        deg_g = deg_h
예제 #17
0
def root_Fp(g, p, flag=True):
    """
    Return a root over F_p of nonzero polynomial g.
    p must be prime.
    If flag = False, return a root randomly
    """
    if isinstance(g, list):
        if not isinstance(g[0], tuple):
            g = zip(range(len(g)), g)
    Fp = finitefield.FinitePrimeField(p)
    g = uniutil.FinitePrimeFieldPolynomial(g, Fp)
    h = uniutil.FinitePrimeFieldPolynomial({1:-1, p:1}, Fp)
    g = g.gcd(h)
    deg_g = g.degree()
    if g[0] == 0:
        deg_g = deg_g - 1
        g = g.shift_degree_to(deg_g) 
    while True:
        if deg_g == 0:
            return None
        if deg_g == 1:
            return (-g[0]/g[1]).toInteger()
        elif deg_g == 2:
            d = g[1]*g[1] - 4*g[0]
            e = arith1.modsqrt(d.toInteger(), p)
            return ((-g[1]-e)/(2*g[2])).toInteger()
        deg_h = 0
        x = uniutil.FinitePrimeFieldPolynomial({0:-1, (p-1)//2:1}, Fp)
        if flag:
            a = 0
            while deg_h == 0 or deg_h == deg_g:
                b = uniutil.FinitePrimeFieldPolynomial({0:-a, 1:1}, Fp)
                v = g(b)
                h = x.gcd(v)
                a = a + 1
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0:a-1, 1:1}, Fp)
        else:
            while deg_h == 0 or deg_h == deg_g:
                a = bigrandom.randrange(p)
                b = uniutil.FinitePrimeFieldPolynomial({0:-a, 1:1}, Fp)
                v = g(b)
                h = x.gcd(v)
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0:a, 1:1}, Fp)
        g = h(b)
        deg_g = deg_h
예제 #18
0
    def TonelliShanks(self, element):
        """ Return square root of element if exist.
        assume that characteristic have to be more than three.
        """
        if self.char == 2:
            return self.sqrt(element)  # should be error

        if self.Legendre(element) == -1:
            raise ValueError("There is no solution")

        # symbol and code reference from Cohen, CCANT 1.5.1
        (e, q) = arith1.vp(card(self) - 1, 2)

        a = element
        n = self.createElement(self.char + 1)
        while self.Legendre(n) != -1:
            n = self.createElement(
                bigrandom.randrange(self.char + 1,
                                    card(self)))  # field maybe large
        y = z = n**q
        r = e
        x = a**((q - 1) // 2)
        b = a * (x**2)
        x = a * x
        while True:
            if b == self.one:
                return x
            m = 1
            while m < r:
                if b**(2**m) == self.one:
                    break
                m = m + 1
            if m == r:
                break
            t = y**(2**(r - m - 1))
            y = t**2
            r = m
            x = x * t
            b = b * y
        raise ValueError("There is no solution")
예제 #19
0
파일: prime.py 프로젝트: nickspoon/part-ii
def randPrime(n):
    """
    Return a random n-digits prime
    """
    if n <= 0:
        raise ValueError("input number must be natural number")

    if n == 1:
        return bigrandom.map_choice(lambda i: (2, 3, 5, 7)[i], 4)

    p = bigrandom.randrange(10**(n-1)+1, 10**n, 2)
    while not primeq(p):
        p += 2
    if p < 10**n:
        return p

    # in very rare case or n is too small case,
    # search continues from the lower bound.
    p = 10**(n-1) + 1
    while not primeq(p):
        p += 2
    return p
예제 #20
0
def randPrime(n):
    """
    Return a random n-digits prime
    """
    if n <= 0:
        raise ValueError("input number must be natural number")

    if n == 1:
        return bigrandom.map_choice(lambda i: (2, 3, 5, 7)[i], 4)

    p = bigrandom.randrange(10**(n - 1) + 1, 10**n, 2)
    while not primeq(p):
        p += 2
    if p < 10**n:
        return p

    # in very rare case or n is too small case,
    # search continues from the lower bound.
    p = 10**(n - 1) + 1
    while not primeq(p):
        p += 2
    return p
예제 #21
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 % 2:
            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
예제 #22
0
 def random_element(self, *args):
     """
     Return a randomly chosen element og the field.
     """
     return self.createElement(bigrandom.randrange(*args))
def random_nbit(n):
    return bigrandom.randrange(2**(n - 1), 2**n)
예제 #24
0
파일: empirical.py 프로젝트: root-z/ECPP
def random_nbit(n):
    return bigrandom.randrange(2**(n-1), 2**n)
예제 #25
0
 def testHugeRange(self):
     self.assertTrue(2 <= bigrandom.randrange(2, 10**500) < 10**500)
예제 #26
0
 def random_element(self, *args):
     """
     Return a randomly chosen element og the field.
     """
     return self.createElement(bigrandom.randrange(*args))