This file is indexed.

/usr/share/axiom-20170501/src/algebra/FFIELDC.spad is in axiom-source 20170501-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
)abbrev category FFIELDC FiniteFieldCategory
++ Author: J. Grabmeier, A. Scheerhorn
++ Date Created: 11 March 1991
++ Date Last Updated: 31 March 1991
++ References:
++ Grab92 Finite Fields in AXIOM.
++ Lips81 Elements of Algebra and Algebraic Computing
++ Description:
++ FiniteFieldCategory is the category of finite fields

FiniteFieldCategory() : Category == SIG where

  FOPC ==> FieldOfPrimeCharacteristic
  F    ==> Finite
  ST   ==> StepThrough
  DR   ==> DifferentialRing

  SIG ==> Join(FOPC,F,ST,DR) with

    charthRoot : $ -> $
      ++ charthRoot(a) takes the characteristic'th root of a.
      ++ Note that such a root is alway defined in finite fields.

    conditionP : Matrix $ -> Union(Vector $,"failed")
      ++ conditionP(mat), given a matrix representing a homogeneous system
      ++ of equations, returns a vector whose characteristic'th powers
      ++ is a non-trivial solution, or "failed" if no such vector exists.

    -- the reason for implementing the following function is that we
    -- can implement the functions order, getGenerator and primitive? on
    -- category level without computing the, may be time intensive,
    -- factorization of size()-1 at every function call again.

    factorsOfCyclicGroupSize :_
      () -> List Record(factor:Integer,exponent:Integer)
      ++ factorsOfCyclicGroupSize() returns the factorization of size()-1

    -- the reason for implementing the function tableForDiscreteLogarithm
    -- is that we can implement the functions discreteLog and
    -- shanksDiscLogAlgorithm on category level
    -- computing the necessary exponentiation tables in the respective
    -- domains once and for all
    -- absoluteDegree : $ -> PositiveInteger
    --  ++ degree of minimal polynomial, if algebraic with respect
    --  ++ to the prime subfield

    tableForDiscreteLogarithm : Integer -> _
             Table(PositiveInteger,NonNegativeInteger)
      ++ tableForDiscreteLogarithm(a,n) returns a table of the discrete
      ++ logarithms of \spad{a**0} up to \spad{a**(n-1)} which, called with
      ++ key \spad{lookup(a**i)} returns i for i in \spad{0..n-1}.
      ++ Error: if not called for prime divisors of order of
      ++        multiplicative group.

    createPrimitiveElement : () -> $
      ++ createPrimitiveElement() computes a generator of the (cyclic)
      ++ multiplicative group of the field.
      -- RDJ: Are these next lines to be included?
      -- we run through the field and test, algorithms which construct
      -- elements of larger order were found to be too slow

    primitiveElement : () -> $
      ++ primitiveElement() returns a primitive element stored in a global
      ++ variable in the domain.
      ++ At first call, the primitive element is computed
      ++ by calling \spadfun{createPrimitiveElement}.

    primitive? : $ -> Boolean
      ++ primitive?(b) tests whether the element b is a generator of the
      ++ (cyclic) multiplicative group of the field, is a primitive
      ++ element.
      ++ Implementation Note that see ch.IX.1.3, th.2 in D. Lipson.

    discreteLog : $ -> NonNegativeInteger
      ++ discreteLog(a) computes the discrete logarithm of \spad{a}
      ++ with respect to \spad{primitiveElement()} of the field.

    order : $ -> PositiveInteger
      ++ order(b) computes the order of an element b in the multiplicative
      ++ group of the field.
      ++ Error: if b equals 0.

    representationType : () -> Union("prime","polynomial","normal","cyclic")
      ++ representationType() returns the type of the representation, one of:
      ++ \spad{prime}, \spad{polynomial}, \spad{normal}, or \spad{cyclic}.

   add

     I   ==> Integer
     PI  ==> PositiveInteger
     NNI ==> NonNegativeInteger
     SUP ==> SparseUnivariatePolynomial
     DLP ==> DiscreteLogarithmPackage
 
     -- exported functions
 
     differentiate x == 0

     init() == 0
 
     nextItem(a) ==
       zero?(a:=index(lookup(a)+1)) => "failed"
       a
 
     order(e):OnePointCompletion(PositiveInteger) ==
       (order(e)@PI)::OnePointCompletion(PositiveInteger)
 
     conditionP(mat:Matrix $) ==
       l:=nullSpace mat
       empty? l or every?(zero?, first l) => "failed"
       map(charthRoot,first l)
 
     charthRoot(x:$):$ == x**(size() quo characteristic())
 
     charthRoot(x:%):Union($,"failed") ==
         (charthRoot(x)@$)::Union($,"failed")
 
     createPrimitiveElement() ==
       sm1  : PositiveInteger := (size()$$-1) pretend PositiveInteger
       start : Integer :=
         -- in the polynomial case, index from 1 to characteristic-1
         -- gives prime field elements
         representationType = "polynomial" => characteristic()::Integer
         1
       found : Boolean := false
       for i in start..  while not found repeat
         e : $ := index(i::PositiveInteger)
         found := (order(e) = sm1)
       e
 
     primitive? a ==
       -- add special implementation for prime field case
       zero?(a) => false
       explist := factorsOfCyclicGroupSize()
       q:=(size()-1)@Integer
       equalone : Boolean := false
       for exp in explist while not equalone repeat
         equalone := ((a**(q quo exp.factor)) = 1)
       not equalone
 
     order e ==
       e = 0 => error "order(0) is not defined "
       ord:Integer:= size()-1 -- order e divides ord
       a:Integer:= 0
       lof:=factorsOfCyclicGroupSize()
       for rec in lof repeat -- run through prime divisors
         a := ord quo (primeDivisor := rec.factor)
         goon := ((e**a) = 1)
         -- run through exponents of the prime divisors
         for j in 0..(rec.exponent)-2 while goon repeat
           -- as long as we get (e**ord = 1) we
           -- continue dividing by primeDivisor
           ord := a
           a := ord quo primeDivisor
           goon := ((e**a) = 1)
         if goon then ord := a
         -- as we do a top down search we have found the
         -- correct exponent of primeDivisor in order e
         -- and continue with next prime divisor
       ord pretend PositiveInteger
 
     discreteLog(b) ==
       zero?(b) => error "discreteLog: logarithm of zero"
       faclist:=factorsOfCyclicGroupSize()
       a:=b
       gen:=primitiveElement()
       -- in GF(2) its necessary to have discreteLog(1) = 1
       b = gen => 1
       disclog:Integer:=0
       mult:Integer:=1
       groupord := (size() - 1)@Integer
       exp:Integer:=groupord
       for f in faclist repeat
         fac:=f.factor
         for t in 0..f.exponent-1 repeat
           exp:=exp quo fac
           -- shanks discrete logarithm algorithm
           exptable:=tableForDiscreteLogarithm(fac)
           n:=#exptable
           c:=a**exp
           end:=(fac - 1) quo n
           found:=false
           disc1:Integer:=0
           for i in 0..end while not found repeat
             rho:= search(lookup(c),exptable)_
                   $Table(PositiveInteger,NNI)
             rho case NNI =>
               found := true
               disc1:=((n * i + rho)@Integer) * mult
             c:=c* gen**((groupord quo fac) * (-n))
           not found => error "discreteLog: ?? discrete logarithm"
           -- end of shanks discrete logarithm algorithm
           mult := mult * fac
           disclog:=disclog+disc1
           a:=a * (gen ** (-disc1))
       disclog pretend NonNegativeInteger
 
     discreteLog(logbase,b) ==
       zero?(b) =>
         messagePrint("discreteLog: logarithm of zero")$OutputForm
         "failed"
       zero?(logbase) =>
         messagePrint("discreteLog: logarithm to base zero")$OutputForm
         "failed"
       b = logbase => 1
       not zero?((groupord:=order(logbase)@PI) rem order(b)@PI) =>
          messagePrint("discreteLog: second argument not in cyclic group_
  generated by first argument")$OutputForm
          "failed"
       faclist:=factors factor groupord
       a:=b
       disclog:Integer:=0
       mult:Integer:=1
       exp:Integer:= groupord
       for f in faclist repeat
         fac:=f.factor
         primroot:= logbase ** (groupord quo fac)
         for t in 0..f.exponent-1 repeat
           exp:=exp quo fac
           rhoHelp:= shanksDiscLogAlgorithm(primroot,_
                 a**exp,fac pretend NonNegativeInteger)$DLP($)
           rhoHelp case "failed" => return "failed"
           rho := (rhoHelp :: NNI) * mult
           disclog := disclog + rho
           mult := mult * fac
           a:=a * (logbase ** (-rho))
       disclog pretend NonNegativeInteger
 
     FP ==> SparseUnivariatePolynomial($)
     FRP ==> Factored FP
     f,g:FP
 
 -- TPDHERE: why is this here? It isn't exported.
     squareFreePolynomial(f:FP):FRP ==
           squareFree(f)$UnivariatePolynomialSquareFree($,FP)
 
 -- TPDHERE: why is this here? It isn't exported.
     factorPolynomial(f:FP):FRP == factor(f)$DistinctDegreeFactorize($,FP)
 
 -- TPDHERE: why is this here? It isn't exported.
     factorSquareFreePolynomial(f:FP):FRP ==
         f = 0 => 0
         flist := distdfact(f,true)$DistinctDegreeFactorize($,FP)
         (flist.cont :: FP) *
             (*/[primeFactor(u.irr,u.pow) for u in flist.factors])
 
     gcdPolynomial(f:FP,g:FP):FP ==
          gcd(f,g)$EuclideanDomain_&(FP)