def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), 'conway', None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), 'conway', None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1, name) p, n = arith.factor(order)[0] if modulus is None or modulus == "default": if exists_conway_polynomial(p, n): modulus = "conway" else: if p == 2: modulus = "minimal_weight" else: modulus = "random" elif modulus == "random": modulus += str(random.randint(0, 1 << 128)) if isinstance(modulus, (list, tuple)): modulus = FiniteField(p)['x'](modulus) # some classes use 'random' as the modulus to # generate a random modulus, but we don't want # to cache it elif sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') elif not isinstance(modulus, str): raise ValueError("Modulus parameter not understood.") else: # Neither a prime, nor a prime power raise ValueError( "the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), 'conway', None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), 'conway', None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof("arithmetic", proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1, name) p, n = arith.factor(order)[0] if modulus is None or modulus == "default": if exists_conway_polynomial(p, n): modulus = "conway" else: if p == 2: modulus = "minimal_weight" else: modulus = "random" elif modulus == "random": modulus += str(random.randint(0, 1 << 128)) if isinstance(modulus, (list, tuple)): modulus = FiniteField(p)["x"](modulus) # some classes use 'random' as the modulus to # generate a random modulus, but we don't want # to cache it elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name("x") elif not isinstance(modulus, str): raise ValueError("Modulus parameter not understood.") else: # Neither a prime, nor a prime power raise ValueError("the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1, name) p, n = arith.factor(order)[0] if modulus is None or isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": # for backward compatibility modulus = None modulus = GF(p)['x'].irreducible_element(n, algorithm=modulus) elif isinstance(modulus, (list, tuple)): modulus = GF(p)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') else: raise TypeError("wrong type for modulus parameter") else: raise ValueError( "the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def __init__(self, p, modulus, name=None): """ Create a finite field of characteristic `p` defined by the polynomial ``modulus``, with distinguished generator called ``name``. EXAMPLE:: sage: from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt sage: R.<x> = PolynomialRing(GF(3)) sage: k = FiniteField_pari_ffelt(3, x^2 + 2*x + 2, 'a'); k Finite Field in a of size 3^2 """ import constructor from sage.libs.pari.all import pari from sage.rings.integer import Integer from sage.structure.proof.all import arithmetic proof = arithmetic() p = Integer(p) if ((p < 2) or (proof and not p.is_prime()) or (not proof and not p.is_pseudoprime())): raise ArithmeticError("p must be a prime number") Fp = constructor.FiniteField(p) if name is None: name = modulus.variable_name() FiniteField.__init__(self, base=Fp, names=name, normalize=True) modulus = self.polynomial_ring()(modulus) n = modulus.degree() if n < 2: raise ValueError("the degree must be at least 2") self._modulus = modulus self._degree = n self._card = p ** n self._kwargs = {} self._gen_pari = pari(modulus).ffgen() self._zero_element = self.element_class(self, 0) self._one_element = self.element_class(self, 1) self._gen = self.element_class(self, self._gen_pari)
def __init__(self, p, modulus, name=None): """ Create a finite field of characteristic `p` defined by the polynomial ``modulus``, with distinguished generator called ``name``. EXAMPLE:: sage: from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt sage: R.<x> = PolynomialRing(GF(3)) sage: k = FiniteField_pari_ffelt(3, x^2 + 2*x + 2, 'a'); k Finite Field in a of size 3^2 """ import constructor from sage.libs.pari.all import pari from sage.rings.integer import Integer from sage.structure.proof.all import arithmetic proof = arithmetic() p = Integer(p) if ((p < 2) or (proof and not p.is_prime()) or (not proof and not p.is_pseudoprime())): raise ArithmeticError("p must be a prime number") Fp = constructor.FiniteField(p) if name is None: name = modulus.variable_name() FiniteField.__init__(self, base=Fp, names=name, normalize=True) modulus = self.polynomial_ring()(modulus) n = modulus.degree() if n < 2: raise ValueError("the degree must be at least 2") self._modulus = modulus self._degree = n self._card = p**n self._kwargs = {} self._gen_pari = pari(modulus).ffgen() self._zero_element = self.element_class(self, 0) self._one_element = self.element_class(self, 1) self._gen = self.element_class(self, self._gen_pari)
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1,name) p, n = arith.factor(order)[0] if modulus is None or isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": # for backward compatibility modulus = None modulus = GF(p)['x'].irreducible_element(n, algorithm=modulus) elif isinstance(modulus, (list, tuple)): modulus = GF(p)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name('x') else: raise TypeError("wrong type for modulus parameter") else: raise ValueError("the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1,name) p, n = arith.factor(order)[0] # The following is a temporary solution that allows us # to construct compatible systems of finite fields # until algebraic closures of finite fields are # implemented in Sage. It requires the user to # specify two parameters: # # - `conway` -- boolean; if True, this field is # constructed to fit in a compatible system using # a Conway polynomial. # - `prefix` -- a string used to generate names for # automatically constructed finite fields # # See the docstring of FiniteFieldFactory for examples. # # Once algebraic closures of finite fields are # implemented, this syntax should be superseded by # something like the following: # # sage: Fpbar = GF(5).algebraic_closure('z') # sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar # sage: F # Finite field in z3 of size 5^3 # # This temporary solution only uses actual Conway # polynomials (no pseudo-Conway polynomials), since # pseudo-Conway polynomials are not unique, and until # we have algebraic closures of finite fields, there # is no good place to store a specific choice of # pseudo-Conway polynomials. if name is None: if not (kwds.has_key('conway') and kwds['conway']): raise ValueError("parameter 'conway' is required if no name given") if not kwds.has_key('prefix'): raise ValueError("parameter 'prefix' is required if no name given") name = kwds['prefix'] + str(n) if kwds.has_key('conway') and kwds['conway']: from conway_polynomials import conway_polynomial if not kwds.has_key('prefix'): raise ValueError("a prefix must be specified if conway=True") if modulus is not None: raise ValueError("no modulus may be specified if conway=True") # The following raises a RuntimeError if no polynomial is found. modulus = conway_polynomial(p, n) if modulus is None or isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": # for backward compatibility modulus = None modulus = GF(p)['x'].irreducible_element(n, algorithm=modulus) elif isinstance(modulus, (list, tuple)): modulus = GF(p)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name('x') else: raise TypeError("wrong type for modulus parameter") else: raise ValueError("the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = int(order) if order <= 1: raise ValueError("the order of a finite field must be > 1.") if arith.is_prime(order): name = None modulus = None p = integer.Integer(order) n = integer.Integer(1) elif arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1, name) p, n = arith.factor(order)[0] # The following is a temporary solution that allows us # to construct compatible systems of finite fields # until algebraic closures of finite fields are # implemented in Sage. It requires the user to # specify two parameters: # # - `conway` -- boolean; if True, this field is # constructed to fit in a compatible system using # a Conway polynomial. # - `prefix` -- a string used to generate names for # automatically constructed finite fields # # See the docstring of FiniteFieldFactory for examples. # # Once algebraic closures of finite fields are # implemented, this syntax should be superseded by # something like the following: # # sage: Fpbar = GF(5).algebraic_closure('z') # sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar # sage: F # Finite field in z3 of size 5^3 # # This temporary solution only uses actual Conway # polynomials (no pseudo-Conway polynomials), since # pseudo-Conway polynomials are not unique, and until # we have algebraic closures of finite fields, there # is no good place to store a specific choice of # pseudo-Conway polynomials. if name is None: if not (kwds.has_key('conway') and kwds['conway']): raise ValueError( "parameter 'conway' is required if no name given") if not kwds.has_key('prefix'): raise ValueError( "parameter 'prefix' is required if no name given") name = kwds['prefix'] + str(n) if kwds.has_key('conway') and kwds['conway']: from conway_polynomials import conway_polynomial if not kwds.has_key('prefix'): raise ValueError( "a prefix must be specified if conway=True") if modulus is not None: raise ValueError( "no modulus may be specified if conway=True") # The following raises a RuntimeError if no polynomial is found. modulus = conway_polynomial(p, n) if modulus is None or isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": # for backward compatibility modulus = None modulus = GF(p)['x'].irreducible_element(n, algorithm=modulus) elif isinstance(modulus, (list, tuple)): modulus = GF(p)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') else: raise TypeError("wrong type for modulus parameter") else: raise ValueError( "the order of a finite field must be a prime power.") return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def __init__(self, q, name, modulus=None): """ Create finite field of order q with variable printed as name. INPUT: - ``q`` -- integer, size of the finite field, not prime - ``name`` -- variable used for printing element of the finite field. Also, two finite fields are considered equal if they have the same variable name, and not otherwise. - ``modulus`` -- you may provide a polynomial to use for reduction or a string: 'conway': force the use of a Conway polynomial, will raise a RuntimeError if none is found in the database; 'random': use a random irreducible polynomial. 'default': a Conway polynomial is used if found. Otherwise a random polynomial is used. OUTPUT: - FiniteField_ext_pari -- a finite field of order q with given variable name. EXAMPLES:: sage: FiniteField(65537) Finite Field of size 65537 sage: FiniteField(2^20, 'c') Finite Field in c of size 2^20 sage: FiniteField(3^11, "b") Finite Field in b of size 3^11 sage: FiniteField(3^11, "b").gen() b You can also create a finite field using GF, which is a synonym for FiniteField. :: sage: GF(19^5, 'a') Finite Field in a of size 19^5 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from constructor import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus,str): if modulus == "conway": from constructor import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree() == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement(self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, prefix=None, repr=None, elem_cache=None, structure=None): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', 3, 2, True, None, 'poly', True), {}) We do not take invalid keyword arguments and raise a value error to better ensure uniqueness:: sage: GF.create_key_and_extra_args(9, 'a', foo='value') Traceback (most recent call last): ... TypeError: create_key_and_extra_args() got an unexpected keyword argument 'foo' Moreover, ``repr`` and ``elem_cache`` are ignored when not using givaro:: sage: GF.create_key_and_extra_args(16, 'a', impl='ntl', repr='poly') ((16, ('a',), x^4 + x + 1, 'ntl', 2, 4, True, None, None, None), {}) sage: GF.create_key_and_extra_args(16, 'a', impl='ntl', elem_cache=False) ((16, ('a',), x^4 + x + 1, 'ntl', 2, 4, True, None, None, None), {}) sage: GF(16, impl='ntl') is GF(16, impl='ntl', repr='foo') True We handle extra arguments for the givaro finite field and create unique objects for their defaults:: sage: GF(25, impl='givaro') is GF(25, impl='givaro', repr='poly') True sage: GF(25, impl='givaro') is GF(25, impl='givaro', elem_cache=True) True sage: GF(625, impl='givaro') is GF(625, impl='givaro', elem_cache=False) True We explicitly take a ``structure`` attribute for compatibility with :class:`~sage.categories.pushout.AlgebraicExtensionFunctor` but we ignore it as it is not used, see :trac:`21433`:: sage: GF.create_key_and_extra_args(9, 'a', structure=None) ((9, ('a',), x^2 + 2*x + 2, 'givaro', 3, 2, True, None, 'poly', True), {}) """ import sage.arith.all from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = Integer(order) if order <= 1: raise ValueError("the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = 'modn' name = ('x',) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False elif order.is_prime_power(): if names is not None: name = names if name is not None: name = normalize_names(1, name) p, n = order.factor()[0] if name is None: if prefix is None: prefix = 'z' name = prefix + str(n) if modulus is not None: raise ValueError("no modulus may be specified if variable name not given") # Fpbar will have a strong reference, since algebraic_closure caches its results, # and the coefficients of modulus lie in GF(p) Fpbar = GF(p).algebraic_closure(prefix) # This will give a Conway polynomial if p,n is small enough to be in the database # and a pseudo-Conway polynomial if it's not. modulus = Fpbar._get_polynomial(n) check_irreducible = False if impl is None: if order < zech_log_bound: impl = 'givaro' elif p == 2: impl = 'ntl' else: impl = 'pari_ffelt' else: raise ValueError("the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": from sage.misc.superseded import deprecation deprecation(16983, "the modulus 'default' is deprecated, use modulus=None instead (which is the default)") modulus = None modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name('x') modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError("the degree of the modulus does not equal the degree of the field") if check_irreducible and not modulus.is_irreducible(): raise ValueError("finite field modulus must be irreducible but it is not") # If modulus is x - 1 for impl="modn", set it to None if impl == 'modn' and modulus[0] == -1: modulus = None # Check extra arguments for givaro and setup their defaults # TODO: ntl takes a repr, but ignores it if impl == 'givaro': if repr is None: repr = 'poly' if elem_cache is None: elem_cache = (order < 500) else: # This has the effect of ignoring these keywords repr = None elem_cache = None return (order, name, modulus, impl, p, n, proof, prefix, repr, elem_cache), {}
def __init__(self, q, name, modulus=None): """ Create finite field of order `q` with variable printed as name. EXAMPLES:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: k = FiniteField_ext_pari(9, 'a'); k Finite Field in a of size 3^2 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from conway_polynomials import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus,str): if modulus == "conway": from conway_polynomials import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree() == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement(self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def create_key_and_extra_args( self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, **kwds ): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, 'givaro', "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ import sage.arith.all from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof("arithmetic", proof): order = Integer(order) if order <= 1: raise ValueError("the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = "modn" name = ("x",) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False elif order.is_prime_power(): if names is not None: name = names if name is not None: name = normalize_names(1, name) p, n = order.factor()[0] if name is None: if "prefix" not in kwds: kwds["prefix"] = "z" name = kwds["prefix"] + str(n) if modulus is not None: raise ValueError("no modulus may be specified if variable name not given") if "conway" in kwds: del kwds["conway"] from sage.misc.superseded import deprecation deprecation( 17569, "the 'conway' argument is deprecated, pseudo-conway polynomials are now used by default if no variable name is given", ) # Fpbar will have a strong reference, since algebraic_closure caches its results, # and the coefficients of modulus lie in GF(p) Fpbar = GF(p).algebraic_closure(kwds.get("prefix", "z")) # This will give a Conway polynomial if p,n is small enough to be in the database # and a pseudo-Conway polynomial if it's not. modulus = Fpbar._get_polynomial(n) check_irreducible = False if impl is None: if order < zech_log_bound: impl = "givaro" elif p == 2: impl = "ntl" else: impl = "pari_ffelt" else: raise ValueError("the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != "modn": R = PolynomialRing(FiniteField(p), "x") if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": from sage.misc.superseded import deprecation deprecation( 16983, "the modulus 'default' is deprecated, use modulus=None instead (which is the default)", ) modulus = None modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name("x") modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError("the degree of the modulus does not equal the degree of the field") if check_irreducible and not modulus.is_irreducible(): raise ValueError("finite field modulus must be irreducible but it is not") # If modulus is x - 1 for impl="modn", set it to None if impl == "modn" and modulus[0] == -1: modulus = None return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, 'givaro', "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ import sage.arith.all from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = Integer(order) if order <= 1: raise ValueError( "the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = 'modn' name = ('x', ) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False elif order.is_prime_power(): if names is not None: name = names if name is not None: name = normalize_names(1, name) p, n = order.factor()[0] if name is None: if 'prefix' not in kwds: kwds['prefix'] = 'z' name = kwds['prefix'] + str(n) if modulus is not None: raise ValueError( "no modulus may be specified if variable name not given" ) if 'conway' in kwds: del kwds['conway'] from sage.misc.superseded import deprecation deprecation( 17569, "the 'conway' argument is deprecated, pseudo-conway polynomials are now used by default if no variable name is given" ) # Fpbar will have a strong reference, since algebraic_closure caches its results, # and the coefficients of modulus lie in GF(p) Fpbar = GF(p).algebraic_closure(kwds.get('prefix', 'z')) # This will give a Conway polynomial if p,n is small enough to be in the database # and a pseudo-Conway polynomial if it's not. modulus = Fpbar._get_polynomial(n) check_irreducible = False if impl is None: if order < zech_log_bound: impl = 'givaro' elif p == 2: impl = 'ntl' else: impl = 'pari_ffelt' else: raise ValueError( "the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": from sage.misc.superseded import deprecation deprecation( 16983, "the modulus 'default' is deprecated, use modulus=None instead (which is the default)" ) modulus = None modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError( "the degree of the modulus does not equal the degree of the field" ) if check_irreducible and not modulus.is_irreducible(): raise ValueError( "finite field modulus must be irreducible but it is not" ) # If modulus is x - 1 for impl="modn", set it to None if impl == 'modn' and modulus[0] == -1: modulus = None return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def __init__(self, q, name, modulus=None): """ Create finite field of order q with variable printed as name. INPUT: - ``q`` -- integer, size of the finite field, not prime - ``name`` -- variable used for printing element of the finite field. Also, two finite fields are considered equal if they have the same variable name, and not otherwise. - ``modulus`` -- you may provide a polynomial to use for reduction or a string: 'conway': force the use of a Conway polynomial, will raise a RuntimeError if none is found in the database; 'random': use a random irreducible polynomial. 'default': a Conway polynomial is used if found. Otherwise a random polynomial is used. OUTPUT: - FiniteField_ext_pari -- a finite field of order q with given variable name. EXAMPLES:: sage: FiniteField(65537) Finite Field of size 65537 sage: FiniteField(2^20, 'c') Finite Field in c of size 2^20 sage: FiniteField(3^11, "b") Finite Field in b of size 3^11 sage: FiniteField(3^11, "b").gen() b You can also create a finite field using GF, which is a synonym for FiniteField. :: sage: GF(19^5, 'a') Finite Field in a of size 19^5 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from constructor import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus, str): if modulus == "conway": from constructor import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree( ) == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement( self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, prefix=None, repr=None, elem_cache=None, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', 3, 2, True, None, 'poly', True), {}) We do not take invalid keyword arguments and raise a value error to better ensure uniqueness:: sage: GF.create_key_and_extra_args(9, 'a', foo='value') Traceback (most recent call last): ... TypeError: create_key_and_extra_args() got an unexpected keyword argument 'foo' Moreover, ``repr`` and ``elem_cache`` are ignored when not using givaro:: sage: GF.create_key_and_extra_args(16, 'a', impl='ntl', repr='poly') ((16, ('a',), x^4 + x + 1, 'ntl', 2, 4, True, None, None, None), {}) sage: GF.create_key_and_extra_args(16, 'a', impl='ntl', elem_cache=False) ((16, ('a',), x^4 + x + 1, 'ntl', 2, 4, True, None, None, None), {}) sage: GF(16, impl='ntl') is GF(16, impl='ntl', repr='foo') True We handle extra arguments for the givaro finite field and create unique objects for their defaults:: sage: GF(25, impl='givaro') is GF(25, impl='givaro', repr='poly') True sage: GF(25, impl='givaro') is GF(25, impl='givaro', elem_cache=True) True sage: GF(625, impl='givaro') is GF(625, impl='givaro', elem_cache=False) True We explicitly take ``structure``, ``implementation`` and ``prec`` attributes for compatibility with :class:`~sage.categories.pushout.AlgebraicExtensionFunctor` but we ignore them as they are not used, see :trac:`21433`:: sage: GF.create_key_and_extra_args(9, 'a', structure=None) ((9, ('a',), x^2 + 2*x + 2, 'givaro', 3, 2, True, None, 'poly', True), {}) """ import sage.arith.all from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() for key, val in kwds.items(): if key not in ['structure', 'implementation', 'prec', 'embedding']: raise TypeError( "create_key_and_extra_args() got an unexpected keyword argument '%s'" % key) if not (val is None or isinstance(val, list) and all(c is None for c in val)): raise NotImplementedError( "ring extension with prescribed %s is not implemented" % key) with WithProof('arithmetic', proof): order = Integer(order) if order <= 1: raise ValueError( "the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = 'modn' name = ('x', ) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False elif order.is_prime_power(): if names is not None: name = names if name is not None: name = normalize_names(1, name) p, n = order.factor()[0] if name is None: if prefix is None: prefix = 'z' name = prefix + str(n) if modulus is not None: raise ValueError( "no modulus may be specified if variable name not given" ) # Fpbar will have a strong reference, since algebraic_closure caches its results, # and the coefficients of modulus lie in GF(p) Fpbar = GF(p).algebraic_closure(prefix) # This will give a Conway polynomial if p,n is small enough to be in the database # and a pseudo-Conway polynomial if it's not. modulus = Fpbar._get_polynomial(n) check_irreducible = False if impl is None: if order < zech_log_bound: impl = 'givaro' elif p == 2: impl = 'ntl' else: impl = 'pari_ffelt' else: raise ValueError( "the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError( "the degree of the modulus does not equal the degree of the field" ) if check_irreducible and not modulus.is_irreducible(): raise ValueError( "finite field modulus must be irreducible but it is not" ) # If modulus is x - 1 for impl="modn", set it to None if impl == 'modn' and modulus[0] == -1: modulus = None # Check extra arguments for givaro and setup their defaults # TODO: ntl takes a repr, but ignores it if impl == 'givaro': if repr is None: repr = 'poly' if elem_cache is None: elem_cache = (order < 500) else: # This has the effect of ignoring these keywords repr = None elem_cache = None return (order, name, modulus, impl, p, n, proof, prefix, repr, elem_cache), {}
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, 'givaro', "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ import sage.arith.all from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = Integer(order) if order <= 1: raise ValueError( "the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = 'modn' name = ('x', ) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False elif order.is_prime_power(): if names is not None: name = names if name is not None: name = normalize_names(1, name) p, n = order.factor()[0] # The following is a temporary solution that allows us # to construct compatible systems of finite fields # until algebraic closures of finite fields are # implemented in Sage. It requires the user to # specify two parameters: # # - `conway` -- boolean; if True, this field is # constructed to fit in a compatible system using # a Conway polynomial. # - `prefix` -- a string used to generate names for # automatically constructed finite fields # # See the docstring of FiniteFieldFactory for examples. # # Once algebraic closures of finite fields are # implemented, this syntax should be superseded by # something like the following: # # sage: Fpbar = GF(5).algebraic_closure('z') # sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar # sage: F # Finite field in z3 of size 5^3 # # This temporary solution only uses actual Conway # polynomials (no pseudo-Conway polynomials), since # pseudo-Conway polynomials are not unique, and until # we have algebraic closures of finite fields, there # is no good place to store a specific choice of # pseudo-Conway polynomials. if name is None: if not ('conway' in kwds and kwds['conway']): raise ValueError( "parameter 'conway' is required if no name given") if 'prefix' not in kwds: raise ValueError( "parameter 'prefix' is required if no name given") name = kwds['prefix'] + str(n) if 'conway' in kwds and kwds['conway']: from conway_polynomials import conway_polynomial if 'prefix' not in kwds: raise ValueError( "a prefix must be specified if conway=True") if modulus is not None: raise ValueError( "no modulus may be specified if conway=True") # The following raises a RuntimeError if no polynomial is found. modulus = conway_polynomial(p, n) if impl is None: if order < zech_log_bound: impl = 'givaro' elif p == 2: impl = 'ntl' else: impl = 'pari_ffelt' else: raise ValueError( "the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": from sage.misc.superseded import deprecation deprecation( 16983, "the modulus 'default' is deprecated, use modulus=None instead (which is the default)" ) modulus = None modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial( modulus): modulus = modulus.change_variable_name('x') modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError( "the degree of the modulus does not equal the degree of the field" ) if check_irreducible and not modulus.is_irreducible(): raise ValueError( "finite field modulus must be irreducible but it is not" ) # If modulus is x - 1 for impl="modn", set it to None if impl == 'modn' and modulus[0] == -1: modulus = None return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
def __init__(self, q, name, modulus=None): """ Create finite field of order `q` with variable printed as name. EXAMPLES:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: k = FiniteField_ext_pari(9, 'a'); k Finite Field in a of size 3^2 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from constructor import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus,str): if modulus == "conway": from constructor import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree() == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement(self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None, impl=None, proof=None, check_irreducible=True, **kwds): """ EXAMPLES:: sage: GF.create_key_and_extra_args(9, 'a') ((9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True), {}) sage: GF.create_key_and_extra_args(9, 'a', foo='value') ((9, ('a',), x^2 + 2*x + 2, 'givaro', "{'foo': 'value'}", 3, 2, True), {'foo': 'value'}) """ import sage.rings.arith from sage.structure.proof.all import WithProof, arithmetic if proof is None: proof = arithmetic() with WithProof('arithmetic', proof): order = Integer(order) if order <= 1: raise ValueError("the order of a finite field must be at least 2") if order.is_prime(): p = order n = Integer(1) if impl is None: impl = 'modn' name = ('x',) # Ignore name # Every polynomial of degree 1 is irreducible check_irreducible = False # This check should be replaced by order.is_prime_power() # if Trac #16878 is fixed. elif sage.rings.arith.is_prime_power(order): if not names is None: name = names name = normalize_names(1,name) p, n = order.factor()[0] # The following is a temporary solution that allows us # to construct compatible systems of finite fields # until algebraic closures of finite fields are # implemented in Sage. It requires the user to # specify two parameters: # # - `conway` -- boolean; if True, this field is # constructed to fit in a compatible system using # a Conway polynomial. # - `prefix` -- a string used to generate names for # automatically constructed finite fields # # See the docstring of FiniteFieldFactory for examples. # # Once algebraic closures of finite fields are # implemented, this syntax should be superseded by # something like the following: # # sage: Fpbar = GF(5).algebraic_closure('z') # sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar # sage: F # Finite field in z3 of size 5^3 # # This temporary solution only uses actual Conway # polynomials (no pseudo-Conway polynomials), since # pseudo-Conway polynomials are not unique, and until # we have algebraic closures of finite fields, there # is no good place to store a specific choice of # pseudo-Conway polynomials. if name is None: if not ('conway' in kwds and kwds['conway']): raise ValueError("parameter 'conway' is required if no name given") if 'prefix' not in kwds: raise ValueError("parameter 'prefix' is required if no name given") name = kwds['prefix'] + str(n) if 'conway' in kwds and kwds['conway']: from conway_polynomials import conway_polynomial if 'prefix' not in kwds: raise ValueError("a prefix must be specified if conway=True") if modulus is not None: raise ValueError("no modulus may be specified if conway=True") # The following raises a RuntimeError if no polynomial is found. modulus = conway_polynomial(p, n) if impl is None: if order < zech_log_bound: impl = 'givaro' elif p == 2: impl = 'ntl' else: impl = 'pari_ffelt' else: raise ValueError("the order of a finite field must be a prime power") # Determine modulus. # For the 'modn' implementation, we use the following # optimization which we also need to avoid an infinite loop: # a modulus of None is a shorthand for x-1. if modulus is not None or impl != 'modn': R = PolynomialRing(FiniteField(p), 'x') if modulus is None: modulus = R.irreducible_element(n) if isinstance(modulus, str): # A string specifies an algorithm to find a suitable modulus. if modulus == "default": from sage.misc.superseded import deprecation deprecation(16983, "the modulus 'default' is deprecated, use modulus=None instead (which is the default)") modulus = None modulus = R.irreducible_element(n, algorithm=modulus) else: if sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): modulus = modulus.change_variable_name('x') modulus = R(modulus).monic() if modulus.degree() != n: raise ValueError("the degree of the modulus does not equal the degree of the field") if check_irreducible and not modulus.is_irreducible(): raise ValueError("finite field modulus must be irreducible but it is not") # If modulus is x - 1 for impl="modn", set it to None if impl == 'modn' and modulus[0] == -1: modulus = None return (order, name, modulus, impl, str(kwds), p, n, proof), kwds