Warning, file /libraries/qca/src/botantools/botan/big_ops3.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 Copyright (C) 1999-2007 The Botan Project. All rights reserved.
0003 
0004 Redistribution and use in source and binary forms, for any use, with or without
0005 modification, is permitted provided that the following conditions are met:
0006 
0007 1. Redistributions of source code must retain the above copyright notice, this
0008 list of conditions, and the following disclaimer.
0009 
0010 2. Redistributions in binary form must reproduce the above copyright notice,
0011 this list of conditions, and the following disclaimer in the documentation
0012 and/or other materials provided with the distribution.
0013 
0014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
0015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
0017 
0018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
0019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
0020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 */
0026 // LICENSEHEADER_END
0027 namespace QCA { // WRAPNS_LINE
0028 /*************************************************
0029  * BigInt Binary Operators Source File            *
0030  * (C) 1999-2007 The Botan Project                *
0031  *************************************************/
0032 
0033 } // WRAPNS_LINE
0034 #include <botan/bigint.h>
0035 namespace QCA { // WRAPNS_LINE
0036 } // WRAPNS_LINE
0037 #include <botan/numthry.h>
0038 namespace QCA { // WRAPNS_LINE
0039 } // WRAPNS_LINE
0040 #include <botan/mp_core.h>
0041 namespace QCA { // WRAPNS_LINE
0042 } // WRAPNS_LINE
0043 #include <botan/bit_ops.h>
0044 namespace QCA { // WRAPNS_LINE
0045 } // WRAPNS_LINE
0046 #include <algorithm>
0047 namespace QCA { // WRAPNS_LINE
0048 
0049 namespace Botan {
0050 
0051 /*************************************************
0052  * Addition Operator                              *
0053  *************************************************/
0054 BigInt operator+(const BigInt &x, const BigInt &y)
0055 {
0056     const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
0057 
0058 #ifdef BOTAN_TYPES_QT
0059     BigInt z(x.sign(), qMax(x_sw, y_sw) + 1);
0060 #else
0061     BigInt z(x.sign(), std::max(x_sw, y_sw) + 1);
0062 #endif
0063 
0064     if ((x.sign() == y.sign()))
0065         bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
0066     else {
0067         s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw);
0068 
0069         if (relative_size < 0) {
0070             bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw);
0071             z.set_sign(y.sign());
0072         } else if (relative_size == 0)
0073             z.set_sign(BigInt::Positive);
0074         else if (relative_size > 0)
0075             bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
0076     }
0077 
0078     return z;
0079 }
0080 
0081 /*************************************************
0082  * Subtraction Operator                           *
0083  *************************************************/
0084 BigInt operator-(const BigInt &x, const BigInt &y)
0085 {
0086     const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
0087 
0088     s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw);
0089 
0090 #ifdef BOTAN_TYPES_QT
0091     BigInt z(BigInt::Positive, qMax(x_sw, y_sw) + 1);
0092 #else
0093     BigInt z(BigInt::Positive, std::max(x_sw, y_sw) + 1);
0094 #endif
0095 
0096     if (relative_size < 0) {
0097         if (x.sign() == y.sign())
0098             bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw);
0099         else
0100             bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
0101         z.set_sign(y.reverse_sign());
0102     } else if (relative_size == 0) {
0103         if (x.sign() != y.sign())
0104             bigint_shl2(z.get_reg(), x.data(), x_sw, 0, 1);
0105     } else if (relative_size > 0) {
0106         if (x.sign() == y.sign())
0107             bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
0108         else
0109             bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw);
0110         z.set_sign(x.sign());
0111     }
0112     return z;
0113 }
0114 
0115 /*************************************************
0116  * Multiplication Operator                        *
0117  *************************************************/
0118 BigInt operator*(const BigInt &x, const BigInt &y)
0119 {
0120     const u32bit x_sw = x.sig_words(), y_sw = y.sig_words();
0121 
0122     BigInt z(BigInt::Positive, x.size() + y.size());
0123 
0124     if (x_sw == 1 && y_sw)
0125         bigint_linmul3(z.get_reg(), y.data(), y_sw, x.word_at(0));
0126     else if (y_sw == 1 && x_sw)
0127         bigint_linmul3(z.get_reg(), x.data(), x_sw, y.word_at(0));
0128     else if (x_sw && y_sw) {
0129         SecureVector<word> workspace(z.size());
0130         bigint_mul(z.get_reg(), z.size(), workspace, x.data(), x.size(), x_sw, y.data(), y.size(), y_sw);
0131     }
0132 
0133     if (x_sw && y_sw && x.sign() != y.sign())
0134         z.flip_sign();
0135     return z;
0136 }
0137 
0138 /*************************************************
0139  * Division Operator                              *
0140  *************************************************/
0141 BigInt operator/(const BigInt &x, const BigInt &y)
0142 {
0143     BigInt q, r;
0144     divide(x, y, q, r);
0145     return q;
0146 }
0147 
0148 /*************************************************
0149  * Modulo Operator                                *
0150  *************************************************/
0151 BigInt operator%(const BigInt &n, const BigInt &mod)
0152 {
0153     if (mod.is_zero())
0154         throw BigInt::DivideByZero();
0155     if (mod.is_negative())
0156         throw Invalid_Argument("BigInt::operator%: modulus must be > 0");
0157     if (n.is_positive() && mod.is_positive() && n < mod)
0158         return n;
0159 
0160     BigInt q, r;
0161     divide(n, mod, q, r);
0162     return r;
0163 }
0164 
0165 /*************************************************
0166  * Modulo Operator                                *
0167  *************************************************/
0168 word operator%(const BigInt &n, word mod)
0169 {
0170     if (mod == 0)
0171         throw BigInt::DivideByZero();
0172     if (power_of_2(mod))
0173         return (n.word_at(0) & (mod - 1));
0174 
0175     word remainder = 0;
0176 
0177     for (u32bit j = n.sig_words(); j > 0; --j)
0178         remainder = bigint_modop(remainder, n.word_at(j - 1), mod);
0179 
0180     if (remainder && n.sign() == BigInt::Negative)
0181         return mod - remainder;
0182     return remainder;
0183 }
0184 
0185 /*************************************************
0186  * Left Shift Operator                            *
0187  *************************************************/
0188 BigInt operator<<(const BigInt &x, u32bit shift)
0189 {
0190     if (shift == 0)
0191         return x;
0192 
0193     const u32bit shift_words = shift / MP_WORD_BITS, shift_bits = shift % MP_WORD_BITS;
0194 
0195     const u32bit x_sw = x.sig_words();
0196 
0197     BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0));
0198     bigint_shl2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits);
0199     return y;
0200 }
0201 
0202 /*************************************************
0203  * Right Shift Operator                           *
0204  *************************************************/
0205 BigInt operator>>(const BigInt &x, u32bit shift)
0206 {
0207     if (shift == 0)
0208         return x;
0209     if (x.bits() <= shift)
0210         return 0;
0211 
0212     const u32bit shift_words = shift / MP_WORD_BITS, shift_bits = shift % MP_WORD_BITS, x_sw = x.sig_words();
0213 
0214     BigInt y(x.sign(), x_sw - shift_words);
0215     bigint_shr2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits);
0216     return y;
0217 }
0218 
0219 }
0220 } // WRAPNS_LINE