1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * BigInt Assignment Operators Source File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33} // WRAPNS_LINE
34#include <botan/bigint.h>
35namespace QCA { // WRAPNS_LINE
36} // WRAPNS_LINE
37#include <botan/numthry.h>
38namespace QCA { // WRAPNS_LINE
39} // WRAPNS_LINE
40#include <botan/mp_core.h>
41namespace QCA { // WRAPNS_LINE
42} // WRAPNS_LINE
43#include <botan/bit_ops.h>
44namespace QCA { // WRAPNS_LINE
45} // WRAPNS_LINE
46#include <botan/util.h>
47namespace QCA { // WRAPNS_LINE
48} // WRAPNS_LINE
49#include <algorithm>
50namespace QCA { // WRAPNS_LINE
51
52namespace Botan {
53
54/*************************************************
55 * Addition Operator *
56 *************************************************/
57BigInt &BigInt::operator+=(const BigInt &y)
58{
59 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
60
61#ifdef BOTAN_TYPES_QT
62 const u32bit reg_size = qMax(a: x_sw, b: y_sw) + 1;
63#else
64 const u32bit reg_size = std::max(x_sw, y_sw) + 1;
65#endif
66 grow_to(reg_size);
67
68 if ((sign() == y.sign()))
69 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
70 else {
71 s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
72
73 if (relative_size < 0) {
74 SecureVector<word> z(reg_size - 1);
75 bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
76 copy_mem(out: reg.begin(), in: z.begin(), n: z.size());
77 set_sign(y.sign());
78 } else if (relative_size == 0) {
79 reg.clear();
80 set_sign(Positive);
81 } else if (relative_size > 0)
82 bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
83 }
84
85 return (*this);
86}
87
88/*************************************************
89 * Subtraction Operator *
90 *************************************************/
91BigInt &BigInt::operator-=(const BigInt &y)
92{
93 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
94
95 s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw);
96
97#ifdef BOTAN_TYPES_QT
98 const u32bit reg_size = qMax(a: x_sw, b: y_sw) + 1;
99#else
100 const u32bit reg_size = std::max(x_sw, y_sw) + 1;
101#endif
102 grow_to(reg_size);
103
104 if (relative_size < 0) {
105 if (sign() == y.sign()) {
106 SecureVector<word> z(reg_size - 1);
107 bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw);
108 copy_mem(out: reg.begin(), in: z.begin(), n: z.size());
109 } else
110 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
111
112 set_sign(y.reverse_sign());
113 } else if (relative_size == 0) {
114 if (sign() == y.sign()) {
115 reg.clear();
116 set_sign(Positive);
117 } else
118 bigint_shl1(get_reg(), x_sw, 0, 1);
119 } else if (relative_size > 0) {
120 if (sign() == y.sign())
121 bigint_sub2(get_reg(), x_sw, y.data(), y_sw);
122 else
123 bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw);
124 }
125
126 return (*this);
127}
128
129/*************************************************
130 * Multiplication Operator *
131 *************************************************/
132BigInt &BigInt::operator*=(const BigInt &y)
133{
134 const u32bit x_sw = sig_words(), y_sw = y.sig_words();
135 set_sign((sign() == y.sign()) ? Positive : Negative);
136
137 if (x_sw == 0 || y_sw == 0) {
138 reg.clear();
139 set_sign(Positive);
140 } else if (x_sw == 1 && y_sw) {
141 grow_to(y_sw + 2);
142 bigint_linmul3(get_reg(), y.data(), y_sw, word_at(n: 0));
143 } else if (y_sw == 1 && x_sw) {
144 grow_to(x_sw + 2);
145 bigint_linmul2(get_reg(), x_sw, y.word_at(n: 0));
146 } else {
147 grow_to(size() + y.size());
148
149 SecureVector<word> z(data(), x_sw);
150 SecureVector<word> workspace(size());
151
152 bigint_mul(get_reg(), size(), workspace, z, z.size(), x_sw, y.data(), y.size(), y_sw);
153 }
154
155 return (*this);
156}
157
158/*************************************************
159 * Division Operator *
160 *************************************************/
161BigInt &BigInt::operator/=(const BigInt &y)
162{
163 if (y.sig_words() == 1 && power_of_2(y.word_at(n: 0)))
164 (*this) >>= (y.bits() - 1);
165 else
166 (*this) = (*this) / y;
167 return (*this);
168}
169
170/*************************************************
171 * Modulo Operator *
172 *************************************************/
173BigInt &BigInt::operator%=(const BigInt &mod)
174{
175 return (*this = (*this) % mod);
176}
177
178/*************************************************
179 * Modulo Operator *
180 *************************************************/
181word BigInt::operator%=(word mod)
182{
183 if (mod == 0)
184 throw BigInt::DivideByZero();
185 if (power_of_2(mod)) {
186 word result = (word_at(n: 0) & (mod - 1));
187 clear();
188 grow_to(2);
189 reg[0] = result;
190 return result;
191 }
192
193 word remainder = 0;
194
195 for (u32bit j = sig_words(); j > 0; --j)
196 remainder = bigint_modop(remainder, word_at(n: j - 1), mod);
197 clear();
198 grow_to(2);
199
200 if (remainder && sign() == BigInt::Negative)
201 reg[0] = mod - remainder;
202 else
203 reg[0] = remainder;
204
205 set_sign(BigInt::Positive);
206
207 return word_at(n: 0);
208}
209
210/*************************************************
211 * Left Shift Operator *
212 *************************************************/
213BigInt &BigInt::operator<<=(u32bit shift)
214{
215 if (shift) {
216 const u32bit shift_words = shift / MP_WORD_BITS, shift_bits = shift % MP_WORD_BITS, words = sig_words();
217
218 grow_to(words + shift_words + (shift_bits ? 1 : 0));
219 bigint_shl1(get_reg(), words, shift_words, shift_bits);
220 }
221
222 return (*this);
223}
224
225/*************************************************
226 * Right Shift Operator *
227 *************************************************/
228BigInt &BigInt::operator>>=(u32bit shift)
229{
230 if (shift) {
231 const u32bit shift_words = shift / MP_WORD_BITS, shift_bits = shift % MP_WORD_BITS;
232
233 bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits);
234
235 if (is_zero())
236 set_sign(Positive);
237 }
238
239 return (*this);
240}
241
242}
243} // WRAPNS_LINE
244

source code of qca/src/botantools/botan/big_ops2.cpp