Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/rings/finite_rings/constructor.py
4069 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_ext_pari.FiniteField_ext_pari_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 2*a
81
2 a + 1
82
3 a + 2
83
4 2
84
5 a
85
6 2*a + 2
86
7 2*a + 1
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_ext_pari.FiniteField_ext_pari_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
import sage.databases.conway
172
173
from sage.structure.factory import UniqueFactory
174
175
class FiniteFieldFactory(UniqueFactory):
176
"""
177
Return the globally unique finite field of given order with
178
generator labeled by the given name and possibly with given
179
modulus.
180
181
INPUT:
182
183
184
- ``order`` - int
185
186
- ``name`` - string; must be specified if not a prime
187
field
188
189
- ``modulus`` - (optional) either a defining polynomial for the
190
field, i.e., generator of the field will be a root of this
191
polynomial; or a string:
192
193
- 'conway': force the use of a Conway polynomial, will
194
raise a RuntimeError if none is found in the database;
195
- 'random': use a random irreducible polynomial;
196
- 'default': a Conway polynomial is used if found. Otherwise
197
a sparse polynomial is used for binary fields and a
198
random polynomial is used for other characteristics.
199
200
Other options might be available depending on the
201
implementation.
202
203
- ``elem_cache`` - cache all elements to avoid
204
creation time (default: order < 500)
205
206
- ``check_irreducible`` - verify that the polynomial
207
modulus is irreducible
208
209
- ``proof`` -- bool (default: True); if True use provable
210
primality test; otherwise only use pseudoprimality test.
211
212
- ``args`` - additional parameters passed to finite
213
field implementations
214
215
- ``kwds`` - additional keyword parameters passed to
216
finite field implementations
217
218
219
ALIAS: You can also use GF instead of FiniteField - they are
220
identical.
221
222
EXAMPLES::
223
224
sage: k.<a> = FiniteField(9); k
225
Finite Field in a of size 3^2
226
sage: parent(a)
227
Finite Field in a of size 3^2
228
sage: charpoly(a, 'y')
229
y^2 + 2*y + 2
230
231
We illustrate the proof flag. The following example would hang
232
for a very long time if we didn't use proof=False. (NOTE: Magma
233
only supports proof=False for making finite fields, so falsely
234
appears to be faster than Sage -- see Trac 10975.)::
235
236
sage: k = FiniteField(10^1000 + 453, proof=False)
237
sage: k = FiniteField((10^1000 + 453)^2, 'a', proof=False) # long time -- about 5 seconds
238
239
::
240
241
sage: F.<x> = GF(5)[]
242
sage: K.<a> = GF(5**5, name='a', modulus=x^5 - x +1 )
243
sage: f = K.modulus(); f
244
x^5 + 4*x + 1
245
sage: type(f)
246
<type 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'>
247
248
The modulus must be irreducible::
249
250
sage: K.<a> = GF(5**5, name='a', modulus=x^5 - x )
251
Traceback (most recent call last):
252
...
253
ValueError: finite field modulus must be irreducible but it is not.
254
255
You can't accidentally fool the constructor into thinking the modulus
256
is irreducible when it isn't mod p, since it actually tests
257
irreducibility modulo p. Also, the modulus has to be of the right degree.
258
259
::
260
261
sage: F.<x> = QQ[]
262
sage: factor(x^5 + 2)
263
x^5 + 2
264
sage: K.<a> = GF(5**5, name='a', modulus=x^5 + 2 )
265
Traceback (most recent call last):
266
...
267
ValueError: finite field modulus must be irreducible but it is not.
268
sage: K.<a> = GF(5**5, name='a', modulus=x^3 + 3*x + 3)
269
Traceback (most recent call last):
270
...
271
ValueError: The degree of the modulus does not correspond to the
272
cardinality of the field.
273
274
If you wish to live dangerously, you can tell the constructor not
275
to test irreducibility using check_irreducible=False, but this can
276
easily lead to crashes and hangs - so do not do it unless you know
277
that the modulus really is irreducible and has the correct degree!
278
279
::
280
281
sage: F.<x> = GF(5)[]
282
sage: K.<a> = GF(5**2, name='a', modulus=x^2 + 2, check_irreducible=False)
283
284
::
285
286
sage: L = GF(3**2, name='a', modulus=QQ[x](x - 1), check_irreducible=False)
287
sage: L.list() # random
288
[0, a, 1, 2, 1, 2, 1, 2, 1]
289
290
The order of a finite field must be a prime power::
291
292
sage: GF(1)
293
Traceback (most recent call last):
294
...
295
ValueError: the order of a finite field must be > 1.
296
sage: GF(100)
297
Traceback (most recent call last):
298
...
299
ValueError: the order of a finite field must be a prime power.
300
301
Finite fields with explicit random modulus are not cached::
302
303
sage: k.<a> = GF(5**10, modulus='random')
304
sage: n.<a> = GF(5**10, modulus='random')
305
sage: n is k
306
False
307
sage: GF(5**10, 'a') is GF(5**10, 'a')
308
True
309
310
We check that various ways of creating the same finite field yield
311
the same object, which is cached.
312
313
::
314
315
sage: K = GF(7, 'a')
316
sage: L = GF(7, 'b')
317
sage: K is L
318
True
319
sage: K = GF(4,'a'); K.modulus()
320
x^2 + x + 1
321
sage: L = GF(4,'a', K.modulus())
322
sage: K is L
323
True
324
sage: M = GF(4,'a', K.modulus().change_variable_name('y'))
325
sage: K is M
326
True
327
328
You may print finite field elements as integers. This
329
currently only works if the order of field is `<2^{16}`,
330
though.
331
332
::
333
334
sage: k.<a> = GF(2^8, repr='int')
335
sage: a
336
2
337
338
"""
339
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
340
impl=None, proof=None, **kwds):
341
"""
342
EXAMPLES::
343
344
sage: GF.create_key_and_extra_args(9, 'a')
345
((9, ('a',), 'conway', None, '{}', 3, 2, True), {})
346
sage: GF.create_key_and_extra_args(9, 'a', foo='value')
347
((9, ('a',), 'conway', None, "{'foo': 'value'}", 3, 2, True), {'foo': 'value'})
348
"""
349
from sage.structure.proof.all import WithProof, arithmetic
350
if proof is None: proof = arithmetic()
351
with WithProof('arithmetic', proof):
352
order = int(order)
353
if order <= 1:
354
raise ValueError("the order of a finite field must be > 1.")
355
356
if arith.is_prime(order):
357
name = None
358
modulus = None
359
p = integer.Integer(order)
360
n = integer.Integer(1)
361
elif arith.is_prime_power(order):
362
if not names is None: name = names
363
name = normalize_names(1,name)
364
365
p, n = arith.factor(order)[0]
366
367
if modulus is None or modulus == "default":
368
if exists_conway_polynomial(p, n):
369
modulus = "conway"
370
else:
371
if p == 2:
372
modulus = "minimal_weight"
373
else:
374
modulus = "random"
375
elif modulus == "random":
376
modulus += str(random.randint(0, 1<<128))
377
378
if isinstance(modulus, (list, tuple)):
379
modulus = FiniteField(p)['x'](modulus)
380
# some classes use 'random' as the modulus to
381
# generate a random modulus, but we don't want
382
# to cache it
383
elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus):
384
modulus = modulus.change_variable_name('x')
385
elif not isinstance(modulus, str):
386
raise ValueError("Modulus parameter not understood.")
387
else: # Neither a prime, nor a prime power
388
raise ValueError("the order of a finite field must be a prime power.")
389
390
return (order, name, modulus, impl, str(kwds), p, n, proof), kwds
391
392
def create_object(self, version, key, check_irreducible=True, elem_cache=None,
393
names=None, **kwds):
394
"""
395
EXAMPLES::
396
397
sage: K = GF(19) # indirect doctest
398
sage: TestSuite(K).run()
399
"""
400
# IMPORTANT! If you add a new class to the list of classes
401
# that get cached by this factor object, then you *must* add
402
# the following method to that class in order to fully support
403
# pickling:
404
#
405
# def __reduce__(self): # and include good doctests, please!
406
# return self._factory_data[0].reduce_data(self)
407
#
408
# This is not in the base class for finite fields, since some finite
409
# fields need not be created using this factory object, e.g., residue
410
# class fields.
411
412
if len(key) == 5:
413
# for backward compatibility of pickles (see trac 10975).
414
order, name, modulus, impl, _ = key
415
p, n = arith.factor(order)[0]
416
proof = True
417
else:
418
order, name, modulus, impl, _, p, n, proof = key
419
420
if isinstance(modulus, str) and modulus.startswith("random"):
421
modulus = "random"
422
423
if elem_cache is None:
424
elem_cache = order < 500
425
426
if n == 1 and (impl is None or impl == 'modn'):
427
from finite_field_prime_modn import FiniteField_prime_modn
428
# Using a check option here is probably a worthwhile
429
# compromise since this constructor is simple and used a
430
# huge amount.
431
K = FiniteField_prime_modn(order, check=False, **kwds)
432
else:
433
# We have to do this with block so that the finite field
434
# constructors below will use the proof flag that was
435
# passed in when checking for primality, factoring, etc.
436
# Otherwise, we would have to complicate all of their
437
# constructors with check options (like above).
438
from sage.structure.proof.all import WithProof
439
with WithProof('arithmetic', proof):
440
if check_irreducible and polynomial_element.is_Polynomial(modulus):
441
if modulus.parent().base_ring().characteristic() == 0:
442
modulus = modulus.change_ring(FiniteField(p))
443
if not modulus.is_irreducible():
444
raise ValueError("finite field modulus must be irreducible but it is not.")
445
if modulus.degree() != n:
446
raise ValueError("The degree of the modulus does not correspond to the cardinality of the field.")
447
if name is None:
448
raise TypeError("you must specify the generator name.")
449
if order < zech_log_bound:
450
# DO *NOT* use for prime subfield, since that would lead to
451
# a circular reference in the call to ParentWithGens in the
452
# __init__ method.
453
K = FiniteField_givaro(order, name, modulus, cache=elem_cache,**kwds)
454
else:
455
if order % 2 == 0 and (impl is None or impl == 'ntl'):
456
from finite_field_ntl_gf2e import FiniteField_ntl_gf2e
457
K = FiniteField_ntl_gf2e(order, name, modulus, **kwds)
458
else:
459
from finite_field_ext_pari import FiniteField_ext_pari
460
K = FiniteField_ext_pari(order, name, modulus, **kwds)
461
462
return K
463
464
def other_keys(self, key, K):
465
"""
466
EXAMPLES::
467
468
sage: key, extra = GF.create_key_and_extra_args(9, 'a'); key
469
(9, ('a',), 'conway', None, '{}', 3, 2, True)
470
sage: K = GF.create_object(0, key); K
471
Finite Field in a of size 3^2
472
sage: GF.other_keys(key, K)
473
[(9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True),
474
(9, ('a',), x^2 + 2*x + 2, 'givaro', '{}', 3, 2, True)]
475
"""
476
if len(key) == 5: # backward compat
477
order, name, modulus, impl, _ = key
478
p, n = arith.factor(order)[0]
479
proof = True
480
else:
481
order, name, modulus, impl, _, p, n, proof = key
482
483
from sage.structure.proof.all import WithProof
484
with WithProof('arithmetic', proof):
485
if K.degree() > 1:
486
modulus = K.modulus().change_variable_name('x')
487
new_keys = [(order, name, modulus, impl, _, p, n, proof)]
488
from finite_field_prime_modn import FiniteField_prime_modn
489
if isinstance(K, FiniteField_prime_modn):
490
impl = 'modn'
491
elif isinstance(K, FiniteField_givaro):
492
impl = 'givaro'
493
else:
494
from finite_field_ntl_gf2e import FiniteField_ntl_gf2e
495
from finite_field_ext_pari import FiniteField_ext_pari
496
if isinstance(K, FiniteField_ntl_gf2e):
497
impl = 'ntl'
498
elif isinstance(K, FiniteField_ext_pari):
499
impl = 'pari'
500
new_keys.append( (order, name, modulus, impl, _, p, n, proof) )
501
return new_keys
502
503
504
GF = FiniteField = FiniteFieldFactory("FiniteField")
505
506
507
def is_PrimeFiniteField(x):
508
"""
509
Returns True if x is a prime finite field.
510
511
EXAMPLES::
512
513
sage: from sage.rings.finite_rings.constructor import is_PrimeFiniteField
514
sage: is_PrimeFiniteField(QQ)
515
False
516
sage: is_PrimeFiniteField(GF(7))
517
True
518
sage: is_PrimeFiniteField(GF(7^2,'a'))
519
False
520
sage: is_PrimeFiniteField(GF(next_prime(10^90,proof=False)))
521
True
522
"""
523
from finite_field_prime_modn import FiniteField_prime_modn
524
from sage.rings.finite_rings.finite_field_base import FiniteField as FiniteField_generic
525
526
return isinstance(x, FiniteField_prime_modn) or \
527
(isinstance(x, FiniteField_generic) and x.degree() == 1)
528
529
##################################################################
530
531
def conway_polynomial(p, n):
532
r"""
533
Return the Conway polynomial of degree n over GF(p), which is
534
loaded from a table.
535
536
If the requested polynomial is not known, this function raises a
537
RuntimeError exception.
538
539
INPUT:
540
541
542
- ``p`` - int
543
544
- ``n`` - int
545
546
547
OUTPUT:
548
549
550
- ``Polynomial`` - a polynomial over the prime finite
551
field GF(p).
552
553
554
.. note::
555
556
The first time this function is called a table is read from
557
disk, which takes a fraction of a second. Subsequent calls do
558
not require reloading the table.
559
560
See also the ``ConwayPolynomials()`` object, which is a
561
table of Conway polynomials. For example, if
562
``c=ConwayPolynomials()``, then
563
``c.primes()`` is a list of all primes for which the
564
polynomials are known, and for a given prime `p`,
565
``c.degree(p)`` is a list of all degrees for which the
566
Conway polynomials are known.
567
568
EXAMPLES::
569
570
sage: conway_polynomial(2,5)
571
x^5 + x^2 + 1
572
sage: conway_polynomial(101,5)
573
x^5 + 2*x + 99
574
sage: conway_polynomial(97,101)
575
Traceback (most recent call last):
576
...
577
RuntimeError: requested conway polynomial not in database.
578
"""
579
(p,n)=(int(p),int(n))
580
R = FiniteField(p)['x']
581
try:
582
return R(sage.databases.conway.ConwayPolynomials()[p][n])
583
except KeyError:
584
raise RuntimeError("requested conway polynomial not in database.")
585
586
def exists_conway_polynomial(p, n):
587
r"""
588
Return True if the Conway polynomial over `F_p` of degree
589
`n` is in the database and False otherwise.
590
591
If the Conway polynomial is in the database, to obtain it use the
592
command ``conway_polynomial(p,n)``.
593
594
EXAMPLES::
595
596
sage: exists_conway_polynomial(2,3)
597
True
598
sage: exists_conway_polynomial(2,-1)
599
False
600
sage: exists_conway_polynomial(97,200)
601
False
602
sage: exists_conway_polynomial(6,6)
603
False
604
"""
605
return sage.databases.conway.ConwayPolynomials().has_polynomial(p,n)
606
607
608
zech_log_bound = 2**16
609
610