@@ -76,10 +76,11 @@ cdef class fq_default_ctx:
76
76
77
77
return var
78
78
79
- def __init__ (self , p = None , degree = None , var = None , modulus = None , fq_type = fq_default_type.DEFAULT):
79
+ def __init__ (self , p = None , degree = None , var = None , modulus = None , fq_type = fq_default_type.DEFAULT,
80
+ check_prime = True , check_modulus = True ):
80
81
# Ensure the var used for the generator of GF(p^d) is a single byte
81
- # TODO: this var is meaningless for GF(p) -- we could handle this somehow?
82
82
var = self ._parse_input_var(var)
83
+ self .var = var
83
84
84
85
# Ensure the fq_type is an integer between 0, 5 -- we allow users to
85
86
# input a string which is converted as an enum
@@ -89,16 +90,17 @@ cdef class fq_default_ctx:
89
90
if modulus is not None :
90
91
# If the polynomial has no known characteristic, we can try and create one
91
92
# using the supplied prime
92
- if not ( typecheck(modulus, fmpz_mod_poly) or typecheck(modulus, nmod_poly) ):
93
+ if not typecheck(modulus, fmpz_mod_poly):
93
94
if p is None :
94
95
raise ValueError (" cannot create from modulus if no characteristic is known" )
95
-
96
96
ring_ctx = fmpz_mod_poly_ctx(p)
97
+ if not ring_ctx.is_prime():
98
+ raise ValueError (" characteristic is not prime" )
97
99
modulus = ring_ctx.any_as_fmpz_mod_poly(modulus)
98
100
if modulus is NotImplemented :
99
101
raise TypeError (" modulus cannot be cast to fmpz_mod_poly" )
100
102
101
- self ._set_from_modulus(modulus, var, fq_type)
103
+ self ._set_from_modulus(modulus, var, fq_type, check_prime = check_prime, check_modulus = check_modulus )
102
104
return
103
105
104
106
# If there's no modulus and no prime, we can't continue
@@ -110,23 +112,16 @@ cdef class fq_default_ctx:
110
112
degree = 1
111
113
112
114
# Construct the field from the prime and degree GF(p^d)
113
- self ._set_from_order(p, degree, var, fq_type)
115
+ self ._set_from_order(p, degree, var, fq_type, check_prime = check_prime )
114
116
115
- cdef _c_set_from_order(self , fmpz p, int d, char * var,
116
- fq_default_type fq_type = fq_default_type.DEFAULT):
117
- self .var = var
118
- fq_default_ctx_init_type(self .val, p.val, d, self .var, fq_type)
119
- self ._initialized = True
120
-
121
- cdef _set_from_order(self , p, d, var,
122
- fq_type = fq_default_type.DEFAULT, check_prime = True ):
117
+ cdef _set_from_order(self , p, d, var, fq_type = fq_default_type.DEFAULT, check_prime = True ):
123
118
"""
124
119
Construct a context for the finite field GF(p^d).
125
120
126
121
`var` is a name for the ring generator of this field over GF(p).
127
122
128
123
The optional parameter `type` select the implementation. For more
129
- information about the types available, see :class:`~.fq_default_type`
124
+ information about the types available, see :class:`~.fq_default_type`
130
125
for possible types.
131
126
"""
132
127
# c_from_order expects the characteristic to be fmpz type
@@ -141,24 +136,11 @@ cdef class fq_default_ctx:
141
136
if d < 1 :
142
137
raise ValueError (f" the degree must be positive, got {d = }" )
143
138
144
- # Cython type conversion and context initalisation
145
- self ._c_set_from_order(prime, d, var, fq_type)
146
-
147
- cdef _c_set_from_modulus(self , modulus, char * var,
148
- fq_default_type fq_type = fq_default_type.DEFAULT):
149
- self .var = var
150
- if typecheck(modulus, fmpz_mod_poly):
151
- fq_default_ctx_init_modulus_type(self .val, (< fmpz_mod_poly> modulus).val,
152
- (< fmpz_mod_poly> modulus).ctx.mod.val, self .var, fq_type)
153
- elif typecheck(modulus, nmod_poly):
154
- fq_default_ctx_init_modulus_nmod_type(self .val, (< nmod_poly> modulus).val,
155
- self .var, fq_type)
156
- else :
157
- raise TypeError (f" modulus must be fmpz_mod_poly or nmod_poly, got {modulus!r}" )
139
+ fq_default_ctx_init_type(self .val, (< fmpz> prime).val, d, self .var, < fq_default_type> fq_type)
158
140
self ._initialized = True
159
141
160
- cdef _set_from_modulus(self , modulus, var,
161
- fq_type = fq_default_type.DEFAULT , check_modulus = True ):
142
+ cdef _set_from_modulus(self , modulus, var, fq_type = fq_default_type.DEFAULT,
143
+ check_prime = True , check_modulus = True ):
162
144
"""
163
145
Construct a context for a finite field from an irreducible polynomial.
164
146
@@ -167,14 +149,18 @@ cdef class fq_default_ctx:
167
149
`var` is a name for the ring generator of this field over the prime field.
168
150
169
151
The optional parameter `type` select the implementation. For more
170
- information about the types available, see :class:`~.fq_default_type`
152
+ information about the types available, see :class:`~.fq_default_type`
171
153
for possible types.
172
154
"""
155
+ if check_prime and not (< fmpz_mod_poly> modulus).ctx.is_prime():
156
+ raise ValueError (" characteristic is not prime" )
157
+
173
158
if check_modulus and not modulus.is_irreducible():
174
159
raise ValueError (" modulus must be irreducible" )
175
160
176
- # Cython type conversion and context initalisation
177
- self ._c_set_from_modulus(modulus, var, fq_type)
161
+ fq_default_ctx_init_modulus_type(self .val, (< fmpz_mod_poly> modulus).val,
162
+ (< fmpz_mod_poly> modulus).ctx.mod.val, self .var, < fq_default_type> fq_type)
163
+ self ._initialized = True
178
164
179
165
@property
180
166
def fq_type (self ):
@@ -517,9 +503,6 @@ cdef class fq_default(flint_scalar):
517
503
def str (self ):
518
504
return self .polynomial().str(var = self .ctx.var.decode())
519
505
520
- def repr (self ):
521
- return f" fq_default({self.to_list(), self.ctx.__repr__()})"
522
-
523
506
def __hash__ (self ):
524
507
return hash ((self .polynomial(), hash (self .ctx)))
525
508
@@ -741,11 +724,8 @@ cdef class fq_default(flint_scalar):
741
724
fq_default_pow_ui(res.val, res.val, < ulong> e, self .ctx.val)
742
725
return res
743
726
744
- # Attempt to cast the exponent to an fmpz type then exponentiate
727
+ # Cast the exponent to fmpz type
745
728
e_fmpz = any_as_fmpz(e)
746
- if e_fmpz is NotImplemented :
747
- raise TypeError (f" exponent {e = } cannot be cast to fmpz" )
748
-
749
729
fq_default_pow(res.val, res.val, (< fmpz> e_fmpz).val, self .ctx.val)
750
730
751
731
return res
0 commit comments