Finite field elements implemented via PARI’s FFELT type¶
AUTHORS:
Peter Bruin (June 2013): initial version, based on element_ext_pari.py by William Stein et al. and element_ntl_gf2e.pyx by Martin Albrecht.
- class sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt[source]¶
Bases:
FinitePolyExtElement
An element of a finite field implemented using PARI.
EXAMPLES:
sage: K = FiniteField(10007^10, 'a', impl='pari_ffelt') sage: a = K.gen(); a a sage: type(a) <class 'sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt'>
>>> from sage.all import * >>> K = FiniteField(Integer(10007)**Integer(10), 'a', impl='pari_ffelt') >>> a = K.gen(); a a >>> type(a) <class 'sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt'>
- charpoly(var='x')[source]¶
Return the characteristic polynomial of
self
.INPUT:
var
– string (default:'x'
); variable name to use
EXAMPLES:
sage: R.<x> = PolynomialRing(FiniteField(3)) sage: F.<a> = FiniteField(3^2, modulus=x^2 + 1, impl='pari_ffelt') sage: a.charpoly('y') y^2 + 1
>>> from sage.all import * >>> R = PolynomialRing(FiniteField(Integer(3)), names=('x',)); (x,) = R._first_ngens(1) >>> F = FiniteField(Integer(3)**Integer(2), modulus=x**Integer(2) + Integer(1), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.charpoly('y') y^2 + 1
- frobenius(k=1)[source]¶
Return the \((p^k)\)-th power of
self
, where \(p\) is the characteristic of the field.INPUT:
k
– integer (default: 1); must fit in a Cint
Note that if \(k\) is negative, then this computes the appropriate root.
- is_one()[source]¶
Return
True
ifself
equals 1.EXAMPLES:
sage: F.<a> = FiniteField(5^3, impl='pari_ffelt') sage: a.is_one() False sage: (a/a).is_one() True
>>> from sage.all import * >>> F = FiniteField(Integer(5)**Integer(3), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.is_one() False >>> (a/a).is_one() True
- is_square()[source]¶
Return
True
if and only ifself
is a square in the finite field.EXAMPLES:
sage: k.<a> = FiniteField(3^2, impl='pari_ffelt') sage: a.is_square() False sage: (a**2).is_square() True sage: k.<a> = FiniteField(2^2, impl='pari_ffelt') sage: (a**2).is_square() True sage: k.<a> = FiniteField(17^5, impl='pari_ffelt') sage: (a**2).is_square() True sage: a.is_square() False sage: k(0).is_square() True
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(2), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> a.is_square() False >>> (a**Integer(2)).is_square() True >>> k = FiniteField(Integer(2)**Integer(2), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> (a**Integer(2)).is_square() True >>> k = FiniteField(Integer(17)**Integer(5), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> (a**Integer(2)).is_square() True >>> a.is_square() False >>> k(Integer(0)).is_square() True
- is_unit()[source]¶
Return
True
ifself
is nonzero.EXAMPLES:
sage: F.<a> = FiniteField(5^3, impl='pari_ffelt') sage: a.is_unit() True
>>> from sage.all import * >>> F = FiniteField(Integer(5)**Integer(3), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.is_unit() True
- is_zero()[source]¶
Return
True
ifself
equals 0.EXAMPLES:
sage: F.<a> = FiniteField(5^3, impl='pari_ffelt') sage: a.is_zero() False sage: (a - a).is_zero() True
>>> from sage.all import * >>> F = FiniteField(Integer(5)**Integer(3), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.is_zero() False >>> (a - a).is_zero() True
- lift()[source]¶
If
self
is an element of the prime field, return a lift of this element to an integer.EXAMPLES:
sage: k = FiniteField(next_prime(10^10)^2, 'u', impl='pari_ffelt') sage: a = k(17)/k(19) sage: b = a.lift(); b 7894736858 sage: b.parent() Integer Ring
>>> from sage.all import * >>> k = FiniteField(next_prime(Integer(10)**Integer(10))**Integer(2), 'u', impl='pari_ffelt') >>> a = k(Integer(17))/k(Integer(19)) >>> b = a.lift(); b 7894736858 >>> b.parent() Integer Ring
- log(base, order=None, check=False)[source]¶
Return a discrete logarithm of
self
with respect to the given base.INPUT:
base
– nonzero field elementorder
– integer (optional), the order of the basecheck
– boolean (default:False
); if set, test whether the givenorder
is correct
OUTPUT:
An integer \(x\) such that
self
equalsbase
raised to the power \(x\). If no such \(x\) exists, aValueError
is raised.EXAMPLES:
sage: F.<g> = FiniteField(2^10, impl='pari_ffelt') sage: b = g; a = g^37 sage: a.log(b) 37 sage: b^37; a g^8 + g^7 + g^4 + g + 1 g^8 + g^7 + g^4 + g + 1
>>> from sage.all import * >>> F = FiniteField(Integer(2)**Integer(10), impl='pari_ffelt', names=('g',)); (g,) = F._first_ngens(1) >>> b = g; a = g**Integer(37) >>> a.log(b) 37 >>> b**Integer(37); a g^8 + g^7 + g^4 + g + 1 g^8 + g^7 + g^4 + g + 1
sage: F.<a> = FiniteField(5^2, impl='pari_ffelt') sage: F(-1).log(F(2)) 2 sage: F(1).log(a) 0
>>> from sage.all import * >>> F = FiniteField(Integer(5)**Integer(2), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> F(-Integer(1)).log(F(Integer(2))) 2 >>> F(Integer(1)).log(a) 0
sage: p = 2^127-1 sage: F.<t> = GF((p, 3)) sage: elt = F.random_element()^(p^2+p+1) sage: (elt^2).log(elt, p-1) 2
>>> from sage.all import * >>> p = Integer(2)**Integer(127)-Integer(1) >>> F = GF((p, Integer(3)), names=('t',)); (t,) = F._first_ngens(1) >>> elt = F.random_element()**(p**Integer(2)+p+Integer(1)) >>> (elt**Integer(2)).log(elt, p-Integer(1)) 2
Passing the
order
argument can lead to huge speedups when factoring the order of the entire unit group is expensive but the order of the base element is much smaller:sage: %timeit (elt^2).log(elt) # not tested 6.18 s ± 85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) sage: %timeit (elt^2).log(elt, p-1) # not tested 147 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> from sage.all import * >>> %timeit (elt**Integer(2)).log(elt) # not tested 6.18 s ± 85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) >>> %timeit (elt**Integer(2)).log(elt, p-Integer(1)) # not tested 147 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Some cases where the logarithm is not defined or does not exist:
sage: F.<a> = GF(3^10, impl='pari_ffelt') sage: a.log(-1) Traceback (most recent call last): ... ArithmeticError: element a does not lie in group generated by 2 sage: a.log(0) Traceback (most recent call last): ... ArithmeticError: discrete logarithm with base 0 is not defined sage: F(0).log(1) Traceback (most recent call last): ... ArithmeticError: discrete logarithm of 0 is not defined
>>> from sage.all import * >>> F = GF(Integer(3)**Integer(10), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.log(-Integer(1)) Traceback (most recent call last): ... ArithmeticError: element a does not lie in group generated by 2 >>> a.log(Integer(0)) Traceback (most recent call last): ... ArithmeticError: discrete logarithm with base 0 is not defined >>> F(Integer(0)).log(Integer(1)) Traceback (most recent call last): ... ArithmeticError: discrete logarithm of 0 is not defined
- minpoly(var='x')[source]¶
Return the minimal polynomial of
self
.INPUT:
var
– string (default:'x'
); variable name to use
EXAMPLES:
sage: R.<x> = PolynomialRing(FiniteField(3)) sage: F.<a> = FiniteField(3^2, modulus=x^2 + 1, impl='pari_ffelt') sage: a.minpoly('y') y^2 + 1
>>> from sage.all import * >>> R = PolynomialRing(FiniteField(Integer(3)), names=('x',)); (x,) = R._first_ngens(1) >>> F = FiniteField(Integer(3)**Integer(2), modulus=x**Integer(2) + Integer(1), impl='pari_ffelt', names=('a',)); (a,) = F._first_ngens(1) >>> a.minpoly('y') y^2 + 1
- multiplicative_order()[source]¶
Return the order of
self
in the multiplicative group.EXAMPLES:
sage: a = FiniteField(5^3, 'a', impl='pari_ffelt').0 sage: a.multiplicative_order() 124 sage: a**124 1
>>> from sage.all import * >>> a = FiniteField(Integer(5)**Integer(3), 'a', impl='pari_ffelt').gen(0) >>> a.multiplicative_order() 124 >>> a**Integer(124) 1
- polynomial(name=None)[source]¶
Return the unique representative of
self
as a polynomial over the prime field whose degree is less than the degree of the finite field over its prime field.INPUT:
name
– (optional) variable name
EXAMPLES:
sage: k.<a> = FiniteField(3^2, impl='pari_ffelt') sage: pol = a.polynomial() sage: pol a sage: parent(pol) Univariate Polynomial Ring in a over Finite Field of size 3
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(2), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> pol = a.polynomial() >>> pol a >>> parent(pol) Univariate Polynomial Ring in a over Finite Field of size 3
sage: k = FiniteField(3^4, 'alpha', impl='pari_ffelt') sage: a = k.gen() sage: a.polynomial() alpha sage: (a**2 + 1).polynomial('beta') beta^2 + 1 sage: (a**2 + 1).polynomial().parent() Univariate Polynomial Ring in alpha over Finite Field of size 3 sage: (a**2 + 1).polynomial('beta').parent() Univariate Polynomial Ring in beta over Finite Field of size 3
>>> from sage.all import * >>> k = FiniteField(Integer(3)**Integer(4), 'alpha', impl='pari_ffelt') >>> a = k.gen() >>> a.polynomial() alpha >>> (a**Integer(2) + Integer(1)).polynomial('beta') beta^2 + 1 >>> (a**Integer(2) + Integer(1)).polynomial().parent() Univariate Polynomial Ring in alpha over Finite Field of size 3 >>> (a**Integer(2) + Integer(1)).polynomial('beta').parent() Univariate Polynomial Ring in beta over Finite Field of size 3
- pth_power(k=1)[source]¶
Return the \((p^k)\)-th power of
self
, where \(p\) is the characteristic of the field.INPUT:
k
– integer (default: 1); must fit in a Cint
Note that if \(k\) is negative, then this computes the appropriate root.
- sqrt(extend=False, all=False)[source]¶
Return a square root of
self
, if it exists.INPUT:
extend
– boolean (default:False
)Warning
This option is not implemented.
all
– boolean (default:False
)
OUTPUT:
A square root of
self
, if it exists. Ifall
isTrue
, a list containing all square roots ofself
(of length zero, one or two) is returned instead.If
extend
isTrue
, a square root is chosen in an extension field if necessary. Ifextend
isFalse
, aValueError
is raised if the element is not a square in the base field.Warning
The
extend
option is not implemented (yet).EXAMPLES:
sage: F = FiniteField(7^2, 'a', impl='pari_ffelt') sage: F(2).sqrt() 4 sage: F(3).sqrt() in (2*F.gen() + 6, 5*F.gen() + 1) True sage: F(3).sqrt()**2 3 sage: F(4).sqrt(all=True) [2, 5] sage: K = FiniteField(7^3, 'alpha', impl='pari_ffelt') sage: K(3).sqrt() Traceback (most recent call last): ... ValueError: element is not a square sage: K(3).sqrt(all=True) [] sage: K.<a> = GF(3^17, impl='pari_ffelt') sage: (a^3 - a - 1).sqrt() a^16 + 2*a^15 + a^13 + 2*a^12 + a^10 + 2*a^9 + 2*a^8 + a^7 + a^6 + 2*a^5 + a^4 + 2*a^2 + 2*a + 2
>>> from sage.all import * >>> F = FiniteField(Integer(7)**Integer(2), 'a', impl='pari_ffelt') >>> F(Integer(2)).sqrt() 4 >>> F(Integer(3)).sqrt() in (Integer(2)*F.gen() + Integer(6), Integer(5)*F.gen() + Integer(1)) True >>> F(Integer(3)).sqrt()**Integer(2) 3 >>> F(Integer(4)).sqrt(all=True) [2, 5] >>> K = FiniteField(Integer(7)**Integer(3), 'alpha', impl='pari_ffelt') >>> K(Integer(3)).sqrt() Traceback (most recent call last): ... ValueError: element is not a square >>> K(Integer(3)).sqrt(all=True) [] >>> K = GF(Integer(3)**Integer(17), impl='pari_ffelt', names=('a',)); (a,) = K._first_ngens(1) >>> (a**Integer(3) - a - Integer(1)).sqrt() a^16 + 2*a^15 + a^13 + 2*a^12 + a^10 + 2*a^9 + 2*a^8 + a^7 + a^6 + 2*a^5 + a^4 + 2*a^2 + 2*a + 2
- sage.rings.finite_rings.element_pari_ffelt.unpickle_FiniteFieldElement_pari_ffelt(parent, elem)[source]¶
EXAMPLES:
sage: # needs sage.modules sage: k.<a> = GF(2^20, impl='pari_ffelt') sage: e = k.random_element() sage: f = loads(dumps(e)) # indirect doctest sage: e == f True
>>> from sage.all import * >>> # needs sage.modules >>> k = GF(Integer(2)**Integer(20), impl='pari_ffelt', names=('a',)); (a,) = k._first_ngens(1) >>> e = k.random_element() >>> f = loads(dumps(e)) # indirect doctest >>> e == f True