Finite fields¶
- class sage.categories.finite_fields.FiniteFields(base_category)[source]¶
Bases:
CategoryWithAxiom_singletonThe category of finite fields.
EXAMPLES:
sage: K = FiniteFields(); K Category of finite enumerated fields
>>> from sage.all import * >>> K = FiniteFields(); K Category of finite enumerated fields
A finite field is a finite monoid with the structure of a field; it is currently assumed to be enumerated:
sage: K.super_categories() [Category of fields, Category of finite commutative rings, Category of finite enumerated sets]
[Python]>>> from sage.all import * >>> K.super_categories() [Category of fields, Category of finite commutative rings, Category of finite enumerated sets]
Some examples of membership testing and coercion:
sage: FiniteField(17) in K True sage: RationalField() in K False sage: K(RationalField()) Traceback (most recent call last): ... TypeError: unable to canonically associate a finite field to Rational Field
>>> from sage.all import * >>> FiniteField(Integer(17)) in K True >>> RationalField() in K False >>> K(RationalField()) Traceback (most recent call last): ... TypeError: unable to canonically associate a finite field to Rational Field
- class ElementMethods[source]¶
Bases:
object- is_square()[source]¶
Test if the element is a square or has a square root element.
- OUTPUT:
Trueif the element is a squareFalseif not
EXAMPLES:
sage: S.<x> = GF(5)[] sage: f = S.irreducible_element(20) sage: k.<y> = S.quotient_ring(f) sage: k in Fields() True sage: k(2).is_square() True sage: k.quadratic_nonresidue().is_square() False
>>> from sage.all import * >>> S = GF(Integer(5))['x']; (x,) = S._first_ngens(1) >>> f = S.irreducible_element(Integer(20)) >>> k = S.quotient_ring(f, names=('y',)); (y,) = k._first_ngens(1) >>> k in Fields() True >>> k(Integer(2)).is_square() True >>> k.quadratic_nonresidue().is_square() False
- sqrt(all=False, algorithm='tonelli')[source]¶
Return the square root of the element if it exists.
INPUT:
all– boolean (default:False); whether to return a list of all square roots or just a square rootalgorithm– string (default: ‘tonelli’); the algorithm to use among'tonelli','cipolla'. Tonelli is typically faster but has a worse worst-case complexity than Cipolla. In particular, if the field cardinality minus 1 is highly divisible by 2 and has a large odd factor then Cipolla may perform better.
OUTPUT:
if
all=False, a square root; raises an error if the element is not a squareif
all=True, a tuple of all distinct square roots. This tuple can have length 0, 1, or 2 depending on how many distinct square roots the element has.
EXAMPLES:
sage: S.<x> = GF(5)[] sage: f = S.irreducible_element(20) sage: k.<y> = S.quotient_ring(f) sage: k in Fields() True sage: k(2).is_square() True sage: k(2).sqrt()^2 == k(2) True sage: my_sqrts = k(4).sqrt(all=True) sage: len(k(4).sqrt(all=True)) 2 sage: 2 in my_sqrts True sage: 3 in my_sqrts True sage: k.quadratic_nonresidue().sqrt() Traceback (most recent call last): ... ValueError: element is not a square sage: k.quadratic_nonresidue().sqrt(all=True) ()
>>> from sage.all import * >>> S = GF(Integer(5))['x']; (x,) = S._first_ngens(1) >>> f = S.irreducible_element(Integer(20)) >>> k = S.quotient_ring(f, names=('y',)); (y,) = k._first_ngens(1) >>> k in Fields() True >>> k(Integer(2)).is_square() True >>> k(Integer(2)).sqrt()**Integer(2) == k(Integer(2)) True >>> my_sqrts = k(Integer(4)).sqrt(all=True) >>> len(k(Integer(4)).sqrt(all=True)) 2 >>> Integer(2) in my_sqrts True >>> Integer(3) in my_sqrts True >>> k.quadratic_nonresidue().sqrt() Traceback (most recent call last): ... ValueError: element is not a square >>> k.quadratic_nonresidue().sqrt(all=True) ()
Here is an example where changing the algorithm results in a faster square root:
sage: p = 141 * 2^141 + 1 sage: S.<x> = GF(p)[] sage: f = S.irreducible_element(2) sage: k.<y> = S.quotient_ring(f) sage: k in Fields() True sage: k(2).sqrt(algorithm="cipolla")^2 == k(2) True
[Python]>>> from sage.all import * >>> p = Integer(141) * Integer(2)**Integer(141) + Integer(1) >>> S = GF(p)['x']; (x,) = S._first_ngens(1) >>> f = S.irreducible_element(Integer(2)) >>> k = S.quotient_ring(f, names=('y',)); (y,) = k._first_ngens(1) >>> k in Fields() True >>> k(Integer(2)).sqrt(algorithm="cipolla")**Integer(2) == k(Integer(2)) True
ALGORITHM:
The algorithms used come from chapter 7 of [BS1996]. Let \(q = p^n\) be the order of the finite field, let \(a\) be the finite field element that we wish to find the square root of.
If \(p = 2\) then \(a\) is always a square, and the square root of \(\sqrt{a} = a^{q / 2}\).
If \(q \equiv 3 \pmod{4}\) then if \(a\) is a square \(\sqrt{a} = a^{\frac{q+1}{4}}\)
For all other cases we use the algorithm given by the
algorithmparameter.
- class ParentMethods[source]¶
Bases:
object- is_perfect()[source]¶
Return whether this field is perfect, i.e., every element has a \(p\)-th root. Always returns
Truesince finite fields are perfect.EXAMPLES:
sage: GF(2).is_perfect() True
>>> from sage.all import * >>> GF(Integer(2)).is_perfect() True
- quadratic_nonresidue()[source]¶
Return a random non square element of the finite field
- OUTPUT:
A non-square element of the finite field; raises an error if the finite field is of even order.
EXAMPLES:
sage: k = GF((3, 10)) sage: k.quadratic_nonresidue().is_square() False sage: k = GF((2, 10)) sage: k in Fields() # to let k be a finite field True sage: k.quadratic_nonresidue() Traceback (most recent call last): ... ValueError: there are no non-squares in finite fields of even order
>>> from sage.all import * >>> k = GF((Integer(3), Integer(10))) >>> k.quadratic_nonresidue().is_square() False >>> k = GF((Integer(2), Integer(10))) >>> k in Fields() # to let k be a finite field True >>> k.quadratic_nonresidue() Traceback (most recent call last): ... ValueError: there are no non-squares in finite fields of even order
- zeta(n=None)[source]¶
Return an element of multiplicative order
nin 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)^3may 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
[Python]>>> 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
ncan 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