algebramix_doc 0.3
|
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