00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <algebramix/kronecker_int.hpp>
00014 #include <algebramix/kronecker_modular_int.hpp>
00015 namespace mmx {
00016
00017
00018
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
00058
00059
00060
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
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 }