Base class for finite fields¶
AUTHORS:
Adrien Brochard, David Roe, Jeroen Demeyer, Julian Rueth, Niles Johnson, Peter Bruin, Travis Scrimshaw, Xavier Caruso: initial version
- class sage.rings.finite_rings.finite_field_base.FiniteField[source]¶
Bases:
Field
Abstract base class for finite fields.
- algebraic_closure(name='z', **kwds)[source]¶
Return an algebraic closure of
self
.INPUT:
name
– string (default:'z'
); prefix to use for variable names of subfieldsimplementation
– string (optional); specifies how to construct the algebraic closure. The only value supported at the moment is'pseudo_conway'
. For more details, seealgebraic_closure_finite_field
.
OUTPUT:
An algebraic closure of
self
. Note that mathematically speaking, this is only unique up to non-unique isomorphism. To obtain canonically defined algebraic closures, one needs an algorithm that also provides a canonical isomorphism between any two algebraic closures constructed using the algorithm.This non-uniqueness problem can in principle be solved by using Conway polynomials; see for example Wikipedia article Conway_polynomial_(finite_fields). These have the drawback that computing them takes a long time. Therefore Sage implements a variant called pseudo-Conway polynomials, which are easier to compute but do not determine an algebraic closure up to unique isomorphism.
The output of this method is cached, so that within the same Sage session, calling it multiple times will return the same algebraic closure (i.e. the same Sage object). Despite this, the non-uniqueness of the current implementation means that coercion and pickling cannot work as one might expect. See below for an example.
EXAMPLES:
sage: F = GF(5).algebraic_closure() sage: F Algebraic closure of Finite Field of size 5 sage: F.gen(3) z3
>>> from sage.all import * >>> F = GF(Integer(5)).algebraic_closure() >>> F Algebraic closure of Finite Field of size 5 >>> F.gen(Integer(3)) z3
For finite fields, the algebraic closure is always (isomorphic to) the algebraic closure of the prime field:
sage: GF(5^2).algebraic_closure() == F True
>>> from sage.all import * >>> GF(Integer(5)**Integer(2)).algebraic_closure() == F True
The default name is ‘z’ but you can change it through the option
name
:sage: Ft = GF(5).algebraic_closure('t') sage: Ft.gen(3) t3
>>> from sage.all import * >>> Ft = GF(Integer(5)).algebraic_closure('t') >>> Ft.gen(Integer(3)) t3
Because Sage currently only implements algebraic closures using a non-unique definition (see above), it is currently impossible to implement pickling in such a way that a pickled and unpickled element compares equal to the original:
sage: F = GF(7).algebraic_closure() sage: x = F.gen(2) sage: loads(dumps(x)) == x False
>>> from sage.all import * >>> F = GF(Integer(7)).algebraic_closure() >>> x = F.gen(Integer(2)) >>> loads(dumps(x)) == x False
Note
For non-prime finite fields, this method currently simply returns the algebraic closure of the prime field. This may or may not change in the future when extension towers are supported properly.
- an_embedding(K)[source]¶
Return some embedding of this field into another field \(K\), and raise a
ValueError
if none exists.See also
EXAMPLES:
sage: GF(4,'a').an_embedding(GF(2).algebraic_closure()) Ring morphism: From: Finite Field in a of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: a |--> ...
>>> from sage.all import * >>> GF(Integer(4),'a').an_embedding(GF(Integer(2)).algebraic_closure()) Ring morphism: From: Finite Field in a of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: a |--> ...
- cardinality()[source]¶
Return the cardinality of
self
.Same as
order()
.EXAMPLES:
sage: GF(997).cardinality() 997
>>> from sage.all import * >>> GF(Integer(997)).cardinality() 997
- construction()[source]¶
Return the construction of this finite field, as a
ConstructionFunctor
and the base field.EXAMPLES:
sage: v = GF(3^3).construction(); v (AlgebraicExtensionFunctor, Finite Field of size 3) sage: v[0].polys[0] 3 sage: v = GF(2^1000, 'a').construction(); v[0].polys[0] a^1000 + a^5 + a^4 + a^3 + 1
>>> from sage.all import * >>> v = GF(Integer(3)**Integer(3)).construction(); v (AlgebraicExtensionFunctor, Finite Field of size 3) >>> v[Integer(0)].polys[Integer(0)] 3 >>> v = GF(Integer(2)**Integer(1000), 'a').construction(); v[Integer(0)].polys[Integer(0)] a^1000 + a^5 + a^4 + a^3 + 1
The implementation is taken into account, by Issue #15223:
sage: k = FiniteField(9, 'a', impl='pari_ffelt') sage: F, R = k.construction() sage: F(R) is k True
>>> from sage.all import * >>> k = FiniteField(Integer(9), 'a', impl='pari_ffelt') >>> F, R = k.construction() >>> F(R) is k True
- dual_basis(basis=None, check=True)[source]¶
Return the dual basis of
basis
, or the dual basis of the power basis if no basis is supplied.If \(e = \{e_0, e_1, ..., e_{n-1}\}\) is a basis of \(\GF{p^n}\) as a vector space over \(\GF{p}\), then the dual basis of \(e\), \(d = \{d_0, d_1, ..., d_{n-1}\}\), is the unique basis such that \(\mathrm{Tr}(e_i d_j) = \delta_{i,j}, 0 \leq i,j \leq n-1\), where \(\mathrm{Tr}\) is the trace function.
INPUT:
basis
– (default:None
); a basis of the finite fieldself
, \(\GF{p^n}\), as a vector space over the base field \(\GF{p}\). Uses the power basis \(\{x^i : 0 \leq i \leq n-1\}\) as input if no basis is supplied, where \(x\) is the generator ofself
.check
– (default:True
); verifies thatbasis
is a valid basis ofself
ALGORITHM:
The algorithm used to calculate the dual basis comes from pages 110–111 of [McE1987].
Let \(e = \{e_0, e_1, ..., e_{n-1}\}\) be a basis of \(\GF{p^n}\) as a vector space over \(\GF{p}\) and \(d = \{d_0, d_1, ..., d_{n-1}\}\) be the dual basis of \(e\). Since \(e\) is a basis, we can rewrite any \(d_c, 0 \leq c \leq n-1\), as \(d_c = \beta_0 e_0 + \beta_1 e_1 + ... + \beta_{n-1} e_{n-1}\), for some \(\beta_0, \beta_1, ..., \beta_{n-1} \in \GF{p}\). Using properties of the trace function, we can rewrite the \(n\) equations of the form \(\mathrm{Tr}(e_i d_c) = \delta_{i,c}\) and express the result as the matrix vector product: \(A [\beta_0, \beta_1, ..., \beta_{n-1}] = i_c\), where the \(i,j\)-th element of \(A\) is \(\mathrm{Tr(e_i e_j)}\) and \(i_c\) is the \(i\)-th column of the \(n \times n\) identity matrix. Since \(A\) is an invertible matrix, \([\beta_0, \beta_1, ..., \beta_{n-1}] = A^{-1} i_c\), from which we can easily calculate \(d_c\).
EXAMPLES:
sage: F.<a> = GF(2^4) sage: F.dual_basis(basis=None, check=False) # needs sage.modules [a^3 + 1, a^2, a, 1]
>>> from sage.all import * >>> F = GF(Integer(2)**Integer(4), names=('a',)); (a,) = F._first_ngens(1) >>> F.dual_basis(basis=None, check=False) # needs sage.modules [a^3 + 1, a^2, a, 1]
We can test that the dual basis returned satisfies the defining property of a dual basis: \(\mathrm{Tr}(e_i d_j) = \delta_{i,j}, 0 \leq i,j \leq n-1\)
sage: # needs sage.modules sage: F.<a> = GF(7^4) sage: e = [4*a^3, 2*a^3 + a^2 + 3*a + 5, ....: 3*a^3 + 5*a^2 + 4*a + 2, 2*a^3 + 2*a^2 + 2] sage: d = F.dual_basis(e, check=True); d [3*a^3 + 4*a^2 + 6*a + 2, a^3 + 6*a + 5, 3*a^3 + 6*a^2 + 2*a + 5, 5*a^2 + 4*a + 3] sage: vals = [[(x * y).trace() for x in e] for y in d] sage: matrix(vals) == matrix.identity(4) True
>>> from sage.all import * >>> # needs sage.modules >>> F = GF(Integer(7)**Integer(4), names=('a',)); (a,) = F._first_ngens(1) >>> e = [Integer(4)*a**Integer(3), Integer(2)*a**Integer(3) + a**Integer(2) + Integer(3)*a + Integer(5), ... Integer(3)*a**Integer(3) + Integer(5)*a**Integer(2) + Integer(4)*a + Integer(2), Integer(2)*a**Integer(3) + Integer(2)*a**Integer(2) + Integer(2)] >>> d = F.dual_basis(e, check=True); d [3*a^3 + 4*a^2 + 6*a + 2, a^3 + 6*a + 5, 3*a^3 + 6*a^2 + 2*a + 5, 5*a^2 + 4*a + 3] >>> vals = [[(x * y).trace() for x in e] for y in d] >>> matrix(vals) == matrix.identity(Integer(4)) True
We can test that if \(d\) is the dual basis of \(e\), then \(e\) is the dual basis of \(d\):
sage: # needs sage.modules sage: F.<a> = GF(7^8) sage: e = [a^0, a^1, a^2, a^3, a^4, a^5, a^6, a^7] sage: d = F.dual_basis(e, check=False); d [6*a^6 + 4*a^5 + 4*a^4 + a^3 + 6*a^2 + 3, 6*a^7 + 4*a^6 + 4*a^5 + 2*a^4 + a^2, 4*a^6 + 5*a^5 + 5*a^4 + 4*a^3 + 5*a^2 + a + 6, 5*a^7 + a^6 + a^4 + 4*a^3 + 4*a^2 + 1, 2*a^7 + 5*a^6 + a^5 + a^3 + 5*a^2 + 2*a + 4, a^7 + 2*a^6 + 5*a^5 + a^4 + 5*a^2 + 4*a + 4, a^7 + a^6 + 2*a^5 + 5*a^4 + a^3 + 4*a^2 + 4*a + 6, 5*a^7 + a^6 + a^5 + 2*a^4 + 5*a^3 + 6*a] sage: F.dual_basis(d) [1, a, a^2, a^3, a^4, a^5, a^6, a^7]
>>> from sage.all import * >>> # needs sage.modules >>> F = GF(Integer(7)**Integer(8), names=('a',)); (a,) = F._first_ngens(1) >>> e = [a**Integer(0), a**Integer(1), a**Integer(2), a**Integer(3), a**Integer(4), a**Integer(5), a**Integer(6), a**Integer(7)] >>> d = F.dual_basis(e, check=False); d [6*a^6 + 4*a^5 + 4*a^4 + a^3 + 6*a^2 + 3, 6*a^7 + 4*a^6 + 4*a^5 + 2*a^4 + a^2, 4*a^6 + 5*a^5 + 5*a^4 + 4*a^3 + 5*a^2 + a + 6, 5*a^7 + a^6 + a^4 + 4*a^3 + 4*a^2 + 1, 2*a^7 + 5*a^6 + a^5 + a^3 + 5*a^2 + 2*a + 4, a^7 + 2*a^6 + 5*a^5 + a^4 + 5*a^2 + 4*a + 4, a^7 + a^6 + 2*a^5 + 5*a^4 + a^3 + 4*a^2 + 4*a + 6, 5*a^7 + a^6 + a^5 + 2*a^4 + 5*a^3 + 6*a] >>> F.dual_basis(d) [1, a, a^2, a^3, a^4, a^5, a^6, a^7]
We cannot calculate the dual basis if
basis
is not a valid basis.sage: F.<a> = GF(2^3) sage: F.dual_basis([a], check=True) # needs sage.modules Traceback (most recent call last): ... ValueError: basis length should be 3, not 1 sage: F.dual_basis([a^0, a, a^0 + a], check=True) # needs sage.modules Traceback (most recent call last): ... ValueError: value of 'basis' keyword is not a basis
>>> from sage.all import * >>> F = GF(Integer(2)**Integer(3), names=('a',)); (a,) = F._first_ngens(1) >>> F.dual_basis([a], check=True) # needs sage.modules Traceback (most recent call last): ... ValueError: basis length should be 3, not 1 >>> F.dual_basis([a**Integer(0), a, a**Integer(0) + a], check=True) # needs sage.modules Traceback (most recent call last): ... ValueError: value of 'basis' keyword is not a basis
AUTHOR:
Thomas Gagne (2015-06-16)
- embeddings(K)[source]¶
Return a list of all embeddings of this field in another field \(K\).
EXAMPLES:
sage: GF(2).embeddings(GF(4)) [Ring morphism: From: Finite Field of size 2 To: Finite Field in z2 of size 2^2 Defn: 1 |--> 1] sage: GF(4).embeddings(GF(2).algebraic_closure()) [Ring morphism: From: Finite Field in z2 of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: z2 |--> z2, Ring morphism: From: Finite Field in z2 of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: z2 |--> z2 + 1]
>>> from sage.all import * >>> GF(Integer(2)).embeddings(GF(Integer(4))) [Ring morphism: From: Finite Field of size 2 To: Finite Field in z2 of size 2^2 Defn: 1 |--> 1] >>> GF(Integer(4)).embeddings(GF(Integer(2)).algebraic_closure()) [Ring morphism: From: Finite Field in z2 of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: z2 |--> z2, Ring morphism: From: Finite Field in z2 of size 2^2 To: Algebraic closure of Finite Field of size 2 Defn: z2 |--> z2 + 1]
- extension(modulus, name=None, names=None, map=False, embedding=None, latex_name=None, latex_names=None, **kwds)[source]¶
Return an extension of this finite field.
INPUT:
modulus
– a polynomial with coefficients inself
, or an integername
ornames
– string; the name of the generator in the new extensionlatex_name
orlatex_names
– string; latex name of the generator in the new extensionmap
– boolean (default:False
); ifFalse
, return just the extension \(E\). IfTrue
, return a pair \((E, f)\), where \(f\) is an embedding ofself
into \(E\).embedding
– currently not used; for compatibility with otherAlgebraicExtensionFunctor
calls**kwds
– further keywords, passed to the finite field constructor.
OUTPUT:
An extension of the given modulus, or pseudo-Conway of the given degree if
modulus
is an integer.EXAMPLES:
sage: k = GF(2) sage: R.<x> = k[] sage: k.extension(x^1000 + x^5 + x^4 + x^3 + 1, 'a') Finite Field in a of size 2^1000 sage: k = GF(3^4) sage: R.<x> = k[] sage: k.extension(3) Finite Field in z12 of size 3^12 sage: K = k.extension(2, 'a') sage: k.is_subring(K) True
>>> from sage.all import * >>> k = GF(Integer(2)) >>> R = k['x']; (x,) = R._first_ngens(1) >>> k.extension(x**Integer(1000) + x**Integer(5) + x**Integer(4) + x**Integer(3) + Integer(1), 'a') Finite Field in a of size 2^1000 >>> k = GF(Integer(3)**Integer(4)) >>> R = k['x']; (x,) = R._first_ngens(1) >>> k.extension(Integer(3)) Finite Field in z12 of size 3^12 >>> K = k.extension(Integer(2), 'a') >>> k.is_subring(K) True
An example using the
map
argument:sage: F = GF(5) sage: E, f = F.extension(2, 'b', map=True) sage: E Finite Field in b of size 5^2 sage: f Ring morphism: From: Finite Field of size 5 To: Finite Field in b of size 5^2 Defn: 1 |--> 1 sage: f.parent() Set of field embeddings from Finite Field of size 5 to Finite Field in b of size 5^2
>>> from sage.all import * >>> F = GF(Integer(5)) >>> E, f = F.extension(Integer(2), 'b', map=True) >>> E Finite Field in b of size 5^2 >>> f Ring morphism: From: Finite Field of size 5 To: Finite Field in b of size 5^2 Defn: 1 |--> 1 >>> f.parent() Set of field embeddings from Finite Field of size 5 to Finite Field in b of size 5^2
Extensions of non-prime finite fields by polynomials are not yet supported: we fall back to generic code:
sage: k.extension(x^5 + x^2 + x - 1) Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2
>>> from sage.all import * >>> k.extension(x**Integer(5) + x**Integer(2) + x - Integer(1)) Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2
- factored_order()[source]¶
Return the factored order of this field. For compatibility with
integer_mod_ring
.EXAMPLES:
sage: GF(7^2,'a').factored_order() 7^2
>>> from sage.all import * >>> GF(Integer(7)**Integer(2),'a').factored_order() 7^2
- factored_unit_order()[source]¶
Return the factorization of
self.order()-1
, as a 1-tuple.The format is for compatibility with
integer_mod_ring
.EXAMPLES:
sage: GF(7^2,'a').factored_unit_order() (2^4 * 3,)
>>> from sage.all import * >>> GF(Integer(7)**Integer(2),'a').factored_unit_order() (2^4 * 3,)
- free_module(base=None, basis=None, map=True)[source]¶
Return the vector space over the subfield isomorphic to this finite field as a vector space, along with the isomorphisms.
INPUT:
base
– a subfield of or a morphism into this finite field. If not given, the prime subfield is assumed. A subfield means a finite field with coercion to this finite field.basis
– a basis of the finite field as a vector space over the subfield. If not given, one is chosen automatically.map
– boolean (default:True
); ifTrue
, isomorphisms from and to the vector space are also returned
The
basis
maps to the standard basis of the vector space by the isomorphisms.OUTPUT: if
map
isFalse
,vector space over the subfield or the domain of the morphism, isomorphic to this finite field.
and if
map
isTrue
, then alsoan isomorphism from the vector space to the finite field.
the inverse isomorphism to the vector space from the finite field.
EXAMPLES:
sage: GF(27,'a').vector_space(map=False) # needs sage.modules Vector space of dimension 3 over Finite Field of size 3 sage: # needs sage.modules sage: F = GF(8) sage: E = GF(64) sage: V, from_V, to_V = E.vector_space(F, map=True) sage: V Vector space of dimension 2 over Finite Field in z3 of size 2^3 sage: to_V(E.gen()) (0, 1) sage: all(from_V(to_V(e)) == e for e in E) True sage: all(to_V(e1 + e2) == to_V(e1) + to_V(e2) for e1 in E for e2 in E) True sage: all(to_V(c * e) == c * to_V(e) for e in E for c in F) True sage: # needs sage.modules sage: basis = [E.gen(), E.gen() + 1] sage: W, from_W, to_W = E.vector_space(F, basis, map=True) sage: all(from_W(to_W(e)) == e for e in E) True sage: all(to_W(c * e) == c * to_W(e) for e in E for c in F) True sage: all(to_W(e1 + e2) == to_W(e1) + to_W(e2) for e1 in E for e2 in E) # long time True sage: to_W(basis[0]); to_W(basis[1]) (1, 0) (0, 1) sage: # needs sage.modules sage: x = polygen(ZZ) sage: F = GF(9, 't', modulus=x^2 + x - 1) sage: E = GF(81) sage: h = Hom(F,E).an_element() sage: V, from_V, to_V = E.vector_space(h, map=True) sage: V Vector space of dimension 2 over Finite Field in t of size 3^2 sage: V.base_ring() is F True sage: all(from_V(to_V(e)) == e for e in E) True sage: all(to_V(e1 + e2) == to_V(e1) + to_V(e2) for e1 in E for e2 in E) True sage: all(to_V(h(c) * e) == c * to_V(e) for e in E for c in F) True
>>> from sage.all import * >>> GF(Integer(27),'a').vector_space(map=False) # needs sage.modules Vector space of dimension 3 over Finite Field of size 3 >>> # needs sage.modules >>> F = GF(Integer(8)) >>> E = GF(Integer(64)) >>> V, from_V, to_V = E.vector_space(F, map=True) >>> V Vector space of dimension 2 over Finite Field in z3 of size 2^3 >>> to_V(E.gen()) (0, 1) >>> all(from_V(to_V(e)) == e for e in E) True >>> all(to_V(e1 + e2) == to_V(e1) + to_V(e2) for e1 in E for e2 in E) True >>> all(to_V(c * e) == c * to_V(e) for e in E for c in F) True >>> # needs sage.modules >>> basis = [E.gen(), E.gen() + Integer(1)] >>> W, from_W, to_W = E.vector_space(F, basis, map=True) >>> all(from_W(to_W(e)) == e for e in E) True >>> all(to_W(c * e) == c * to_W(e) for e in E for c in F) True >>> all(to_W(e1 + e2) == to_W(e1) + to_W(e2) for e1 in E for e2 in E) # long time True >>> to_W(basis[Integer(0)]); to_W(basis[Integer(1)]) (1, 0) (0, 1) >>> # needs sage.modules >>> x = polygen(ZZ) >>> F = GF(Integer(9), 't', modulus=x**Integer(2) + x - Integer(1)) >>> E = GF(Integer(81)) >>> h = Hom(F,E).an_element() >>> V, from_V, to_V = E.vector_space(h, map=True) >>> V Vector space of dimension 2 over Finite Field in t of size 3^2 >>> V.base_ring() is F True >>> all(from_V(to_V(e)) == e for e in E) True >>> all(to_V(e1 + e2) == to_V(e1) + to_V(e2) for e1 in E for e2 in E) True >>> all(to_V(h(c) * e) == c * to_V(e) for e in E for c in F) True
- frobenius_endomorphism(n=1)[source]¶
INPUT:
n
– integer (default: 1)
OUTPUT:
The \(n\)-th power of the absolute arithmetic Frobenius endomorphism on this finite field.
EXAMPLES:
sage: k.<t> = GF(3^5) sage: Frob = k.frobenius_endomorphism(); Frob Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5 sage: a = k.random_element() # needs sage.modules sage: Frob(a) == a^3 # needs sage.modules True
>>> from sage.all import * >>> k = GF(Integer(3)**Integer(5), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism(); Frob Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5 >>> a = k.random_element() # needs sage.modules >>> Frob(a) == a**Integer(3) # needs sage.modules True
We can specify a power:
sage: k.frobenius_endomorphism(2) Frobenius endomorphism t |--> t^(3^2) on Finite Field in t of size 3^5
>>> from sage.all import * >>> k.frobenius_endomorphism(Integer(2)) Frobenius endomorphism t |--> t^(3^2) on Finite Field in t of size 3^5
The result is simplified if possible:
sage: k.frobenius_endomorphism(6) Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5 sage: k.frobenius_endomorphism(5) Identity endomorphism of Finite Field in t of size 3^5
>>> from sage.all import * >>> k.frobenius_endomorphism(Integer(6)) Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5 >>> k.frobenius_endomorphism(Integer(5)) Identity endomorphism of Finite Field in t of size 3^5
Comparisons work:
sage: k.frobenius_endomorphism(6) == Frob True sage: from sage.categories.morphism import IdentityMorphism sage: k.frobenius_endomorphism(5) == IdentityMorphism(k) True
>>> from sage.all import * >>> k.frobenius_endomorphism(Integer(6)) == Frob True >>> from sage.categories.morphism import IdentityMorphism >>> k.frobenius_endomorphism(Integer(5)) == IdentityMorphism(k) True
AUTHOR:
Xavier Caruso (2012-06-29)
- from_bytes(input_bytes, byteorder='big')[source]¶
Return the integer represented by the given array of bytes.
Internally relies on the python
int.from_bytes()
method.INPUT:
input_bytes
– a bytes-like object or iterable producing bytesbyteorder
– string (default:'big'
); determines the byte order ofinput_bytes
(can only be'big'
or'little'
)
EXAMPLES:
sage: input_bytes = b"some_bytes" sage: F = GF(2**127 - 1) sage: F.from_bytes(input_bytes) 545127616933790290830707 sage: a = F.from_bytes(input_bytes, byteorder='little'); a 544943659528996309004147 sage: type(a) <class 'sage.rings.finite_rings.integer_mod.IntegerMod_gmp'>
>>> from sage.all import * >>> input_bytes = b"some_bytes" >>> F = GF(Integer(2)**Integer(127) - Integer(1)) >>> F.from_bytes(input_bytes) 545127616933790290830707 >>> a = F.from_bytes(input_bytes, byteorder='little'); a 544943659528996309004147 >>> type(a) <class 'sage.rings.finite_rings.integer_mod.IntegerMod_gmp'>
sage: input_bytes = b"some_bytes" sage: F_ext = GF(65537**5) sage: F_ext.from_bytes(input_bytes) 29549*z5^4 + 40876*z5^3 + 52171*z5^2 + 13604*z5 + 20843 sage: F_ext.from_bytes(input_bytes, byteorder='little') 29539*z5^4 + 42728*z5^3 + 47440*z5^2 + 12423*z5 + 27473
>>> from sage.all import * >>> input_bytes = b"some_bytes" >>> F_ext = GF(Integer(65537)**Integer(5)) >>> F_ext.from_bytes(input_bytes) 29549*z5^4 + 40876*z5^3 + 52171*z5^2 + 13604*z5 + 20843 >>> F_ext.from_bytes(input_bytes, byteorder='little') 29539*z5^4 + 42728*z5^3 + 47440*z5^2 + 12423*z5 + 27473
- from_integer(n, reverse=False)[source]¶
Return the finite field element obtained by reinterpreting the base-\(p\) expansion of \(n\) as a polynomial and evaluating it at the generator of this finite field.
If
reverse
is set toTrue
(default:False
), the list of digits is reversed prior to evaluation.Inverse of
sage.rings.finite_rings.element_base.FinitePolyExtElement.to_integer()
.INPUT:
n
– integer between \(0\) and the cardinality of this field minus \(1\)
EXAMPLES:
sage: p = 4091 sage: F = GF(p^4, 'a') sage: n = 100*p^3 + 37*p^2 + 12*p + 6 sage: F.from_integer(n) 100*a^3 + 37*a^2 + 12*a + 6 sage: F.from_integer(n) in F True sage: F.from_integer(n, reverse=True) 6*a^3 + 12*a^2 + 37*a + 100
>>> from sage.all import * >>> p = Integer(4091) >>> F = GF(p**Integer(4), 'a') >>> n = Integer(100)*p**Integer(3) + Integer(37)*p**Integer(2) + Integer(12)*p + Integer(6) >>> F.from_integer(n) 100*a^3 + 37*a^2 + 12*a + 6 >>> F.from_integer(n) in F True >>> F.from_integer(n, reverse=True) 6*a^3 + 12*a^2 + 37*a + 100
- galois_group()[source]¶
Return the Galois group of this finite field, a cyclic group generated by Frobenius.
EXAMPLES:
sage: # needs sage.groups sage: G = GF(3^6).galois_group(); G Galois group C6 of GF(3^6) sage: F = G.gen() sage: F^2 Frob^2 sage: F^6 1
>>> from sage.all import * >>> # needs sage.groups >>> G = GF(Integer(3)**Integer(6)).galois_group(); G Galois group C6 of GF(3^6) >>> F = G.gen() >>> F**Integer(2) Frob^2 >>> F**Integer(6) 1
- gen()[source]¶
Return a generator of this field (over its prime field). As this is an abstract base class, this just raises a
NotImplementedError
.EXAMPLES:
sage: K = GF(17) sage: sage.rings.finite_rings.finite_field_base.FiniteField.gen(K) Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> K = GF(Integer(17)) >>> sage.rings.finite_rings.finite_field_base.FiniteField.gen(K) Traceback (most recent call last): ... NotImplementedError
- is_conway()[source]¶
Return
True
ifself
is defined by a Conway polynomial.EXAMPLES:
sage: GF(5^3, 'a').is_conway() True sage: GF(5^3, 'a', modulus='adleman-lenstra').is_conway() False sage: GF(next_prime(2^16, 2), 'a').is_conway() False
>>> from sage.all import * >>> GF(Integer(5)**Integer(3), 'a').is_conway() True >>> GF(Integer(5)**Integer(3), 'a', modulus='adleman-lenstra').is_conway() False >>> GF(next_prime(Integer(2)**Integer(16), Integer(2)), 'a').is_conway() False
- is_field(proof=True)[source]¶
Return whether or not the finite field is a field, i.e., always returns
True
.EXAMPLES:
sage: k.<a> = FiniteField(3^4) sage: k.is_field() True
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(4), names=('a',)); (a,) = k._first_ngens(1) >>> k.is_field() True
- is_perfect()[source]¶
Return whether this field is perfect, i.e., every element has a \(p\)-th root. Always returns
True
since finite fields are perfect.EXAMPLES:
sage: GF(2).is_perfect() True
>>> from sage.all import * >>> GF(Integer(2)).is_perfect() True
- is_prime_field()[source]¶
Return
True
ifself
is a prime field, i.e., has degree 1.EXAMPLES:
sage: GF(3^7, 'a').is_prime_field() False sage: GF(3, 'a').is_prime_field() True
>>> from sage.all import * >>> GF(Integer(3)**Integer(7), 'a').is_prime_field() False >>> GF(Integer(3), 'a').is_prime_field() True
- modulus()[source]¶
Return the minimal polynomial of the generator of
self
over the prime finite field.The minimal polynomial of an element \(a\) in a field is the unique monic irreducible polynomial of smallest degree with coefficients in the base field that has \(a\) as a root. In finite field extensions, \(\GF{p^n}\), the base field is \(\GF{p}\).
OUTPUT: a monic polynomial over \(\GF{p}\) in the variable \(x\)
EXAMPLES:
sage: F.<a> = GF(7^2); F Finite Field in a of size 7^2 sage: F.polynomial_ring() Univariate Polynomial Ring in a over Finite Field of size 7 sage: f = F.modulus(); f x^2 + 6*x + 3 sage: f(a) 0
>>> from sage.all import * >>> F = GF(Integer(7)**Integer(2), names=('a',)); (a,) = F._first_ngens(1); F Finite Field in a of size 7^2 >>> F.polynomial_ring() Univariate Polynomial Ring in a over Finite Field of size 7 >>> f = F.modulus(); f x^2 + 6*x + 3 >>> f(a) 0
Although \(f\) is irreducible over the base field, we can double-check whether or not \(f\) factors in \(F\) as follows. The command
F['x'](f)
coerces \(f\) as a polynomial with coefficients in \(F\). (Instead of a polynomial with coefficients over the base field.)sage: f.factor() x^2 + 6*x + 3 sage: F['x'](f).factor() (x + a + 6) * (x + 6*a)
>>> from sage.all import * >>> f.factor() x^2 + 6*x + 3 >>> F['x'](f).factor() (x + a + 6) * (x + 6*a)
Here is an example with a degree 3 extension:
sage: G.<b> = GF(7^3); G Finite Field in b of size 7^3 sage: g = G.modulus(); g x^3 + 6*x^2 + 4 sage: g.degree(); G.degree() 3 3
>>> from sage.all import * >>> G = GF(Integer(7)**Integer(3), names=('b',)); (b,) = G._first_ngens(1); G Finite Field in b of size 7^3 >>> g = G.modulus(); g x^3 + 6*x^2 + 4 >>> g.degree(); G.degree() 3 3
For prime fields, this returns \(x - 1\) unless a custom modulus was given when constructing this field:
sage: k = GF(199) sage: k.modulus() x + 198 sage: var('x') x sage: k = GF(199, modulus=x+1) sage: k.modulus() x + 1
>>> from sage.all import * >>> k = GF(Integer(199)) >>> k.modulus() x + 198 >>> var('x') x >>> k = GF(Integer(199), modulus=x+Integer(1)) >>> k.modulus() x + 1
The given modulus is always made monic:
sage: k.<a> = GF(7^2, modulus=2*x^2 - 3, impl='pari_ffelt') sage: k.modulus() x^2 + 2
>>> from sage.all import * >>> k = GF(Integer(7)**Integer(2), modulus=Integer(2)*x**Integer(2) - Integer(3), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> k.modulus() x^2 + 2
- multiplicative_generator()[source]¶
Return a primitive element of this finite field, i.e. a generator of the multiplicative group.
You can use
multiplicative_generator()
orprimitive_element()
, these mean the same thing.Warning
This generator might change from one version of Sage to another.
EXAMPLES:
sage: k = GF(997) sage: k.multiplicative_generator() 7 sage: k.<a> = GF(11^3) sage: k.primitive_element() a sage: k.<b> = GF(19^32) sage: k.multiplicative_generator() b + 4
>>> from sage.all import * >>> k = GF(Integer(997)) >>> k.multiplicative_generator() 7 >>> k = GF(Integer(11)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> k.primitive_element() a >>> k = GF(Integer(19)**Integer(32), names=('b',)); (b,) = k._first_ngens(1) >>> k.multiplicative_generator() b + 4
- ngens()[source]¶
The number of generators of the finite field. Always 1.
EXAMPLES:
sage: k = FiniteField(3^4, 'b') sage: k.ngens() 1
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(4), 'b') >>> k.ngens() 1
- order()[source]¶
Return the order of this finite field.
EXAMPLES:
sage: GF(997).order() 997
>>> from sage.all import * >>> GF(Integer(997)).order() 997
- polynomial(name=None)[source]¶
Return the minimal polynomial of the generator of
self
over the prime finite field.INPUT:
name
– a variable name to use for the polynomial. By default, use the name given when constructing this field.
OUTPUT: a monic polynomial over \(\GF{p}\) in the variable
name
See also
Except for the
name
argument, this is identical to themodulus()
method.EXAMPLES:
sage: k.<a> = FiniteField(9) sage: k.polynomial('x') x^2 + 2*x + 2 sage: k.polynomial() a^2 + 2*a + 2 sage: F = FiniteField(9, 'a', impl='pari_ffelt') sage: F.polynomial() a^2 + 2*a + 2 sage: F = FiniteField(7^20, 'a', impl='pari_ffelt') sage: f = F.polynomial(); f a^20 + a^12 + 6*a^11 + 2*a^10 + 5*a^9 + 2*a^8 + 3*a^7 + a^6 + 3*a^5 + 3*a^3 + a + 3 sage: f(F.gen()) 0 sage: # needs sage.libs.ntl sage: k.<a> = GF(2^20, impl='ntl') sage: k.polynomial() a^20 + a^10 + a^9 + a^7 + a^6 + a^5 + a^4 + a + 1 sage: k.polynomial('FOO') FOO^20 + FOO^10 + FOO^9 + FOO^7 + FOO^6 + FOO^5 + FOO^4 + FOO + 1 sage: a^20 a^10 + a^9 + a^7 + a^6 + a^5 + a^4 + a + 1
>>> from sage.all import * >>> k = FiniteField(Integer(9), names=('a',)); (a,) = k._first_ngens(1) >>> k.polynomial('x') x^2 + 2*x + 2 >>> k.polynomial() a^2 + 2*a + 2 >>> F = FiniteField(Integer(9), 'a', impl='pari_ffelt') >>> F.polynomial() a^2 + 2*a + 2 >>> F = FiniteField(Integer(7)**Integer(20), 'a', impl='pari_ffelt') >>> f = F.polynomial(); f a^20 + a^12 + 6*a^11 + 2*a^10 + 5*a^9 + 2*a^8 + 3*a^7 + a^6 + 3*a^5 + 3*a^3 + a + 3 >>> f(F.gen()) 0 >>> # needs sage.libs.ntl >>> k = GF(Integer(2)**Integer(20), impl='ntl', names=('a',)); (a,) = k._first_ngens(1) >>> k.polynomial() a^20 + a^10 + a^9 + a^7 + a^6 + a^5 + a^4 + a + 1 >>> k.polynomial('FOO') FOO^20 + FOO^10 + FOO^9 + FOO^7 + FOO^6 + FOO^5 + FOO^4 + FOO + 1 >>> a**Integer(20) a^10 + a^9 + a^7 + a^6 + a^5 + a^4 + a + 1
- polynomial_ring(variable_name=None)[source]¶
Return the polynomial ring over the prime subfield in the same variable as this finite field.
EXAMPLES:
sage: k.<alpha> = FiniteField(3^4) sage: k.polynomial_ring() Univariate Polynomial Ring in alpha over Finite Field of size 3
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(4), names=('alpha',)); (alpha,) = k._first_ngens(1) >>> k.polynomial_ring() Univariate Polynomial Ring in alpha over Finite Field of size 3
- primitive_element()[source]¶
Return a primitive element of this finite field, i.e. a generator of the multiplicative group.
You can use
multiplicative_generator()
orprimitive_element()
, these mean the same thing.Warning
This generator might change from one version of Sage to another.
EXAMPLES:
sage: k = GF(997) sage: k.multiplicative_generator() 7 sage: k.<a> = GF(11^3) sage: k.primitive_element() a sage: k.<b> = GF(19^32) sage: k.multiplicative_generator() b + 4
>>> from sage.all import * >>> k = GF(Integer(997)) >>> k.multiplicative_generator() 7 >>> k = GF(Integer(11)**Integer(3), names=('a',)); (a,) = k._first_ngens(1) >>> k.primitive_element() a >>> k = GF(Integer(19)**Integer(32), names=('b',)); (b,) = k._first_ngens(1) >>> k.multiplicative_generator() b + 4
- random_element(*args, **kwds)[source]¶
A random element of the finite field. Passes arguments to
random_element()
function of underlying vector space.EXAMPLES:
sage: k = GF(19^4, 'a') sage: k.random_element().parent() is k # needs sage.modules True
>>> from sage.all import * >>> k = GF(Integer(19)**Integer(4), 'a') >>> k.random_element().parent() is k # needs sage.modules True
Passes extra positional or keyword arguments through:
sage: k.random_element(prob=0) # needs sage.modules 0
>>> from sage.all import * >>> k.random_element(prob=Integer(0)) # needs sage.modules 0
- some_elements()[source]¶
Return a collection of elements of this finite field for use in unit testing.
EXAMPLES:
sage: k = GF(2^8,'a') sage: k.some_elements() # random output # needs sage.modules [a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]
>>> from sage.all import * >>> k = GF(Integer(2)**Integer(8),'a') >>> k.some_elements() # random output # needs sage.modules [a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]
- subfield(degree, name=None, map=False)[source]¶
Return the subfield of the field of
degree
.The inclusion maps between these subfields will always commute, but they are only added as coercion maps if the following condition holds for the generator \(g\) of the field, where \(d\) is the degree of this field over the prime field:
The element \(g^{(p^d - 1)/(p^n - 1)}\) generates the subfield of degree \(n\) for all divisors \(n\) of \(d\).
INPUT:
degree
– integer; degree of the subfieldname
– string; name of the generator of the subfieldmap
– boolean (default:False
); whether to also return the inclusion map
EXAMPLES:
sage: k = GF(2^21) sage: k.subfield(3) Finite Field in z3 of size 2^3 sage: k.subfield(7, 'a') Finite Field in a of size 2^7 sage: k.coerce_map_from(_) Ring morphism: From: Finite Field in a of size 2^7 To: Finite Field in z21 of size 2^21 Defn: a |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^14 + z21^6 + z21^4 + z21^3 + z21 sage: k.subfield(8) Traceback (most recent call last): ... ValueError: no subfield of order 2^8
>>> from sage.all import * >>> k = GF(Integer(2)**Integer(21)) >>> k.subfield(Integer(3)) Finite Field in z3 of size 2^3 >>> k.subfield(Integer(7), 'a') Finite Field in a of size 2^7 >>> k.coerce_map_from(_) Ring morphism: From: Finite Field in a of size 2^7 To: Finite Field in z21 of size 2^21 Defn: a |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^14 + z21^6 + z21^4 + z21^3 + z21 >>> k.subfield(Integer(8)) Traceback (most recent call last): ... ValueError: no subfield of order 2^8
- subfields(degree=0, name=None)[source]¶
Return all subfields of
self
of the givendegree
, or all possible degrees ifdegree
is \(0\).The subfields are returned as absolute fields together with an embedding into
self
.INPUT:
degree
– integer (default: \(0\))name
– string; a dictionary orNone
:If
degree
is nonzero, thenname
must be a string (orNone
, if this is a pseudo-Conway extension), and will be the variable name of the returned field.If
degree
is zero, the dictionary should have keys the divisors of the degree of this field, with the desired variable name for the field of that degree as an entry.As a shortcut, you can provide a string and the degree of each subfield will be appended for the variable name of that subfield.
If
None
, uses the prefix of this field.
OUTPUT:
A list of pairs
(K, e)
, whereK
ranges over the subfields of this field ande
gives an embedding ofK
intoself
.EXAMPLES:
sage: k = GF(2^21) sage: k.subfields() [(Finite Field of size 2, Ring morphism: From: Finite Field of size 2 To: Finite Field in z21 of size 2^21 Defn: 1 |--> 1), (Finite Field in z3 of size 2^3, Ring morphism: From: Finite Field in z3 of size 2^3 To: Finite Field in z21 of size 2^21 Defn: z3 |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^11 + z21^9 + z21^8 + z21^6 + z21^2), (Finite Field in z7 of size 2^7, Ring morphism: From: Finite Field in z7 of size 2^7 To: Finite Field in z21 of size 2^21 Defn: z7 |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^14 + z21^6 + z21^4 + z21^3 + z21), (Finite Field in z21 of size 2^21, Identity endomorphism of Finite Field in z21 of size 2^21)]
>>> from sage.all import * >>> k = GF(Integer(2)**Integer(21)) >>> k.subfields() [(Finite Field of size 2, Ring morphism: From: Finite Field of size 2 To: Finite Field in z21 of size 2^21 Defn: 1 |--> 1), (Finite Field in z3 of size 2^3, Ring morphism: From: Finite Field in z3 of size 2^3 To: Finite Field in z21 of size 2^21 Defn: z3 |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^11 + z21^9 + z21^8 + z21^6 + z21^2), (Finite Field in z7 of size 2^7, Ring morphism: From: Finite Field in z7 of size 2^7 To: Finite Field in z21 of size 2^21 Defn: z7 |--> z21^20 + z21^19 + z21^17 + z21^15 + z21^14 + z21^6 + z21^4 + z21^3 + z21), (Finite Field in z21 of size 2^21, Identity endomorphism of Finite Field in z21 of size 2^21)]
- unit_group_exponent()[source]¶
The exponent of the unit group of the finite field. For a finite field, this is always the order minus 1.
EXAMPLES:
sage: k = GF(2^10, 'a') sage: k.order() 1024 sage: k.unit_group_exponent() 1023
>>> from sage.all import * >>> k = GF(Integer(2)**Integer(10), 'a') >>> k.order() 1024 >>> k.unit_group_exponent() 1023
- zeta(n=None)[source]¶
Return an element of multiplicative order
n
in this finite field. If there is no such element, raiseValueError
.Warning
In general, this returns an arbitrary element of the correct order. There are no compatibility guarantees:
F.zeta(9)^3
may not be equal toF.zeta(3)
.EXAMPLES:
sage: k = GF(7) sage: k.zeta() 3 sage: k.zeta().multiplicative_order() 6 sage: k.zeta(3) 2 sage: k.zeta(3).multiplicative_order() 3 sage: k = GF(49, 'a') sage: k.zeta().multiplicative_order() 48 sage: k.zeta(6) 3 sage: k.zeta(5) Traceback (most recent call last): ... ValueError: no 5th root of unity in Finite Field in a of size 7^2
>>> from sage.all import * >>> k = GF(Integer(7)) >>> k.zeta() 3 >>> k.zeta().multiplicative_order() 6 >>> k.zeta(Integer(3)) 2 >>> k.zeta(Integer(3)).multiplicative_order() 3 >>> k = GF(Integer(49), 'a') >>> k.zeta().multiplicative_order() 48 >>> k.zeta(Integer(6)) 3 >>> k.zeta(Integer(5)) Traceback (most recent call last): ... ValueError: no 5th root of unity in Finite Field in a of size 7^2
Even more examples:
sage: GF(9,'a').zeta_order() 8 sage: GF(9,'a').zeta() a sage: GF(9,'a').zeta(4) a + 1 sage: GF(9,'a').zeta()^2 a + 1
>>> from sage.all import * >>> GF(Integer(9),'a').zeta_order() 8 >>> GF(Integer(9),'a').zeta() a >>> GF(Integer(9),'a').zeta(Integer(4)) a + 1 >>> GF(Integer(9),'a').zeta()**Integer(2) a + 1
This works even in very large finite fields, provided that
n
can be factored (see Issue #25203):sage: k.<a> = GF(2^2000) sage: p = 8877945148742945001146041439025147034098690503591013177336356694416517527310181938001 sage: z = k.zeta(p) sage: z a^1999 + a^1996 + a^1995 + a^1994 + ... + a^7 + a^5 + a^4 + 1 sage: z ^ p 1
>>> from sage.all import * >>> k = GF(Integer(2)**Integer(2000), names=('a',)); (a,) = k._first_ngens(1) >>> p = Integer(8877945148742945001146041439025147034098690503591013177336356694416517527310181938001) >>> z = k.zeta(p) >>> z a^1999 + a^1996 + a^1995 + a^1994 + ... + a^7 + a^5 + a^4 + 1 >>> z ** p 1
- zeta_order()[source]¶
Return the order of the distinguished root of unity in
self
.EXAMPLES:
sage: GF(9,'a').zeta_order() 8 sage: GF(9,'a').zeta() a sage: GF(9,'a').zeta().multiplicative_order() 8
>>> from sage.all import * >>> GF(Integer(9),'a').zeta_order() 8 >>> GF(Integer(9),'a').zeta() a >>> GF(Integer(9),'a').zeta().multiplicative_order() 8
- sage.rings.finite_rings.finite_field_base.is_FiniteField(R)[source]¶
Return whether the implementation of
R
has the interface provided by the standard finite field implementation.This function is deprecated.
EXAMPLES:
sage: from sage.rings.finite_rings.finite_field_base import is_FiniteField sage: is_FiniteField(GF(9,'a')) doctest:...: DeprecationWarning: the function is_FiniteField is deprecated; use isinstance(x, sage.rings.finite_rings.finite_field_base.FiniteField) instead See https://github.com/sagemath/sage/issues/32664 for details. True sage: is_FiniteField(GF(next_prime(10^10))) True
>>> from sage.all import * >>> from sage.rings.finite_rings.finite_field_base import is_FiniteField >>> is_FiniteField(GF(Integer(9),'a')) doctest:...: DeprecationWarning: the function is_FiniteField is deprecated; use isinstance(x, sage.rings.finite_rings.finite_field_base.FiniteField) instead See https://github.com/sagemath/sage/issues/32664 for details. True >>> is_FiniteField(GF(next_prime(Integer(10)**Integer(10)))) True
Note that the integers modulo n are not backed by the finite field type:
sage: is_FiniteField(Integers(7)) False
>>> from sage.all import * >>> is_FiniteField(Integers(Integer(7))) False