Пример #1
0
def fibonacci_primitive_roots(p):
    """Returns a sorted list of the Fibonacci primitive roots mod p.

    Input:
        * p: int
            A prime number. The primality of p is not verified.

    Returns:
        * roots: list
            This is a list of the Fibonacci primitive roots mod p. This list
            will contain no more than 2 elements.

    Examples:
        >>> fibonacci_primitive_roots(11)
        [8]
        >>> fibonacci_primitive_roots(19)
        [15]
        >>> fibonacci_primitive_roots(41)
        [7, 35]

    Details:
        A Fibonacci primitive root mod p is a primitive root satisfying g**2 = g
        + 1. These can only exist for primes p = 1, 9 (mod 10). See the paper
        "Fibonacci Primitive Roots" by Shanks for details.
    """
    if p % 2 == 0:
        return []
    if p == 5:
        return [3]
    if p < 5 or jacobi_symbol(5, p) != 1:
        return []

    sqrts = sqrts_mod_p(5, p)
    inverse = inverse_mod(2, p)
    quad_roots = [(1 + root) * inverse % p for root in sqrts]
    phi_divisors = factor.prime_divisors(p - 1)
    roots = []

    for r in quad_roots:
        if is_primitive_root(r, p, phi=p - 1, phi_divisors=phi_divisors):
            roots.append(r)

    return sorted(roots)
Пример #2
0
def fibonacci_primitive_roots(p):
    """Returns a sorted list of the Fibonacci primitive roots mod p.

    Input:
        * p: int
            A prime number. The primality of p is not verified.

    Returns:
        * roots: list
            This is a list of the Fibonacci primitive roots mod p. This list
            will contain no more than 2 elements.

    Examples:
        >>> fibonacci_primitive_roots(11)
        [8]
        >>> fibonacci_primitive_roots(19)
        [15]
        >>> fibonacci_primitive_roots(41)
        [7, 35]

    Details:
        A Fibonacci primitive root mod p is a primitive root satisfying g**2 = g
        + 1. These can only exist for primes p = 1, 9 (mod 10). See the paper
        "Fibonacci Primitive Roots" by Shanks for details.
    """
    if p % 2 == 0:
        return []
    if p == 5:
        return [3]
    if p < 5 or jacobi_symbol(5, p) != 1:
        return []

    sqrts = sqrts_mod_p(5, p)
    inverse = inverse_mod(2, p)
    quad_roots = [(1 + root)*inverse % p for root in sqrts]
    phi_divisors = factor.prime_divisors(p - 1)
    roots = []

    for r in quad_roots:
        if is_primitive_root(r, p, phi=p - 1, phi_divisors=phi_divisors):
            roots.append(r)

    return sorted(roots)
Пример #3
0
def primitive_root(n, n_factorization=None, phi=None, phi_divisors=None):
    """Returns a primitive root modulo n.

    Given a positive integer n of the form n = 2, 4, p**a, or 2*p**a for p an
    odd prime and a >= 1, this function returns the least primitive root of n.

    Input:
        * n: int (n > 1)

        * n_factorization: list (default=None)
            The prime factorization of n.

        * phi: int (default=None)
            The value of euler_phi(n).

        * phi_divisors: list (default=None)
            A list of the prime divisors of euler_phi(n).

    Returns:
        * g: int
            The least primitive root of n.

    Raises:
        * ValueError: if primitive roots don't exist modulo n.

    Examples:
        >>> primitive_root(7)
        3
        >>> primitive_root(11)
        2
        >>> primitive_root(14)
        3
        >>> primitive_root(12)
        Traceback (most recent call last):
        ...
        ValueError: primitive_root: No primitive root for n.

    Details:
        An integer a is called a primitive root mod n if a generates the
        multiplicative group of units modulo n. Equivalently, a is a primitive
        root modulo n if the order of a modulo m is euler_phi(n).

        As noted above, primitive roots only exist for moduli of the form n = 2,
        4, p**a, 2*p**a, where p > 2 is prime, and a >= 1. See Theorem 6.11 of
        "Elementary Number Theory" by Jones and Jones for a proof of this fact.
        See also Chapter 10 of "Introduction to Analytic Number Theory" by
        Apostol.

        This method uses the fact that an integer a coprime to n is a primitive
        root if and only if a**(euler_phi(n)/p) != 1 (mod n) for each prime p
        dividing euler_phi(n). See Lemma 6.4 in Jones and Jones for a proof of
        this.

        Note also that there is another way to construct primitive roots for
        composite moduli. To find a primitive root modulu p**a for p an odd
        prime and a >= 2, first compute g, a primitive root modulo p using the
        above criteria. Next, compute g1 = g**(p - 1) (mod p**2). If g1 != 1,
        then g is a primitive root modulo p**a for every a >= 1. Otherwise, g +
        p is. Finally, note that when p is an odd prime, if g is a primitive
        root modulo p**a, then either g or g + p**a (whichever is odd) is a
        primitive root modulo 2*p**a. See Lemma 1.4.5 of "A Course in
        Computational Algebraic Number Theory" by Cohen for more details.
    """
    if n_factorization is None:
        n_factorization = factor.factor(n)

    if n % 4 == 0 and n != 4:
        raise ValueError("primitive_root: No primitive root for n.")

    if len(n_factorization) > 2:
        raise ValueError("primitive_root: No primitive root for n.")

    if n % 2 == 1 and len(n_factorization) > 1:
        raise ValueError("primitive_root: No primitive root for n.")

    if phi is None:
        phi = functions.euler_phi(n_factorization)

    if phi_divisors is None:
        phi_divisors = factor.prime_divisors(phi)

    for g in xrange(1, n):
        if is_primitive_root(g, n, phi=phi, phi_divisors=phi_divisors):
            return g
