Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/ntl/ntl_GF2E.pyx
4097 views
1
#*****************************************************************************
2
# Copyright (C) 2005 William Stein <[email protected]>
3
# Copyright (C) 2007 Martin Albrecht <[email protected]>
4
#
5
# Distributed under the terms of the GNU General Public License (GPL)
6
#
7
# This code is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
# General Public License for more details.
11
#
12
# The full text of the GPL is available at:
13
#
14
# http://www.gnu.org/licenses/
15
#*****************************************************************************
16
17
include "../../ext/interrupt.pxi"
18
include "../../ext/stdsage.pxi"
19
include "../../ext/random.pxi"
20
include 'misc.pxi'
21
include 'decl.pxi'
22
23
from ntl_ZZ cimport ntl_ZZ
24
from ntl_GF2 cimport ntl_GF2
25
from ntl_GF2X cimport ntl_GF2X
26
from ntl_GF2EContext cimport ntl_GF2EContext_class
27
from ntl_GF2EContext import ntl_GF2EContext
28
29
from sage.libs.ntl.ntl_ZZ import unpickle_class_args
30
31
##############################################################################
32
#
33
# ntl_GF2E: GF(2**x) via NTL
34
#
35
# AUTHORS:
36
# - Martin Albrecht <[email protected]>
37
# 2006-01: initial version (based on code by William Stein)
38
# - Martin Albrecht <[email protected]>
39
# 2007-10: adapted to new conventions
40
#
41
##############################################################################
42
43
def ntl_GF2E_random(ntl_GF2EContext_class ctx):
44
"""
45
Returns a random element from GF2E modulo the current modulus.
46
47
INPUT:
48
ctx -- the GF2E context for which an random element should be created
49
50
EXAMPLES:
51
sage: ctx = ntl.GF2EContext([1,1,0,1,1,0,0,0,1])
52
sage: ntl.GF2E_random(ctx)
53
[1 0 1 0 1 0 0 1]
54
"""
55
current_randstate().set_seed_ntl(False)
56
57
cdef ntl_GF2E r
58
ctx.restore_c()
59
r = PY_NEW(ntl_GF2E)
60
r.c = ctx
61
r.x = GF2E_random()
62
return r
63
64
cdef class ntl_GF2E:
65
r"""
66
The \\class{GF2E} represents a finite extension field over GF(2)
67
using NTL. Elements are represented as polynomials over GF(2)
68
modulo a modulus.
69
70
This modulus must be set by creating a GF2EContext first and pass
71
that context to the constructor of all elements.
72
"""
73
74
def __init__(self, x=None, modulus=None):
75
"""
76
Constructs a new finite field element in GF(2**x).
77
78
If you pass a string to the constructor please note that byte
79
sequences and the hexadecimal notation are Little Endian in
80
NTL. So e.g. '[0 1]' == '0x2' == x.
81
82
INPUT:
83
x -- value to be assigned to this element. Same types as
84
ntl.GF2X() are accepted.
85
modulus -- the context/modulus of the field
86
87
OUTPUT:
88
a new ntl.GF2E element
89
90
EXAMPLES:
91
sage: k.<a> = GF(2^8)
92
sage: e = ntl.GF2E(a,k); e
93
[0 1]
94
sage: ctx = e.modulus_context()
95
sage: ntl.GF2E('0x1c', ctx)
96
[1 0 0 0 0 0 1 1]
97
sage: ntl.GF2E('[1 0 1 0]', ctx)
98
[1 0 1]
99
sage: ntl.GF2E([1,0,1,0], ctx)
100
[1 0 1]
101
sage: ntl.GF2E(ntl.GF2(1),ctx)
102
[1]
103
"""
104
if modulus is None:
105
raise ValueError, "You must specify a modulus when creating a GF2E."
106
107
cdef ntl_GF2X _x
108
109
if PY_TYPE_CHECK(x, ntl_GF2X):
110
GF2E_conv_GF2X(self.x, (<ntl_GF2X>x).x)
111
112
elif PY_TYPE_CHECK(x, int):
113
GF2E_conv_long(self.x, x)
114
115
elif PY_TYPE_CHECK(x, ntl_ZZ):
116
GF2E_conv_ZZ(self.x, (<ntl_ZZ>x).x)
117
118
elif PY_TYPE_CHECK(x, ntl_GF2):
119
GF2E_conv_GF2(self.x, (<ntl_GF2>x).x)
120
else:
121
_x = ntl_GF2X(x)
122
GF2E_conv_GF2X(self.x, _x.x)
123
124
def __cinit__(self, x=None, modulus=None):
125
#################### WARNING ###################
126
## Before creating a GF2E, you must create a ##
127
## GF2EContext, and restore it. In Python, ##
128
## the error checking in __init__ will prevent##
129
## you from constructing an ntl_GF2E ##
130
## inappropriately. However, from Cython, you##
131
## could do r = PY_NEW(ntl_GF2E) without ##
132
## first restoring a GF2EContext, which could ##
133
## have unfortunate consequences. See _new ##
134
## defined below for an example of the right ##
135
## way to short-circuit __init__ (or just call##
136
## _new in your own code). ##
137
################################################
138
if modulus is None:
139
return
140
if PY_TYPE_CHECK( modulus, ntl_GF2EContext_class ):
141
self.c = <ntl_GF2EContext_class>modulus
142
self.c.restore_c()
143
GF2E_construct(&self.x)
144
else:
145
self.c = <ntl_GF2EContext_class>ntl_GF2EContext(modulus)
146
self.c.restore_c()
147
GF2E_construct(&self.x)
148
149
def __dealloc__(self):
150
GF2E_destruct(&self.x)
151
152
cdef ntl_GF2E _new(self):
153
cdef ntl_GF2E r
154
self.c.restore_c()
155
r = PY_NEW(ntl_GF2E)
156
r.c = self.c
157
return r
158
159
def __reduce__(self):
160
"""
161
sage: ctx = ntl.GF2EContext( ntl.GF2X([1,1,0,1,1,0,0,0,1]) )
162
sage: a = ntl.GF2E(ntl.ZZ_pX([1,1,3],2), ctx)
163
sage: loads(dumps(a)) == a
164
True
165
"""
166
return unpickle_class_args, (ntl_GF2E, (str(self), self.modulus_context()))
167
168
def modulus_context(self):
169
"""
170
Returns the structure that holds the underlying NTL GF2E modulus.
171
172
EXAMPLES:
173
sage: ctx = ntl.GF2EContext( ntl.GF2X([1,1,0,1,1,0,0,0,1]) )
174
sage: a = ntl.GF2E(ntl.ZZ_pX([1,1,3],2), ctx)
175
sage: cty = a.modulus_context(); cty
176
NTL modulus [1 1 0 1 1 0 0 0 1]
177
sage: ctx == cty
178
True
179
"""
180
return self.c
181
182
def __repr__(self):
183
"""
184
Return the string representation of self.
185
186
EXAMPLES:
187
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
188
sage: ntl.GF2E([1,1,0,1], ctx) # indirect doctest
189
[1 1 0 1]
190
"""
191
self.c.restore_c()
192
return GF2E_to_PyString(&self.x)
193
194
def __copy__(self):
195
"""
196
Return a copy of self.
197
198
EXAMPLES:
199
sage: x = ntl.GF2E([0,1,1],GF(2^4,'a'))
200
sage: y = copy(x)
201
sage: x == y
202
True
203
sage: x is y
204
False
205
"""
206
cdef ntl_GF2E r = self._new()
207
r.x = self.x
208
return r
209
210
def __mul__(ntl_GF2E self, other):
211
"""
212
EXAMPLES:
213
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
214
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1], ctx)
215
sage: x*y ## indirect doctest
216
[0 0 1 1 1 0 1 1]
217
"""
218
cdef ntl_GF2E r
219
if not PY_TYPE_CHECK(other, ntl_GF2E):
220
other = ntl_GF2E(other,self.c)
221
elif self.c is not (<ntl_GF2E>other).c:
222
raise ValueError, "You can not perform arithmetic with elements in different fields."
223
r = self._new()
224
GF2E_mul(r.x, self.x, (<ntl_GF2E>other).x)
225
return r
226
227
def __sub__(ntl_GF2E self, other):
228
"""
229
EXAMPLES:
230
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
231
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1], ctx)
232
sage: x - y ## indirect doctest
233
[0 1 1 1]
234
"""
235
cdef ntl_GF2E r
236
if not PY_TYPE_CHECK(other, ntl_GF2E):
237
other = ntl_GF2E(other,self.c)
238
elif self.c is not (<ntl_GF2E>other).c:
239
raise ValueError, "You can not perform arithmetic with elements in different fields."
240
r = self._new()
241
GF2E_sub(r.x, self.x, (<ntl_GF2E>other).x)
242
return r
243
244
def __add__(ntl_GF2E self, other):
245
"""
246
EXAMPLES:
247
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
248
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1], ctx)
249
sage: x+y ## indirect doctest
250
[0 1 1 1]
251
"""
252
cdef ntl_GF2E r
253
if not PY_TYPE_CHECK(other, ntl_GF2E):
254
other = ntl_GF2E(other,self.c)
255
elif self.c is not (<ntl_GF2E>other).c:
256
raise ValueError, "You can not perform arithmetic with elements in different fields."
257
r = self._new()
258
GF2E_add(r.x, self.x, (<ntl_GF2E>other).x)
259
return r
260
261
def __div__(ntl_GF2E self, other):
262
"""
263
EXAMPLES:
264
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
265
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1], ctx)
266
sage: x/y ## indirect doctest
267
[1 0 1 0 0 1 0 1]
268
"""
269
cdef ntl_GF2E r
270
if not PY_TYPE_CHECK(other, ntl_GF2E):
271
other = ntl_GF2E(other,self.c)
272
elif self.c is not (<ntl_GF2E>other).c:
273
raise ValueError, "You can not perform arithmetic with elements in different fields."
274
r = self._new()
275
GF2E_div(r.x, self.x, (<ntl_GF2E>other).x)
276
return r
277
278
def __neg__(ntl_GF2E self):
279
"""
280
EXAMPLES:
281
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
282
sage: x = ntl.GF2E([1,0,1,0,1], ctx)
283
sage: -x ## indirect doctest
284
[1 0 1 0 1]
285
"""
286
cdef ntl_GF2E r = self._new()
287
r.x = self.x
288
return r
289
290
def __pow__(ntl_GF2E self, long e, ignored):
291
"""
292
EXAMPLES:
293
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
294
sage: x = ntl.GF2E([1,0,1,0,1], ctx)
295
sage: x**2 ## indirect doctest
296
[0 1 0 1]
297
"""
298
cdef ntl_GF2E r = self._new()
299
GF2E_power(r.x, self.x, e)
300
return r
301
302
def __richcmp__(ntl_GF2E self, other, op):
303
r"""
304
EXAMPLES:
305
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
306
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1], ctx)
307
sage: x == x
308
True
309
sage: x == y
310
False
311
sage: ntl.GF2E(0,ctx) == 0
312
True
313
sage: a = ntl.GF2E([0,1],GF(2^2,'a'))
314
sage: a == x
315
False
316
"""
317
self.c.restore_c()
318
319
if not PY_TYPE_CHECK(other, ntl_GF2E):
320
other = ntl_GF2E(other,self.c)
321
322
if op != 2 and op != 3:
323
raise TypeError, "Elements in GF2E are not ordered."
324
325
cdef int t
326
t = GF2E_equal(self.x, (<ntl_GF2E>other).x)
327
if op == 2:
328
return t == 1
329
elif op == 3:
330
return t == 0
331
332
def IsZero(ntl_GF2E self):
333
"""
334
Returns True if this element equals zero, False otherwise.
335
336
EXAMPLES:
337
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
338
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([1,1,0,1,1,0,0,0,1], ctx)
339
sage: x.IsZero()
340
False
341
sage: y.IsZero()
342
True
343
"""
344
return bool(GF2E_IsZero(self.x))
345
346
def IsOne(ntl_GF2E self):
347
"""
348
Returns True if this element equals one, False otherwise.
349
350
EXAMPLES:
351
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
352
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([0,1,0,1,1,0,0,0,1], ctx)
353
sage: x.IsOne()
354
False
355
sage: y.IsOne()
356
True
357
"""
358
return bool(GF2E_IsOne(self.x))
359
360
def trace(ntl_GF2E self):
361
"""
362
Returns the trace of this element.
363
364
EXAMPLES:
365
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
366
sage: x = ntl.GF2E([1,0,1,0,1], ctx) ; y = ntl.GF2E([0,1,1,0,1,1], ctx)
367
sage: x.trace()
368
0
369
sage: y.trace()
370
1
371
"""
372
cdef ntl_GF2 x = PY_NEW(ntl_GF2)
373
x.x = GF2E_trace(self.x)
374
return x
375
376
def rep(ntl_GF2E self):
377
"""
378
Returns a ntl.GF2X copy of this element.
379
380
EXAMPLE:
381
sage: ctx = ntl.GF2EContext(ntl.GF2X([1,1,0,1,1,0,0,0,1]))
382
sage: a = ntl.GF2E('0x1c', ctx)
383
sage: a.rep()
384
[1 0 0 0 0 0 1 1]
385
sage: type(a.rep())
386
<type 'sage.libs.ntl.ntl_GF2X.ntl_GF2X'>
387
"""
388
cdef ntl_GF2X x = PY_NEW(ntl_GF2X)
389
x.x = GF2E_rep(self.x)
390
return x
391
392
def list(ntl_GF2E self):
393
"""
394
Represents this element as a list of binary digits.
395
396
EXAMPLES:
397
sage: e=ntl.GF2E([0,1,1],GF(2^4,'a'))
398
sage: e.list()
399
[0, 1, 1]
400
sage: e=ntl.GF2E('0xff',GF(2^8,'a'))
401
sage: e.list()
402
[1, 1, 1, 1, 1, 1, 1, 1]
403
404
OUTPUT:
405
a list of digits representing the coefficients in this element's
406
polynomial representation
407
"""
408
cdef int i
409
cdef GF2X_c x = GF2E_rep(self.x)
410
cdef ntl_GF2 b
411
412
l = []
413
414
for i from 0 <= i <= GF2X_deg(x):
415
b = PY_NEW(ntl_GF2)
416
b.x = GF2X_coeff(x,i)
417
l.append(b)
418
return l
419
420
def _sage_(ntl_GF2E self, k=None):
421
"""
422
Returns a \class{FiniteFieldElement} representation
423
of this element. If a \class{FiniteField} k is provided
424
it is constructed in this field if possible. A \class{FiniteField}
425
will be constructed if none is provided.
426
427
INPUT:
428
k -- optional GF(2**deg)
429
430
OUTPUT:
431
FiniteFieldElement over k
432
433
EXAMPLE:
434
sage: ctx = ntl.GF2EContext([1,1,0,1,1,0,0,0,1])
435
sage: e = ntl.GF2E([0,1], ctx)
436
sage: a = e._sage_(); a
437
a
438
"""
439
cdef int i
440
cdef int length
441
442
self.c.restore_c()
443
444
e = GF2E_degree()
445
446
if k is None:
447
from sage.rings.finite_rings.constructor import FiniteField
448
f = self.c.m._sage_()
449
k = FiniteField(2**e, name='a', modulus=f)
450
451
a=k.gen()
452
l = self.list()
453
454
length = len(l)
455
ret = 0
456
457
for i from 0 <= i < length:
458
if l[i]==1:
459
ret = ret + a**i
460
461
return ret
462
463