Main Page   Reference Manual   Compound List   File List  

libecc/fieldmath.h

Go to the documentation of this file.
00001 //
00014 //
00015 // This file is part of the libecc package.
00016 // Copyright (C) 2002, by
00017 //
00018 // Carlo Wood, Run on IRC <carlo@alinoe.com>
00019 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
00020 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
00021 //
00022 // This program is free software; you can redistribute it and/or
00023 // modify it under the terms of the GNU General Public License
00024 // as published by the Free Software Foundation; either version 2
00025 // of the License, or (at your option) any later version.
00026 //
00027 // This program is distributed in the hope that it will be useful,
00028 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00029 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030 // GNU General Public License for more details.
00031 //
00032 // You should have received a copy of the GNU General Public License
00033 // along with this program; if not, write to the Free Software
00034 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     // Determine the highest degree bit that is set, in the two polynomial_coefficients.
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];                // The other polynomials is zero.
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;                          // Found the gcd.
00151       distance = (iter[largest] - iter[smallest]);
00152     }
00153     return *polycoef[smallest];
00154   }
00155   
00156 } // namespace libecc
00157 
00158 #endif // LIBECC_FIELDMATH_H
Copyright © 2002-2008 Carlo Wood.  All rights reserved.