00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__MODULUS__HPP
00014 #define __MMX__MODULUS__HPP
00015 #include <numerix/modulus_naive.hpp>
00016 #include <basix/wrap.hpp>
00017
00018 namespace mmx {
00019
00020 #define Modulus_variant(C) modulus_variant_helper<C>::MV
00021 #define TMPL_DEF \
00022 template<typename C, typename V=typename Modulus_variant(C) >
00023 #define TMPL template<typename C, typename V>
00024 #define Modulus modulus<C,V>
00025
00026
00027
00028
00029
00030 TMPL_DEF
00031 class modulus {
00032 MMX_ALLOCATORS
00033 public:
00034 C p;
00035 typedef C base;
00036 typedef V variant;
00037 typedef modulus <C, V> self_type;
00038
00039 inline C operator * () const { return p; }
00040
00041 inline modulus () : p (C(0)) {
00042 ASSERT (V::normalize (p), "modulus: bad value"); }
00043
00044 inline modulus (const self_type& x) : p (x.p) {}
00045
00046 template<typename X>
00047 inline modulus (const X& x) : p (C(x)) {
00048 ASSERT (V::normalize (p), "modulus: bad value"); }
00049
00050 template<typename X, X _p>
00051 inline modulus (const fixed_value<X, _p>& x) {
00052 p = _p < 0 ? -_p : _p; }
00053
00054 inline Modulus& operator = (const Modulus& m) {
00055 p = m.p;
00056 return *this; }
00057
00058 inline bool operator == (const Modulus& a) const {
00059 return p == a.p; }
00060
00061 inline bool operator != (const Modulus& a) const {
00062 return p != a.p; }
00063 };
00064
00065 WRAP_WRAPPED_IMPL(TMPL inline,Modulus)
00066
00067 template<typename T, typename F, typename TV, typename FV>
00068 struct as_helper<modulus<T,TV>,modulus<F,FV> > {
00069 static inline modulus<T,TV>
00070 cv (const modulus<F,FV>& m) { return modulus<T,TV> (*m); }
00071 };
00072
00073
00074
00075
00076
00077 TMPL inline void
00078 reduce_mod (C& dest, const Modulus& m) {
00079 V::reduce_mod (dest, m); }
00080
00081 TMPL inline void
00082 reduce_mod (C& dest, const Modulus& m, C& carry) {
00083 V::reduce_mod (dest, m, carry); }
00084
00085 TMPL inline void
00086 reduce_mod (C& dest, const C& s, const Modulus& m) {
00087 V::reduce_mod (dest, s, m); }
00088
00089 TMPL inline void
00090 reduce_mod (C& dest, const C& s, const Modulus& m, C& carry) {
00091 V::reduce_mod (dest, s, m, carry); }
00092
00093 TMPL inline void
00094 encode_mod (C& dest, const C& s, const Modulus& m) {
00095 V::encode_mod (dest, s, m); }
00096
00097 TMPL inline void
00098 decode_mod (C& dest, const C& s, const Modulus& m) {
00099 V::decode_mod (dest, s, m); }
00100
00101 TMPL inline void
00102 neg_mod (C& dest, const Modulus& m) {
00103 V::neg_mod (dest, m); }
00104
00105 TMPL inline void
00106 neg_mod (C& dest, const Modulus& m, C& carry) {
00107 V::neg_mod (dest, m, carry); }
00108
00109 TMPL inline void
00110 neg_mod (C& dest, const C& s, const Modulus& m) {
00111 V::neg_mod (dest, s, m); }
00112
00113 TMPL inline void
00114 neg_mod (C& dest, const C& s, const Modulus& m, C& carry) {
00115 V::neg_mod (dest, s, m, carry); }
00116
00117 TMPL inline void
00118 add_mod (C& dest, const C& s, const Modulus& m) {
00119 V::add_mod (dest, s, m); }
00120
00121 TMPL inline void
00122 add_mod (C& dest, const C& s, const Modulus& m, C& carry) {
00123 V::add_mod (dest, s, m, carry); }
00124
00125 TMPL inline void
00126 add_mod (C& dest, const C& s1, const C& s2, const Modulus& m) {
00127 V::add_mod (dest, s1, s2, m); }
00128
00129 TMPL inline void
00130 add_mod (C& dest, const C& s1, const C& s2, const Modulus& m, C& carry) {
00131 V::add_mod (dest, s1, s2, m, carry); }
00132
00133 TMPL inline void
00134 sub_mod (C& dest, const C& s, const Modulus& m) {
00135 V::sub_mod (dest, s, m); }
00136
00137 TMPL inline void
00138 sub_mod (C& dest, const C& s, const Modulus& m, C& carry) {
00139 V::sub_mod (dest, s, m, carry); }
00140
00141 TMPL inline void
00142 sub_mod (C& dest, const C& s1, const C& s2, const Modulus& m) {
00143 V::sub_mod (dest, s1, s2, m); }
00144
00145 TMPL inline void
00146 sub_mod (C& dest, const C& s1, const C& s2, const Modulus& m, C& carry) {
00147 V::sub_mod (dest, s1, s2, m, carry); }
00148
00149 TMPL inline void
00150 mul_mod (C& dest, const C& s, const Modulus& m) {
00151 V::mul_mod (dest, s, m); }
00152
00153 TMPL inline void
00154 mul_mod (C& dest, const C& s, const Modulus& m, C& carry) {
00155 V::mul_mod (dest, s, m, carry); }
00156
00157 TMPL inline void
00158 mul_mod (C& dest, const C& s1, const C& s2, const Modulus& m) {
00159 V::mul_mod (dest, s1, s2, m); }
00160
00161 TMPL inline void
00162 mul_mod (C& dest, const C& s1, const C& s2, const Modulus& m, C& carry) {
00163 V::mul_mod (dest, s1, s2, m, carry); }
00164
00165 TMPL inline void
00166 inv_mod (C& dest, const Modulus& m) {
00167 V::inv_mod (dest, m); }
00168
00169 TMPL inline void
00170 inv_mod (C& dest, const C& s, const Modulus& m) {
00171 V::inv_mod (dest, s, m); }
00172
00173 TMPL inline void
00174 div_mod (C& dest, const C& s, const Modulus& m) {
00175 V::div_mod (dest, s, m); }
00176
00177 TMPL inline void
00178 div_mod (C& dest, const C& s1, const C& s2, const Modulus& m) {
00179 V::div_mod (dest, s1, s2, m); }
00180
00181 TMPL inline bool
00182 is_invertible_mod (const C& s, const Modulus& m) {
00183 return V::is_invertible_mod (s, m); }
00184
00185
00186
00187
00188
00189 template<typename V> inline syntactic
00190 flatten (const modulus<char,V>& c) {
00191 return as_syntactic ((int) (*c)); }
00192
00193 template<typename V> inline syntactic
00194 flatten (const modulus<unsigned char,V>& c) {
00195 return as_syntactic ((int) (*c)); }
00196
00197 WRAP_PRINT_IMPL(TMPL inline,Modulus)
00198
00199 #undef TMPL_DEF
00200 #undef TMPL
00201 #undef Modulus
00202 }
00203 #endif //__MMX__MODULUS__HPP