Botan: src/math/bigint/bigint.cpp Source File

Botan 1.10.16

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