Botan  1.11.15
src/lib/math/numbertheory/mp_numth.cpp
Go to the documentation of this file.
00001 /*
00002 * Fused and Important MP Algorithms
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/numthry.h>
00009 #include <botan/internal/mp_core.h>
00010 #include <botan/internal/rounding.h>
00011 #include <algorithm>
00012 
00013 namespace Botan {
00014 
00015 /*
00016 * Square a BigInt
00017 */
00018 BigInt square(const BigInt& x)
00019    {
00020    const size_t x_sw = x.sig_words();
00021 
00022    BigInt z(BigInt::Positive, round_up<size_t>(2*x_sw, 16));
00023    secure_vector<word> workspace(z.size());
00024 
00025    bigint_sqr(z.mutable_data(), z.size(),
00026               &workspace[0],
00027               x.data(), x.size(), x_sw);
00028    return z;
00029    }
00030 
00031 /*
00032 * Multiply-Add Operation
00033 */
00034 BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c)
00035    {
00036    if(c.is_negative() || c.is_zero())
00037       throw Invalid_Argument("mul_add: Third argument must be > 0");
00038 
00039    BigInt::Sign sign = BigInt::Positive;
00040    if(a.sign() != b.sign())
00041       sign = BigInt::Negative;
00042 
00043    const size_t a_sw = a.sig_words();
00044    const size_t b_sw = b.sig_words();
00045    const size_t c_sw = c.sig_words();
00046 
00047    BigInt r(sign, std::max(a.size() + b.size(), c_sw) + 1);
00048    secure_vector<word> workspace(r.size());
00049 
00050    bigint_mul(r.mutable_data(), r.size(),
00051               &workspace[0],
00052               a.data(), a.size(), a_sw,
00053               b.data(), b.size(), b_sw);
00054 
00055    const size_t r_size = std::max(r.sig_words(), c_sw);
00056    bigint_add2(r.mutable_data(), r_size, c.data(), c_sw);
00057    return r;
00058    }
00059 
00060 /*
00061 * Subtract-Multiply Operation
00062 */
00063 BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c)
00064    {
00065    if(a.is_negative() || b.is_negative())
00066       throw Invalid_Argument("sub_mul: First two arguments must be >= 0");
00067 
00068    BigInt r = a;
00069    r -= b;
00070    r *= c;
00071    return r;
00072    }
00073 
00074 }