Пример #4
0
def is_primitive_root(a, n, phi=None, phi_divisors=None):
    """Returns True if a is a primitive root mod n and False otherwise.

    Given an integer a and modulus n, this method determines whether or not a is
    a primitive root modulo n.

    Input:
        * a: int

        * n: int (n > 0)
            The modulus.

        * phi: int (default=None)
            Value of euler_phi(n).

        * phi_divisors: list (default=None)
            List of prime divisors of euler_phi(n).

    Returns:
        * b: bool
            b is True if a is a primitive root mod n and False otherwise. Note
            that b will be False when no primitive roots exist modulo n.

    Raises:
        * ValueError: if n <= 1.

    Examples:
        >>> is_primitive_root(2, 11)
        True
        >>> is_primitive_root(3, 11)
        False
        >>> is_primitive_root(3, -2)
        Traceback (most recent call last):
        ...
        ValueError: is_primitive_root: n must be >= 2.

    Details:
        An integer a is called a primitive root mod n if a generates the
        multiplicative group of units modulo n. Equivalently, a is a primitive
        root modulo n if the order of a modulo m is euler_phi(n).

        The algorithm is based on the observation that an integer a coprime to n
        is a primitive root modulo n if and only if a**(euler_phi(n)/d) != 1
        (mod n) for each divisor d of euler_phi(n). See Lemma 6.4 of "Elementary
        Number Theory" by Jones and Jones for a proof.

        Primitive roots exist only for the moduli n = 1, 2, 4, p**a, and 2*p**a,
        where p is an odd prime and a >= 1. These cases are captured in the
        above Lemma, however some simple divisibility tests allow us to exit
        early for certain moduli. See Chapter 6 of "Elementary Number Theory" by
        Jones and Jones for more details. See also Chapter 10 of "Introduction
        to Analytic Number Theory" by Apostol.
    """
    if n <= 1:
        raise ValueError("is_primitive_root: n must be >= 2.")

    if n > 4 and n % 4 == 0:
        return False

    if gcd(a, n) != 1:
        return False

    if phi is None:
        phi = functions.euler_phi(n)

    if phi_divisors is None:
        phi_divisors = factor.prime_divisors(phi)

    for d in phi_divisors:
        if pow(a, phi // d, n) == 1:
            return False

    return True
Пример #5
0
def primitive_root(n, n_factorization=None, phi=None, phi_divisors=None):
    """Returns a primitive root modulo n.

    Given a positive integer n of the form n = 2, 4, p**a, or 2*p**a for p an
    odd prime and a >= 1, this function returns the least primitive root of n.

    Input:
        * n: int (n > 1)

        * n_factorization: list (default=None)
            The prime factorization of n.

        * phi: int (default=None)
            The value of euler_phi(n).

        * phi_divisors: list (default=None)
            A list of the prime divisors of euler_phi(n).

    Returns:
        * g: int
            The least primitive root of n.

    Raises:
        * ValueError: if primitive roots don't exist modulo n.

    Examples:
        >>> primitive_root(7)
        3
        >>> primitive_root(11)
        2
        >>> primitive_root(14)
        3
        >>> primitive_root(12)
        Traceback (most recent call last):
        ...
        ValueError: primitive_root: No primitive root for n.

    Details:
        An integer a is called a primitive root mod n if a generates the
        multiplicative group of units modulo n. Equivalently, a is a primitive
        root modulo n if the order of a modulo m is euler_phi(n).

        As noted above, primitive roots only exist for moduli of the form n = 2,
        4, p**a, 2*p**a, where p > 2 is prime, and a >= 1. See Theorem 6.11 of
        "Elementary Number Theory" by Jones and Jones for a proof of this fact.
        See also Chapter 10 of "Introduction to Analytic Number Theory" by
        Apostol.

        This method uses the fact that an integer a coprime to n is a primitive
        root if and only if a**(euler_phi(n)/p) != 1 (mod n) for each prime p
        dividing euler_phi(n). See Lemma 6.4 in Jones and Jones for a proof of
        this.

        Note also that there is another way to construct primitive roots for
        composite moduli. To find a primitive root modulu p**a for p an odd
        prime and a >= 2, first compute g, a primitive root modulo p using the
        above criteria. Next, compute g1 = g**(p - 1) (mod p**2). If g1 != 1,
        then g is a primitive root modulo p**a for every a >= 1. Otherwise, g +
        p is. Finally, note that when p is an odd prime, if g is a primitive
        root modulo p**a, then either g or g + p**a (whichever is odd) is a
        primitive root modulo 2*p**a. See Lemma 1.4.5 of "A Course in
        Computational Algebraic Number Theory" by Cohen for more details.
    """
    if n_factorization is None:
        n_factorization = factor.factor(n)

    if n % 4 == 0 and n != 4:
        raise ValueError("primitive_root: No primitive root for n.")

    if len(n_factorization) > 2:
        raise ValueError("primitive_root: No primitive root for n.")

    if n % 2 == 1 and len(n_factorization) > 1:
        raise ValueError("primitive_root: No primitive root for n.")

    if phi is None:
        phi = functions.euler_phi(n_factorization)

    if phi_divisors is None:
        phi_divisors = factor.prime_divisors(phi)

    for g in xrange(1, n):
        if is_primitive_root(g, n, phi=phi, phi_divisors=phi_divisors):
            return g
Пример #6
0
def is_primitive_root(a, n, phi=None, phi_divisors=None):
    """Returns True if a is a primitive root mod n and False otherwise.

    Given an integer a and modulus n, this method determines whether or not a is
    a primitive root modulo n.

    Input:
        * a: int

        * n: int (n > 0)
            The modulus.

        * phi: int (default=None)
            Value of euler_phi(n).

        * phi_divisors: list (default=None)
            List of prime divisors of euler_phi(n).

    Returns:
        * b: bool
            b is True if a is a primitive root mod n and False otherwise. Note
            that b will be False when no primitive roots exist modulo n.

    Raises:
        * ValueError: if n <= 1.

    Examples:
        >>> is_primitive_root(2, 11)
        True
        >>> is_primitive_root(3, 11)
        False
        >>> is_primitive_root(3, -2)
        Traceback (most recent call last):
        ...
        ValueError: is_primitive_root: n must be >= 2.

    Details:
        An integer a is called a primitive root mod n if a generates the
        multiplicative group of units modulo n. Equivalently, a is a primitive
        root modulo n if the order of a modulo m is euler_phi(n).

        The algorithm is based on the observation that an integer a coprime to n
        is a primitive root modulo n if and only if a**(euler_phi(n)/d) != 1
        (mod n) for each divisor d of euler_phi(n). See Lemma 6.4 of "Elementary
        Number Theory" by Jones and Jones for a proof.

        Primitive roots exist only for the moduli n = 1, 2, 4, p**a, and 2*p**a,
        where p is an odd prime and a >= 1. These cases are captured in the
        above Lemma, however some simple divisibility tests allow us to exit
        early for certain moduli. See Chapter 6 of "Elementary Number Theory" by
        Jones and Jones for more details. See also Chapter 10 of "Introduction
        to Analytic Number Theory" by Apostol.
    """
    if n <= 1:
        raise ValueError("is_primitive_root: n must be >= 2.")

    if n > 4 and n % 4 == 0:
        return False

    if gcd(a, n) != 1:
        return False

    if phi is None:
        phi = functions.euler_phi(n)

    if phi_divisors is None:
        phi_divisors = factor.prime_divisors(phi)

    for d in phi_divisors:
        if pow(a, phi//d, n) == 1:
            return False

    return True