algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/src/kronecker_modular_int.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : kronecker_modular_int.cpp
00004 * DESCRIPTION: Kronecker substitution for hardware modular integers
00005 * COPYRIGHT  : (C) 2009  Gregoire Lecerf
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #include <algebramix/kronecker_int.hpp>
00014 #include <algebramix/kronecker_modular_int.hpp>
00015 namespace mmx {
00016 
00017 /******************************************************************************
00018 * Naive encoding and decoding of integer polynomials using Kronecker's method
00019 ******************************************************************************/
00020 
00021 #if !defined(__GNU_MP__)
00022 
00023 template<typename I> inline void
00024 decode_kronecker_mod_int (I* dest, nat n, xnat bits, const integer& src,
00025                           const I& p) {
00026   if (n == 0);
00027   else if (n == 1) dest[0]= as<I> (p == 0 ? src : src % p);
00028   else {
00029     nat h= n>>1;
00030     integer aux= src >> (h*bits);
00031     decode_kronecker_mod_int (dest+h, n-h, bits, aux, p);
00032     aux= src - (aux << (h*bits));
00033     decode_kronecker_mod_int (dest, h, bits, aux, p);
00034   }
00035 }
00036 
00037 #define IMPLEMENTATION_HELPER(I)                                        \
00038   void                                                                  \
00039   decode_kronecker_mod (I* dest, nat n, xnat bits, const integer& src,  \
00040                         const I& p) {                                   \
00041     decode_kronecker_mod_int (dest, n, bits, src, p); }
00042 IMPLEMENTATION_HELPER (signed char)
00043 IMPLEMENTATION_HELPER (unsigned char)
00044 IMPLEMENTATION_HELPER (short int)
00045 IMPLEMENTATION_HELPER (unsigned short int)
00046 IMPLEMENTATION_HELPER (int)
00047 IMPLEMENTATION_HELPER (unsigned int)
00048 IMPLEMENTATION_HELPER (long int)
00049 IMPLEMENTATION_HELPER (unsigned long int)
00050 IMPLEMENTATION_HELPER (long long int)
00051 IMPLEMENTATION_HELPER (unsigned long long int)
00052 #undef IMPLEMENTATION_HELPER
00053 
00054 #else
00055 
00056 /******************************************************************************
00057 * Specific implementation for GMP
00058 ******************************************************************************/
00059 
00060 // from polynomial_gmp.cpp
00061 #define DECLARE_HELPER(I)                                               \
00062   void mpz_decode_kronecker_mod (I* dest, unsigned long n,              \
00063                                  unsigned long bits, const mpz_t src,   \
00064                                  const I& p);
00065 DECLARE_HELPER(unsigned char)
00066 DECLARE_HELPER(unsigned short)
00067 DECLARE_HELPER(unsigned int)
00068 DECLARE_HELPER(unsigned long int)
00069 DECLARE_HELPER(unsigned long long int)
00070 #undef DECLARE_HELPER
00071 
00072 #define IMPLEMENTATION_HELPER(I)                                        \
00073   inline void                                                           \
00074   decode_kronecker_mod (I* dest, nat n, xnat bits,                      \
00075                                     const integer& src,                 \
00076                                     const I& p) {                       \
00077     typedef unsigned_of_helper<I>::type U;                              \
00078     mpz_decode_kronecker_mod ((U*) (void*) dest, (unsigned long) n,     \
00079                               (unsigned long) bits, *src, (U) p); }
00080 IMPLEMENTATION_HELPER(signed char)
00081 IMPLEMENTATION_HELPER(unsigned char)
00082 IMPLEMENTATION_HELPER(short int)
00083 IMPLEMENTATION_HELPER(unsigned short)
00084 IMPLEMENTATION_HELPER(int)
00085 IMPLEMENTATION_HELPER(unsigned int)
00086 IMPLEMENTATION_HELPER(long int)
00087 IMPLEMENTATION_HELPER(unsigned long int)
00088 IMPLEMENTATION_HELPER(long long int)
00089 IMPLEMENTATION_HELPER(unsigned long long int)
00090 #undef IMPLEMENTATION_HELPER
00091 
00092 #endif // __GNU_MP__
00093 
00094 /******************************************************************************
00095 * Multiply two integer polynomials stored in segments using Kronecker's method
00096 ******************************************************************************/
00097 
00098 template<typename I> static inline void
00099 mul_kronecker_mod_int (I* dest,
00100                        const I* src1, nat n1,
00101                        const I* src2, nat n2, const I& p)
00102 {
00103   if (n1 == 0 && n2 == 0) return;
00104   for (nat i= 0; i < n1 + n2 - 1; i++) dest[i]= 0;
00105   while (n1 > 0 && src1[n1-1] == 0) n1--;
00106   while (n2 > 0 && src2[n2-1] == 0) n2--;
00107   if (n1 == 0 || n2 == 0) return;
00108 
00109   xnat bits= 2 * bit_size (p-1) + bit_size (min (n1, n2));
00110   integer aux1, aux2;
00111   encode_kronecker (aux1, src1, n1, bits);
00112   encode_kronecker (aux2, src2, n2, bits);
00113   integer aux= aux1*aux2;
00114   decode_kronecker_mod (dest, n1+n2-1, bits, aux, p);
00115 }
00116 
00117 #define IMPLEMENTATION_HELPER(I)                                        \
00118   void mul_kronecker_mod (I* dest, const I* src1, nat n1,               \
00119                           const I* src2, nat n2, const I& p) {          \
00120     mul_kronecker_mod_int (dest, src1, n1, src2, n2, p); }
00121 IMPLEMENTATION_HELPER (signed char)
00122 IMPLEMENTATION_HELPER (unsigned char)
00123 IMPLEMENTATION_HELPER (short int)
00124 IMPLEMENTATION_HELPER (unsigned short int)
00125 IMPLEMENTATION_HELPER (int)
00126 IMPLEMENTATION_HELPER (unsigned int)
00127 IMPLEMENTATION_HELPER (long int)
00128 IMPLEMENTATION_HELPER (unsigned long int)
00129 IMPLEMENTATION_HELPER (long long int)
00130 IMPLEMENTATION_HELPER (unsigned long long int)
00131 #undef IMPLEMENTATION_HELPER
00132 
00133 template<typename I> static inline void
00134 square_kronecker_mod_int (I* dest, const I* src, nat n, const I& p) {
00135   if (n == 0) return;
00136   for (nat i= 0; i < 2 * n - 1; i++) dest[i]= 0;
00137   while (n > 0 && src[n-1] == 0) n--;
00138   if (n == 0) return;
00139   if (n == 1) { dest[0]= square (src[0]); return; }
00140 
00141   xnat bits= 2 * bit_size (p-1) + bit_size (n);
00142   integer aux1;
00143   encode_kronecker (aux1, src, n, bits);
00144   integer aux= square (aux1);
00145   decode_kronecker_mod (dest, 2*n - 1, bits, aux, p);
00146 }
00147 
00148 #define IMPLEMENTATION_HELPER(I)                                         \
00149   void square_kronecker_mod (I* dest, const I* src, nat n, const I& p) { \
00150     square_kronecker_mod_int (dest, src, n, p); }
00151 IMPLEMENTATION_HELPER (signed char)
00152 IMPLEMENTATION_HELPER (unsigned char)
00153 IMPLEMENTATION_HELPER (short int)
00154 IMPLEMENTATION_HELPER (unsigned short int)
00155 IMPLEMENTATION_HELPER (int)
00156 IMPLEMENTATION_HELPER (unsigned int)
00157 IMPLEMENTATION_HELPER (long int)
00158 IMPLEMENTATION_HELPER (unsigned long int)
00159 IMPLEMENTATION_HELPER (long long int)
00160 IMPLEMENTATION_HELPER (unsigned long long int)
00161 #undef IMPLEMENTATION_HELPER
00162 
00163 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines