Botan  1.10.17
bigint.cpp
Go to the documentation of this file.
1 /*
2 * BigInt Base
3 * (C) 1999-2011 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/bigint.h>
9 #include <botan/internal/mp_core.h>
10 #include <botan/get_byte.h>
11 #include <botan/parsing.h>
12 #include <botan/internal/rounding.h>
13 #include <botan/internal/ct_utils.h>
14 
15 namespace Botan {
16 
17 /*
18 * Construct a BigInt from a regular number
19 */
21  {
23 
24  if(n == 0)
25  return;
26 
27  const size_t limbs_needed = sizeof(u64bit) / sizeof(word);
28 
29  reg.resize(4*limbs_needed);
30  for(size_t i = 0; i != limbs_needed; ++i)
31  reg[i] = ((n >> (i*MP_WORD_BITS)) & MP_WORD_MASK);
32  }
33 
34 /*
35 * Construct a BigInt of the specified size
36 */
37 BigInt::BigInt(Sign s, size_t size)
38  {
39  reg.resize(round_up<size_t>(size, 8));
40  signedness = s;
41  }
42 
43 /*
44 * Construct a BigInt from a "raw" BigInt
45 */
47  {
48  const size_t b_words = b.sig_words();
49 
50  if(b_words)
51  {
52  reg.resize(round_up<size_t>(b_words, 8));
53  reg.copy(b.data(), b_words);
54  set_sign(b.sign());
55  }
56  else
57  {
58  reg.resize(2);
60  }
61  }
62 
63 /*
64 * Construct a BigInt from a string
65 */
66 BigInt::BigInt(const std::string& str)
67  {
68  Base base = Decimal;
69  size_t markers = 0;
70  bool negative = false;
71  if(str.length() > 0 && str[0] == '-') { markers += 1; negative = true; }
72 
73  if(str.length() > markers + 2 && str[markers ] == '0' &&
74  str[markers + 1] == 'x')
75  { markers += 2; base = Hexadecimal; }
76  else if(str.length() > markers + 1 && str[markers] == '0')
77  { markers += 1; base = Octal; }
78 
79  *this = decode(reinterpret_cast<const byte*>(str.data()) + markers,
80  str.length() - markers, base);
81 
82  if(negative) set_sign(Negative);
83  else set_sign(Positive);
84  }
85 
86 /*
87 * Construct a BigInt from an encoded BigInt
88 */
89 BigInt::BigInt(const byte input[], size_t length, Base base)
90  {
92  *this = decode(input, length, base);
93  }
94 
95 /*
96 * Construct a BigInt from an encoded BigInt
97 */
99  {
101  randomize(rng, bits);
102  }
103 
104 /*
105 * Swap this BigInt with another
106 */
107 void BigInt::swap(BigInt& other)
108  {
109  reg.swap(other.reg);
110  std::swap(signedness, other.signedness);
111  }
112 
113 /*
114 * Grow the internal storage
115 */
116 void BigInt::grow_reg(size_t n)
117  {
118  reg.resize(round_up<size_t>(size() + n, 8));
119  }
120 
121 /*
122 * Grow the internal storage
123 */
124 void BigInt::grow_to(size_t n)
125  {
126  if(n > size())
127  reg.resize(round_up<size_t>(n, 8));
128  }
129 
130 /*
131 * Comparison Function
132 */
133 s32bit BigInt::cmp(const BigInt& n, bool check_signs) const
134  {
135  if(check_signs)
136  {
137  if(n.is_positive() && this->is_negative()) return -1;
138  if(n.is_negative() && this->is_positive()) return 1;
139  if(n.is_negative() && this->is_negative())
140  return (-bigint_cmp(data(), sig_words(), n.data(), n.sig_words()));
141  }
142  return bigint_cmp(data(), sig_words(), n.data(), n.sig_words());
143  }
144 
145 /*
146 * Return byte n of this number
147 */
148 byte BigInt::byte_at(size_t n) const
149  {
150  const size_t WORD_BYTES = sizeof(word);
151  size_t word_num = n / WORD_BYTES, byte_num = n % WORD_BYTES;
152  if(word_num >= size())
153  return 0;
154  else
155  return get_byte(WORD_BYTES - byte_num - 1, reg[word_num]);
156  }
157 
158 /*
159 * Return bit n of this number
160 */
161 bool BigInt::get_bit(size_t n) const
162  {
163  return ((word_at(n / MP_WORD_BITS) >> (n % MP_WORD_BITS)) & 1);
164  }
165 
166 /*
167 * Return bits {offset...offset+length}
168 */
169 u32bit BigInt::get_substring(size_t offset, size_t length) const
170  {
171  if(length > 32)
172  throw Invalid_Argument("BigInt::get_substring: Substring size too big");
173 
174  u64bit piece = 0;
175  for(size_t i = 0; i != 8; ++i)
176  {
177  const byte part = byte_at((offset / 8) + (7-i));
178  piece = (piece << 8) | part;
179  }
180 
181  const u64bit mask = (static_cast<u64bit>(1) << length) - 1;
182  const size_t shift = (offset % 8);
183 
184  return static_cast<u32bit>((piece >> shift) & mask);
185  }
186 
187 /*
188 * Convert this number to a u32bit, if possible
189 */
191  {
192  if(is_negative())
193  throw Encoding_Error("BigInt::to_u32bit: Number is negative");
194  if(bits() > 32)
195  throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
196 
197  u32bit out = 0;
198  for(u32bit j = 0; j != 4; ++j)
199  out = (out << 8) | byte_at(3-j);
200  return out;
201  }
202 
203 /*
204 * Set bit number n
205 */
206 void BigInt::set_bit(size_t n)
207  {
208  const size_t which = n / MP_WORD_BITS;
209  const word mask = static_cast<word>(1) << (n % MP_WORD_BITS);
210  if(which >= size()) grow_to(which + 1);
211  reg[which] |= mask;
212  }
213 
214 /*
215 * Clear bit number n
216 */
217 void BigInt::clear_bit(size_t n)
218  {
219  const size_t which = n / MP_WORD_BITS;
220  const word mask = static_cast<word>(1) << (n % MP_WORD_BITS);
221  if(which < size())
222  reg[which] &= ~mask;
223  }
224 
225 /*
226 * Clear all but the lowest n bits
227 */
228 void BigInt::mask_bits(size_t n)
229  {
230  if(n == 0) { clear(); return; }
231  if(n >= bits()) return;
232 
233  const size_t top_word = n / MP_WORD_BITS;
234  const word mask = (static_cast<word>(1) << (n % MP_WORD_BITS)) - 1;
235 
236  if(top_word < size())
237  for(size_t i = top_word + 1; i != size(); ++i)
238  reg[i] = 0;
239 
240  reg[top_word] &= mask;
241  }
242 
243 /*
244 * Count how many bytes are being used
245 */
246 size_t BigInt::bytes() const
247  {
248  return (bits() + 7) / 8;
249  }
250 
251 /*
252 * Count how many bits are being used
253 */
254 size_t BigInt::bits() const
255  {
256  const size_t words = sig_words();
257 
258  if(words == 0)
259  return 0;
260 
261  size_t full_words = words - 1, top_bits = MP_WORD_BITS;
262  word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT;
263 
264  while(top_bits && ((top_word & mask) == 0))
265  { mask >>= 1; top_bits--; }
266 
267  return (full_words * MP_WORD_BITS + top_bits);
268  }
269 
270 /*
271 * Calcluate the size in a certain base
272 */
273 size_t BigInt::encoded_size(Base base) const
274  {
275  static const double LOG_2_BASE_10 = 0.30102999566;
276 
277  if(base == Binary)
278  return bytes();
279  else if(base == Hexadecimal)
280  return 2*bytes();
281  else if(base == Octal)
282  return ((bits() + 2) / 3);
283  else if(base == Decimal)
284  return static_cast<size_t>((bits() * LOG_2_BASE_10) + 1);
285  else
286  throw Invalid_Argument("Unknown base for BigInt encoding");
287  }
288 
289 /*
290 * Set the sign
291 */
293  {
294  if(is_zero())
295  signedness = Positive;
296  else
297  signedness = s;
298  }
299 
300 /*
301 * Reverse the value of the sign flag
302 */
304  {
306  }
307 
308 /*
309 * Return the opposite value of the current sign
310 */
312  {
313  if(sign() == Positive)
314  return Negative;
315  return Positive;
316  }
317 
318 /*
319 * Return the negation of this number
320 */
322  {
323  BigInt x = (*this);
324  x.flip_sign();
325  return x;
326  }
327 
328 /*
329 * Return the absolute value of this number
330 */
332  {
333  BigInt x = (*this);
334  x.set_sign(Positive);
335  return x;
336  }
337 
338 /*
339 * Encode this number into bytes
340 */
341 void BigInt::binary_encode(byte output[]) const
342  {
343  const size_t sig_bytes = bytes();
344  for(size_t i = 0; i != sig_bytes; ++i)
345  output[sig_bytes-i-1] = byte_at(i);
346  }
347 
348 /*
349 * Set this number to the value in buf
350 */
351 void BigInt::binary_decode(const byte buf[], size_t length)
352  {
353  const size_t WORD_BYTES = sizeof(word);
354 
355  clear();
356  reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8));
357 
358  for(size_t i = 0; i != length / WORD_BYTES; ++i)
359  {
360  const size_t top = length - WORD_BYTES*i;
361  for(size_t j = WORD_BYTES; j > 0; --j)
362  reg[i] = (reg[i] << 8) | buf[top - j];
363  }
364 
365  for(size_t i = 0; i != length % WORD_BYTES; ++i)
366  reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[i];
367  }
368 
369 /*
370 * Set this number to the value in buf
371 */
373  {
374  binary_decode(buf, buf.size());
375  }
376 
378  {
379  reg.resize(sig_words());
380  }
381 
383  const std::vector<BigInt>& vec,
384  size_t idx)
385  {
386  const size_t words = output.size();
387 
388  clear_mem(output.data(), output.size());
389 
390  for(size_t i = 0; i != vec.size(); ++i)
391  {
392  for(size_t w = 0; w != words; ++w)
393  output[w] |= CT::select<word>(CT::is_equal(i, idx), vec[i].word_at(w), 0);
394  }
395  }
396 
397 
398 }
bool get_bit(size_t n) const
Definition: bigint.cpp:161
Sign reverse_sign() const
Definition: bigint.cpp:311
void resize(size_t n)
Definition: secmem.h:217
bool is_negative() const
Definition: bigint.h:245
s32bit cmp(const BigInt &n, bool check_signs=true) const
Definition: bigint.cpp:133
size_t bits() const
Definition: bigint.cpp:254
void binary_decode(const byte buf[], size_t length)
Definition: bigint.cpp:351
u32bit get_substring(size_t offset, size_t length) const
Definition: bigint.cpp:169
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:32
void set_bit(size_t n)
Definition: bigint.cpp:206
Sign sign() const
Definition: bigint.h:257
bool is_zero() const
Definition: bigint.h:176
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
void swap(BigInt &other)
Definition: bigint.cpp:107
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
word word_at(size_t n) const
Definition: bigint.h:238
void mask_bits(size_t n)
Definition: bigint.cpp:228
BigInt operator-() const
Definition: bigint.cpp:321
T is_equal(T x, T y)
Definition: ct_utils.h:63
void copy(const T in[], size_t n)
Definition: secmem.h:126
const word * data() const
Definition: bigint.h:317
signed int s32bit
Definition: types.h:37
unsigned char byte
Definition: types.h:22
unsigned long long u64bit
Definition: types.h:49
void grow_reg(size_t n)
Definition: bigint.cpp:116
void randomize(RandomNumberGenerator &rng, size_t bitsize=0)
Definition: big_rand.cpp:29
void binary_encode(byte buf[]) const
Definition: bigint.cpp:341
size_t size() const
Definition: bigint.h:284
size_t sig_words() const
Definition: bigint.h:290
size_t bytes() const
Definition: bigint.cpp:246
byte byte_at(size_t n) const
Definition: bigint.cpp:148
void clear()
Definition: bigint.h:143
const word MP_WORD_MASK
Definition: mp_types.h:27
size_t size() const
Definition: secmem.h:29
void swap(MemoryRegion< T > &other)
Definition: secmem.h:260
void grow_to(size_t n)
Definition: bigint.cpp:124
size_t encoded_size(Base base=Binary) const
Definition: bigint.cpp:273
BigInt abs() const
Definition: bigint.cpp:331
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:102
static void const_time_lookup(SecureVector< word > &output, const std::vector< BigInt > &vec, size_t idx)
Definition: bigint.cpp:382
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
Definition: secmem.h:438
void shrink_to_fit()
Definition: bigint.cpp:377
void flip_sign()
Definition: bigint.cpp:303
void clear_bit(size_t n)
Definition: bigint.cpp:217
void set_sign(Sign sign)
Definition: bigint.cpp:292
const word MP_WORD_TOP_BIT
Definition: mp_types.h:28
s32bit bigint_cmp(const word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_misc.cpp:41
bool is_positive() const
Definition: bigint.h:251
unsigned int u32bit
Definition: types.h:32
const size_t MP_WORD_BITS
Definition: mp_core.h:18
u32bit to_u32bit() const
Definition: bigint.cpp:190