Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/rings/finite_rings/constructor.py
8820 views
1
r"""
2
Finite Fields
3
4
Sage supports arithmetic in finite prime and extension fields.
5
Several implementation for prime fields are implemented natively in
6
Sage for several sizes of primes `p`. These implementations
7
are
8
9
10
- ``sage.rings.finite_rings.integer_mod.IntegerMod_int``,
11
12
- ``sage.rings.finite_rings.integer_mod.IntegerMod_int64``, and
13
14
- ``sage.rings.finite_rings.integer_mod.IntegerMod_gmp``.
15
16
17
Small extension fields of cardinality `< 2^{16}` are
18
implemented using tables of Zech logs via the Givaro C++ library
19
(``sage.rings.finite_rings.finite_field_givaro.FiniteField_givaro``).
20
While this representation is very fast it is limited to finite
21
fields of small cardinality. Larger finite extension fields of
22
order `q >= 2^{16}` are internally represented as
23
polynomials over smaller finite prime fields. If the
24
characteristic of such a field is 2 then NTL is used internally to
25
represent the field
26
(``sage.rings.finite_rings.finite_field_ntl_gf2e.FiniteField_ntl_gf2e``).
27
In all other case the PARI C library is used
28
(``sage.rings.finite_rings.finite_field_ext_pari.FiniteField_ext_pari``).
29
30
However, this distinction is internal only and the user usually
31
does not have to worry about it because consistency across all
32
implementations is aimed for. In all extension field
33
implementations the user may either specify a minimal polynomial or
34
leave the choice to Sage.
35
36
For small finite fields the default choice are Conway polynomials.
37
38
The Conway polynomial `C_n` is the lexicographically first
39
monic irreducible, primitive polynomial of degree `n` over
40
`GF(p)` with the property that for a root `\alpha`
41
of `C_n` we have that
42
`\beta=
43
\alpha^{(p^n - 1)/(p^m - 1)}` is a root of
44
`C_m` for all `m` dividing `n`. Sage
45
contains a database of Conway polynomials which also can be queried
46
independently of finite field construction.
47
48
While Sage supports basic arithmetic in finite fields some more
49
advanced features for computing with finite fields are still not
50
implemented. For instance, Sage does not calculate embeddings of
51
finite fields yet.
52
53
EXAMPLES::
54
55
sage: k = GF(5); type(k)
56
<class 'sage.rings.finite_rings.finite_field_prime_modn.FiniteField_prime_modn_with_category'>
57
58
::
59
60
sage: k = GF(5^2,'c'); type(k)
61
<class 'sage.rings.finite_rings.finite_field_givaro.FiniteField_givaro_with_category'>
62
63
::
64
65
sage: k = GF(2^16,'c'); type(k)
66
<class 'sage.rings.finite_rings.finite_field_ntl_gf2e.FiniteField_ntl_gf2e_with_category'>
67
68
::
69
70
sage: k = GF(3^16,'c'); type(k)
71
<class 'sage.rings.finite_rings.finite_field_pari_ffelt.FiniteField_pari_ffelt_with_category'>
72
73
Finite Fields support iteration, starting with 0.
74
75
::
76
77
sage: k = GF(9, 'a')
78
sage: for i,x in enumerate(k): print i,x
79
0 0
80
1 a
81
2 a + 1
82
3 2*a + 1
83
4 2
84
5 2*a
85
6 2*a + 2
86
7 a + 2
87
8 1
88
sage: for a in GF(5):
89
... print a
90
0
91
1
92
2
93
3
94
4
95
96
We output the base rings of several finite fields.
97
98
::
99
100
sage: k = GF(3); type(k)
101
<class 'sage.rings.finite_rings.finite_field_prime_modn.FiniteField_prime_modn_with_category'>
102
sage: k.base_ring()
103
Finite Field of size 3
104
105
::
106
107
sage: k = GF(9,'alpha'); type(k)
108
<class 'sage.rings.finite_rings.finite_field_givaro.FiniteField_givaro_with_category'>
109
sage: k.base_ring()
110
Finite Field of size 3
111
112
::
113
114
sage: k = GF(3^40,'b'); type(k)
115
<class 'sage.rings.finite_rings.finite_field_pari_ffelt.FiniteField_pari_ffelt_with_category'>
116
sage: k.base_ring()
117
Finite Field of size 3
118
119
Further examples::
120
121
sage: GF(2).is_field()
122
True
123
sage: GF(next_prime(10^20)).is_field()
124
True
125
sage: GF(19^20,'a').is_field()
126
True
127
sage: GF(8,'a').is_field()
128
True
129
130
AUTHORS:
131
132
- William Stein: initial version
133
134
- Robert Bradshaw: prime field implementation
135
136
- Martin Albrecht: Givaro and ntl.GF2E implementations
137
"""
138
139
#*****************************************************************************
140
# Copyright (C) 2006 William Stein <[email protected]>
141
#
142
# Distributed under the terms of the GNU General Public License (GPL)
143
#
144
# This code is distributed in the hope that it will be useful,
145
# but WITHOUT ANY WARRANTY; without even the implied warranty of
146
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
147
# General Public License for more details.
148
#
149
# The full text of the GPL is available at:
150
#
151
# http://www.gnu.org/licenses/
152
#*****************************************************************************
153
154
import random
155
156
from sage.rings.finite_rings.finite_field_base import is_FiniteField
157
from sage.structure.parent_gens import normalize_names
158
159
import sage.rings.arith as arith
160
import sage.rings.integer as integer
161
162
import sage.rings.polynomial.polynomial_element as polynomial_element
163
import sage.rings.polynomial.multi_polynomial_element as multi_polynomial_element
164
165
# We don't late import this because this means trouble with the Givaro library
166
# On a Macbook Pro OSX 10.5.8, this manifests as a Bus Error on exiting Sage.
167
# TODO: figure out why
168
from finite_field_givaro import FiniteField_givaro
169
170
import sage.interfaces.gap
171
172
from sage.structure.factory import UniqueFactory
173
174
class FiniteFieldFactory(UniqueFactory):
175
"""
176
Return the globally unique finite field of given order with
177
generator labeled by the given name and possibly with given
178
modulus.
179
180
INPUT:
181
182
- ``order`` -- a prime power
183
184
- ``name`` -- string; must be specified unless ``order`` is prime.
185
186
- ``modulus`` -- (optional) either a defining polynomial for the
187
field, or a string specifying an algorithm to use to generate
188
such a polynomial. If ``modulus`` is a string, it is passed to
189
:meth:`~sage.rings.polynomial.irreducible_element()` as the
190
parameter ``algorithm``; see there for the permissible values of
191
this parameter.
192
193
- ``elem_cache`` -- cache all elements to avoid creation time
194
(default: order < 500)
195
196
- ``check_irreducible`` -- verify that the polynomial modulus is
197
irreducible
198
199
- ``proof`` -- bool (default: ``True``): if ``True``, use provable
200
primality test; otherwise only use pseudoprimality test.
201
202
- ``args`` -- additional parameters passed to finite field
203
implementations
204
205
- ``kwds`` -- additional keyword parameters passed to finite field
206
implementations
207
208
ALIAS: You can also use ``GF`` instead of ``FiniteField`` -- they
209
are identical.
210
211
EXAMPLES::
212
213
sage: k.<a> = FiniteField(9); k
214
Finite Field in a of size 3^2
215
sage: parent(a)
216
Finite Field in a of size 3^2
217
sage: charpoly(a, 'y')
218
y^2 + 2*y + 2
219
220
We illustrate the proof flag. The following example would hang
221
for a very long time if we didn't use ``proof=False``.
222
223
.. NOTE::
224
225
Magma only supports ``proof=False`` for making finite fields,
226
so falsely appears to be faster than Sage -- see :trac:10975.
227
228
::
229
230
sage: k = FiniteField(10^1000 + 453, proof=False)
231
sage: k = FiniteField((10^1000 + 453)^2, 'a', proof=False) # long time -- about 5 seconds
232
233
::
234
235
sage: F.<x> = GF(5)[]
236
sage: K.<a> = GF(5**5, name='a', modulus=x^5 - x +1 )
237
sage: f = K.modulus(); f
238
x^5 + 4*x + 1
239
sage: type(f)
240
<type 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'>
241
242
The modulus must be irreducible::
243
244
sage: K.<a> = GF(5**5, name='a', modulus=x^5 - x)
245
Traceback (most recent call last):
246
...
247
ValueError: finite field modulus must be irreducible but it is not.
248
249
You can't accidentally fool the constructor into thinking the
250
modulus is irreducible when it is not, since it actually tests
251
irreducibility modulo `p`. Also, the modulus has to be of the
252
right degree::
253
254
sage: F.<x> = QQ[]
255
sage: factor(x^5 + 2)
256
x^5 + 2
257
sage: K.<a> = GF(5**5, name='a', modulus=x^5 + 2)
258
Traceback (most recent call last):
259
...
260
ValueError: finite field modulus must be irreducible but it is not.
261
sage: K.<a> = GF(5**5, name='a', modulus=x^3 + 3*x + 3)
262
Traceback (most recent call last):
263
...
264
ValueError: The degree of the modulus does not correspond to the
265
cardinality of the field.
266
267
If you wish to live dangerously, you can tell the constructor not
268
to test irreducibility using ``check_irreducible=False``, but this
269
can easily lead to crashes and hangs -- so do not do it unless you
270
know that the modulus really is irreducible and has the correct
271
degree!
272
273
::
274
275
sage: F.<x> = GF(5)[]
276
sage: K.<a> = GF(5**2, name='a', modulus=x^2 + 2, check_irreducible=False)
277
278
sage: L = GF(3**2, name='a', modulus=QQ[x](x - 1), check_irreducible=False)
279
sage: L.list() # random
280
[0, a, 1, 2, 1, 2, 1, 2, 1]
281
282
The order of a finite field must be a prime power::
283
284
sage: GF(1)
285
Traceback (most recent call last):
286
...
287
ValueError: the order of a finite field must be > 1.
288
sage: GF(100)
289
Traceback (most recent call last):
290
...
291
ValueError: the order of a finite field must be a prime power.
292
293
Finite fields with explicit random modulus are not cached::
294
295
sage: k.<a> = GF(5**10, modulus='random')
296
sage: n.<a> = GF(5**10, modulus='random')
297
sage: n is k
298
False
299
sage: GF(5**10, 'a') is GF(5**10, 'a')
300
True
301
302
We check that various ways of creating the same finite field yield
303
the same object, which is cached::
304
305
sage: K = GF(7, 'a')
306
sage: L = GF(7, 'b')
307
sage: K is L
308
True
309
sage: K = GF(4,'a'); K.modulus()
310
x^2 + x + 1
311
sage: L = GF(4,'a', K.modulus())
312
sage: K is L
313
True
314
sage: M = GF(4,'a', K.modulus().change_variable_name('y'))
315
sage: K is M
316
True
317
318
You may print finite field elements as integers. This currently
319
only works if the order of field is `<2^{16}`, though::
320
321
sage: k.<a> = GF(2^8, repr='int')
322
sage: a
323
2
324
325
The following demonstrate coercions for finite fields using Conway
326
polynomials::
327
328
sage: k = GF(5^2, conway=True, prefix='z'); a = k.gen()
329
sage: l = GF(5^5, conway=True, prefix='z'); b = l.gen()
330
sage: a + b
331
3*z10^5 + z10^4 + z10^2 + 3*z10 + 1
332
333
Note that embeddings are compatible in lattices of such finite
334
fields::
335
336
sage: m = GF(5^3, conway=True, prefix='z'); c = m.gen()
337
sage: (a+b)+c == a+(b+c)
338
True
339
sage: (a*b)*c == a*(b*c)
340
True
341
sage: from sage.categories.pushout import pushout
342
sage: n = pushout(k, l)
343
sage: o = pushout(l, m)
344
sage: q = pushout(n, o)
345
sage: q(o(b)) == q(n(b))
346
True
347
348
Another check that embeddings are defined properly::
349
350
sage: k = GF(3**10, conway=True, prefix='z')
351
sage: l = GF(3**20, conway=True, prefix='z')
352
sage: l(k.gen()**10) == l(k.gen())**10
353
True
354
"""
355
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
356
impl=None, proof=None, **kwds):
357
"""
358
EXAMPLES::
359
360
sage: GF.create_key_and_extra_args(9, 'a')
361
((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {})
362
sage: GF.create_key_and_extra_args(9, 'a', foo='value')
363
((9, ('a',), x^2 + 2*x + 2, None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'})
364
"""
365
from sage.structure.proof.all import WithProof, arithmetic
366
if proof is None: proof = arithmetic()
367
with WithProof('arithmetic', proof):
368
order = int(order)
369
if order <= 1:
370
raise ValueError("the order of a finite field must be > 1.")
371
372
if arith.is_prime(order):
373
name = None
374
modulus = None
375
p = integer.Integer(order)
376
n = integer.Integer(1)
377
elif arith.is_prime_power(order):
378
if not names is None: name = names
379
name = normalize_names(1,name)
380
381
p, n = arith.factor(order)[0]
382
383
# The following is a temporary solution that allows us
384
# to construct compatible systems of finite fields
385
# until algebraic closures of finite fields are
386
# implemented in Sage. It requires the user to
387
# specify two parameters:
388
#
389
# - `conway` -- boolean; if True, this field is
390
# constructed to fit in a compatible system using
391
# a Conway polynomial.
392
# - `prefix` -- a string used to generate names for
393
# automatically constructed finite fields
394
#
395
# See the docstring of FiniteFieldFactory for examples.
396
#
397
# Once algebraic closures of finite fields are
398
# implemented, this syntax should be superseded by
399
# something like the following:
400
#
401
# sage: Fpbar = GF(5).algebraic_closure('z')
402
# sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar
403
# sage: F
404
# Finite field in z3 of size 5^3
405
#
406
# This temporary solution only uses actual Conway
407
# polynomials (no pseudo-Conway polynomials), since
408
# pseudo-Conway polynomials are not unique, and until
409
# we have algebraic closures of finite fields, there
410
# is no good place to store a specific choice of
411
# pseudo-Conway polynomials.
412
if name is None:
413
if not (kwds.has_key('conway') and kwds['conway']):
414
raise ValueError("parameter 'conway' is required if no name given")
415
if not kwds.has_key('prefix'):
416
raise ValueError("parameter 'prefix' is required if no name given")
417
name = kwds['prefix'] + str(n)
418
419
if kwds.has_key('conway') and kwds['conway']:
420
from conway_polynomials import conway_polynomial
421
if not kwds.has_key('prefix'):
422
raise ValueError("a prefix must be specified if conway=True")
423
if modulus is not None:
424
raise ValueError("no modulus may be specified if conway=True")
425
# The following raises a RuntimeError if no polynomial is found.
426
modulus = conway_polynomial(p, n)
427
428
if modulus is None or isinstance(modulus, str):
429
# A string specifies an algorithm to find a suitable modulus.
430
if modulus == "default": # for backward compatibility
431
modulus = None
432
modulus = GF(p)['x'].irreducible_element(n, algorithm=modulus)
433
elif isinstance(modulus, (list, tuple)):
434
modulus = GF(p)['x'](modulus)
435
elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus):
436
modulus = modulus.change_variable_name('x')
437
else:
438
raise TypeError("wrong type for modulus parameter")
439
else:
440
raise ValueError("the order of a finite field must be a prime power.")
441
442
return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
443
444
def create_object(self, version, key, check_irreducible=True, elem_cache=None,
445
names=None, **kwds):
446
"""
447
EXAMPLES::
448
449
sage: K = GF(19) # indirect doctest
450
sage: TestSuite(K).run()
451
"""
452
# IMPORTANT! If you add a new class to the list of classes
453
# that get cached by this factor object, then you *must* add
454
# the following method to that class in order to fully support
455
# pickling:
456
#
457
# def __reduce__(self): # and include good doctests, please!
458
# return self._factory_data[0].reduce_data(self)
459
#
460
# This is not in the base class for finite fields, since some finite
461
# fields need not be created using this factory object, e.g., residue
462
# class fields.
463
464
if len(key) == 5:
465
# for backward compatibility of pickles (see trac 10975).
466
order, name, modulus, impl, _ = key
467
p, n = arith.factor(order)[0]
468
proof = True
469
else:
470
order, name, modulus, impl, _, p, n, proof = key
471
472
if elem_cache is None:
473
elem_cache = order < 500
474
475
if n == 1 and (impl is None or impl == 'modn'):
476
from finite_field_prime_modn import FiniteField_prime_modn
477
# Using a check option here is probably a worthwhile
478
# compromise since this constructor is simple and used a
479
# huge amount.
480
K = FiniteField_prime_modn(order, check=False)
481
else:
482
# We have to do this with block so that the finite field
483
# constructors below will use the proof flag that was
484
# passed in when checking for primality, factoring, etc.
485
# Otherwise, we would have to complicate all of their
486
# constructors with check options (like above).
487
from sage.structure.proof.all import WithProof
488
with WithProof('arithmetic', proof):
489
if check_irreducible and polynomial_element.is_Polynomial(modulus):
490
if modulus.parent().base_ring().characteristic() == 0:
491
modulus = modulus.change_ring(FiniteField(p))
492
if not modulus.is_irreducible():
493
raise ValueError("finite field modulus must be irreducible but it is not.")
494
if modulus.degree() != n:
495
raise ValueError("The degree of the modulus does not correspond to the cardinality of the field.")
496
if name is None:
497
raise TypeError("you must specify the generator name.")
498
if impl is None:
499
if order < zech_log_bound:
500
# DO *NOT* use for prime subfield, since that would lead to
501
# a circular reference in the call to ParentWithGens in the
502
# __init__ method.
503
impl = 'givaro'
504
elif order % 2 == 0:
505
impl = 'ntl'
506
else:
507
impl = 'pari_ffelt'
508
if impl == 'givaro':
509
if kwds.has_key('repr'):
510
repr = kwds['repr']
511
else:
512
repr = 'poly'
513
K = FiniteField_givaro(order, name, modulus, repr=repr, cache=elem_cache)
514
elif impl == 'ntl':
515
from finite_field_ntl_gf2e import FiniteField_ntl_gf2e
516
K = FiniteField_ntl_gf2e(order, name, modulus)
517
elif impl == 'pari_ffelt':
518
from finite_field_pari_ffelt import FiniteField_pari_ffelt
519
K = FiniteField_pari_ffelt(p, modulus, name)
520
elif (impl == 'pari_mod'
521
or impl == 'pari'): # for unpickling old pickles
522
from finite_field_ext_pari import FiniteField_ext_pari
523
K = FiniteField_ext_pari(order, name, modulus)
524
else:
525
raise ValueError("no such finite field implementation: %s" % impl)
526
527
# Temporary; see create_key_and_extra_args() above.
528
if kwds.has_key('prefix'):
529
K._prefix = kwds['prefix']
530
531
return K
532
533
def other_keys(self, key, K):
534
"""
535
EXAMPLES::
536
537
sage: key, extra = GF.create_key_and_extra_args(9, 'a'); key
538
(9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True)
539
sage: K = GF.create_object(0, key); K
540
Finite Field in a of size 3^2
541
sage: GF.other_keys(key, K)
542
[(9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True),
543
(9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True)]
544
"""
545
if len(key) == 5: # backward compat
546
order, name, modulus, impl, _ = key
547
p, n = arith.factor(order)[0]
548
proof = True
549
else:
550
order, name, modulus, impl, _, p, n, proof = key
551
552
from sage.structure.proof.all import WithProof
553
with WithProof('arithmetic', proof):
554
if K.degree() > 1:
555
modulus = K.modulus().change_variable_name('x')
556
new_keys = [(order, name, modulus, impl, _, p, n, proof)]
557
from finite_field_prime_modn import FiniteField_prime_modn
558
if isinstance(K, FiniteField_prime_modn):
559
impl = 'modn'
560
elif isinstance(K, FiniteField_givaro):
561
impl = 'givaro'
562
else:
563
from finite_field_ntl_gf2e import FiniteField_ntl_gf2e
564
from finite_field_ext_pari import FiniteField_ext_pari
565
from finite_field_pari_ffelt import FiniteField_pari_ffelt
566
if isinstance(K, FiniteField_ntl_gf2e):
567
impl = 'ntl'
568
elif isinstance(K, FiniteField_ext_pari):
569
impl = 'pari_mod'
570
elif isinstance(K, FiniteField_pari_ffelt):
571
impl = 'pari_ffelt'
572
new_keys.append( (order, name, modulus, impl, _, p, n, proof) )
573
return new_keys
574
575
576
GF = FiniteField = FiniteFieldFactory("FiniteField")
577
578
579
def is_PrimeFiniteField(x):
580
"""
581
Returns True if x is a prime finite field.
582
583
EXAMPLES::
584
585
sage: from sage.rings.finite_rings.constructor import is_PrimeFiniteField
586
sage: is_PrimeFiniteField(QQ)
587
False
588
sage: is_PrimeFiniteField(GF(7))
589
True
590
sage: is_PrimeFiniteField(GF(7^2,'a'))
591
False
592
sage: is_PrimeFiniteField(GF(next_prime(10^90,proof=False)))
593
True
594
"""
595
from finite_field_prime_modn import FiniteField_prime_modn
596
from sage.rings.finite_rings.finite_field_base import FiniteField as FiniteField_generic
597
598
return isinstance(x, FiniteField_prime_modn) or \
599
(isinstance(x, FiniteField_generic) and x.degree() == 1)
600
601
zech_log_bound = 2**16
602
603