Go to the documentation of this file.00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef LIBECC_FIELDMATH_H
00038 #define LIBECC_FIELDMATH_H
00039
00040 #include <gmpxx.h>
00041 #include <libecc/bitset.h>
00042
00043 namespacelibecc {
00044
00045 template<class field_type>
00046 classmultiplicative_square {
00047 public:
00048 void operator()(field_type& field_element) const{ field_element *= field_element; }
00049 };
00050
00085 template<class field_type, class square_functor>
00086 field_type exponentiation(field_type const& base, mpz_class const& exponent,
00087 square_functor const& do_square = multiplicative_square<field_type>())
00088 {
00089 field_type result(mpz_tstbit(exponent.get_mpz_t(), 0) ? base : field_type::unity());
00090 field_type current_factor(base);
00091 unsigned long next_bit = 1;
00092 for(;;)
00093 {
00094 unsigned long current_bit = mpz_scan1(exponent.get_mpz_t(), next_bit);
00095 if (current_bit == (unsigned long)-1)
00096 break;
00097 for(int cnt = current_bit - next_bit; cnt >= 0; --cnt)
00098 do_square(current_factor);
00099 result *= current_factor;
00100 next_bit = current_bit + 1;
00101 }
00102 return result;
00103 }
00104
00113 template<unsigned int m>
00114 bitset<m>&
00115 gcd(bitset<m>& polynomial_coefficients0, bitset<m>& polynomial_coefficients1)
00116 {
00117 bitset<m>* polycoef[2];
00118 polycoef[0] = &polynomial_coefficients0;
00119 polycoef[1] = &polynomial_coefficients1;
00120 typename bitset<m>::const_reverse_iterator iter[2];
00121
00122
00123 for (int p = 0; p < 2; ++p)
00124 {
00125 iter[p] = polycoef[p]->rbegin();
00126 iter[p].find1();
00127 if (iter[p] == polycoef[p]->rend())
00128 return *polycoef[1 - p];
00129 }
00130 int distance = (iter[0] - iter[1]);
00131 if (distance < 0)
00132 distance = -distance;
00133 int smallest = (iter[0] > iter[1]) ? 0 : 1;
00134 for (int largest = 1 - smallest;; largest = 1 - largest, smallest = 1 - smallest)
00135 {
00136 bitset<m> temp(*polycoef[smallest]);
00137 temp <<= distance;
00138 int last_shift = distance;
00139 *polycoef[largest] ^= temp;
00140 for(int shift = distance - 1; shift >= 0; --shift)
00141 {
00142 if (!*(iter[largest] + (distance - shift)))
00143 continue;
00144 temp >>= (last_shift - shift);
00145 last_shift = shift;
00146 *polycoef[largest] ^= temp;
00147 }
00148 iter[largest].find1();
00149 if (iter[largest] == polycoef[largest]->rend())
00150 break;
00151 distance = (iter[largest] - iter[smallest]);
00152 }
00153 return *polycoef[smallest];
00154 }
00155
00156 }
00157
00158 #endif // LIBECC_FIELDMATH_H