2
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
4
Redistribution and use in source and binary forms, for any use, with or without
5
modification, is permitted provided that the following conditions are met:
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions, and the following disclaimer.
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions, and the following disclaimer in the documentation
12
and/or other materials provided with the distribution.
14
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
18
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
namespace QCA { // WRAPNS_LINE
28
/*************************************************
29
* BigInt Assignment Operators Source File *
30
* (C) 1999-2007 The Botan Project *
31
*************************************************/
34
#include <botan/bigint.h>
35
namespace QCA { // WRAPNS_LINE
37
#include <botan/numthry.h>
38
namespace QCA { // WRAPNS_LINE
40
#include <botan/mp_core.h>
41
namespace QCA { // WRAPNS_LINE
43
#include <botan/bit_ops.h>
44
namespace QCA { // WRAPNS_LINE
46
#include <botan/util.h>
47
namespace QCA { // WRAPNS_LINE
50
namespace QCA { // WRAPNS_LINE
54
/*************************************************
56
*************************************************/
57
BigInt& BigInt::operator+=(const BigInt& y)
59
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
62
const u32bit reg_size = qMax(x_sw, y_sw) + 1;
64
const u32bit reg_size = std::max(x_sw, y_sw) + 1;
68
if((sign() == y.sign()))
69
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
72
s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
76
SecureVector<word> z(reg_size - 1);
77
bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
78
copy_mem(reg.begin(), z.begin(), z.size());
81
else if(relative_size == 0)
86
else if(relative_size > 0)
87
bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
93
/*************************************************
94
* Subtraction Operator *
95
*************************************************/
96
BigInt& BigInt::operator-=(const BigInt& y)
98
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
100
s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
102
#ifdef BOTAN_TYPES_QT
103
const u32bit reg_size = qMax(x_sw, y_sw) + 1;
105
const u32bit reg_size = std::max(x_sw, y_sw) + 1;
109
if(relative_size < 0)
111
if(sign() == y.sign())
113
SecureVector<word> z(reg_size - 1);
114
bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
115
copy_mem(reg.begin(), z.begin(), z.size());
118
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
120
set_sign(y.reverse_sign());
122
else if(relative_size == 0)
124
if(sign() == y.sign())
130
bigint_shl1(get_reg(), x_sw, 0, 1);
132
else if(relative_size > 0)
134
if(sign() == y.sign())
135
bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
137
bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
143
/*************************************************
144
* Multiplication Operator *
145
*************************************************/
146
BigInt& BigInt::operator*=(const BigInt& y)
148
const u32bit x_sw = sig_words(), y_sw = y.sig_words();
149
set_sign((sign() == y.sign()) ? Positive : Negative);
151
if(x_sw == 0 || y_sw == 0)
156
else if(x_sw == 1 && y_sw)
159
bigint_linmul3(get_reg(), y.data(), y_sw, word_at(0));
161
else if(y_sw == 1 && x_sw)
164
bigint_linmul2(get_reg(), x_sw, y.word_at(0));
168
grow_to(size() + y.size());
170
SecureVector<word> z(data(), x_sw);
171
SecureVector<word> workspace(size());
173
bigint_mul(get_reg(), size(), workspace,
175
y.data(), y.size(), y_sw);
181
/*************************************************
182
* Division Operator *
183
*************************************************/
184
BigInt& BigInt::operator/=(const BigInt& y)
186
if(y.sig_words() == 1 && power_of_2(y.word_at(0)))
187
(*this) >>= (y.bits() - 1);
189
(*this) = (*this) / y;
193
/*************************************************
195
*************************************************/
196
BigInt& BigInt::operator%=(const BigInt& mod)
198
return (*this = (*this) % mod);
201
/*************************************************
203
*************************************************/
204
word BigInt::operator%=(word mod)
207
throw BigInt::DivideByZero();
210
word result = (word_at(0) & (mod - 1));
219
for(u32bit j = sig_words(); j > 0; --j)
220
remainder = bigint_modop(remainder, word_at(j-1), mod);
224
if(remainder && sign() == BigInt::Negative)
225
reg[0] = mod - remainder;
229
set_sign(BigInt::Positive);
234
/*************************************************
235
* Left Shift Operator *
236
*************************************************/
237
BigInt& BigInt::operator<<=(u32bit shift)
241
const u32bit shift_words = shift / MP_WORD_BITS,
242
shift_bits = shift % MP_WORD_BITS,
245
grow_to(words + shift_words + (shift_bits ? 1 : 0));
246
bigint_shl1(get_reg(), words, shift_words, shift_bits);
252
/*************************************************
253
* Right Shift Operator *
254
*************************************************/
255
BigInt& BigInt::operator>>=(u32bit shift)
259
const u32bit shift_words = shift / MP_WORD_BITS,
260
shift_bits = shift % MP_WORD_BITS;
262
bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits);