qca
big_base.cpp
Go to the documentation of this file.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/mp_core.h>
00038 namespace QCA {
00039 }
00040 #include <botan/bit_ops.h>
00041 namespace QCA {
00042 }
00043 #include <botan/parsing.h>
00044 namespace QCA {
00045 }
00046 #include <botan/util.h>
00047 namespace QCA {
00048
00049 namespace Botan {
00050
00051
00052
00053
00054 BigInt::BigInt(u64bit n)
00055 {
00056 set_sign(Positive);
00057
00058 if(n == 0)
00059 return;
00060
00061 const u32bit limbs_needed = sizeof(u64bit) / sizeof(word);
00062
00063 reg.create(4*limbs_needed);
00064 for(u32bit j = 0; j != limbs_needed; ++j)
00065 reg[j] = (word)((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK);
00066 }
00067
00068
00069
00070
00071 BigInt::BigInt(Sign s, u32bit size)
00072 {
00073 reg.create(round_up(size, 8));
00074 signedness = s;
00075 }
00076
00077
00078
00079
00080 BigInt::BigInt(const BigInt& b)
00081 {
00082 const u32bit b_words = b.sig_words();
00083
00084 if(b_words)
00085 {
00086 reg.create(round_up(b_words, 8));
00087 reg.copy(b.data(), b_words);
00088 set_sign(b.sign());
00089 }
00090 else
00091 {
00092 reg.create(2);
00093 set_sign(Positive);
00094 }
00095 }
00096
00097
00098
00099
00100 BigInt::BigInt(const std::string& str)
00101 {
00102 Base base = Decimal;
00103 u32bit markers = 0;
00104 bool negative = false;
00105 if(str.length() > 0 && str[0] == '-') { markers += 1; negative = true; }
00106
00107 if(str.length() > markers + 2 && str[markers ] == '0' &&
00108 str[markers + 1] == 'x')
00109 { markers += 2; base = Hexadecimal; }
00110 else if(str.length() > markers + 1 && str[markers] == '0')
00111 { markers += 1; base = Octal; }
00112
00113 *this = decode((const byte*)str.data() + markers,
00114 str.length() - markers, base);
00115
00116 if(negative) set_sign(Negative);
00117 else set_sign(Positive);
00118 }
00119
00120
00121
00122
00123 BigInt::BigInt(const byte input[], u32bit length, Base base)
00124 {
00125 set_sign(Positive);
00126 *this = decode(input, length, base);
00127 }
00128
00129
00130
00131
00132 void BigInt::swap(BigInt& other)
00133 {
00134 std::swap(reg, other.reg);
00135 std::swap(signedness, other.signedness);
00136 }
00137
00138
00139
00140
00141 void BigInt::grow_reg(u32bit n) const
00142 {
00143 reg.grow_to(round_up(size() + n, 8));
00144 }
00145
00146
00147
00148
00149 void BigInt::grow_to(u32bit n) const
00150 {
00151 if(n > size())
00152 reg.grow_to(round_up(n, 8));
00153 }
00154
00155
00156
00157
00158 s32bit BigInt::cmp(const BigInt& n, bool check_signs) const
00159 {
00160 if(check_signs)
00161 {
00162 if(n.is_positive() && this->is_negative()) return -1;
00163 if(n.is_negative() && this->is_positive()) return 1;
00164 if(n.is_negative() && this->is_negative())
00165 return (-bigint_cmp(data(), sig_words(), n.data(), n.sig_words()));
00166 }
00167 return bigint_cmp(data(), sig_words(), n.data(), n.sig_words());
00168 }
00169
00170
00171
00172
00173 u32bit BigInt::to_u32bit() const
00174 {
00175 if(is_negative())
00176 throw Encoding_Error("BigInt::to_u32bit: Number is negative");
00177 if(bits() >= 32)
00178 throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
00179
00180 u32bit out = 0;
00181 for(u32bit j = 0; j != 4; ++j)
00182 out = (out << 8) | byte_at(3-j);
00183 return out;
00184 }
00185
00186
00187
00188
00189 byte BigInt::byte_at(u32bit n) const
00190 {
00191 const u32bit WORD_BYTES = sizeof(word);
00192 u32bit word_num = n / WORD_BYTES, byte_num = n % WORD_BYTES;
00193 if(word_num >= size())
00194 return 0;
00195 else
00196 return get_byte(WORD_BYTES - byte_num - 1, reg[word_num]);
00197 }
00198
00199
00200
00201
00202 bool BigInt::get_bit(u32bit n) const
00203 {
00204 return ((word_at(n / MP_WORD_BITS) >> (n % MP_WORD_BITS)) & 1);
00205 }
00206
00207
00208
00209
00210 u32bit BigInt::get_substring(u32bit offset, u32bit length) const
00211 {
00212 if(length > 32)
00213 throw Invalid_Argument("BigInt::get_substring: Substring size too big");
00214
00215 u64bit piece = 0;
00216 for(u32bit j = 0; j != 8; ++j)
00217 piece = (piece << 8) | byte_at((offset / 8) + (7-j));
00218
00219 u64bit mask = (1 << length) - 1;
00220 u32bit shift = (offset % 8);
00221
00222 return static_cast<u32bit>((piece >> shift) & mask);
00223 }
00224
00225
00226
00227
00228 void BigInt::set_bit(u32bit n)
00229 {
00230 const u32bit which = n / MP_WORD_BITS;
00231 const word mask = (word)1 << (n % MP_WORD_BITS);
00232 if(which >= size()) grow_to(which + 1);
00233 reg[which] |= mask;
00234 }
00235
00236
00237
00238
00239 void BigInt::clear_bit(u32bit n)
00240 {
00241 const u32bit which = n / MP_WORD_BITS;
00242 const word mask = (word)1 << (n % MP_WORD_BITS);
00243 if(which < size())
00244 reg[which] &= ~mask;
00245 }
00246
00247
00248
00249
00250 void BigInt::mask_bits(u32bit n)
00251 {
00252 if(n == 0) { clear(); return; }
00253 if(n >= bits()) return;
00254
00255 const u32bit top_word = n / MP_WORD_BITS;
00256 const word mask = ((word)1 << (n % MP_WORD_BITS)) - 1;
00257
00258 if(top_word < size())
00259 for(u32bit j = top_word + 1; j != size(); ++j)
00260 reg[j] = 0;
00261
00262 reg[top_word] &= mask;
00263 }
00264
00265
00266
00267
00268 u32bit BigInt::sig_words() const
00269 {
00270 const word* x = data();
00271 u32bit top_set = size();
00272
00273 while(top_set >= 4)
00274 {
00275 word sum = x[top_set-1] | x[top_set-2] | x[top_set-3] | x[top_set-4];
00276 if(sum) break;
00277 else top_set -= 4;
00278 }
00279 while(top_set && (x[top_set-1] == 0))
00280 top_set--;
00281 return top_set;
00282 }
00283
00284
00285
00286
00287 u32bit BigInt::bytes() const
00288 {
00289 return (bits() + 7) / 8;
00290 }
00291
00292
00293
00294
00295 u32bit BigInt::bits() const
00296 {
00297 if(sig_words() == 0)
00298 return 0;
00299
00300 u32bit full_words = sig_words() - 1, top_bits = MP_WORD_BITS;
00301 word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT;
00302
00303 while(top_bits && ((top_word & mask) == 0))
00304 { mask >>= 1; top_bits--; }
00305
00306 return (full_words * MP_WORD_BITS + top_bits);
00307 }
00308
00309
00310
00311
00312 u32bit BigInt::encoded_size(Base base) const
00313 {
00314 static const double LOG_2_BASE_10 = 0.30102999566;
00315
00316 if(base == Binary)
00317 return bytes();
00318 else if(base == Hexadecimal)
00319 return 2*bytes();
00320 else if(base == Octal)
00321 return ((bits() + 2) / 3);
00322 else if(base == Decimal)
00323 return (u32bit)((bits() * LOG_2_BASE_10) + 1);
00324 else
00325 throw Invalid_Argument("Unknown base for BigInt encoding");
00326 }
00327
00328
00329
00330
00331 bool BigInt::is_zero() const
00332 {
00333 for(u32bit j = 0; j != size(); ++j)
00334 if(reg[j]) return false;
00335 return true;
00336 }
00337
00338
00339
00340
00341 void BigInt::set_sign(Sign s)
00342 {
00343 if(is_zero())
00344 signedness = Positive;
00345 else
00346 signedness = s;
00347 }
00348
00349
00350
00351
00352 void BigInt::flip_sign()
00353 {
00354 set_sign(reverse_sign());
00355 }
00356
00357
00358
00359
00360 BigInt::Sign BigInt::reverse_sign() const
00361 {
00362 if(sign() == Positive)
00363 return Negative;
00364 return Positive;
00365 }
00366
00367
00368
00369
00370 BigInt BigInt::operator-() const
00371 {
00372 BigInt x = (*this);
00373 x.flip_sign();
00374 return x;
00375 }
00376
00377
00378
00379
00380 BigInt BigInt::abs() const
00381 {
00382 BigInt x = (*this);
00383 x.set_sign(Positive);
00384 return x;
00385 }
00386
00387
00388
00389
00390 void BigInt::binary_encode(byte output[]) const
00391 {
00392 const u32bit sig_bytes = bytes();
00393 for(u32bit j = 0; j != sig_bytes; ++j)
00394 output[sig_bytes-j-1] = byte_at(j);
00395 }
00396
00397
00398
00399
00400 void BigInt::binary_decode(const byte buf[], u32bit length)
00401 {
00402 const u32bit WORD_BYTES = sizeof(word);
00403 reg.create(round_up((length / WORD_BYTES) + 1, 8));
00404
00405 for(u32bit j = 0; j != length / WORD_BYTES; ++j)
00406 {
00407 u32bit top = length - WORD_BYTES*j;
00408 for(u32bit k = WORD_BYTES; k > 0; --k)
00409 reg[j] = (reg[j] << 8) | buf[top - k];
00410 }
00411 for(u32bit j = 0; j != length % WORD_BYTES; ++j)
00412 reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j];
00413 }
00414
00415 }
00416 }