00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __GALOIS_H__
00021 #define __GALOIS_H__
00022
00023 template unsigned int bits, const unsigned int generator, typename valuetype> class GaloisTable;
00024 template unsigned int bits, const unsigned int generator, typename valuetype> class Galois;
00025
00026 template class g> class GaloisLongMultiplyTable;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 template unsigned int bits, const unsigned int generator, typename valuetype>
00037 class GaloisTable
00038 {
00039 public:
00040 typedef valuetype ValueType;
00041
00042 GaloisTable(void);
00043
00044 enum
00045 {
00046 Bits = bits,
00047 Count = 100048 Limit = Count-1,
00049 Generator = generator,
00050 };
00051
00052 ValueType log[Count];
00053 ValueType antilog[Count];
00054 };
00055
00056 template unsigned int bits, const unsigned int generator, typename valuetype>
00057 class Galois
00058 {
00059 public:
00060 typedef valuetype ValueType;
00061
00062
00063 Galois(void) {};
00064 Galois(ValueType v);
00065
00066
00067 Galois(const Galois &right) {value = right.value;}
00068 Galois& operator = (const Galois &right) { value = right.value; return *this;}
00069
00070
00071 Galois operator + (const Galois &right) const { return (value ^ right.value); }
00072 Galois& operator += (const Galois &right) { value ^= right.value; return *this;}
00073
00074
00075 Galois operator - (const Galois &right) const { return (value ^ right.value); }
00076 Galois& operator -= (const Galois &right) { value ^= right.value; return *this;}
00077
00078
00079 Galois operator * (const Galois &right) const;
00080 Galois& operator *= (const Galois &right);
00081
00082
00083 Galois operator / (const Galois &right) const;
00084 Galois& operator /= (const Galois &right);
00085
00086
00087 Galois pow(unsigned int right) const;
00088 Galois operator ^ (unsigned int right) const;
00089 Galois& operator ^= (unsigned int right);
00090
00091
00092 operator ValueType(void) const {return value;}
00093 ValueType Value(void) const {return value;}
00094
00095
00096 ValueType Log(void) const;
00097 ValueType ALog(void) const;
00098
00099 enum
00100 {
00101 Bits = GaloisTable::Bits,
00102 Count = GaloisTable::Count,
00103 Limit = GaloisTable::Limit,
00104 };
00105
00106 protected:
00107 ValueType value;
00108
00109 static GaloisTable table;
00110 };
00111
00112 #ifdef LONGMULTIPLY
00113 template class g>
00114 class GaloisLongMultiplyTable
00115 {
00116 public:
00117 GaloisLongMultiplyTable(void);
00118
00119 typedef g G;
00120
00121 enum
00122 {
00123 Bytes = ((G::Bits + 7) >> 3),
00124 Count = ((Bytes * (Bytes+1)) / 2),
00125 };
00126
00127 G tables[Count * 256 * 256];
00128 };
00129 #endif
00130
00131
00132
00133 template unsigned int bits, const unsigned int generator, typename valuetype>
00134 inline GaloisTable::GaloisTable(void)
00135 {
00136 u32 b = 1;
00137
00138 for (u32 l=0; l00139 {
00140 log[b] = (ValueType)l;
00141 antilog[l] = (ValueType)b;
00142
00143 b 00144 if (b & Count) b ^= Generator;
00145 }
00146
00147 log[0] = (ValueType)Limit;
00148 antilog[Limit] = 0;
00149 }
00150
00151
00152
00153
00154 template unsigned int bits, const unsigned int generator, typename valuetype>
00155 GaloisTable Galois::table;
00156
00157
00158 template unsigned int bits, const unsigned int generator, typename valuetype>
00159 inline Galois::Galois(typename Galois::ValueType v)
00160 {
00161 value = v;
00162 }
00163
00164 template unsigned int bits, const unsigned int generator, typename valuetype>
00165 inline Galois Galois::operator * (const Galois &right) const
00166 {
00167 if (value == 0 || right.value == 0) return 0;
00168 unsigned int sum = table.log[value] + table.log[right.value];
00169 if (sum >= Limit)
00170 {
00171 return table.antilog[sum-Limit];
00172 }
00173 else
00174 {
00175 return table.antilog[sum];
00176 }
00177 }
00178
00179 template unsigned int bits, const unsigned int generator, typename valuetype>
00180 inline Galois& Galois::operator *= (const Galois &right)
00181 {
00182 if (value == 0 || right.value == 0)
00183 {
00184 value = 0;
00185 }
00186 else
00187 {
00188 unsigned int sum = table.log[value] + table.log[right.value];
00189 if (sum >= Limit)
00190 {
00191 value = table.antilog[sum-Limit];
00192 }
00193 else
00194 {
00195 value = table.antilog[sum];
00196 }
00197 }
00198
00199 return *this;
00200 }
00201
00202 template unsigned int bits, const unsigned int generator, typename valuetype>
00203 inline Galois Galois::operator / (const Galois &right) const
00204 {
00205 if (value == 0) return 0;
00206
00207 assert(right.value != 0);
00208 if (right.value == 0) {return 0;}
00209
00210 int sum = table.log[value] - table.log[right.value];
00211 if (sum 00212 {
00213 return table.antilog[sum+Limit];
00214 }
00215 else
00216 {
00217 return table.antilog[sum];
00218 }
00219 }
00220
00221 template unsigned int bits, const unsigned int generator, typename valuetype>
00222 inline Galois& Galois::operator /= (const Galois &right)
00223 {
00224 if (value == 0) return *this;
00225
00226 assert(right.value != 0);
00227 if (right.value == 0) {return *this;}
00228
00229 int sum = table.log[value] - table.log[right.value];
00230 if (sum 00231 {
00232 value = table.antilog[sum+Limit];
00233 }
00234 else
00235 {
00236 value = table.antilog[sum];
00237 }
00238
00239 return *this;
00240 }
00241
00242 template unsigned int bits, const unsigned int generator, typename valuetype>
00243 inline Galois Galois::pow(unsigned int right) const
00244 {
00245 if (right == 0) return 1;
00246 if (value == 0) return 0;
00247
00248 unsigned int sum = table.log[value] * right;
00249
00250 sum = (sum >> Bits) + (sum & Limit);
00251 if (sum >= Limit)
00252 {
00253 return table.antilog[sum-Limit];
00254 }
00255 else
00256 {
00257 return table.antilog[sum];
00258 }
00259 }
00260
00261 template unsigned int bits, const unsigned int generator, typename valuetype>
00262 inline Galois Galois::operator ^ (unsigned int right) const
00263 {
00264 if (right == 0) return 1;
00265 if (value == 0) return 0;
00266
00267 unsigned int sum = table.log[value] * right;
00268
00269 sum = (sum >> Bits) + (sum & Limit);
00270 if (sum >= Limit)
00271 {
00272 return table.antilog[sum-Limit];
00273 }
00274 else
00275 {
00276 return table.antilog[sum];
00277 }
00278 }
00279
00280 template unsigned int bits, const unsigned int generator, typename valuetype>
00281 inline Galois& Galois::operator ^= (unsigned int right)
00282 {
00283 if (right == 1) {value = 1; return *this;}
00284 if (value == 0) return *this;
00285
00286 unsigned int sum = table.log[value] * right;
00287
00288 sum = (sum >> Bits) + (sum & Limit);
00289 if (sum >= Limit)
00290 {
00291 value = table.antilog[sum-Limit];
00292 }
00293 else
00294 {
00295 value = table.antilog[sum];
00296 }
00297
00298 return *this;
00299 }
00300
00301 template unsigned int bits, const unsigned int generator, typename valuetype>
00302 inline valuetype Galois::Log(void) const
00303 {
00304 return table.log[value];
00305 }
00306
00307 template unsigned int bits, const unsigned int generator, typename valuetype>
00308 inline valuetype Galois::ALog(void) const
00309 {
00310 return table.antilog[value];
00311 }
00312
00313 #ifdef LONGMULTIPLY
00314 template class g>
00315 inline GaloisLongMultiplyTable::GaloisLongMultiplyTable(void)
00316 {
00317 G *table = tables;
00318
00319 for (unsigned int i=0; i00320 {
00321 for (unsigned int j=i; j00322 {
00323 for (unsigned int ii=0; ii00324 {
00325 for (unsigned int jj=0; jj00326 {
00327 *table++ = G(ii 00328 }
00329 }
00330 }
00331 }
00332 }
00333 #endif
00334
00335 typedef Galois Galois8;
00336 typedef Galois Galois16;
00337
00338 #endif // __GALOIS_H__