@@ -76,10 +76,11 @@ cdef class fq_default_ctx:
7676
7777 return var
7878
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 ):
8081 # 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?
8282 var = self ._parse_input_var(var)
83+ self .var = var
8384
8485 # Ensure the fq_type is an integer between 0, 5 -- we allow users to
8586 # input a string which is converted as an enum
@@ -89,16 +90,17 @@ cdef class fq_default_ctx:
8990 if modulus is not None :
9091 # If the polynomial has no known characteristic, we can try and create one
9192 # 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):
9394 if p is None :
9495 raise ValueError (" cannot create from modulus if no characteristic is known" )
95-
9696 ring_ctx = fmpz_mod_poly_ctx(p)
97+ if not ring_ctx.is_prime():
98+ raise ValueError (" characteristic is not prime" )
9799 modulus = ring_ctx.any_as_fmpz_mod_poly(modulus)
98100 if modulus is NotImplemented :
99101 raise TypeError (" modulus cannot be cast to fmpz_mod_poly" )
100102
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 )
102104 return
103105
104106 # If there's no modulus and no prime, we can't continue
@@ -110,23 +112,16 @@ cdef class fq_default_ctx:
110112 degree = 1
111113
112114 # 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 )
114116
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 ):
123118 """
124119 Construct a context for the finite field GF(p^d).
125120
126121 `var` is a name for the ring generator of this field over GF(p).
127122
128123 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`
130125 for possible types.
131126 """
132127 # c_from_order expects the characteristic to be fmpz type
@@ -141,24 +136,11 @@ cdef class fq_default_ctx:
141136 if d < 1 :
142137 raise ValueError (f" the degree must be positive, got {d = }" )
143138
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)
158140 self ._initialized = True
159141
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 ):
162144 """
163145 Construct a context for a finite field from an irreducible polynomial.
164146
@@ -167,14 +149,18 @@ cdef class fq_default_ctx:
167149 `var` is a name for the ring generator of this field over the prime field.
168150
169151 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`
171153 for possible types.
172154 """
155+ if check_prime and not (< fmpz_mod_poly> modulus).ctx.is_prime():
156+ raise ValueError (" characteristic is not prime" )
157+
173158 if check_modulus and not modulus.is_irreducible():
174159 raise ValueError (" modulus must be irreducible" )
175160
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
178164
179165 @property
180166 def fq_type (self ):
@@ -517,9 +503,6 @@ cdef class fq_default(flint_scalar):
517503 def str (self ):
518504 return self .polynomial().str(var = self .ctx.var.decode())
519505
520- def repr (self ):
521- return f" fq_default({self.to_list(), self.ctx.__repr__()})"
522-
523506 def __hash__ (self ):
524507 return hash ((self .polynomial(), hash (self .ctx)))
525508
@@ -741,11 +724,8 @@ cdef class fq_default(flint_scalar):
741724 fq_default_pow_ui(res.val, res.val, < ulong> e, self .ctx.val)
742725 return res
743726
744- # Attempt to cast the exponent to an fmpz type then exponentiate
727+ # Cast the exponent to fmpz type
745728 e_fmpz = any_as_fmpz(e)
746- if e_fmpz is NotImplemented :
747- raise TypeError (f" exponent {e = } cannot be cast to fmpz" )
748-
749729 fq_default_pow(res.val, res.val, (< fmpz> e_fmpz).val, self .ctx.val)
750730
751731 return res
0 commit comments