00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 namespace QCA {
00028
00029
00030
00031
00032
00033 }
00034 #include <botan/bigint.h>
00035 namespace QCA {
00036 }
00037 #include <botan/numthry.h>
00038 namespace QCA {
00039 }
00040 #include <botan/mp_core.h>
00041 namespace QCA {
00042 }
00043 #include <botan/bit_ops.h>
00044 namespace QCA {
00045 }
00046 #include <botan/util.h>
00047 namespace QCA {
00048 }
00049 #include <algorithm>
00050 namespace QCA {
00051
00052 namespace Botan {
00053
00054
00055
00056
00057 BigInt& BigInt::operator+=(const BigInt& y)
00058 {
00059 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
00060
00061 #ifdef BOTAN_TYPES_QT
00062 const u32bit reg_size = qMax(x_sw, y_sw) + 1;
00063 #else
00064 const u32bit reg_size = std::max(x_sw, y_sw) + 1;
00065 #endif
00066 grow_to(reg_size);
00067
00068 if((sign() == y.sign()))
00069 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
00070 else
00071 {
00072 s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
00073
00074 if(relative_size < 0)
00075 {
00076 SecureVector<word> z(reg_size - 1);
00077 bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
00078 copy_mem(reg.begin(), z.begin(), z.size());
00079 set_sign(y.sign());
00080 }
00081 else if(relative_size == 0)
00082 {
00083 reg.clear();
00084 set_sign(Positive);
00085 }
00086 else if(relative_size > 0)
00087 bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
00088 }
00089
00090 return (*this);
00091 }
00092
00093
00094
00095
00096 BigInt& BigInt::operator-=(const BigInt& y)
00097 {
00098 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
00099
00100 s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
00101
00102 #ifdef BOTAN_TYPES_QT
00103 const u32bit reg_size = qMax(x_sw, y_sw) + 1;
00104 #else
00105 const u32bit reg_size = std::max(x_sw, y_sw) + 1;
00106 #endif
00107 grow_to(reg_size);
00108
00109 if(relative_size < 0)
00110 {
00111 if(sign() == y.sign())
00112 {
00113 SecureVector<word> z(reg_size - 1);
00114 bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
00115 copy_mem(reg.begin(), z.begin(), z.size());
00116 }
00117 else
00118 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
00119
00120 set_sign(y.reverse_sign());
00121 }
00122 else if(relative_size == 0)
00123 {
00124 if(sign() == y.sign())
00125 {
00126 reg.clear();
00127 set_sign(Positive);
00128 }
00129 else
00130 bigint_shl1(get_reg(), x_sw, 0, 1);
00131 }
00132 else if(relative_size > 0)
00133 {
00134 if(sign() == y.sign())
00135 bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
00136 else
00137 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
00138 }
00139
00140 return (*this);
00141 }
00142
00143
00144
00145
00146 BigInt& BigInt::operator*=(const BigInt& y)
00147 {
00148 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
00149 set_sign((sign() == y.sign()) ? Positive : Negative);
00150
00151 if(x_sw == 0 || y_sw == 0)
00152 {
00153 reg.clear();
00154 set_sign(Positive);
00155 }
00156 else if(x_sw == 1 && y_sw)
00157 {
00158 grow_to(y_sw + 2);
00159 bigint_linmul3(get_reg(), y.data(), y_sw, word_at(0));
00160 }
00161 else if(y_sw == 1 && x_sw)
00162 {
00163 grow_to(x_sw + 2);
00164 bigint_linmul2(get_reg(), x_sw, y.word_at(0));
00165 }
00166 else
00167 {
00168 grow_to(size() + y.size());
00169
00170 SecureVector<word> z(data(), x_sw);
00171 SecureVector<word> workspace(size());
00172
00173 bigint_mul(get_reg(), size(), workspace,
00174 z, z.size(), x_sw,
00175 y.data(), y.size(), y_sw);
00176 }
00177
00178 return (*this);
00179 }
00180
00181
00182
00183
00184 BigInt& BigInt::operator/=(const BigInt& y)
00185 {
00186 if(y.sig_words() == 1 && power_of_2(y.word_at(0)))
00187 (*this) >>= (y.bits() - 1);
00188 else
00189 (*this) = (*this) / y;
00190 return (*this);
00191 }
00192
00193
00194
00195
00196 BigInt& BigInt::operator%=(const BigInt& mod)
00197 {
00198 return (*this = (*this) % mod);
00199 }
00200
00201
00202
00203
00204 word BigInt::operator%=(word mod)
00205 {
00206 if(mod == 0)
00207 throw BigInt::DivideByZero();
00208 if(power_of_2(mod))
00209 {
00210 word result = (word_at(0) & (mod - 1));
00211 clear();
00212 grow_to(2);
00213 reg[0] = result;
00214 return result;
00215 }
00216
00217 word remainder = 0;
00218
00219 for(u32bit j = sig_words(); j > 0; --j)
00220 remainder = bigint_modop(remainder, word_at(j-1), mod);
00221 clear();
00222 grow_to(2);
00223
00224 if(remainder && sign() == BigInt::Negative)
00225 reg[0] = mod - remainder;
00226 else
00227 reg[0] = remainder;
00228
00229 set_sign(BigInt::Positive);
00230
00231 return word_at(0);
00232 }
00233
00234
00235
00236
00237 BigInt& BigInt::operator<<=(u32bit shift)
00238 {
00239 if(shift)
00240 {
00241 const u32bit shift_words = shift / MP_WORD_BITS,
00242 shift_bits = shift % MP_WORD_BITS,
00243 words = sig_words();
00244
00245 grow_to(words + shift_words + (shift_bits ? 1 : 0));
00246 bigint_shl1(get_reg(), words, shift_words, shift_bits);
00247 }
00248
00249 return (*this);
00250 }
00251
00252
00253
00254
00255 BigInt& BigInt::operator>>=(u32bit shift)
00256 {
00257 if(shift)
00258 {
00259 const u32bit shift_words = shift / MP_WORD_BITS,
00260 shift_bits = shift % MP_WORD_BITS;
00261
00262 bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits);
00263
00264 if(is_zero())
00265 set_sign(Positive);
00266 }
00267
00268 return (*this);
00269 }
00270
00271 }
00272 }