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__