Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49446 - in sandbox/mp_math: . boost boost/mp_math boost/mp_math/mp_int boost/mp_math/mp_int/detail boost/mp_math/mp_int/detail/asm boost/mp_math/mp_int/detail/asm/x86 libs libs/mp_math libs/mp_math/doc libs/mp_math/doc/html libs/mp_math/doc/html/benchmark_imgs libs/mp_math/doc/html/benchmark_imgs/k7 libs/mp_math/doc/html/mp_int_ libs/mp_math/test libs/mp_math/tools libs/mp_math/tools/benchmark
From: baraclese_at_[hidden]
Date: 2008-10-24 14:49:44


Author: baraclese
Date: 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
New Revision: 49446
URL: http://svn.boost.org/trac/boost/changeset/49446

Log:
Initial commit.
Added:
   sandbox/mp_math/
   sandbox/mp_math/LICENSE_1_0.txt (contents, props changed)
   sandbox/mp_math/boost/
   sandbox/mp_math/boost.png (contents, props changed)
   sandbox/mp_math/boost/mp_math/
   sandbox/mp_math/boost/mp_math/mp_int/
   sandbox/mp_math/boost/mp_math/mp_int.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/abs.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/add.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/ctors.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/
   sandbox/mp_math/boost/mp_math/mp_int/detail/asm/
   sandbox/mp_math/boost/mp_math/mp_int/detail/asm/x86/
   sandbox/mp_math/boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/integral_ops.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/meta_math.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/prime_tab.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/detail/string_conversion_constants.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/div.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/mod.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/modular_reduction.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/mul.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/numeric_limits.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/operators.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/pow.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/prime.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/random.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/root.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/sqr.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/sub.hpp (contents, props changed)
   sandbox/mp_math/boost/mp_math/mp_int/traits.hpp (contents, props changed)
   sandbox/mp_math/libs/
   sandbox/mp_math/libs/mp_math/
   sandbox/mp_math/libs/mp_math/doc/
   sandbox/mp_math/libs/mp_math/doc/bibliography.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/add.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/ctor_dec.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/ctor_hex.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/divide.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/input_vecs.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/modpow.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/modulo.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/multiply.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/square.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/subtract.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/to_dec.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/to_hex.png (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/boostbook.css (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/index.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/bibliography.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/implementation_notes.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_reference.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_traits_reference.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/performance.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/primality_tests_reference.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/tutorial.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_bits_reference.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_reference.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/implementation_notes.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/introduction.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/jamfile.v2 (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/mp_int.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/mp_int_reference.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/mp_int_traits_reference.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/performance.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/primality_tests_reference.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/tutorial.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_bits_reference.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_reference.qbk (contents, props changed)
   sandbox/mp_math/libs/mp_math/index.html (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/
   sandbox/mp_math/libs/mp_math/test/add.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/cmp.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/compile_all.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/ctors.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/div.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/gcd.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/integral_ops.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/jacobi.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/jamfile.v2 (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/mul.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/pow.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/prerequisite.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/prime.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/random.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/root.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/serialization.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/shift.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/sqr.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/stream_io.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/string_ops.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/sub.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/to_integral.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/traits.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/
   sandbox/mp_math/libs/mp_math/tools/benchmark/
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_result.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.hpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2 (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.cpp (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.h (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_class.h (contents, props changed)
   sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_superclass.h (contents, props changed)
   sandbox/mp_math/project-root.jam (contents, props changed)

Added: sandbox/mp_math/LICENSE_1_0.txt
==============================================================================
--- (empty file)
+++ sandbox/mp_math/LICENSE_1_0.txt 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.

Added: sandbox/mp_math/boost.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/boost/mp_math/mp_int.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,11 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_HPP
+#define BOOST_MP_MATH_MP_INT_HPP
+
+#include <boost/mp_math/mp_int/mp_int.hpp>
+
+#endif

Added: sandbox/mp_math/boost/mp_math/mp_int/abs.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/abs.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,12 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+mp_int<A,T> abs(const mp_int<A,T>& x)
+{
+ mp_int<A,T> tmp(x);
+ tmp.sign_ = 1;
+ return tmp;
+}

Added: sandbox/mp_math/boost/mp_math/mp_int/add.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/add.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,87 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+void mp_int<A,T>::add_digit(digit_type b)
+{
+ if (is_positive())
+ {
+ grow_capacity(used_ + 1);
+ const digit_type carry =
+ ops_type::add_single_digit(digits_, digits_, used_, b);
+ if (carry)
+ digits_[used_++] = carry;
+ }
+ else
+ {
+ if (digits_[0] >= b) // example: -16 + 5 = -11; or -5 + 5 = 0
+ {
+ digits_[0] -= b;
+ if (is_zero())
+ sign_ = 1;
+ }
+ else
+ {
+ if (used_ == 1) // example: -1 + 5 = 4
+ digits_[0] = b - digits_[0];
+ else // example -11 + 5 = -6
+ {
+ sign_ = 1;
+ sub_digit(b);
+ sign_ = -1;
+ }
+ }
+ }
+}
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+// does not handle sign
+template<class A, class T>
+void mp_int<A,T>::add_magnitude(const mp_int& rhs)
+{
+ const mp_int* x;
+ const mp_int* y;
+
+ // x will point to the number with the most digits
+ if (used_ > rhs.used_)
+ {
+ x = this;
+ y = &rhs;
+ }
+ else
+ {
+ x = &rhs;
+ y = this;
+ }
+
+ grow_capacity(x->used_ + 1);
+
+ digit_type carry = ops_type::add_digits(digits_,
+ x->digits_,
+ y->digits_, y->used_);
+
+ size_type n = ops_type::ripple_carry(digits_ + y->used_,
+ x->digits_ + y->used_,
+ x->used_ - y->used_, carry);
+ n += y->used_;
+
+ if (n < x->used_) // this implies that there is no carry left
+ {
+ if (x != this)
+ {
+ std::memcpy(digits_ + n, x->digits_ + n, sizeof(digit_type) * (x->used_ - n));
+ used_ = x->used_;
+ }
+ return;
+ }
+ else if (carry) // at this point n equals x->used_
+ {
+ digits_[n] = carry;
+ ++n;
+ }
+
+ used_ = n;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/ctors.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/ctors.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,270 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+mp_int<A,T>::mp_int()
+:
+ digits_(0),
+ used_(0),
+ capacity_(0),
+ sign_(1)
+{
+}
+
+template<class A, class T>
+template<typename IntegralT>
+mp_int<A,T>::mp_int(
+ IntegralT b,
+ typename enable_if<is_integral<IntegralT> >::type*)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ detail::integral_ops<IntegralT>::assign(*this, b);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+void mp_int<A,T>::init(RandomAccessIterator c, RandomAccessIterator last)
+{
+ assert(used_ == 0);
+
+ if (c == last)
+ {
+ sign_ = 1;
+ return;
+ }
+
+ int sign;
+
+ if (*c == '-')
+ {
+ ++c;
+ sign = -1;
+ }
+ else
+ {
+ if (*c == '+')
+ ++c;
+ sign = 1;
+ }
+
+ // detect the radix
+ unsigned int radix;
+
+ if (c != last)
+ {
+ if (*c == '0') // octal
+ {
+ ++c;
+ if (c != last && (*c == 'x' || *c == 'X')) // hex
+ {
+ radix = 16;
+ ++c;
+ }
+ else
+ {
+ radix = 8;
+ --c; // keep the zero, necessary for mp_int("0")
+ }
+ }
+ else // decimal
+ radix = 10;
+ }
+ else
+ throw std::invalid_argument("mp_int ctor: malformed string");
+
+ sign_ = sign;
+
+ from_string(c, last, radix);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+void mp_int<A,T>::init(RandomAccessIterator c,
+ RandomAccessIterator last,
+ std::ios_base::fmtflags f)
+{
+ assert(used_ == 0);
+
+ if (c == last)
+ {
+ sign_ = 1;
+ return;
+ }
+
+ if (*c == '-')
+ {
+ sign_ = -1;
+ ++c;
+ }
+ else
+ {
+ if (f & std::ios_base::showpos)
+ {
+ if (*c == '+')
+ ++c;
+ else
+ throw std::invalid_argument("mp_int<>::init: expected a '+' sign");
+ }
+ sign_ = 1;
+ }
+
+ const bool uppercase = f & std::ios_base::uppercase;
+ const bool showbase = f & std::ios_base::showbase;
+
+ bool bad_prefix = false;
+ unsigned radix;
+
+ if (f & std::ios_base::hex)
+ {
+ if (showbase)
+ {
+ if (*c == '0')
+ ++c;
+ else
+ bad_prefix = true;
+ if (*c == 'x' || (*c == 'X' && uppercase))
+ ++c;
+ else
+ bad_prefix = true;
+ }
+ radix = 16;
+ }
+ else if (f & std::ios_base::oct)
+ {
+ if (showbase)
+ {
+ if (*c == '0')
+ ++c;
+ else
+ bad_prefix = true;
+ }
+ radix = 8;
+ }
+ else if (f & std::ios_base::dec)
+ radix = 10;
+ else
+ throw std::invalid_argument("mp_int<>::init: unknown radix");
+
+ if (bad_prefix)
+ throw std::invalid_argument("mp_int<>::init: bad radix prefix");
+
+ from_string(c, last, radix);
+}
+
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+mp_int<A,T>::mp_int(RandomAccessIterator first, RandomAccessIterator last)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(first, last);
+}
+
+template<class A, class T>
+mp_int<A,T>::mp_int(const char* s)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s, s + std::strlen(s));
+}
+
+template<class A, class T>
+mp_int<A,T>::mp_int(const char* s, std::ios_base::fmtflags f)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s, s + std::strlen(s), f);
+}
+
+
+#ifndef BOOST_NO_CWCHAR
+template<class A, class T>
+mp_int<A,T>::mp_int(const wchar_t* s)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s, s + std::wcslen(s));
+}
+
+ template<class A, class T>
+mp_int<A,T>::mp_int(const wchar_t* s, std::ios_base::fmtflags f)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s, s + std::wcslen(s), f);
+}
+#endif
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+mp_int<A,T>::mp_int(const std::basic_string<charT,traits,Alloc>& s)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s.begin(), s.end());
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+mp_int<A,T>::mp_int(const std::basic_string<charT,traits,Alloc>& s,
+ std::ios_base::fmtflags f)
+:
+ digits_(0),
+ used_(0),
+ capacity_(0)
+{
+ init(s.begin(), s.end(), f);
+}
+
+
+template<class A, class T>
+mp_int<A,T>::mp_int(const mp_int& copy)
+{
+ digits_ = this->allocate(copy.used_);
+ std::memcpy(digits_, copy.digits_, copy.used_ * sizeof(digit_type));
+ used_ = copy.used_;
+ capacity_ = copy.used_;
+ sign_ = copy.sign_;
+}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+template<class A, class T>
+mp_int<A,T>::mp_int(mp_int&& copy)
+:
+ digits_(copy.digits_),
+ used_(copy.used_),
+ capacity_(copy.capacity_),
+ sign_(copy.sign_)
+{
+ copy.digits_ = 0;
+ copy.used_ = 0;
+ copy.capacity_ = 0;
+ copy.sign_ = 1;
+}
+#endif
+
+
+template<class A, class T>
+mp_int<A,T>::~mp_int()
+{
+ this->deallocate(digits_, capacity_);
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,75 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template
+struct primitive_ops<unsigned int, unsigned int, std::size_t>
+{
+ typedef unsigned int dword;
+ static unsigned int add_digits(dword* dst, const dword* y, std::size_t n);
+ static unsigned int subtract_digits(dword* dst, const dword* y, std::size_t n);
+};
+
+
+template
+inline
+unsigned int
+primitive_ops<unsigned int, unsigned int, std::size_t>::
+add_digits(unsigned int* x, const unsigned int* y, std::size_t n)
+{
+ unsigned int carry = 0;
+
+ __asm__ __volatile__(
+ "clc \n\t"
+ "0: \n\t"
+ "mov (%[y]), %%eax \n\t"
+ "adc %%eax, (%[x]) \n\t"
+ "lea 4(%[y]), %[y] \n\t" // increment pointer
+ "lea 4(%[x]), %[x] \n\t" // increment pointer
+ "loop 0b \n\t"
+ "adc $0, %[carry] "
+ :
+ [carry] "=m" (carry)
+ :
+ [y] "r" (y),
+ [x] "r" (x),
+ [n] "c" (n)
+ :
+ "cc", "memory", "%eax"
+ );
+
+ return carry;
+}
+
+
+template
+inline
+unsigned int
+primitive_ops<unsigned int, unsigned int, std::size_t>::
+subtract_digits(unsigned int* x, const unsigned int* y, std::size_t n)
+{
+ unsigned int carry = 0;
+
+ __asm__ __volatile__(
+ "clc \n\t"
+ "0: \n\t"
+ "mov (%[y]), %%eax \n\t"
+ "sbb %%eax, (%[x]) \n\t"
+ "lea 4(%[y]), %[y] \n\t"
+ "lea 4(%[x]), %[x] \n\t"
+ "loop 0b \n\t"
+ "adc $0, %[carry] "
+ :
+ [carry] "=m" (carry)
+ :
+ [y] "r" (y),
+ [x] "r" (x),
+ [n] "c" (n)
+ :
+ "cc", "memory", "%eax"
+ );
+
+ return carry;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/integral_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/integral_ops.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,708 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_DETAIL_INTEGRAL_OPS_HPP
+#define BOOST_MP_MATH_MP_INT_DETAIL_INTEGRAL_OPS_HPP
+
+#include <boost/static_assert.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/mp_math/mp_int/detail/meta_math.hpp>
+
+// here we optimize interaction with built in integral types
+
+namespace boost {
+namespace mp_math {
+
+template<class A, class T>
+struct mp_int;
+
+namespace detail {
+
+
+template<
+ typename IntegralT,
+ class MpInt,
+ bool is_signed = std::numeric_limits<IntegralT>::is_signed
+>
+struct integral_ops_impl
+{};
+
+
+template<
+ typename IntegralT,
+ class MpInt
+>
+struct integral_ops_impl<IntegralT, MpInt, false>
+{
+ static void assign (MpInt& lhs, IntegralT rhs);
+
+ static bool equal (const MpInt& lhs, IntegralT rhs);
+ static bool less (const MpInt& lhs, IntegralT rhs);
+
+ static void add (MpInt& lhs, IntegralT rhs);
+ static void subtract(MpInt& lhs, IntegralT rhs);
+ static void multiply(MpInt& lhs, IntegralT rhs);
+ static void divide (MpInt& lhs, IntegralT rhs);
+ static void modulo (MpInt& lhs, IntegralT rhs);
+
+ static void bitwise_or (MpInt& lhs, IntegralT rhs);
+ static void bitwise_and(MpInt& lhs, IntegralT rhs);
+ static void bitwise_xor(MpInt& lhs, IntegralT rhs);
+
+private:
+
+ static const typename MpInt::size_type q =
+ std::numeric_limits<IntegralT>::digits / (MpInt::valid_bits + 1) + 1;
+
+ static bool equal_to_integral_type(const MpInt& x, IntegralT y)
+ {
+ try
+ {
+ return x.template to_integral<IntegralT>() == y;
+ }
+ catch (const std::overflow_error&)
+ {
+ return false;
+ }
+ }
+};
+
+
+template<
+ typename IntegralT,
+ class MpInt
+>
+struct integral_ops_impl<IntegralT, MpInt, true>
+{
+ static void assign (MpInt& lhs, IntegralT rhs);
+
+ static bool equal (const MpInt& lhs, IntegralT rhs);
+ static bool less (const MpInt& lhs, IntegralT rhs);
+
+ static void add (MpInt& lhs, IntegralT rhs);
+ static void subtract(MpInt& lhs, IntegralT rhs);
+ static void multiply(MpInt& lhs, IntegralT rhs);
+ static void divide (MpInt& lhs, IntegralT rhs);
+ static void modulo (MpInt& lhs, IntegralT rhs);
+
+ static void bitwise_or (MpInt& lhs, IntegralT rhs);
+ static void bitwise_and(MpInt& lhs, IntegralT rhs);
+ static void bitwise_xor(MpInt& lhs, IntegralT rhs);
+
+private:
+
+ typedef typename make_unsigned<IntegralT>::type unsigned_type;
+
+ static const typename MpInt::size_type q =
+ std::numeric_limits<IntegralT>::digits + (MpInt::valid_bits - 1)
+ / MpInt::valid_bits;
+
+ static bool equal_to_integral_type(const MpInt& x, IntegralT y)
+ {
+ try
+ {
+ return x.template to_integral<IntegralT>() == y;
+ }
+ catch (const std::overflow_error&)
+ {
+ return false;
+ }
+ }
+};
+
+
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::assign(MpInt& lhs, IntegralT rhs)
+{
+ lhs.zero();
+
+ if (rhs <= MpInt::digit_max)
+ lhs[0] = rhs;
+ else
+ {
+ typedef typename MpInt::digit_type digit_type;
+ static const int ud = std::numeric_limits<IntegralT>::digits;
+ static const int dd = MpInt::valid_bits;
+ static const int m = dd < ud ? dd : ud;
+ static const int h = m / 2;
+ /* set h bits at a time */
+ for (int i = 0; i < ud / h; ++i)
+ {
+ /* shift the number up h bits */
+ lhs <<= h;
+ // TODO optimize shift. only need to call grow_capacity once here
+ // then use lower level shift_left(lhs.digits_, h);
+
+ /* OR in the top h bits of the source */
+ lhs[0] |= (rhs >> (ud-h)) & (power<IntegralT,2,h>::value - 1);
+
+ /* shift the source up to the next h bits */
+ rhs <<= h;
+ }
+ lhs.clamp();
+ }
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::assign(MpInt& lhs, IntegralT rhs)
+{
+ int sign;
+ unsigned_type tmp;
+ if (rhs >= 0)
+ {
+ sign = 1;
+ tmp = rhs;
+ }
+ else
+ {
+ sign = -1;
+ // XXX using unary - may lose information on platforms without two's
+ // complement binary representation of integers. This conversion is well
+ // defined only within the minimum guaranteed integral limits given by the
+ // standard. In the functions below we use this several times again.
+ tmp = -rhs;
+ }
+
+ integral_ops_impl<unsigned_type,MpInt>::assign(lhs, tmp);
+
+ lhs.set_sign(sign);
+}
+
+template<typename IntegralT, class MpInt>
+bool
+integral_ops_impl<IntegralT, MpInt, false>::equal(const MpInt& lhs, IntegralT rhs)
+{
+ if (lhs.size() > q)
+ return false;
+
+ return equal_to_integral_type(lhs, rhs);
+}
+
+template<typename IntegralT, class MpInt>
+bool
+integral_ops_impl<IntegralT, MpInt, true>::equal(const MpInt& lhs, IntegralT rhs)
+{
+ const int r_sign = rhs < 0 ? -1 : 1;
+
+ if (lhs.sign() != r_sign)
+ return false;
+
+ if (lhs.size() > q)
+ return false;
+
+ return equal_to_integral_type(lhs, rhs);
+}
+
+template<typename IntegralT, class MpInt>
+bool
+integral_ops_impl<IntegralT, MpInt, false>::less(const MpInt& lhs, IntegralT rhs)
+{
+ if (lhs.sign() == -1)
+ return true;
+
+ if (lhs.size() > q)
+ return false;
+
+ return lhs.template to_integral<IntegralT>() < rhs;
+}
+
+template<typename IntegralT, class MpInt>
+bool
+integral_ops_impl<IntegralT, MpInt, true>::less(const MpInt& lhs, IntegralT rhs)
+{
+ if (lhs.sign() == -1 && rhs >= 0)
+ return true;
+
+ if (lhs.sign() == 1 && rhs < 0)
+ return false;
+
+ if (lhs.size() > q)
+ return false;
+
+ return lhs.template to_integral<IntegralT>() < rhs;
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::add(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs.add_digit(static_cast<typename MpInt::digit_type>(rhs));
+ else
+ lhs += MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::add(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs >= 0)
+ {
+ if (static_cast<unsigned_type>(rhs) <= MpInt::digit_max)
+ {
+ lhs.add_digit(static_cast<typename MpInt::digit_type>(rhs));
+ return;
+ }
+ }
+ else
+ {
+ const unsigned_type tmp(-rhs);
+ if (tmp <= MpInt::digit_max)
+ {
+ lhs.sub_digit(static_cast<typename MpInt::digit_type>(tmp));
+ return;
+ }
+ }
+
+ // TODO: we're touching the allocator below...
+ // we can probably do better maybe we can store the Integral to a
+ // digits array on the stack, then use the addition algorithm to
+ // add the numbers, or create a fixed precision int that can live on
+ // the stack and write operator += to let mp_int interact with fp_int
+ // the same goes for all other ops in this file that do this kind of stuff.
+ lhs += MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::subtract(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs.sub_digit(static_cast<typename MpInt::digit_type>(rhs));
+ else
+ lhs -= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::subtract(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs >= 0)
+ {
+ if (static_cast<unsigned_type>(rhs) <= MpInt::digit_max)
+ {
+ lhs.sub_digit(static_cast<typename MpInt::digit_type>(rhs));
+ return;
+ }
+ }
+ else
+ {
+ const unsigned_type tmp(-rhs);
+ if (tmp <= MpInt::digit_max)
+ {
+ lhs.add_digit(static_cast<typename MpInt::digit_type>(tmp));
+ return;
+ }
+ }
+
+ lhs -= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::multiply(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs.multiply_by_digit(static_cast<typename MpInt::digit_type>(rhs));
+ else
+ lhs *= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::multiply(MpInt& lhs, IntegralT rhs)
+{
+ int sign;
+ unsigned_type tmp;
+ if (rhs >= 0)
+ {
+ sign = 1;
+ tmp = rhs;
+ }
+ else
+ {
+ sign = -1;
+ tmp = -rhs;
+ }
+
+ if (tmp <= MpInt::digit_max)
+ {
+ lhs.multiply_by_digit(static_cast<typename MpInt::digit_type>(tmp));
+ lhs.set_sign(lhs.sign() * sign);
+ }
+ else
+ lhs *= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::divide(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs.divide_by_digit(rhs);
+ else
+ lhs /= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::divide(MpInt& lhs, IntegralT rhs)
+{
+ int sign;
+ unsigned_type tmp;
+ if (rhs >= 0)
+ {
+ sign = 1;
+ tmp = rhs;
+ }
+ else
+ {
+ sign = -1;
+ tmp = -rhs;
+ }
+
+ if (tmp <= MpInt::digit_max)
+ {
+ lhs.divide_by_digit(static_cast<typename MpInt::digit_type>(tmp));
+ lhs.set_sign(lhs.sign() / sign);
+ }
+ else
+ lhs /= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::modulo(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ {
+ lhs[0] = lhs.divide_by_digit(rhs);
+ lhs.set_size(1);
+ }
+ else
+ lhs %= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::modulo(MpInt& lhs, IntegralT rhs)
+{
+ unsigned_type tmp;
+ if (rhs >= 0)
+ tmp = rhs;
+ else
+ tmp = -rhs;
+
+ if (tmp <= MpInt::digit_max)
+ {
+ lhs[0] = lhs.divide_by_digit(static_cast<typename MpInt::digit_type>(tmp));
+ lhs.set_size(1);
+ }
+ else
+ lhs %= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::bitwise_or(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs[0] |= rhs;
+ else
+ lhs |= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::bitwise_or(MpInt& lhs, IntegralT rhs)
+{
+ // we care only about the absolute value of rhs
+ unsigned_type tmp;
+ if (rhs >= 0)
+ tmp = rhs;
+ else
+ tmp = -rhs;
+
+ if (tmp <= MpInt::digit_max)
+ lhs[0] |= static_cast<typename MpInt::digit_type>(tmp);
+ else
+ lhs |= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::bitwise_and(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs[0] &= rhs;
+ else
+ lhs &= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::bitwise_and(MpInt& lhs, IntegralT rhs)
+{
+ unsigned_type tmp;
+ if (rhs >= 0)
+ tmp = rhs;
+ else
+ tmp = -rhs;
+
+ if (tmp <= MpInt::digit_max)
+ lhs[0] &= static_cast<typename MpInt::digit_type>(tmp);
+ else
+ lhs &= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, false>::bitwise_xor(MpInt& lhs, IntegralT rhs)
+{
+ if (rhs <= MpInt::digit_max)
+ lhs[0] ^= rhs;
+ else
+ lhs ^= MpInt(rhs);
+}
+
+template<typename IntegralT, class MpInt>
+void
+integral_ops_impl<IntegralT, MpInt, true>::bitwise_xor(MpInt& lhs, IntegralT rhs)
+{
+ unsigned_type tmp;
+ if (rhs >= 0)
+ tmp = rhs;
+ else
+ tmp = -rhs;
+
+ if (tmp <= MpInt::digit_max)
+ lhs[0] ^= static_cast<typename MpInt::digit_type>(tmp);
+ else
+ lhs ^= MpInt(rhs);
+}
+
+
+
+
+
+template<
+ typename IntegralT,
+ class MpInt,
+ bool is_signed = std::numeric_limits<IntegralT>::is_signed,
+ bool is_larger = (std::numeric_limits<IntegralT>::digits > MpInt::valid_bits)
+>
+struct integral_ops2
+{};
+
+
+template<typename IntegralT, class MpInt>
+struct integral_ops2<IntegralT, MpInt, true, true>
+{
+ typedef std::numeric_limits<IntegralT> integral_type_limits;
+ typedef typename make_unsigned<IntegralT>::type unsigned_type;
+
+ static IntegralT to_integral(const MpInt& x);
+};
+
+template<typename IntegralT, class MpInt>
+struct integral_ops2<IntegralT, MpInt, true, false>
+{
+ typedef std::numeric_limits<IntegralT> integral_type_limits;
+ typedef typename make_unsigned<IntegralT>::type unsigned_type;
+
+ static IntegralT to_integral(const MpInt& x);
+};
+
+template<typename IntegralT, class MpInt>
+struct integral_ops2<IntegralT, MpInt, false, true>
+{
+ typedef std::numeric_limits<IntegralT> integral_type_limits;
+
+ static IntegralT apply_shift(const MpInt& x);
+ static IntegralT to_integral(const MpInt& x);
+};
+
+template<typename IntegralT, class MpInt>
+struct integral_ops2<IntegralT, MpInt, false, false>
+{
+ typedef std::numeric_limits<IntegralT> integral_type_limits;
+
+ static IntegralT apply_shift(const MpInt& x);
+ static IntegralT to_integral(const MpInt& x);
+};
+
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, true, true>::to_integral(const MpInt& x)
+{
+ if (x.size() == 1)
+ {
+ if (x.digits()[0] <= integral_type_limits::max())
+ return static_cast<IntegralT>(x.sign()) *
+ static_cast<IntegralT>(x[0]);
+ throw std::overflow_error(
+ "to_integral: integral type does not have enough precision to hold result");
+ }
+
+ const unsigned_type tmp = integral_ops2<unsigned_type, MpInt>::apply_shift(x);
+
+ return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(tmp);
+}
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, true, false>::to_integral(const MpInt& x)
+{
+ if (x.size() == 1)
+ return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(x[0]);
+
+ const unsigned_type tmp = integral_ops2<unsigned_type, MpInt>::apply_shift(x);
+
+ return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(tmp);
+}
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, false, true>::apply_shift(const MpInt& x)
+{
+ int shift_count = 0;
+ IntegralT tmp = 0;
+
+ for (typename MpInt::const_reverse_iterator digit = x.rbegin();
+ digit != x.rend(); ++digit)
+ {
+ tmp <<= MpInt::valid_bits;
+ if (shift_count++ * MpInt::valid_bits > integral_type_limits::digits)
+ throw std::overflow_error(
+ "to_integral: integral type does not have enough precision to hold result");
+ tmp |= *digit & (power<IntegralT,2,MpInt::valid_bits>::value - 1);
+ }
+
+ return tmp;
+}
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, false, true>::to_integral(const MpInt& x)
+{
+ if (x.sign() == 1)
+ {
+ if (x.size() == 1 && x[0] <= integral_type_limits::max())
+ return static_cast<IntegralT>(x[0]);
+ }
+ else
+ throw std::overflow_error(
+ "to_integral: cannot convert negative number to unsigned integral type");
+
+ return apply_shift(x);
+}
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, false, false>::apply_shift(const MpInt&)
+{
+ throw std::overflow_error(
+ "to_integral: integral type does not have enough precision to hold result");
+}
+
+template<typename IntegralT, class MpInt>
+IntegralT integral_ops2<IntegralT, MpInt, false, false>::to_integral(const MpInt& x)
+{
+ if (x.size() == 1)
+ return static_cast<IntegralT>(x[0]);
+ else
+ return apply_shift(x);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+
+template<typename IntegralT>
+struct integral_ops
+{
+ BOOST_STATIC_ASSERT(boost::is_integral<IntegralT>::value);
+
+ template<class A, class T>
+ static IntegralT convert(const mp_int<A,T>& x)
+ {
+ return integral_ops2<IntegralT, mp_int<A,T> >::to_integral(x);
+ }
+
+ template<class A, class T>
+ static void assign(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::assign(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static bool equal(const mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ return integral_ops_impl<IntegralT, mp_int<A,T> >::equal(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static bool less(const mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ return integral_ops_impl<IntegralT, mp_int<A,T> >::less(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void add(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::add(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void subtract(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::subtract(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void multiply(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::multiply(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void divide(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::divide(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void modulo(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::modulo(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void bitwise_or(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_or(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void bitwise_and(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_and(lhs, rhs);
+ }
+
+ template<class A, class T>
+ static void bitwise_xor(mp_int<A,T>& lhs, IntegralT rhs)
+ {
+ integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_xor(lhs, rhs);
+ }
+};
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/meta_math.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/meta_math.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,74 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_DETAIL_META_MATH_HPP
+#define BOOST_MP_MATH_MP_INT_DETAIL_META_MATH_HPP
+
+#include <boost/config.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+
+// power -----------------------------------------------------------------------
+
+template<
+ typename IntegralT,
+ IntegralT X, IntegralT Y,
+ IntegralT Result = X, IntegralT Count = 0, bool EndRecursion = Count == Y-1>
+struct power_impl
+{
+ static const IntegralT value =
+ power_impl<IntegralT, X, Y, Result*X, Count + 1>::value;
+};
+
+template<
+ typename IntegralT,
+ IntegralT X, IntegralT Y,
+ IntegralT Result, IntegralT Count>
+struct power_impl<IntegralT, X, Y, Result, Count, true>
+{
+ static const IntegralT value = Result;
+};
+
+
+// calculate x to the power of y
+template<typename IntegralT, IntegralT X, IntegralT Y>
+struct power
+{
+ static const IntegralT value = power_impl<IntegralT,X,Y>::value;
+};
+
+
+
+// logarithm to base 2 ---------------------------------------------------------
+
+template<typename T, T Temp, T Count = 1, bool continue_loop = (Temp > 1)>
+struct binary_log_impl
+{
+ static const T value = binary_log_impl<T, (Temp >> 1), Count + 1>::value;
+};
+
+template<typename T, T Temp, T Count>
+struct binary_log_impl<T, Temp, Count, false>
+{
+ static const T value = Count;
+};
+
+template<typename T, T Val>
+struct binary_log
+{
+ static const T value = binary_log_impl<T, Val>::value;
+};
+
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/prime_tab.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/prime_tab.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,95 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_DETAIL_PRIME_TAB_HPP
+#define BOOST_MP_MATH_DETAIL_PRIME_TAB_HPP
+
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+
+template<
+ typename T = unsigned short // this exists solely to keep this header-only
+>
+struct prime_tab_impl
+{
+ static const T values[];
+};
+
+template<typename T>
+const T prime_tab_impl<T>::values[] =
+{
+ /*0x2*/ 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+ 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+ 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+ 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+ // for greater than 8bit digit_type:
+ 0x0083,
+ 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+ 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+ 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+ 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+ 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+ 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+ 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+ 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+ 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+ 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+ 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+ 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+ 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+ 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+ 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+ 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+ 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+ 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+ 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+ 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+ 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+ 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+ 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+ 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+ 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+ 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+ 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+ 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+};
+
+
+template<
+ typename DigitT,
+ bool is_small =
+ std::numeric_limits<DigitT>::digits ==
+ std::numeric_limits<unsigned char>::digits
+>
+struct prime_tab
+:
+ prime_tab_impl<>
+{
+ static const int num_primes = 255;
+};
+
+// XXX For an unsigned char type that is larger than 8 bits, num_primes will be
+// wrong. Oh well.
+template<typename DigitT>
+struct prime_tab<DigitT,true>
+:
+ prime_tab_impl<>
+{
+ static const int num_primes = 30;
+};
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,533 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
+#define BOOST_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+
+// this struct contains some basic arithmetic algorithms
+// which can be implemented via assembly rather easily
+
+template<typename DigitT, typename WordT, typename SizeT>
+struct basic_primitive_ops
+{
+ typedef DigitT digit_type;
+ typedef WordT word_type;
+ typedef SizeT size_type;
+
+ static const word_type digit_bits = std::numeric_limits<digit_type>::digits;
+
+ // ADD ------------------------------------
+
+ // add x to the digits in y and store result in z
+ // ylen must be > 0
+ // returns: the last carry (it will not get stored in z)
+ static digit_type add_single_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x);
+
+ // z = x + y, returns last carry
+ static digit_type add_digits(digit_type* z,
+ const digit_type* x,
+ const digit_type* y,
+ size_type num);
+
+ // ripples the carry c up through n digits of x and stores results in z
+ // returns the number of digits the carry rippled through and stores the last
+ // carry in c. If there isn't a last carry then c will be 0.
+ static size_type ripple_carry(digit_type* z,
+ const digit_type* x,
+ size_type n,
+ digit_type& c);
+
+ // z = x + y, where xlen >= ylen
+ // z and x may not overlap
+ static void add_magnitude(digit_type* z,
+ const digit_type* x, size_type xlen,
+ const digit_type* y, size_type ylen);
+
+ // SUB ------------------------------------
+
+ // subtracts x from the digits in y and store result in z
+ static void subtract_single_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x);
+
+ // z = x - y, returns last borrow
+ static digit_type subtract_digits(digit_type* z,
+ const digit_type* x,
+ const digit_type* y,
+ size_type num);
+
+ // ripples the borrow up through n digits of x and stores results in z
+ // returns the number of digits the borrow rippled through
+ static size_type ripple_borrow(digit_type* z,
+ const digit_type* x,
+ size_type n,
+ digit_type borrow);
+
+ // z = x - y, where x >= y
+ static void sub_smaller_magnitude(digit_type* z,
+ const digit_type* x, size_type xlen,
+ const digit_type* y, size_type ylen);
+
+ // MUL ------------------------------------
+
+ // multiply y of length ylen with x and store result in z
+ // returns: the last carry (it will not get stored in z)
+ static digit_type multiply_by_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x);
+
+ // z = x * y
+ static void classic_mul(digit_type* z, const digit_type* x, size_type x_size,
+ const digit_type* y, size_type y_size);
+
+ // z = x * y; precondition: x_size >= y_size
+ static void comba_mul(digit_type* z, const digit_type* x, size_type x_size,
+ const digit_type* y, size_type y_size);
+
+ // z = x * y; for numbers of the same size
+ static void comba_mul(digit_type* z,
+ const digit_type* x,
+ const digit_type* y, size_type xy_size);
+
+ // SQR ------------------------------------
+
+ // z = x * x;
+ static void comba_sqr(digit_type* z, const digit_type* x, size_type x_size);
+};
+
+
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::digit_type
+basic_primitive_ops<D,W,S>::add_single_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x)
+{
+ word_type carry = static_cast<word_type>(*y++) + x;
+ *z++ = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+
+ while (carry && --ylen)
+ {
+ carry += static_cast<word_type>(*y++);
+ *z++ = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ return static_cast<digit_type>(carry);
+}
+
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::digit_type
+basic_primitive_ops<D,W,S>::add_digits(digit_type* z,
+ const digit_type* x,
+ const digit_type* y, size_type n)
+{
+ word_type carry = 0;
+
+ while (n--)
+ {
+ carry += static_cast<word_type>(*x++) + static_cast<word_type>(*y++);
+ *z++ = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ return static_cast<digit_type>(carry);
+}
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::size_type
+basic_primitive_ops<D,W,S>::ripple_carry(digit_type* z,
+ const digit_type* x,
+ size_type n,
+ digit_type& carry)
+{
+ word_type c = carry;
+ size_type i = 0;
+
+ for (; c && (i < n); ++i)
+ {
+ c += static_cast<word_type>(*x++);
+ *z++ = static_cast<digit_type>(c);
+ c >>= digit_bits;
+ }
+
+ carry = static_cast<digit_type>(c);
+
+ return i;
+}
+
+template<typename D, typename W, typename S>
+inline
+void basic_primitive_ops<D,W,S>::add_magnitude(
+ digit_type* z,
+ const digit_type* x, size_type xlen,
+ const digit_type* y, size_type ylen)
+{
+ digit_type carry = add_digits(z, x, y, ylen);
+
+ size_type n = ripple_carry(z + ylen, x + ylen, xlen - ylen, carry);
+
+ if (carry)
+ *(z + n++) = carry; // wrong
+
+ const size_type cur = ylen + n;
+ if (cur < xlen)
+ std::memcpy(z + cur, x + cur, (xlen - cur) * sizeof(digit_type));
+}
+
+template<typename D, typename W, typename S>
+inline
+void
+basic_primitive_ops<D,W,S>::subtract_single_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x)
+{
+ word_type borrow = static_cast<word_type>(*y++) - x;
+ *z++ = static_cast<digit_type>(borrow);
+ borrow >>= static_cast<word_type>(std::numeric_limits<word_type>::digits - 1);
+
+ while (borrow && --ylen)
+ {
+ borrow = static_cast<word_type>(*y++) - borrow;
+ *z++ = static_cast<digit_type>(borrow);
+ borrow >>= static_cast<word_type>(std::numeric_limits<word_type>::digits - 1);
+ }
+}
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::digit_type
+basic_primitive_ops<D,W,S>::subtract_digits(digit_type* z,
+ const digit_type* x,
+ const digit_type* y,
+ size_type n)
+{
+ word_type borrow = 0;
+
+ while (n--)
+ {
+ borrow = static_cast<word_type>(*x++) - static_cast<word_type>(*y++) - borrow;
+ *z++ = static_cast<digit_type>(borrow);
+ borrow >>= std::numeric_limits<word_type>::digits - 1;
+ }
+
+ return static_cast<digit_type>(borrow);
+}
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::size_type
+basic_primitive_ops<D,W,S>::ripple_borrow(digit_type* z,
+ const digit_type* x,
+ size_type n,
+ digit_type borrow)
+{
+ word_type b = borrow;
+ size_type i = 0;
+ for (; b && (i < n); ++i)
+ {
+ b = static_cast<word_type>(*x++) - b;
+ *z++ = static_cast<digit_type>(b);
+ b >>= std::numeric_limits<word_type>::digits - 1;
+ }
+
+ return i;
+}
+
+template<typename D, typename W, typename S>
+inline
+void basic_primitive_ops<D,W,S>::sub_smaller_magnitude(
+ digit_type* z,
+ const digit_type* x, size_type xlen,
+ const digit_type* y, size_type ylen)
+{
+ const digit_type borrow = subtract_digits(z, x, y, ylen);
+
+ const size_type n = ripple_borrow(z + ylen, x + ylen, xlen - ylen, borrow);
+
+ const size_type cur = ylen + n;
+ std::memcpy(z + cur, x + cur, (xlen - cur) * sizeof(digit_type));
+}
+
+
+template<typename D, typename W, typename S>
+inline
+typename basic_primitive_ops<D,W,S>::digit_type
+basic_primitive_ops<D,W,S>::multiply_by_digit(digit_type* z,
+ const digit_type* y, size_type ylen,
+ digit_type x)
+{
+ digit_type carry = 0;
+
+ while (ylen--)
+ {
+ const word_type tmp = static_cast<word_type>(carry)
+ + static_cast<word_type>(*y++)
+ * static_cast<word_type>(x);
+ *z++ = static_cast<digit_type>(tmp);
+ carry = static_cast<digit_type>(tmp >> digit_bits);
+ }
+ return carry;
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::classic_mul(
+ digit_type* z, const digit_type* x, size_type x_size,
+ const digit_type* y, size_type y_size)
+{
+ // phase 1
+ word_type tmp = static_cast<word_type>(x[0]) * static_cast<word_type>(y[0]);
+ z[0] = static_cast<digit_type>(tmp);
+
+ for (size_type i = 1; i < x_size; ++i)
+ {
+ tmp = (tmp >> digit_bits)
+ + static_cast<word_type>(x[i])
+ * static_cast<word_type>(y[0]);
+ z[i] = static_cast<digit_type>(tmp);
+ }
+
+ tmp >>= digit_bits;
+ z[x_size] = static_cast<digit_type>(tmp);
+
+ // phase 2
+ for (size_type i = 1; i < y_size; ++i)
+ {
+ tmp = static_cast<word_type>(y[i])
+ * static_cast<word_type>(x[0])
+ + static_cast<word_type>(z[i]);
+ z[i] = static_cast<digit_type>(tmp);
+
+ for (size_type j = 1; j < x_size; ++j)
+ {
+ tmp = (tmp >> digit_bits)
+ + static_cast<word_type>(y[i]) * static_cast<word_type>(x[j])
+ + static_cast<word_type>(z[i+j]);
+ z[i+j] = static_cast<digit_type>(tmp);
+ }
+
+ tmp >>= digit_bits;
+ z[i + x_size] = static_cast<digit_type>(tmp);
+ }
+}
+
+
+// K = 2 ^ (alpha - (2*beta-1))
+// alpha = num bits of word_type, beta = num bits of digit_type
+// calculation works in 3 phases
+// 65432
+// x 223
+//----------------------------------
+// | 18 15 | 12 9 6
+// 12 | 10 8 | 6 4
+// 12 10 | 8 6 | 4
+// | |
+// phase: 3 | 2 | 1
+//
+// TODO handle too long columns => carry may overflow. This can happen if
+// digit_type is 8bit; in that case delegate to classic_mul routine in
+// operator *= (). Just check if (smaller number).used_ >= overflow_count.
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_mul(
+ digit_type* z, const digit_type* x, size_type x_size,
+ const digit_type* y, size_type y_size)
+{
+ assert(x_size >= y_size);
+
+ const size_type k = x_size + y_size;
+
+ word_type acc = 0; // accumulator in each column
+ word_type carry = 0;
+
+ // phase 1
+ for (size_type i = 0; i < y_size; ++i)
+ {
+ for (size_type j = 0; j <= i; ++j)
+ {
+ const word_type r = static_cast<word_type>(y[j])
+ * static_cast<word_type>(x[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ // phase 2
+ for (size_type i = 0; i < x_size - y_size; ++i)
+ {
+ size_type j = 0;
+ size_type m = y_size;
+ while (j < y_size)
+ {
+ const word_type r = static_cast<word_type>(y[j])
+ * static_cast<word_type>(x[m+i]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ ++j; --m;
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ // phase 3
+ for (size_type i = x_size; i < k - 1; ++i)
+ {
+ for (size_type j = y_size - (k - i - 1); j < y_size; ++j)
+ {
+ const word_type r = static_cast<word_type>(y[j])
+ * static_cast<word_type>(x[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ *z = static_cast<digit_type>(acc);
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_mul(digit_type* z,
+ const digit_type* x,
+ const digit_type* y, size_type xy_size)
+{
+ word_type acc = 0; // accumulator for each column
+ word_type carry = 0;
+
+ // phase 1
+ for (size_type i = 0; i < xy_size; ++i)
+ {
+ for (size_type j = 0; j <= i; ++j)
+ {
+ const word_type r = static_cast<word_type>(x[j])
+ * static_cast<word_type>(y[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ // phase 2
+ for (size_type i = xy_size; i < 2 * xy_size - 1; ++i)
+ {
+ for (size_type j = i - xy_size + 1; j < xy_size; ++j)
+ {
+ const word_type r = static_cast<word_type>(x[j])
+ * static_cast<word_type>(y[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ *z = static_cast<digit_type>(acc);
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_sqr(digit_type* z,
+ const digit_type* x,
+ size_type x_size)
+{
+ word_type acc = 0; // accumulator for each column
+ word_type carry = 0;
+
+ // phase 1
+ for (size_type i = 0; i < x_size; ++i)
+ {
+ for (size_type j = 0; j <= i; ++j)
+ {
+ const word_type r = static_cast<word_type>(x[j])
+ * static_cast<word_type>(x[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ // phase 2
+ for (size_type i = x_size; i < 2 * x_size - 1; ++i)
+ {
+ for (size_type j = i - x_size + 1; j < x_size; ++j)
+ {
+ const word_type r = static_cast<word_type>(x[j])
+ * static_cast<word_type>(x[i-j]);
+ acc += r;
+ carry += acc >> digit_bits;
+ acc = static_cast<digit_type>(acc);
+ }
+ *z++ = static_cast<digit_type>(acc);
+ acc = static_cast<digit_type>(carry);
+ carry >>= digit_bits;
+ }
+
+ *z = static_cast<digit_type>(acc);
+}
+
+
+
+
+
+// This exists to ease development of primitive_ops specializations. If a
+// specialized function isn't available yet, the compiler will just choose the
+// inherited one. It also means that whenever we add a new function to
+// basic_primitive_ops no code will break since it will be available to all
+// specializations as well.
+template<typename D, typename W, typename S>
+struct primitive_ops : basic_primitive_ops<D,W,S>
+{};
+
+
+// Here we include primitive_ops specializations that use assembler
+
+#if defined(BOOST_MP_MATH_MP_INT_USE_ASM)
+
+ #if defined(__GNU__)
+ #if defined(__386__)
+ #include <boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp>
+ #endif
+ #endif
+
+#endif
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+

Added: sandbox/mp_math/boost/mp_math/mp_int/detail/string_conversion_constants.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/detail/string_conversion_constants.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,111 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_DETAIL_STRING_CONVERSION_CONSTANTS_HPP
+#define BOOST_MP_MATH_MP_INT_DETAIL_STRING_CONVERSION_CONSTANTS_HPP
+
+#include <boost/mp_math/mp_int/detail/meta_math.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+// radix 8, 10, 16
+
+
+template<
+ class MpInt,
+ typename MpInt::size_type Base,
+ typename MpInt::word_type Temp = 1,
+ typename MpInt::size_type Count = 0,
+ bool continue_loop = (Temp < MpInt::digit_max)
+>
+struct max_power_impl
+{
+ typedef max_power_impl<MpInt, Base, Temp * Base, Count + 1> result;
+ static const typename MpInt::size_type value = result::value;
+ static const typename MpInt::digit_type max_value = result::max_value;
+};
+
+template<
+ class MpInt,
+ typename MpInt::size_type Base,
+ typename MpInt::word_type Temp,
+ typename MpInt::size_type Count
+>
+struct max_power_impl<MpInt, Base, Temp, Count, false>
+{
+ static const typename MpInt::size_type value = Count - 1;
+ static const typename MpInt::digit_type max_value =
+ static_cast<typename MpInt::digit_type>(Temp / Base);
+};
+
+
+template<class MpInt, typename MpInt::size_type Base>
+struct max_power
+{
+ // convenience typedef ICEs on VC9 + SP1
+ //typedef max_power_impl<MpInt, Base> result;
+ static const typename MpInt::size_type value = max_power_impl<MpInt, Base>::value;
+ static const typename MpInt::digit_type max_value = max_power_impl<MpInt, Base>::max_value;
+};
+
+
+
+template<class MpInt, unsigned B>
+struct data
+{
+ typedef max_power<MpInt, B> x;
+ static const typename MpInt::size_type max_power_ = x::value;
+ static const typename MpInt::digit_type max_power_value_ = x::max_value;
+ static const typename MpInt::size_type radix_storage_bits_ =
+ binary_log<typename MpInt::size_type, B - 1>::value;
+};
+
+
+template<class MpInt>
+struct string_conversion_constants
+{
+ // maximum power of radix that fits into a digit_type
+ typename MpInt::size_type max_power;
+ // the corresponding power value (=radix**max_power)
+ typename MpInt::digit_type max_power_value;
+ // how many bits do we need to store the value radix
+ typename MpInt::size_type radix_storage_bits;
+
+ explicit string_conversion_constants(unsigned radix)
+ {
+ switch (radix)
+ {
+ case 8: *this = data<MpInt, 8>(); break;
+ case 10: *this = data<MpInt, 10>(); break;
+ case 16: *this = data<MpInt, 16>(); break;
+ default:
+ throw std::invalid_argument(
+ "mp_int<>::string_conversion_constants: unsupported radix used");
+ }
+ }
+
+ template<unsigned B>
+ string_conversion_constants& operator = (const data<MpInt, B>&)
+ {
+ max_power = data<MpInt, B>::max_power_;
+ max_power_value = data<MpInt, B>::max_power_value_;
+ radix_storage_bits = data<MpInt, B>::radix_storage_bits_;
+ return *this;
+ }
+};
+
+
+
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+

Added: sandbox/mp_math/boost/mp_math/mp_int/div.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/div.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,323 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+typename mp_int<A,T>::digit_type
+mp_int<A,T>::divide_by_digit(digit_type b)
+{
+ if (b == 0)
+ throw std::domain_error("mp_int::divide_by_digit: division by zero");
+
+ if (b == 1 || is_zero())
+ return 0;
+
+ const bool is_power_of_two = (b & (b-1)) == 0;
+ if (is_power_of_two)
+ {
+ for (int i = 0; i < valid_bits; ++i)
+ {
+ if (b == digit_type(1) << i)
+ {
+ const digit_type remainder = digits_[0] & ((digit_type(1) << i) - 1);
+ *this >>= i;
+ return remainder;
+ }
+ }
+ }
+
+ word_type w = 0;
+ for (reverse_iterator d = rbegin(); d != rend(); ++d)
+ {
+ w = (w << static_cast<word_type>(valid_bits)) | static_cast<word_type>(*d);
+ digit_type tmp;
+ if (w >= b)
+ {
+ tmp = static_cast<digit_type>(w / b);
+ w -= tmp * b;
+ }
+ else
+ tmp = 0;
+ *d = tmp;
+ }
+
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+
+ return static_cast<digit_type>(w);
+}
+
+/* b = a/2 */
+template<class A, class T>
+void mp_int<A,T>::divide_by_2()
+{
+ digit_type carry = 0;
+ for (reverse_iterator d = rbegin(); d != rend(); ++d)
+ {
+ /* get the carry for the next iteration */
+ const digit_type rr = *d & 1;
+ /* shift the current digit, add in carry and store */
+ *d = (*d >> 1) | (carry << (valid_bits - 1));
+ /* forward carry to next iteration */
+ carry = rr;
+ }
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+}
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+template<class A, class T>
+typename mp_int<A,T>::digit_type
+mp_int<A,T>::divide_by_3()
+{
+ /* b = 2**valid_bits / 3 */
+ const word_type b = (word_type(1) << static_cast<word_type>(valid_bits)) / word_type(3);
+
+ word_type w = 0;
+ for (reverse_iterator d = rbegin(); d != rend(); ++d)
+ {
+ w = (w << static_cast<word_type>(valid_bits)) | static_cast<word_type>(*d);
+
+ word_type t;
+ if (w >= 3)
+ {
+ /* multiply w by [1/3] */
+ t = (w * b) >> static_cast<word_type>(valid_bits);
+
+ /* now subtract 3 * [w/3] from w, to get the remainder */
+ w -= t+t+t;
+
+ /* fixup the remainder as required since
+ * the optimization is not exact.
+ */
+ while (w >= 3)
+ {
+ t += 1;
+ w -= 3;
+ }
+ }
+ else
+ t = 0;
+
+ *d = static_cast<digit_type>(t);
+ }
+
+ // *this is now the quotient
+ // return remainder
+ return static_cast<digit_type>(w);
+}
+
+/* shift right by a certain bit count */
+template<class A, class T>
+void mp_int<A,T>::shift_right(size_type b, mp_int* remainder)
+{
+ if (b == 0)
+ {
+ if (remainder)
+ remainder->zero();
+ return;
+ }
+
+ /* get the remainder */
+ mp_int t;
+ if (remainder)
+ {
+ *remainder = *this;
+ remainder->modulo_2_to_the_power_of(b);
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= static_cast<size_type>(valid_bits))
+ shift_digits_right(b / valid_bits);
+
+ /* shift any bit count < valid_bits */
+ const digit_type D = b % valid_bits;
+ if (D)
+ {
+ const digit_type mask = (digit_type(1) << D) - 1;
+
+ /* shift for lsb */
+ const digit_type shift = valid_bits - D;
+
+ digit_type carry = 0;
+ for (reverse_iterator d = rbegin(); d != rend(); ++d)
+ {
+ /* get the lower bits of this word in a temp */
+ const digit_type rr = *d & mask;
+
+ /* shift the current word and mix in the carry bits from the previous word */
+ *d = (*d >> D) | (carry << shift);
+
+ /* set the carry to the carry bits of the current word found above */
+ carry = rr;
+ }
+ }
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+}
+
+/* integer signed division.
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly
+ * incomplete. For example, it doesn't consider
+ * the case where digits are removed from 'x' in
+ * the inner loop. It also doesn't consider the
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+// divide *this by rhs, optionally store remainder
+template<class A, class T>
+void mp_int<A,T>::divide(const mp_int& rhs, mp_int* remainder)
+{
+ if (rhs.is_zero())
+ throw std::domain_error("mp_int::divide: division by zero");
+
+ /* if *this < rhs then q=0, r = *this */
+ if (compare_magnitude(rhs) == -1)
+ {
+ if (remainder)
+ *remainder = *this;
+ zero();
+ return;
+ }
+
+ mp_int q;
+ q.grow_capacity(used_ + 2);
+ q.used_ = used_ + 2;
+ std::memset(q.digits_, 0, q.used_ * sizeof(digit_type));
+
+ mp_int x(*this);
+ mp_int y(rhs);
+
+ /* fix the sign */
+ const int neg = (sign_ == rhs.sign_) ? 1 : -1;
+ x.sign_ = y.sign_ = 1;
+
+ /* normalize both x and y, ensure that y >= beta/2, [beta == 2**valid_bits] */
+ size_type norm = y.precision() % valid_bits;
+ if (norm < valid_bits-1)
+ {
+ norm = valid_bits - 1 - norm;
+ x <<= norm;
+ y <<= norm;
+ }
+ else
+ norm = 0;
+
+ /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+ const size_type n = x.used_ - 1;
+ const size_type t = y.used_ - 1;
+
+ // find leading digit of the quotient
+ /* while (x >= y*beta**(n-t)) do { q[n-t] += 1; x -= y*beta**(n-t) } */
+ y.shift_digits_left(n - t); /* y = y*beta**(n-t) */
+
+ while (x.compare(y) != -1)
+ {
+ ++q[n - t];
+ x -= y;
+ }
+
+ /* reset y by shifting it back down */
+ y.shift_digits_right(n - t);
+
+ // find the remainder of the digits
+ /* step 3. for i from n down to (t + 1) */
+ for (size_type i = n; i >= (t + 1); i--)
+ {
+ if (i > x.used_)
+ continue;
+
+ /* step 3.1 if xi == yt then set q{i-t-1} to beta-1,
+ * otherwise set q{i-t-1} to (xi*beta + x{i-1})/yt */
+ if (x[i] == y[t])
+ q[i - t - 1] = std::numeric_limits<digit_type>::max();
+ else
+ {
+ word_type tmp = static_cast<word_type>(x[i])
+ << static_cast<word_type>(valid_bits);
+ tmp |= x[i - 1];
+ tmp /= y[t];
+ q[i - t - 1] = static_cast<digit_type>(tmp);
+ }
+
+ // now fixup quotient estimation
+ /* while (q{i-t-1} * (yt * beta + y{t-1})) >
+ xi * beta**2 + xi-1 * beta + xi-2
+
+ do q{i-t-1} -= 1;
+ */
+
+ mp_int t1, t2;
+ t1.grow_capacity(3);
+ t2.grow_capacity(3);
+
+ ++q[i - t - 1];
+ do
+ {
+ --q[i - t - 1];
+
+ /* find left hand */
+ t1.zero();
+ t1[0] = (t == 0) ? 0 : y[t - 1];
+ t1[1] = y[t];
+ t1.used_ = 2;
+ t1.multiply_by_digit(q[i - t - 1]);
+
+ /* find right hand */
+ t2[0] = (i < 2) ? 0 : x[i - 2];
+ t2[1] = (i == 0) ? 0 : x[i - 1];
+ t2[2] = x[i];
+ t2.used_ = 3;
+ } while (t1.compare_magnitude(t2) == 1);
+
+ /* step 3.3 x = x - q{i-t-1} * y * beta**{i-t-1} */
+ t1 = y;
+ t1.multiply_by_digit(q[i - t -1]);
+ t1.shift_digits_left(i - t - 1);
+ x -= t1;
+
+ /* if x < 0 then { x = x + y*beta**{i-t-1}; q{i-t-1} -= 1; } */
+ if (x.sign_ == -1)
+ {
+ t1 = y;
+ t1.shift_digits_left(i - t -1);
+ x += t1;
+
+ --q[i - t - 1] = q[i - t - 1];
+ }
+ }
+
+ /* now q is the quotient and x is the remainder
+ * [which we have to normalize]
+ */
+
+ /* get sign before writing to c */
+ x.sign_ = x.is_zero() ? 1 : sign_;
+
+ q.clamp();
+ swap(q);
+ sign_ = neg;
+
+ if (remainder)
+ {
+ x >>= norm;
+ remainder->swap(x);
+ }
+}
+
+/*
+template<class A, class T>
+void divide(const mp_int<A,T>& x, const mp_int<A,T>& y, mp_int<A,T>& q, mp_int<A,T>& r)
+{
+ divide(x, y, &q, &r);
+}
+*/

Added: sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,60 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* Greatest Common Divisor using the binary method */
+template<class A, class T>
+mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b)
+{
+ typedef typename mp_int<A,T>::size_type size_type;
+
+ /* either zero then gcd is the largest */
+ if (a.is_zero())
+ return abs(b);
+ if (b.is_zero())
+ return abs(a);
+
+ /* get copies of a and b we can modify */
+ mp_int<A,T> u = abs(a);
+ mp_int<A,T> v = abs(b);
+
+ /* B1. Find the common power of two for u and v */
+ const size_type u_lsb = u.count_lsb();
+ const size_type v_lsb = v.count_lsb();
+ const size_type k = std::min(u_lsb, v_lsb);
+
+ if (k > 0)
+ {
+ /* divide the power of two out */
+ u.shift_right(k,0);
+ v.shift_right(k,0);
+ }
+
+ /* divide any remaining factors of two out */
+ if (u_lsb != k)
+ u.shift_right(u_lsb - k, 0);
+
+ if (v_lsb != k)
+ v.shift_right(v_lsb - k, 0);
+
+ while (!v.is_zero())
+ {
+ /* make sure v is the largest */
+ if (u.compare_magnitude(v) == 1)
+ /* swap u and v to make sure v is >= u */
+ u.swap(v);
+
+ /* subtract smallest from largest */
+ v.sub_smaller_magnitude(u);
+
+ /* Divide out all factors of two */
+ v.shift_right(v.count_lsb(), 0);
+ }
+
+ /* multiply by 2**k which we divided out at the beginning */
+ u <<= k;
+
+ return u;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,60 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// computes the jacobi c = (a | p) (or Legendre if p is prime)
+// HAC pp. 73 Algorithm 2.149
+template<class A, class T>
+int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& p)
+{
+ typedef typename mp_int<A,T>::digit_type digit_type;
+ typedef typename mp_int<A,T>::size_type size_type;
+
+ if (p <= digit_type(0))
+ throw std::domain_error("jacobi: p must be greater than 0");
+
+ if (a.is_zero())
+ return 0;
+
+ if (a == digit_type(1))
+ return 1;
+
+ /* default */
+ int s = 0;
+
+ /* write a = a1 * 2**k */
+ mp_int<A,T> a1(a);
+
+ // find largest power of two that divides a1
+ const size_type k = a1.count_lsb();
+ // now divide by it
+ a1.shift_right(k,0);
+
+ /* if k is even set s=1 */
+ if ((k & 1) == 0)
+ s = 1;
+ else
+ {
+ // calculate p.digits_[0] mod 8
+ const digit_type residue = p.digits_[0] & 7;
+
+ if (residue == 1 || residue == 7)
+ s = 1;
+ else if (residue == 3 || residue == 5)
+ s = -1;
+ }
+
+ /* if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+ if (((p.digits_[0] & 3) == 3) && ((a1.digits_[0] & 3) == 3))
+ s = -s;
+
+ if (a1 == digit_type(1))
+ return s;
+ else
+ {
+ const mp_int<A,T> p1(p % a1);
+ return s * jacobi(p1, a1);
+ }
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,22 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* computes least common multiple as |a*b|/(a, b) */
+template<class A, class T>
+mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b)
+{
+ /* t1 = get the GCD of the two inputs */
+ const mp_int<A,T> t1 = gcd(a,b);
+
+ /* divide the smallest by the GCD */
+ const mp_int<A,T>* smallest = a.compare_magnitude(b) == -1 ? &a : &b;
+
+ mp_int<A,T> t2 = *smallest / t1;
+
+ t2.sign_ = 1;
+
+ return t2;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/mod.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/mod.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,209 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* calc a value mod 2**b */
+template<class A, class T>
+void mp_int<A,T>::modulo_2_to_the_power_of(int b)
+{
+ /* if b is <= 0 then zero the int */
+ if (b <= 0)
+ {
+ zero();
+ return;
+ }
+
+ /* if the modulus is larger than the value then return */
+ if (b >= static_cast<int>(used_ * valid_bits))
+ return;
+
+ /* zero digits above the last digit of the modulus */
+ for (size_type x = (b / valid_bits) + ((b % valid_bits) == 0 ? 0 : 1); x < used_; ++x)
+ digits_[x] = 0;
+
+ /* clear the digit that is not completely outside/inside the modulus */
+ digits_[b / valid_bits] &= static_cast<digit_type>(
+ ((digit_type(1)) << ((static_cast<digit_type>(b)) % valid_bits)) - (digit_type(1)));
+
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+}
+
+// hac 14.61, pp608
+// *this = *this**-1 (mod b)
+template<class A, class T>
+void mp_int<A,T>::modinv(const mp_int& b)
+{
+ /* b cannot be negative */
+ if (b.is_negative() || b.is_zero())
+ throw std::domain_error("modinv: b is negative or zero");
+
+ /* if the modulus is odd we can use a faster routine instead */
+ if (b.is_odd())
+ fast_modinv(b);
+ else
+ slow_modinv(b);
+}
+
+/* hac 14.61, pp608 */
+template<class Al, class T>
+void mp_int<Al,T>::slow_modinv(const mp_int& b)
+{
+ /* b cannot be negative */
+ if (b.is_negative() || b.is_zero())
+ throw std::domain_error("mp_int::slow_modinv: b is negative or zero"); // XXX: this is already tested in modinv
+
+ const mp_int x = *this % b;
+ const mp_int y(b); // TODO no need to copy b here since b or y is never changed
+
+ /* [modified] if x,y are both even then return an error! */
+ if (x.is_even() && y.is_even())
+ throw std::domain_error("mp_int::slow_modinv: no inverse exists");// TODO: different text?
+
+ mp_int u(x);
+ mp_int v(y);
+ mp_int A = digit_type(1);
+ mp_int B = digit_type(0);
+ mp_int C = digit_type(0);
+ mp_int D = digit_type(1);
+
+top:
+ while (u.is_even())
+ {
+ u.divide_by_2();
+
+ if (A.is_odd() || B.is_odd())
+ {
+ /* A = (A+y)/2, B = (B-x)/2 */
+ A += y;
+ B -= x;
+ }
+ A.divide_by_2();
+ B.divide_by_2();
+ }
+
+ while (v.is_even())
+ {
+ v.divide_by_2();
+
+ if (C.is_odd() || D.is_odd())
+ {
+ /* C = (C+y)/2, D = (D-x)/2 */
+ C += y;
+ D -= x;
+ }
+ C.divide_by_2();
+ D.divide_by_2();
+ }
+
+ if (u >= v)
+ {
+ u -= v;
+ A -= C;
+ B -= D;
+ }
+ else
+ {
+ v -= u;
+ C -= A;
+ D -= B;
+ }
+
+ if (!u.is_zero())
+ goto top;
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (v != digit_type(1))
+ throw std::domain_error("mp_int::slow_modinv: no inverse exists"); // TODO return false if no inverse exists?
+
+ /* if its too low */
+ while (C.compare_to_digit(0) == -1)
+ C += b;
+
+ /* too big */
+ while (C.compare_magnitude(b) != -1)
+ C -= b;
+
+ /* C is now the inverse */
+ swap(C);
+}
+
+/* computes the modular inverse via binary extended euclidean algorithm,
+ * that is *this = 1 / *this mod b
+ *
+ * Based on slow modinv except this is optimized for the case where b is
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+template<class Al, class T>
+void mp_int<Al,T>::fast_modinv(const mp_int& b)
+{
+ if (b.is_even())
+ throw std::domain_error("mp_int::fast_modinv: b must be odd");
+
+ /* x == modulus, y == value to invert */
+ mp_int x = b;
+
+ /* we need y = |a| */
+ mp_int y = *this % b;
+
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ mp_int u(x);
+ mp_int v(y);
+ mp_int A = digit_type(1);
+ mp_int B = digit_type(0);
+ mp_int C = digit_type(0);
+ mp_int D = digit_type(1);
+
+top:
+ while (u.is_even())
+ {
+ u.divide_by_2();
+
+ if (B.is_odd())
+ B -= x;
+
+ B.divide_by_2();
+ }
+
+ while (v.is_even())
+ {
+ v.divide_by_2();
+
+ if (D.is_odd())
+ D -= x;
+
+ D.divide_by_2();
+ }
+
+ if (u >= v)
+ {
+ /* u = u - v, B = B - D */
+ u -= v;
+ B -=D;
+ }
+ else
+ {
+ v -= u;
+ D -= B;
+ }
+
+ if (!u.is_zero())
+ goto top;
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (v != digit_type(1))
+ throw std::domain_error("mp_int::fast_modinv: no inverse exists");
+
+ /* D is now the inverse */
+ while (D.sign_ == -1)
+ D += b;
+
+ swap(D);
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/modular_reduction.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/modular_reduction.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,521 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+template<class A, class T>
+void mp_int<A,T>::reduce_setup(const mp_int& b)
+{
+ pow2(b.used_ * 2 * digit_bits);
+ *this /= b;
+}
+
+// reduces *this mod m, assumes 0 < *this < m**2, mu is
+// precomputed via reduce_setup.
+// From HAC pp.604 Algorithm 14.42
+template<class A, class T>
+void mp_int<A,T>::reduce(const mp_int& m, const mp_int& mu)
+{
+ const size_type k = m.used_;
+
+ mp_int q(*this);
+
+ /* q1 = x / b**(k-1) */
+ q.shift_digits_right(k - 1);
+
+ /* according to HAC this optimization is ok */
+ if (k > digit_type(1) << (valid_bits - 1))
+ q *= mu;
+ else
+ q.fast_mul_high_digits(mu, k);
+
+ /* q3 = q2 / b**(k+1) */
+ q.shift_digits_right(k + 1);
+
+ /* x = x mod b**(k+1), quick (no division) */
+ modulo_2_to_the_power_of(valid_bits * (k + 1));
+
+ /* q = q * m mod b**(k+1), quick (no division) */
+ q.mul_digits(m, k + 1);
+
+ /* x = x - q */
+ *this -= q;
+
+ /* If x < 0, add b**(k+1) to it */
+ if (is_negative())
+ {
+ q = digit_type(1);
+ q.shift_digits_left(k + 1);
+ *this += q;
+ }
+
+ /* Back off if it's too big */
+ while (compare(m) != -1)
+ sub_smaller_magnitude(m);
+}
+
+/* setups the montgomery reduction stuff */
+template<class A, class T>
+typename mp_int<A,T>::digit_type
+mp_int<A,T>::montgomery_setup() const
+{
+ /* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
+ * => 2*X*A - X*X*A*A = 1
+ * => 2*(1) - (1) = 1
+ */
+ const digit_type b = digits_[0];
+
+ if (is_even())
+ throw std::domain_error("montgomery_setup: integer must be odd");
+
+ static const size_type S = sizeof(digit_type) * CHAR_BIT;
+
+ digit_type x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**8 */
+ if (S != 8)
+ x *= 2 - b * x; /* here x*a==1 mod 2**16 */
+ if (S == 64 || !(S == 8 || S == 16))
+ x *= 2 - b * x; /* here x*a==1 mod 2**32 */
+ if (S == 64)
+ x *= 2 - b * x; /* here x*a==1 mod 2**64 */
+
+ /* rho = -1/m mod b */
+ const digit_type rho = (word_type(1) << (static_cast<word_type>(valid_bits))) - x;
+ return rho;
+}
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+template<class A, class T>
+void mp_int<A,T>::montgomery_reduce(const mp_int& n, digit_type rho)
+{
+ /* can the fast reduction [comba] method be used?
+ *
+ * Note that unlike in mul you're safely allowed *less*
+ * than the available columns [255 per default] since carries
+ * are fixed up in the inner loop.
+ */
+ const size_type digs = n.used_ * 2 + 1;
+/* const size_type ws = sizeof(word_type) * CHAR_BIT;
+ if (digs < mp_warray && n.used_ < 1 << (ws - (2 * valid_bits)))
+ {
+ fast_montgomery_reduce(n, rho);
+ return;
+ }*/
+ /* grow the input as required */
+ grow_capacity(digs);
+ std::memset(digits_ + used_, 0, (capacity_ - used_) * sizeof(digit_type));
+ used_ = digs;
+
+ for (size_type i = 0; i < n.used_; ++i)
+ {
+ /* mu = ai * rho mod b
+ *
+ * The value of rho must be precalculated via
+ * montgomery_setup() such that
+ * it equals -1/n0 mod b this allows the
+ * following inner loop to reduce the
+ * input one digit at a time
+ */
+ const digit_type mu = static_cast<word_type>(digits_[i]) * rho;
+
+ /* a = a + mu * m * b**i */
+
+ /* alias for digits of the modulus */
+ digit_type* tmpn = n.digits_;
+
+ /* alias for the digits of x [the input] */
+ digit_type* tmpx = digits_ + i;
+
+ digit_type carry = 0;
+
+ /* Multiply and add in place */
+ for (size_type j = 0; j < n.used_; ++j)
+ {
+ /* compute product and sum */
+ const word_type r = static_cast<word_type>(mu)
+ * static_cast<word_type>(*tmpn++)
+ + static_cast<word_type>(carry)
+ + static_cast<word_type>(*tmpx);
+
+ carry = r >> digit_bits;
+
+ /* fix digit */
+ *tmpx++ = r;
+ }
+ /* At this point the i'th digit of x should be zero */
+
+ /* propagate carries upwards as required*/
+ while (carry)
+ {
+ const word_type r = static_cast<word_type>(*tmpx) + carry;
+ *tmpx++ = r;
+ carry = r >> digit_bits;
+ }
+ }
+
+ /* at this point the n.used'th least
+ * significant digits of x are all zero
+ * which means we can shift x to the
+ * right by n.used digits and the
+ * residue is unchanged.
+ */
+
+ /* x = x/b**n.used */
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+ shift_digits_right(n.used_);
+
+ /* if x >= n then x = x - n */
+ if (compare_magnitude(n) != -1)
+ sub_smaller_magnitude(n);
+}
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b. This saves alot of multiple precision shifting.
+ */
+template<class A, class T>
+void mp_int<A,T>::montgomery_calc_normalization(const mp_int& b)
+{
+ /* how many bits of last digit does b use */
+ size_type bits = b.precision() % valid_bits;
+
+ if (b.used_ > 1)
+ pow2((b.used_ - 1) * valid_bits + bits - 1);
+ else
+ {
+ *this = digit_type(1);
+ bits = 1;
+ }
+
+ /* now compute C = A * B mod b */
+ for (int x = bits - 1; x < valid_bits; ++x)
+ {
+ multiply_by_2();
+ if (compare_magnitude(b) != -1)
+ sub_smaller_magnitude(b);
+ }
+}
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+template<class A, class T>
+void mp_int<A,T>::fast_montgomery_reduce(const mp_int& n, digit_type rho)
+{
+ word_type W[mp_warray];
+
+ /* grow a as required */
+ grow_capacity(n.used_ + 1);
+
+ /* first we have to get the digits of the input into
+ * an array of double precision words W[...]
+ */
+
+ /* copy the digits of a into W[0..a->used-1] */
+ for (size_type i = 0; i < used_; ++i)
+ W[i] = digits_[i];
+
+ /* zero the high words of W[a->used..m->used*2] */
+ std::memset(W + used_, 0, (n.used_ * 2 + 1) * sizeof(word_type));
+
+ /* now we proceed to zero successive digits
+ * from the least significant upwards
+ */
+ for (size_type i = 0; i < n.used_; ++i)
+ {
+ /* mu = ai * m' mod b
+ *
+ * We avoid a double precision multiplication (which isn't required)
+ * by casting the value down to a mp_digit. Note this requires
+ * that W[ix-1] have the carry cleared (see after the inner loop)
+ */
+ const digit_type mu = ((W[i] & mp_mask) * rho) & mp_mask;
+
+ /* a = a + mu * m * b**i
+ *
+ * This is computed in place and on the fly. The multiplication
+ * by b**i is handled by offseting which columns the results
+ * are added to.
+ *
+ * Note the comba method normally doesn't handle carries in the
+ * inner loop In this case we fix the carry from the previous
+ * column since the Montgomery reduction requires digits of the
+ * result (so far) [see above] to work. This is
+ * handled by fixing up one carry after the inner loop. The
+ * carry fixups are done in order so after these loops the
+ * first m->used words of W[] have the carries fixed
+ */
+ /* inner loop */
+ for (size_type j = 0; j < n.used_; ++j)
+ W[i+j] += static_cast<word_type>(mu) * static_cast<word_type>(n.digits_[j]);
+
+ /* now fix carry for next digit, W[ix+1] */
+ W[i + 1] += W[i] >> static_cast<word_type>(valid_bits);
+ }
+
+ /* now we have to propagate the carries and
+ * shift the words downward [all those least
+ * significant digits we zeroed].
+ */
+
+ /* now fix rest of carries */
+
+ for (size_type i = n.used_ + 1; i <= n.used_ * 2 + 1; ++i)
+ W[i] += W[i-1] >> static_cast<word_type>(valid_bits);
+
+ /* copy out, A = A/b**n
+ *
+ * The result is A/b**n but instead of converting from an
+ * array of mp_word to mp_digit than calling mp_rshd
+ * we just copy them in the right order
+ */
+
+ for (size_type i = 0; i < n.used_ + 1; ++i)
+ digits_[i] = W[n.used_ + i] & static_cast<word_type>(mp_mask);
+
+ /* set the max used and clamp */
+ used_ = n.used_ + 1;
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+
+ /* if A >= m then A = A - m */
+ if (compare_magnitude(n) != -1)
+ sub_smaller_magnitude(n);
+}
+
+/* determines the setup value */
+template<class A, class T>
+typename mp_int<A,T>::digit_type
+mp_int<A,T>::dr_setup() const
+{
+ /* the casts are required if valid_bits is one less than
+ * the number of bits in a valid_bits [e.g. valid_bits==31]
+ */
+ const digit_type d = (word_type(1) << static_cast<word_type>(valid_bits))
+ - static_cast<word_type>(digits_[0]);
+ return d;
+}
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ * Chae Hoon Lim, Pil Joong Lee,
+ * POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input *this must be in the range 0 <= *this <= (n-1)**2
+ */
+template<class A, class T>
+void mp_int<A,T>::dr_reduce(const mp_int& n, digit_type k)
+{
+ /* m = digits in modulus */
+ const size_type m = n.used_;
+
+ /* ensure that *this has at least 2m digits */
+ grow_capacity(m + m);
+ std::memset(digits_ + used_, 0, (m + m - used_) * sizeof(digit_type));
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+ /* set carry to zero */
+ digit_type mu = 0;
+
+ /* compute (*this mod B**m) + k * [*this/B**m] inline and inplace */
+ for (size_type i = 0; i < m; ++i)
+ {
+ const word_type r = static_cast<word_type>(digits_[m+i])
+ * static_cast<word_type>(k) + digits_[i] + mu;
+ digits_[i] = static_cast<digit_type>(r);
+ mu = static_cast<digit_type>(r >> static_cast<word_type>(digit_bits));
+ }
+
+ /* set final carry */
+ digits_[m] = mu;
+
+ /* zero words above m */
+ if (used_ > m + 1) // guard against overflow
+ std::memset(digits_ + m + 1, 0, (used_ - (m + 1)) * sizeof(digit_type));
+
+ /* clamp, sub and return */
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+
+ /* if *this >= n then subtract and reduce again
+ * Each successive "recursion" makes the input smaller and smaller.
+ */
+ if (compare_magnitude(n) != -1)
+ {
+ sub_smaller_magnitude(n);
+ goto top;
+ }
+}
+
+/* determines if a number is a valid DR modulus */
+template<class A, class T>
+bool mp_int<A,T>::is_dr_modulus() const
+{
+ /* must be at least two digits */
+ if (used_ < 2)
+ return false;
+
+ /* must be of the form b**k - a [a <= b] so all
+ * but the first digit must be equal to -1 (mod b).
+ */
+ for (size_type i = 1; i < used_; ++i)
+ {
+ if (digits_[i] != digit_max)
+ return false;
+ }
+ return true;
+}
+
+/* determines the setup value */
+template<class A, class T>
+typename mp_int<A,T>::digit_type
+mp_int<A,T>::reduce_2k_setup() const
+{
+ mp_int tmp;
+ const size_type p = precision();
+
+ tmp.pow2(p);
+ tmp.sub_smaller_magnitude(*this);
+
+ return tmp.digits_[0];
+}
+
+/* reduces *this modulo n where n is of the form 2**p - d */
+template<class A, class T>
+void mp_int<A,T>::reduce_2k(const mp_int& n, digit_type d)
+{
+ const size_type p = n.precision();
+
+top:
+
+ mp_int q(*this);
+
+ /* q = a/2**p, a = a mod 2**p */
+ q.shift_right(p, this);
+
+ if (d != 1)
+ /* q = q * d */
+ q.multiply_by_digit(d);
+ /* a = a + q */
+ add_magnitude(q);
+
+ if (compare_magnitude(n) != -1)
+ {
+ sub_smaller_magnitude(n);
+ goto top;
+ }
+}
+
+/* determines if mp_reduce_2k can be used */
+template<class A, class T>
+bool mp_int<A,T>::reduce_is_2k() const
+{
+ if (used_ == 1)
+ return true;
+ else if (used_ > 1)
+ {
+ const size_type bits = precision();
+ size_type j = 1;
+ digit_type k = 1;
+
+ /* Test every bit from the second digit up, must be 1 */
+ for (size_type i = valid_bits; i < bits; ++i)
+ {
+ if ((digits_[j] & k) == 0)
+ return false;
+ k <<= 1;
+ if (k > mp_mask) // FIXME this can never happen with the new code
+ {
+ ++j;
+ k = 1;
+ }
+ }
+ }
+ return true;
+}
+
+/* determines the setup value */
+template<class A, class T>
+mp_int<A,T> mp_int<A,T>::reduce_2k_l_setup()
+{
+ mp_int tmp;
+
+ tmp.pow2(precision());
+ return tmp - *this;
+}
+
+/* reduces *this modulo n where n is of the form 2**p - d
+ This differs from reduce_2k since "d" can be larger
+ than a single digit.
+*/
+template<class A, class T>
+void mp_int<A,T>::reduce_2k_l(const mp_int& n, const mp_int& d)
+{
+ const size_type p = n.precision();
+
+top:
+
+ mp_int q(*this);
+
+ /* q = a/2**p, a = a mod 2**p */
+ q.shift_right(p, this);
+
+ /* q = q * d */
+ q *= d;
+
+ /* a = a + q */
+ add_magnitude(q);
+
+ if (compare_magnitude(n) != -1)
+ {
+ sub_smaller_magnitude(n);
+ goto top;
+ }
+}
+
+/* determines if reduce_2k_l can be used */
+template<class A, class T>
+bool mp_int<A,T>::reduce_is_2k_l() const
+{
+ if (used_ == 1)
+ return true;
+ else if (used_ > 1)
+ {
+ size_type count = 0;
+ // if more than half of the digits are -1 we're sold
+ for (size_type i = 0; i < used_; ++i)
+ if (digits_[i] == digit_max)
+ ++count;
+ return count >= used_ / 2 ? true : false;
+ }
+ return false;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,893 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_MP_INT_HPP
+#define BOOST_MP_MATH_MP_INT_MP_INT_HPP
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <iosfwd>
+#include <iterator> // reverse_iterator
+#include <limits>
+#include <stdexcept>
+#include <sstream>
+#include <string>
+
+#include <boost/config.hpp>
+#include <boost/random.hpp>
+#include <boost/serialization/split_member.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mp_math/mp_int/traits.hpp>
+#include <boost/mp_math/mp_int/detail/string_conversion_constants.hpp>
+#include <boost/mp_math/mp_int/detail/integral_ops.hpp>
+#include <boost/mp_math/mp_int/detail/meta_math.hpp>
+#include <boost/mp_math/mp_int/detail/prime_tab.hpp>
+#include <boost/mp_math/mp_int/detail/primitive_ops.hpp>
+
+
+namespace boost {
+namespace mp_math {
+
+
+// digits are stored in least significant order
+
+template<
+ class Allocator = std::allocator<void>,
+ class Traits = mp_int_traits<>
+>
+struct mp_int
+:
+ Allocator::template rebind<typename Traits::digit_type>::other
+{
+ typedef Allocator allocator_type;
+ typedef Traits traits_type;
+ typedef typename traits_type::size_type size_type;
+
+ mp_int();
+
+ template<typename IntegralT>
+ mp_int(IntegralT, typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
+
+ mp_int(const char*);
+ mp_int(const char*, std::ios_base::fmtflags);
+
+ #ifndef BOOST_NO_CWCHAR
+ mp_int(const wchar_t*);
+ mp_int(const wchar_t*, std::ios_base::fmtflags);
+ #endif
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>&);
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>&, std::ios_base::fmtflags);
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last);
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last,
+ std::ios_base::fmtflags f);
+
+ mp_int(const mp_int& copy);
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ mp_int(mp_int&& copy);
+ #endif
+
+ ~mp_int();
+
+ mp_int& operator = (const mp_int& rhs);
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ mp_int& operator = (mp_int&& rhs);
+ #endif
+
+ template<typename IntegralT>
+ mp_int& operator = (IntegralT rhs);
+
+ mp_int& operator = (const char*);
+
+ #ifndef BOOST_NO_CWCHAR
+ mp_int& operator = (const wchar_t*);
+ #endif
+
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator = (const std::basic_string<charT,traits,Alloc>&);
+
+ void assign(const char*, std::ios_base::fmtflags);
+
+ #ifndef BOOST_NO_CWCHAR
+ void assign(const wchar_t*, std::ios_base::fmtflags);
+ #endif
+
+ template<typename charT, class traits, class Alloc>
+ void assign(const std::basic_string<charT,traits,Alloc>&,
+ std::ios_base::fmtflags);
+
+ template<typename RandomAccessIterator>
+ void assign(RandomAccessIterator first, RandomAccessIterator last,
+ std::ios_base::fmtflags);
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ void swap(mp_int&& other);
+ #else
+ void swap(mp_int& other);
+ #endif
+
+ mp_int& operator ++();
+ mp_int& operator --();
+ mp_int operator ++(int);
+ mp_int operator --(int);
+ mp_int& operator <<= (size_type);
+ mp_int& operator >>= (size_type);
+ mp_int& operator - ();
+
+ mp_int& operator += (const mp_int&);
+ mp_int& operator -= (const mp_int&);
+ mp_int& operator *= (const mp_int&);
+ mp_int& operator /= (const mp_int&);
+ mp_int& operator %= (const mp_int&);
+ mp_int& operator |= (const mp_int&);
+ mp_int& operator &= (const mp_int&);
+ mp_int& operator ^= (const mp_int&);
+
+ template<typename IntegralT> mp_int& operator += (IntegralT);
+ template<typename IntegralT> mp_int& operator -= (IntegralT);
+ template<typename IntegralT> mp_int& operator *= (IntegralT);
+ template<typename IntegralT> mp_int& operator /= (IntegralT);
+ template<typename IntegralT> mp_int& operator %= (IntegralT);
+ template<typename IntegralT> mp_int& operator |= (IntegralT);
+ template<typename IntegralT> mp_int& operator &= (IntegralT);
+ template<typename IntegralT> mp_int& operator ^= (IntegralT);
+
+ mp_int& operator += (const char*);
+ mp_int& operator -= (const char*);
+ mp_int& operator *= (const char*);
+ mp_int& operator /= (const char*);
+ mp_int& operator %= (const char*);
+ mp_int& operator |= (const char*);
+ mp_int& operator &= (const char*);
+ mp_int& operator ^= (const char*);
+
+ #ifndef BOOST_NO_CWCHAR
+ mp_int& operator += (const wchar_t*);
+ mp_int& operator -= (const wchar_t*);
+ mp_int& operator *= (const wchar_t*);
+ mp_int& operator /= (const wchar_t*);
+ mp_int& operator %= (const wchar_t*);
+ mp_int& operator |= (const wchar_t*);
+ mp_int& operator &= (const wchar_t*);
+ mp_int& operator ^= (const wchar_t*);
+ #endif
+
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator += (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator -= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator *= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator /= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator %= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator |= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator &= (const std::basic_string<charT,traits,Alloc>&);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator ^= (const std::basic_string<charT,traits,Alloc>&);
+
+ allocator_type get_allocator() const { return allocator_type(); }
+
+private:
+
+ typedef int mp_int::*unspecified_bool_type;
+
+public:
+
+ operator unspecified_bool_type() const
+ {
+ return is_zero() ? 0 : &mp_int::sign_;
+ }
+
+ bool is_even() const { return (digits_[0] & digit_type(1)) == 0; }
+ bool is_odd () const { return (digits_[0] & digit_type(1)) == 1; }
+
+ bool is_positive() const { return sign_ == 1; }
+ bool is_negative() const { return sign_ == -1; }
+
+ template<class StringT>
+ StringT to_string(std::ios_base::fmtflags f = std::ios_base::dec) const;
+
+ template<typename IntegralT>
+ IntegralT to_integral() const;
+
+public: // low level interface
+
+ typedef typename traits_type::digit_type digit_type;
+ typedef typename traits_type::word_type word_type;
+ typedef typename traits_type::digit_type* iterator;
+ typedef const typename traits_type::digit_type* const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef detail::primitive_ops<digit_type, word_type, size_type> ops_type;
+
+ // bits per digit, we subtract one because we count from 0
+ static const int valid_bits = std::numeric_limits<digit_type>::digits;
+ static const int digit_bits = std::numeric_limits<digit_type>::digits;
+ // used to mask off the most significant bit(s)
+ static const digit_type mp_mask = (word_type(1) << valid_bits) - 1;
+ static const size_type mp_warray = 512;
+ //1 << (std::numeric_limits<word_type>::digits - 2 * valid_bits + 1);
+ static const digit_type digit_max = static_cast<digit_type>(-1);
+
+ template<typename RandomAccessIterator>
+ void init(RandomAccessIterator first, RandomAccessIterator last);
+
+ template<typename RandomAccessIterator>
+ void init(RandomAccessIterator first, RandomAccessIterator last,
+ std::ios_base::fmtflags f);
+
+ iterator begin() { return digits_; }
+ iterator end () { return digits_ + used_; }
+ const_iterator begin() const { return digits_; }
+ const_iterator end () const { return digits_ + used_; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend () { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend () const { return const_reverse_iterator(begin()); }
+
+ digit_type& operator[](size_type i) { return digits_[i]; }
+ const digit_type& operator[](size_type i) const { return digits_[i]; }
+
+ digit_type& at(size_type i)
+ {
+ if (i >= used_)
+ throw std::out_of_range("mp_int::at: array subscript out of range");
+ return digits_[i];
+ }
+ const digit_type& at(size_type i) const
+ {
+ if (i >= used_)
+ throw std::out_of_range("mp_int::at: array subscript out of range");
+ return digits_[i];
+ }
+
+ void zero();
+
+ // debug functionality
+ void print(bool all=false) const;
+ bool test_invariants() const;
+
+ size_type size() const { return used_; }
+ size_type capacity() const { return capacity_; }
+
+ void set_size(size_type s) { used_ = s; }
+
+ int sign() const { return sign_; }
+ void set_sign(int s) { sign_ = s; }
+
+ digit_type* digits() { return digits_; }
+ const digit_type* digits() const { return digits_; }
+
+ void grow_capacity(size_type n);
+ void clamp();
+
+ int compare_magnitude(const mp_int& rhs) const;
+ int compare_to_digit(digit_type) const;
+ int compare(const mp_int& rhs) const;
+
+ void add_magnitude(const mp_int& rhs);
+ void sub_smaller_magnitude(const mp_int& rhs);
+
+ bool is_zero() const;
+ bool is_power_of_two() const;
+ void add_digit(digit_type);
+ void sub_digit(digit_type);
+
+ void shift_digits_left(size_type);
+ void shift_digits_right(size_type);
+
+ void multiply_by_digit(digit_type);
+ void karatsuba_mul(const mp_int&);
+ void toom_cook_mul(const mp_int&);
+ void multiply_by_2();
+ void mul_digits(const mp_int&, size_type num_digits);
+ void mul_high_digits(const mp_int&, size_type num_digits);
+ void fast_mul_digits(const mp_int&, size_type num_digits);
+ void fast_mul_high_digits(const mp_int&, size_type num_digits);
+
+ void sqr();
+ void toom_sqr();
+ void karatsuba_sqr();
+ void comba_sqr();
+
+ digit_type divide_by_digit(digit_type); // returns remainder
+ void divide(const mp_int& divisor, mp_int* remainder);
+ void divide_by_2();
+ digit_type divide_by_3();
+ void modulo_2_to_the_power_of(int);
+ size_type precision() const;
+ size_type count_lsb() const;
+ void shift_right(size_type b, mp_int* remainder);
+
+ void reduce_setup(const mp_int&);
+ void reduce(const mp_int& m, const mp_int& mu);
+
+ digit_type montgomery_setup() const;
+ void montgomery_reduce(const mp_int& n, digit_type rho);
+ void montgomery_calc_normalization(const mp_int&);
+ void fast_montgomery_reduce(const mp_int& n, digit_type rho);
+
+ void dr_reduce(const mp_int& n, digit_type k);
+ digit_type dr_setup() const;
+ bool is_dr_modulus() const;
+
+ digit_type reduce_2k_setup() const;
+ void reduce_2k(const mp_int& n, digit_type d);
+ bool reduce_is_2k() const;
+
+ mp_int reduce_2k_l_setup();
+ void reduce_2k_l(const mp_int& n, const mp_int& d);
+ bool reduce_is_2k_l() const;
+
+ void pow2(size_type b);
+ void pow(digit_type);
+
+ void modpow(const mp_int& exp, const mp_int& m);
+ void barret_modpow(const mp_int& exp, const mp_int& m, int reduction_mode);
+ void fast_modpow(const mp_int& exp, const mp_int& m, int reduction_mode);
+
+ void modinv(const mp_int& b);
+ void slow_modinv(const mp_int& b);
+ void fast_modinv(const mp_int& b);
+
+ void set_least_significant_bit()
+ {
+ digits_[0] |= digit_type(1);
+ }
+
+ void set_bit(size_type bit)
+ {
+ digits_[bit / valid_bits] |=
+ digit_type(1) << digit_type(bit % valid_bits);
+ }
+
+ template<class A, class T>
+ friend bool operator == (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ friend bool operator < (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ friend mp_int<A,T> abs(const mp_int<A,T>& x);
+ template<class A, class T>
+ friend mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b);
+ template<class A, class T>
+ friend int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& b);
+
+ template<typename Iter>
+ void from_string(Iter first, Iter last, unsigned radix);
+
+private:
+
+ friend class boost::serialization::access;
+ template<class Archive>
+ void save(Archive & ar, const unsigned int /*version*/) const
+ {
+ const std::string s = to_string<std::string>(std::ios_base::hex);
+ ar & s;
+ }
+ template<class Archive>
+ void load(Archive & ar, const unsigned int /*version*/)
+ {
+ std::string s;
+ ar & s;
+ assign(s, std::ios_base::hex);
+ }
+ BOOST_SERIALIZATION_SPLIT_MEMBER()
+
+ digit_type* digits_;
+ size_type used_, capacity_;
+ int sign_;
+};
+
+
+
+template<class A, class T>
+void mp_int<A,T>::print(bool all) const
+{
+ using std::cout;
+ if (is_negative())
+ cout << '-';
+ cout << used_ << "{";
+ for (size_type i = 0; i < used_; ++i)
+ {
+ cout << static_cast<word_type>(digits_[i]);
+ if (i < used_ - 1)
+ cout << ",";
+ }
+ cout << "}";
+
+ if (all)
+ {
+ cout << capacity_ - used_ << "{";
+ for (size_type i = used_; i < capacity_; ++i)
+ {
+ cout << static_cast<word_type>(digits_[i]);
+ if (i < capacity_ - 1)
+ cout << ",";
+ }
+ cout << "}";
+ }
+ cout << "\n";
+}
+
+template<class A, class T>
+bool mp_int<A,T>::test_invariants() const
+{
+ if (used_) // don't test uninitialized mp_ints
+ {
+ if (used_ > capacity_)
+ return false;
+ if (digits_[used_-1] == 0)
+ return false;
+ if (sign_ != 1 && sign_ != -1)
+ return false;
+ if (is_zero() && sign_ != 1)
+ return false;
+ }
+ return true;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator = (const mp_int<A,T>& rhs)
+{
+ if (this != &rhs)
+ {
+ if ((capacity_ == 0) || (capacity_ < rhs.capacity_))
+ mp_int(rhs).swap(*this);
+ else
+ {
+ std::memcpy(digits_, rhs.digits_, rhs.used_ * sizeof(digit_type));
+ used_ = rhs.used_;
+ sign_ = rhs.sign_;
+ }
+ }
+ return *this;
+}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator = (mp_int<A,T>&& rhs)
+{
+ if (this != &rhs)
+ {
+ this->deallocate(digits_, capacity_);
+ digits_ = 0;
+ used_ = 0;
+ capacity_ = 0;
+ sign_ = 1;
+ swap(rhs);
+ }
+ return *this;
+}
+#endif
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator = (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::assign(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator = (const char* s)
+{
+ used_ = 0;
+ init(s, s + std::strlen(s));
+ return *this;
+}
+
+#ifndef BOOST_NO_CWCHAR
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator = (const wchar_t* s)
+{
+ used_ = 0;
+ init(s, s + std::wcslen(s));
+ return *this;
+}
+#endif
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+mp_int<A,T>& mp_int<A,T>::operator = (const std::basic_string<charT,traits,Alloc>& s)
+{
+ used_ = 0;
+ init(s.begin(), s.end());
+ return *this;
+}
+
+template<class A, class T>
+inline void
+mp_int<A,T>::assign(const char* s, std::ios_base::fmtflags f)
+{
+ assign(s, s + std::strlen(s), f);
+}
+
+#ifndef BOOST_NO_CWCHAR
+template<class A, class T>
+inline void
+mp_int<A,T>::assign(const wchar_t* s, std::ios_base::fmtflags f)
+{
+ assign(s, s + std::wcslen(s), f);
+}
+#endif
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline void
+mp_int<A,T>::assign(const std::basic_string<charT,traits,Alloc>& s,
+ std::ios_base::fmtflags f)
+{
+ assign(s.begin(), s.end(), f);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+inline void
+mp_int<A,T>::assign(RandomAccessIterator first, RandomAccessIterator last,
+ std::ios_base::fmtflags f)
+{
+ used_ = 0;
+ init(first, last, f);
+}
+
+
+template<class A, class T>
+#ifdef BOOST_HAS_RVALUE_REFS
+void mp_int<A,T>::swap(mp_int&& other)
+#else
+void mp_int<A,T>::swap(mp_int& other)
+#endif
+{
+ std::swap(digits_, other.digits_);
+ std::swap(used_, other.used_);
+ std::swap(capacity_, other.capacity_);
+ std::swap(sign_, other.sign_);
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator += (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::add(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator -= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::subtract(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator *= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::multiply(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator /= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::divide(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator %= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::modulo(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator |= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::bitwise_or(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator &= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::bitwise_and(*this, rhs);
+ return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline mp_int<A,T>& mp_int<A,T>::operator ^= (IntegralT rhs)
+{
+ detail::integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+ return *this;
+}
+
+
+template<class A, class T>
+void mp_int<A,T>::zero()
+{
+ grow_capacity(1);
+ digits_[0] = 0;
+ used_ = 1;
+ sign_ = 1;
+}
+
+template<class A, class T>
+void mp_int<A,T>::grow_capacity(size_type n)
+{
+ if (capacity_ < n)
+ {
+ const size_type new_cap = capacity_ + capacity_;
+ if (new_cap > n)
+ n = new_cap;
+ digit_type* d = this->allocate(n, digits_);
+ std::memcpy(d, digits_, sizeof(digit_type) * used_);
+ this->deallocate(digits_, capacity_);
+ digits_ = d;
+ capacity_ = n;
+ }
+}
+
+/* trim unused digits
+ *
+ * This is used to ensure that leading zero digits are trimmed.
+ * Typically very fast.
+ */
+template<class A, class T>
+void mp_int<A,T>::clamp()
+{
+ /* decrease used while the most significant digit is zero. */
+ while (used_ > 1 && digits_[used_-1] == 0)
+ --used_;
+}
+
+template<class A, class T>
+inline bool mp_int<A,T>::is_zero() const
+{
+ return used_ == 1 && digits_[0] == 0;
+}
+
+// disregards the sign of the numbers
+// return 1 if *this is greater
+// returns 0 if both are equal
+// return -1 if *this is smaller
+template<class A, class T>
+int mp_int<A,T>::compare_magnitude(const mp_int& rhs) const
+{
+ /* compare based on # of non-zero digits */
+ if (used_ > rhs.used_)
+ return 1;
+
+ if (used_ < rhs.used_)
+ return -1;
+
+ /* compare based on digits */
+ const_reverse_iterator d = rbegin();
+ const_reverse_iterator d2 = rhs.rbegin();
+ for (; d != rend(); ++d, ++d2)
+ {
+ if (*d > *d2)
+ return 1;
+ if (*d < *d2)
+ return -1;
+ }
+ return 0;
+}
+
+template<class A, class T>
+int mp_int<A,T>::compare_to_digit(digit_type d) const
+{
+ /* compare based on sign */
+ if (is_negative())
+ return -1;
+
+ /* compare based on magnitude */
+ if (used_ > 1)
+ return 1;
+
+ /* compare the only digit of *this to d */
+ if (digits_[0] > d)
+ return 1;
+ else if (digits_[0] < d)
+ return -1;
+ else
+ return 0;
+}
+
+template<class A, class T>
+int mp_int<A,T>::compare(const mp_int& rhs) const
+{
+ /* compare based on sign */
+ if (sign_ != rhs.sign_)
+ {
+ if (is_negative())
+ return -1;
+ else
+ return 1;
+ }
+
+ /* compare digits */
+ if (is_negative())
+ /* if negative compare opposite direction */
+ return rhs.compare_magnitude(*this);
+ else
+ return compare_magnitude(rhs);
+}
+
+// {A,B,C,D,E} shifted left by 2 digits becomes
+// {0,0,A,B,C,D,E}
+template<class A, class T>
+void mp_int<A,T>::shift_digits_left(size_type b)
+{
+ if (b <= 0)
+ return;
+
+ grow_capacity(used_ + b);
+
+ std::memmove(digits_ + b, digits_, used_ * sizeof(digit_type));
+
+ // zero the lower digits
+ std::memset(digits_, 0, b * sizeof(digit_type));
+
+ used_ += b;
+}
+
+// {A,B,C,D,E} shifted right by 2 digits becomes
+// {C,D,E}
+template<class A, class T>
+void mp_int<A,T>::shift_digits_right(size_type b)
+{
+ if (b <= 0)
+ return;
+
+ if (used_ <= b)
+ {
+ zero();
+ return;
+ }
+
+ /* shift the digits down */
+ std::memmove(digits_, digits_ + b, (used_ - b) * sizeof(digit_type));
+
+ /* zero the top digits */
+ std::memset(digits_ + used_ - b, 0, b * sizeof(digit_type));
+
+ /* remove excess digits */
+ used_ -= b;
+}
+
+template<class A, class T>
+typename mp_int<A,T>::size_type
+mp_int<A,T>::precision() const
+{
+ /* get number of digits and add that */
+ size_type r = (used_ - 1) * valid_bits;
+
+ /* take the last digit and count the bits in it */
+ digit_type q = digits_[used_ - 1];
+ while (q > 0U)
+ {
+ ++r;
+ q >>= 1;
+ }
+ return r;
+}
+
+/* Counts the number of lsbs which are zero before the first one bit */
+template<class A, class T>
+typename mp_int<A,T>::size_type
+mp_int<A,T>::count_lsb() const
+{
+ static const size_type lnz[16] = {
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+ };
+
+ /* easy out */
+ if (is_zero())
+ return 0;
+
+ /* scan lower digits until non-zero */
+ size_type x = 0;
+ while (x < used_ && digits_[x] == 0)
+ ++x;
+ digit_type q = digits_[x];
+ x *= valid_bits;
+
+ /* now scan this digit until a 1 is found */
+ if ((q & 1) == 0)
+ {
+ digit_type qq;
+ do
+ {
+ qq = q & 15;
+ x += lnz[qq];
+ q >>= 4;
+ } while (qq == 0);
+ }
+ return x;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline IntegralT mp_int<A,T>::to_integral() const
+{
+ return detail::integral_ops<IntegralT>::convert(*this);
+}
+
+
+template<class A, class T>
+inline void swap(mp_int<A,T>& lhs, mp_int<A,T>& rhs)
+{
+ lhs.swap(rhs);
+}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+template<class A, class T>
+inline void swap(mp_int<A,T>&& lhs, mp_int<A,T>& rhs)
+{
+ lhs.swap(rhs);
+}
+template<class A, class T>
+inline void swap(mp_int<A,T>& lhs, mp_int<A,T>&& rhs)
+{
+ lhs.swap(rhs);
+}
+#endif
+
+
+
+
+
+
+#include <boost/mp_math/mp_int/abs.hpp>
+#include <boost/mp_math/mp_int/add.hpp>
+#include <boost/mp_math/mp_int/ctors.hpp>
+#include <boost/mp_math/mp_int/div.hpp>
+#include <boost/mp_math/mp_int/gcd.hpp>
+#include <boost/mp_math/mp_int/jacobi.hpp>
+#include <boost/mp_math/mp_int/lcm.hpp>
+#include <boost/mp_math/mp_int/mod.hpp>
+#include <boost/mp_math/mp_int/modular_reduction.hpp>
+#include <boost/mp_math/mp_int/mul.hpp>
+#include <boost/mp_math/mp_int/operators.hpp>
+#include <boost/mp_math/mp_int/pow.hpp>
+#include <boost/mp_math/mp_int/random.hpp>
+#include <boost/mp_math/mp_int/prime.hpp>
+#include <boost/mp_math/mp_int/root.hpp>
+#include <boost/mp_math/mp_int/sqr.hpp>
+#include <boost/mp_math/mp_int/sub.hpp>
+#include <boost/mp_math/mp_int/string_conversion.hpp>
+
+} // namespace mp_math
+} // namespace boost
+
+#include <boost/mp_math/mp_int/numeric_limits.hpp>
+
+
+#endif

Added: sandbox/mp_math/boost/mp_math/mp_int/mul.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/mul.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,375 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// multiplies by a single digit
+template<class A, class T>
+void mp_int<A,T>::multiply_by_digit(digit_type x)
+{
+ if (x == 0)
+ {
+ zero();
+ return;
+ }
+ else if (x == 1)
+ return;
+
+ // make sure we can hold the result
+ grow_capacity(used_ + 1);
+
+ const digit_type carry = ops_type::multiply_by_digit(digits_, digits_, used_, x);
+
+ if (carry)
+ digits_[used_++] = carry;
+}
+
+/* *this *= 2 */
+template<class A, class T>
+void mp_int<A,T>::multiply_by_2()
+{
+ grow_capacity(used_ + 1);
+
+ digit_type carry = 0;
+ for (size_type x = 0; x < used_; ++x)
+ {
+ /* get what will be the *next* carry bit from the
+ * MSB of the current digit
+ */
+ const digit_type rr = digits_[x] >> static_cast<digit_type>(valid_bits - 1);
+
+ /* now shift up this digit, add in the carry [from the previous] */
+ digits_[x] = (digits_[x] << digit_type(1)) | carry;
+
+ /* copy the carry that would be from the source
+ * digit into the next iteration
+ */
+ carry = rr;
+ }
+
+ /* new leading digit? */
+ if (carry)
+ {
+ /* add a MSB which is always 1 at this point */
+ digits_[used_] = 1;
+ ++used_;
+ }
+}
+
+
+// multiplication using the Toom-Cook 3-way algorithm
+//
+// Much more complicated than Karatsuba but has a lower
+// asymptotic running time of O(N**1.464). This algorithm is
+// only particularly useful on VERY large inputs
+// (we're talking 1000s of digits here...).
+template<class A, class T>
+void mp_int<A,T>::toom_cook_mul(const mp_int& b)
+{
+ const size_type B = std::min(used_, b.used_) / 3;
+
+ // a = a2 * B**2 + a1 * B + a0
+ mp_int a0(*this);
+ a0.modulo_2_to_the_power_of(valid_bits * B);
+ mp_int a1(*this);
+ a1.shift_digits_right(B);
+ a1.modulo_2_to_the_power_of(valid_bits * B);
+ mp_int a2(*this);
+ a2.shift_digits_right(B*2);
+
+ // b = b2 * B**2 + b1 * B + b0
+ mp_int b0(b);
+ b0.modulo_2_to_the_power_of(valid_bits * B);
+ mp_int b1(b);
+ b1.shift_digits_right(B);
+ b1.modulo_2_to_the_power_of(valid_bits * B);
+ mp_int b2(b);
+ b2.shift_digits_right(B*2);
+
+ // w0 = a0*b0
+ const mp_int w0(a0 * b0);
+
+ // w4 = a2 * b2
+ mp_int w4 = a2 * b2;
+
+ // w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0))
+ mp_int tmp1 = a0;
+ tmp1.multiply_by_2();
+ tmp1 += a1;
+ tmp1.multiply_by_2();
+ tmp1 += a2;
+
+ mp_int tmp2 = b0;
+ tmp2.multiply_by_2();
+ tmp2 += b1;
+ tmp2.multiply_by_2();
+ tmp2 += b2;
+
+ mp_int w1 = tmp1 * tmp2;
+
+ // w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2))
+ tmp1 = a2;
+ tmp1.multiply_by_2();
+ tmp1 += a1;
+ tmp1.multiply_by_2();
+ tmp1 += a0;
+
+ tmp2 = b2;
+ tmp2.multiply_by_2();
+ tmp2 += b1;
+ tmp2.multiply_by_2();
+ tmp2 += b0;
+
+ mp_int w3 = tmp1 * tmp2;
+
+ // w2 = (a2 + a1 + a0)(b2 + b1 + b0)
+ tmp1 = a2 + a1;
+ tmp1 += a0;
+ tmp2 = b2 + b1;
+ tmp2 += b0;
+ mp_int w2 = tmp1 * tmp2;
+
+ // now solve the matrix
+ //
+ // 0 0 0 0 1
+ // 1 2 4 8 16
+ // 1 1 1 1 1
+ // 16 8 4 2 1
+ // 1 0 0 0 0
+ //
+ // using 12 subtractions, 4 shifts,
+ // 2 small divisions and 1 small multiplication
+
+ // r1 - r4
+ w1 -= w4;
+ // r3 - r0
+ w3 -= w0;
+ // r1/2
+ w1.divide_by_2();
+ // r3/2
+ w3.divide_by_2();
+ // r2 - r0 - r4
+ w2 -= w0;
+ w2 -= w4;
+ // r1 - r2
+ w1 -= w2;
+ // r3 - r2
+ w3 -= w2;
+ // r1 - 8r0
+ tmp1 = w0 << 3;
+ w1 -= tmp1;
+ // r3 - 8r4
+ tmp1 = w4 << 3;
+ w3 -= tmp1;
+ // 3r2 - r1 - r3
+ w2.multiply_by_digit(3);
+ w2 -= w1;
+ w2 -= w3;
+ // r1 - r2
+ w1 -= w2;
+ // r3 - r2
+ w3 -= w2;
+ // r1/3
+ w1.divide_by_3();
+ // r3/3
+ w3.divide_by_3();
+
+ // at this point shift W[n] by B*n
+ w1.shift_digits_left(1*B);
+ w2.shift_digits_left(2*B);
+ w3.shift_digits_left(3*B);
+ w4.shift_digits_left(4*B);
+
+ *this = w0 + w1;
+ tmp1 = w2 + w3;
+ tmp1 += w4;
+ *this += tmp1;
+}
+
+// c = |a| * |b| using Karatsuba Multiplication using
+// three half size multiplications
+//
+// Let B represent the radix [e.g. 2**valid_bits] and
+// let n represent half of the number of digits in
+// the min(a,b)
+//
+// a = x1 * B**n + x0
+// b = y1 * B**n + y0
+//
+// Then, a * b =>
+// x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
+//
+// Note that x1y1 and x0y0 are used twice and only need to be
+// computed once. So in total three half size (half # of
+// digit) multiplications are performed, x0y0, x1y1 and
+// (x1+y1)(x0+y0)
+//
+// Note that a multiplication of half the digits requires
+// 1/4th the number of single precision multiplications so in
+// total after one call 25% of the single precision multiplications
+// are saved. Note also that the call to mp_mul can end up back
+// in this function if the x0, x1, y0, or y1 are above the threshold.
+// This is known as divide-and-conquer and leads to the famous
+// O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
+// the standard O(N**2) that the baseline/comba methods use.
+// Generally though the overhead of this method doesn't pay off
+// until a certain size (N ~ 80) is reached.
+template<class A, class T>
+void mp_int<A,T>::karatsuba_mul(const mp_int& b)
+{
+ mp_int x0, x1, y0, y1, /*tmp,*/ x0y0, x1y1;
+
+ // min # of digits
+ const size_type B = std::min(used_, b.used_) / 2;
+
+ // allocate memory
+ x0.grow_capacity(B);
+ x1.grow_capacity(used_ + b.used_);
+ y0.grow_capacity(B);
+ y1.grow_capacity(b.used_ - B + 1);
+
+ // set used_ count
+ x0.used_ = y0.used_ = B;
+ x1.used_ = used_ - B;
+ y1.used_ = b.used_ - B;
+
+ // copy digits over
+ static const size_type s = sizeof(digit_type);
+ std::memcpy(x0.digits_, digits_, s * B);
+ std::memcpy(y0.digits_, b.digits_, s * B);
+ std::memcpy(x1.digits_, digits_ + B, s * ( used_ - B));
+ std::memcpy(y1.digits_, b.digits_ + B, s * (b.used_ - B));
+
+ // only need to clamp the lower words since by definition the
+ // upper words x1/y1 must have a known number of digits
+ x0.clamp();
+ y0.clamp();
+
+ // now evaluate the term
+ // x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
+
+ // first calc the products x0y0 and x1y1
+ x0y0 = x0 * y0;
+ x1y1 = x1 * y1;
+
+ // tmp = (x1 + x0) * (y1 + y0)
+ x1.add_magnitude(x0);
+ y1.add_magnitude(y0);
+ // we don't need a tmp just reuse x1
+ x1 *= y1;
+
+ // tmp -= (x0y0 + x1y1);
+ x1.sub_smaller_magnitude(x0y0);
+ x1.sub_smaller_magnitude(x1y1);
+
+ // shift by B
+ x1.shift_digits_left(B);
+ x1y1.shift_digits_left(B * 2);
+
+ x1.add_magnitude(x0y0);
+ x1.add_magnitude(x1y1);
+ swap(x1);
+}
+
+
+// multiplies |a| * |b| and only computes up to digs digits of result
+// HAC pp. 595, Algorithm 14.12 Modified so you can control how
+// many digits of output are created.
+template<class A, class T>
+void mp_int<A,T>::mul_digits(const mp_int& b, size_type digs)
+{
+ mp_int tmp;
+ tmp.grow_capacity(digs);
+ // zero allocated digits
+ std::memset(tmp.digits_, 0, sizeof(digit_type) * digs);
+ tmp.used_ = digs;
+
+ // compute the digits of the product directly
+ for (size_type i = 0; i < used_; ++i)
+ {
+ digit_type carry = 0;
+
+ // limit ourselves to making digs digits of output
+ const size_type pb = std::min(b.used_, digs - i);
+
+ // compute the columns of the output and propagate the carry
+ for (size_type j = 0; j < pb; ++j)
+ {
+ // compute the column as a word_type
+ const word_type r = static_cast<word_type>(tmp.digits_[i+j])
+ + static_cast<word_type>(digits_[i])
+ * static_cast<word_type>(b.digits_[j])
+ + static_cast<word_type>(carry);
+
+ // the new column is the lower part of the result
+ tmp.digits_[i+j] = static_cast<digit_type>(r);
+
+ // get the carry word from the result
+ carry = static_cast<digit_type>(r >> static_cast<word_type>(valid_bits));
+ }
+ // set carry if it is placed below digs
+ if (i + pb < digs)
+ tmp.digits_[i+pb] = carry;
+ }
+
+ tmp.clamp();
+ if (tmp.is_zero())
+ tmp.sign_ = 1;
+ swap(tmp);
+}
+
+// FIXME no routine seems to use this
+//
+// multiplies |a| * |b| and does not compute the lower digs digits
+// [meant to get the higher part of the product]
+template<class A, class T>
+void mp_int<A,T>::mul_high_digits(const mp_int& b, size_type digs)
+{
+ mp_int tmp;
+ tmp.grow_capacity(used_ + b.used_ + 1);
+ tmp.used_ = used_ + b.used_ + 1;
+ std::memset(tmp.digits_, 0, sizeof(digit_type) * tmp.used_);
+
+ for (size_type i = 0; i < used_; ++i)
+ {
+ digit_type* dst = tmp.digits_ + digs;
+ digit_type* z = b.digits_ + (digs - i);
+ digit_type carry = 0;
+
+ for (size_type j = digs - i; j < b.used_; ++j)
+ {
+ const word_type r = static_cast<word_type>(*dst)
+ + static_cast<word_type>(digits_[i])
+ * static_cast<word_type>(*z++)
+ + static_cast<word_type>(carry);
+
+ // get the lower part
+ *dst++ = static_cast<digit_type>(r);
+
+ // update carry
+ carry = static_cast<digit_type>(r >> valid_bits);
+ }
+ *dst = carry;
+ }
+
+ tmp.clamp();
+ if (tmp.is_zero())
+ tmp.sign_ = 1;
+ swap(tmp);
+}
+
+
+// this is a modified version of fast_s_mul_digs that only produces
+// output digits *above* digs. See the comments for fast_s_mul_digs
+// to see how it works.
+//
+// This is used in the Barrett reduction since for one of the multiplications
+// only the higher digits were needed. This essentially halves the work.
+//
+// Based on Algorithm 14.12 on pp.595 of HAC.
+template<class A, class T>
+void mp_int<A,T>::fast_mul_high_digits(const mp_int& b, size_type digs)
+{
+ mul_high_digits(b, digs);
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/numeric_limits.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/numeric_limits.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,52 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+namespace std
+{
+
+template<class A, class T>
+class numeric_limits<boost::mp_math::mp_int<A,T> >
+{
+public:
+
+ static const bool is_specialized = true;
+ static boost::mp_math::mp_int<A,T> min() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+ static boost::mp_math::mp_int<A,T> max() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+
+ static const int digits = 0;
+ static const int digits10 = 0;
+ static const bool is_signed = true;
+ static const bool is_integer = true;
+ static const bool is_exact = true;
+ static const int radix = 2;
+ static boost::mp_math::mp_int<A,T> epsilon () throw() { return boost::mp_math::mp_int<A,T>(0U); }
+ static boost::mp_math::mp_int<A,T> round_error() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+
+ static const int min_exponent = 0;
+ static const int min_exponent10 = 0;
+ static const int max_exponent = 0;
+ static const int max_exponent10 = 0;
+
+ static const bool has_infinity = false;
+ static const bool has_quiet_NaN = false;
+ static const bool has_signaling_NaN = false;
+ static const float_denorm_style has_denorm = denorm_absent;
+ static const bool has_denorm_loss = false;
+ static boost::mp_math::mp_int<A,T> infinity () throw() { return boost::mp_math::mp_int<A,T>(0U); }
+ static boost::mp_math::mp_int<A,T> quiet_NaN () throw() { return boost::mp_math::mp_int<A,T>(0U); }
+ static boost::mp_math::mp_int<A,T> signaling_NaN() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+ static boost::mp_math::mp_int<A,T> denorm_min () throw() { return boost::mp_math::mp_int<A,T>(0U); }
+
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+
+ static const bool traps = false;
+ static const bool tinyness_before = false;
+ static const float_round_style round_style = round_toward_zero;
+};
+
+} // namespace std
+

Added: sandbox/mp_math/boost/mp_math/mp_int/operators.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/operators.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,1148 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// compare mp_int to mp_int
+template<class A, class T>
+inline bool
+operator == (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ return lhs.sign_ == rhs.sign_ && lhs.used_ == rhs.used_ &&
+ std::equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+template<class A, class T>
+inline bool
+operator != (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs) { return !(lhs == rhs); }
+
+template<class A, class T>
+bool
+operator < (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ /* compare based on sign */
+ if (lhs.sign_ != rhs.sign_)
+ {
+ if (lhs.is_negative())
+ return true;
+ else
+ return false;
+ }
+
+ if (lhs.size() < rhs.size())
+ return true;
+ if (lhs.size() > rhs.size())
+ return false;
+
+ /* compare digits */
+ if (lhs.is_negative())
+ return std::lexicographical_compare(
+ rhs.rbegin(), rhs.rend(), lhs.rbegin(), lhs.rend());
+ else
+ return std::lexicographical_compare(
+ lhs.rbegin(), lhs.rend(), rhs.rbegin(), rhs.rend());
+}
+
+template<class A, class T>
+inline bool
+operator > (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs) { return rhs < lhs; }
+
+template<class A, class T>
+inline bool
+operator <= (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs) { return !(rhs < lhs); }
+
+template<class A, class T>
+inline bool
+operator >= (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs) { return !(lhs < rhs); }
+
+
+// compare mp_int to integral
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ return detail::integral_ops<IntegralT>::equal(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (const mp_int<A,T>& lhs, IntegralT rhs) { return !(lhs == rhs); }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ return detail::integral_ops<IntegralT>::less(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (const mp_int<A,T>& lhs, IntegralT rhs) { return rhs < lhs; }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (const mp_int<A,T>& lhs, IntegralT rhs) { return (lhs < rhs) || (lhs == rhs); }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (const mp_int<A,T>& lhs, IntegralT rhs) { return !(lhs < rhs); }
+
+// compare integral to mp_int
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (IntegralT lhs, const mp_int<A,T>& rhs) { return rhs == lhs; }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (IntegralT lhs, const mp_int<A,T>& rhs) { return !(lhs == rhs); }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (IntegralT lhs, const mp_int<A,T>& rhs) { return !(rhs <= lhs); }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (IntegralT lhs, const mp_int<A,T>& rhs) { return rhs < lhs; }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (IntegralT lhs, const mp_int<A,T>& rhs) { return !(rhs < lhs); }
+
+template<class A, class T, typename IntegralT>
+inline typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (IntegralT lhs, const mp_int<A,T>& rhs) { return rhs <= lhs; }
+
+
+// compare mp_int to const char*
+template<class A, class T>
+inline bool
+operator == (const mp_int<A,T>& lhs, const char* rhs) { return lhs == mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator != (const mp_int<A,T>& lhs, const char* rhs) { return lhs != mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator < (const mp_int<A,T>& lhs, const char* rhs) { return lhs < mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator > (const mp_int<A,T>& lhs, const char* rhs) { return lhs > mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator <= (const mp_int<A,T>& lhs, const char* rhs) { return lhs <= mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator >= (const mp_int<A,T>& lhs, const char* rhs) { return lhs >= mp_int<A,T>(rhs); }
+
+// compare const char* to mp_int
+template<class A, class T>
+inline bool
+operator == (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) == rhs; }
+
+template<class A, class T>
+inline bool
+operator != (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) != rhs; }
+
+template<class A, class T>
+inline bool
+operator < (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) < rhs; }
+
+template<class A, class T>
+inline bool
+operator > (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) > rhs; }
+
+template<class A, class T>
+inline bool
+operator <= (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) <= rhs; }
+
+template<class A, class T>
+inline bool
+operator >= (const char* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) >= rhs; }
+
+
+#ifndef BOOST_NO_CWCHAR
+// compare mp_int to const wchar_t*
+template<class A, class T>
+inline bool
+operator == (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs == mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator != (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs != mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator < (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs < mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator > (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs > mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator <= (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs <= mp_int<A,T>(rhs); }
+
+template<class A, class T>
+inline bool
+operator >= (const mp_int<A,T>& lhs, const wchar_t* rhs) { return lhs >= mp_int<A,T>(rhs); }
+
+// compare const wchar_t* to mp_int
+template<class A, class T>
+inline bool
+operator == (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) == rhs; }
+
+template<class A, class T>
+inline bool
+operator != (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) != rhs; }
+
+template<class A, class T>
+inline bool
+operator < (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) < rhs; }
+
+template<class A, class T>
+inline bool
+operator > (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) > rhs; }
+
+template<class A, class T>
+inline bool
+operator <= (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) <= rhs; }
+
+template<class A, class T>
+inline bool
+operator >= (const wchar_t* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) >= rhs; }
+#endif // BOOST_NO_CWCHAR
+
+
+// compare mp_int to basic_string
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs == mp_int<A,T>(rhs); }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs != mp_int<A,T>(rhs); }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs < mp_int<A,T>(rhs); }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs > mp_int<A,T>(rhs); }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs <= mp_int<A,T>(rhs); }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs >= mp_int<A,T>(rhs); }
+
+// compare basic_string to mp_int
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) == rhs; }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) != rhs; }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) < rhs; }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) > rhs; }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) <= rhs; }
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) >= rhs; }
+
+
+
+
+// prefix ops
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator ++()
+{
+ add_digit(1);
+ return *this;
+}
+
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator --()
+{
+ sub_digit(1);
+ return *this;
+}
+
+// postfix ops
+template<class A, class T>
+inline mp_int<A,T> mp_int<A,T>::operator ++(int)
+{
+ mp_int<A,T> tmp(*this);
+ ++(*this);
+ return tmp;
+}
+
+template<class A, class T>
+inline mp_int<A,T> mp_int<A,T>::operator --(int)
+{
+ mp_int<A,T> tmp(*this);
+ --(*this);
+ return tmp;
+}
+
+// shift ops
+// this function corresponds to mp_mul_2d()
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator <<= (size_type b)
+{
+ grow_capacity(used_ + b/valid_bits + 1);
+
+ /* shift by as many digits in the bit count */
+ if (b >= static_cast<size_type>(valid_bits))
+ shift_digits_left(b / valid_bits);
+
+ /* shift any bit count < valid_bits */
+ const digit_type d = static_cast<digit_type>(b % valid_bits);
+
+ if (d)
+ {
+ /* bitmask for carries */
+ const digit_type mask = (digit_type(1) << d) - 1;
+
+ /* shift for msbs */
+ const digit_type shift = valid_bits - d;
+
+ digit_type carry = 0;
+ for (size_type i = 0; i < used_; ++i)
+ {
+ /* get the higher bits of the current word */
+ const digit_type carry_cur = (digits_[i] >> shift) & mask;
+
+ /* shift the current word and OR in the carry */
+ digits_[i] = (digits_[i] << d) | carry;
+
+ /* set the carry to the carry bits of the current word */
+ carry = carry_cur;
+ }
+
+ if (carry)
+ digits_[used_++] = carry;
+ }
+
+ clamp();
+ return *this;
+}
+
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator >>= (size_type b)
+{
+ shift_right(b, 0);
+ return *this;
+}
+
+// unary negate
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator - ()
+{
+ if (!is_zero())
+ sign_ = sign_ == 1 ? -1 : 1;
+ return *this;
+}
+
+
+// arithmetic
+
+
+// this is the high level addition function
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator += (const mp_int<A,T>& rhs)
+{
+ if (sign_ == rhs.sign_)
+ add_magnitude(rhs);
+ else
+ {
+ // subtract the one with the lesser magnitude from
+ // the one of the greater magnitude. The result gets
+ // the sign of the one with the greater magnitude.
+ const mp_int* x;
+ const mp_int* y;
+ if (compare_magnitude(rhs) != -1) // |*this| >= |rhs|
+ {
+ x = this;
+ y = &rhs;
+ }
+ else // |*this| < |rhs|
+ {
+ grow_capacity(rhs.used_);
+ sign_ = rhs.sign_;
+ x = &rhs;
+ y = this;
+ }
+
+ ops_type::sub_smaller_magnitude(digits_, x->digits_, x->used_,
+ y->digits_, y->used_);
+ used_ = x->used_;
+
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+ }
+ return *this;
+}
+
+// high level subtraction (handles signs)
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator -= (const mp_int<A,T>& rhs)
+{
+ if (sign_ != rhs.sign_)
+ // add magnitudes, and use the sign of *this.
+ add_magnitude(rhs);
+ else
+ {
+ const mp_int* x;
+ const mp_int* y;
+ if (compare_magnitude(rhs) != -1) // [*this] >= rhs
+ {
+ x = this;
+ y = &rhs;
+ }
+ else // |*this| < |rhs|
+ {
+ grow_capacity(rhs.used_);
+ // result has opposite sign from *this
+ sign_ = is_positive() ? -1 : 1;
+ x = &rhs;
+ y = this;
+ }
+
+ ops_type::sub_smaller_magnitude(digits_, x->digits_, x->used_,
+ y->digits_, y->used_);
+
+ used_ = x->used_;
+
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+ }
+ return *this;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator *= (const mp_int<A,T>& rhs)
+{
+ if (this == &rhs)
+ {
+ sqr();
+ return *this;
+ }
+
+ const int neg = (sign_ == rhs.sign_) ? 1 : -1;
+ const size_type min = std::min(used_, rhs.used_);
+
+ if (min >= traits_type::toom_mul_cutoff)
+ toom_cook_mul(rhs);
+ else if (min >= traits_type::karatsuba_mul_cutoff)
+ karatsuba_mul(rhs);
+ else
+ {
+ mp_int tmp;
+ tmp.grow_capacity(used_ + rhs.used_);
+
+ if (used_ == rhs.used_)
+ ops_type::comba_mul(tmp.digits(), digits(), rhs.digits(), used_);
+ else
+ {
+ // always multiply larger by smaller number
+ const mp_int* a = this;
+ const mp_int* b = &rhs;
+ if (a->used_ < b->used_)
+ std::swap(a, b);
+
+ ops_type::comba_mul(tmp.digits(), a->digits(), a->used_, b->digits(), b->used_);
+ }
+
+ tmp.used_ = used_ + rhs.used_;
+ tmp.clamp();
+ swap(tmp);
+ }
+
+ sign_ = is_zero() ? 1 : neg;
+
+ return *this;
+}
+
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator /= (const mp_int<A,T>& rhs)
+{
+ divide(rhs, 0);
+ return *this;
+}
+
+// The sign of the result is the sign of the dividend, i.e. *this.
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator %= (const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> remainder;
+ divide(rhs, &remainder);
+ swap(remainder);
+ return *this;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator |= (const mp_int<A,T>& rhs)
+{
+ size_type px;
+ mp_int tmp;
+ const mp_int* x;
+
+ if (used_ > rhs.used_)
+ {
+ tmp = *this;
+ px = rhs.used_;
+ x = &rhs;
+ }
+ else
+ {
+ tmp = rhs;
+ px = used_;
+ x = this;
+ }
+
+ for (size_type i = 0; i < px; ++i)
+ tmp[i] |= (*x)[i];
+
+ tmp.clamp();
+ swap(tmp);
+
+ return *this;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator &= (const mp_int<A,T>& rhs)
+{
+ size_type px;
+ mp_int tmp;
+ const mp_int *x;
+
+ if (used_ > rhs.used_)
+ {
+ tmp = *this;
+ px = rhs.used_;
+ x = &rhs;
+ }
+ else
+ {
+ tmp = rhs;
+ px = used_;
+ x = this;
+ }
+
+ for (size_type i = 0; i < px; ++i)
+ tmp[i] &= (*x)[i];
+
+ /* zero digits above the last from the smallest mp_int */
+ std::memset(tmp.digits_ + px, 0, (tmp.used_ - px) * sizeof(digit_type));
+ tmp.clamp();
+ swap(tmp);
+
+ return *this;
+}
+
+template<class A, class T>
+mp_int<A,T>& mp_int<A,T>::operator ^= (const mp_int<A,T>& rhs)
+{
+ size_type px;
+ mp_int tmp;
+ const mp_int *x;
+
+ if (used_ > rhs.used_)
+ {
+ tmp = *this;
+ px = rhs.used_;
+ x = &rhs;
+ }
+ else
+ {
+ tmp = rhs;
+ px = used_;
+ x = this;
+ }
+
+ for (size_type i = 0; i < px; ++i)
+ tmp[i] ^= (*x)[i];
+
+ tmp.clamp();
+ swap(tmp);
+
+ return *this;
+}
+
+template<class A, class T>
+inline mp_int<A,T>
+operator << (const mp_int<A,T>& lhs, typename mp_int<A,T>::size_type b)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv <<= b;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T>
+operator >> (const mp_int<A,T>& lhs, typename mp_int<A,T>::size_type b)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv >>= b;
+ return nrv;
+}
+
+
+template<class A, class T>
+inline mp_int<A,T> operator - (const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(rhs);
+ -nrv;
+ return nrv;
+}
+
+
+
+template<class A, class T>
+inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv += rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv -= rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ if (&lhs != &rhs)
+ nrv *= rhs;
+ else
+ nrv *= nrv; // this uses special squaring code in operator *=
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv /= rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv %= rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv |= rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv &= rhs;
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv ^= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv += rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv -= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv *= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv /= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv %= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv |= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv &= rhs;
+ return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, IntegralT rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv ^= rhs;
+ return nrv;
+}
+
+
+// Arithmetic and bitwise operators involving const char*
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator += (const char* s) { return *this += mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator -= (const char* s) { return *this -= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator *= (const char* s) { return *this *= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator /= (const char* s) { return *this /= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator %= (const char* s) { return *this %= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator |= (const char* s) { return *this |= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator &= (const char* s) { return *this &= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator ^= (const char* s) { return *this ^= mp_int<A,T>(s); }
+
+template<class A, class T>
+inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv += mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv -= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv *= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv /= mp_int<A,T>(rhs);
+ return nrv;
+}
+template<class A, class T>
+inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv %= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv |= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv &= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, const char* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv ^= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+
+#ifndef BOOST_NO_CWCHAR
+// Arithmetic and bitwise operators involving const wchar_t*
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator += (const wchar_t* s) { return *this += mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator -= (const wchar_t* s) { return *this -= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator *= (const wchar_t* s) { return *this *= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator /= (const wchar_t* s) { return *this /= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator %= (const wchar_t* s) { return *this %= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator |= (const wchar_t* s) { return *this |= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator &= (const wchar_t* s) { return *this &= mp_int<A,T>(s); }
+template<class A, class T>
+inline mp_int<A,T>& mp_int<A,T>::operator ^= (const wchar_t* s) { return *this ^= mp_int<A,T>(s); }
+
+template<class A, class T>
+inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv += mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv -= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv *= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv /= mp_int<A,T>(rhs);
+ return nrv;
+}
+template<class A, class T>
+inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv %= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv |= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv &= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T>
+inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, const wchar_t* rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv ^= mp_int<A,T>(rhs);
+ return nrv;
+}
+#endif // BOOST_NO_CWCHAR
+
+
+// Arithmetic and bitwise operators involving basic_string
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator += (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this += mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator -= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this -= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator *= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this *= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator /= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this /= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator %= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this %= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator |= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this |= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator &= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this &= mp_int<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline mp_int<A,T>&
+mp_int<A,T>::operator ^= (const std::basic_string<charT,traits,Alloc>& s)
+{
+ return *this ^= mp_int<A,T>(s);
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator + (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv += mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator - (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv -= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator * (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv *= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator / (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv /= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator % (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv %= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator | (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv |= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator & (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv &= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline mp_int<A,T>
+operator ^ (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
+{
+ mp_int<A,T> nrv(lhs);
+ nrv ^= mp_int<A,T>(rhs);
+ return nrv;
+}
+
+
+
+
+// Input/Output
+template<class A, class T, typename charT, class traits>
+std::basic_istream<charT, traits>&
+operator >> (std::basic_istream<charT, traits>& is, mp_int<A,T>& x)
+{
+ typename std::basic_istream<charT, traits>::sentry sentry(is);
+ if (!sentry)
+ return is;
+
+ std::string s;
+
+ const std::istreambuf_iterator<charT, traits> end;
+ std::istreambuf_iterator<charT, traits> c(is);
+
+ if (*c == '+' || *c == '-')
+ {
+ s.push_back(*c);
+ ++c;
+ }
+
+ int base;
+ if (*c == '0')
+ {
+ base = 8;
+ s.push_back(*c);
+ ++c;
+ if (*c == 'x' || *c == 'X')
+ {
+ base = 16;
+ s.push_back(*c);
+ ++c;
+ }
+ }
+ else if (*c >= '0' && *c <= '9')
+ base = 10;
+ else
+ {
+ is.setstate(std::ios_base::failbit);
+ return is;
+ }
+
+ switch (base)
+ {
+ case 8:
+ while (c != end)
+ {
+ if (*c >= '0' && *c <= '7')
+ s.push_back(*c);
+ else
+ break;
+ ++c;
+ }
+ break;
+ case 10:
+ while (c != end)
+ {
+ if (*c >= '0' && *c <= '9')
+ s.push_back(*c);
+ else
+ break;
+ ++c;
+ }
+ break;
+ case 16:
+ while (c != end)
+ {
+ if ((*c >= '0' && *c <= '9') ||
+ (*c >= 'A' && *c <= 'F') ||
+ (*c >= 'a' && *c <= 'f'))
+ s.push_back(*c);
+ else
+ break;
+ ++c;
+ }
+ break;
+ }
+
+ const mp_int<A,T> tmp(s.begin(), s.end());
+ x = tmp;
+
+ return is;
+}
+
+template<class A, class T, typename charT, class traits>
+std::basic_ostream<charT, traits>&
+operator << (std::basic_ostream<charT, traits>& os, const mp_int<A,T>& x)
+{
+ return os << x.template to_string<std::string>(os.flags());
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/pow.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/pow.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,496 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* computes a = 2**b
+ *
+ * Simple algorithm which zeroes the int, grows it then just sets one bit
+ * as required.
+ */
+template<class A, class T>
+void mp_int<A,T>::pow2(typename mp_int<A,T>::size_type b)
+{
+ /* grow a to accomodate the single bit */
+ grow_capacity(b / digit_bits + 1);
+
+ /* set the used count of where the bit will go */
+ used_ = b / digit_bits + 1;
+
+ // set all bits to zero
+ std::memset(digits_, 0, used_ * sizeof(digit_type));
+
+ /* put the single bit in its place */
+ digits_[b / digit_bits] = digit_type(1) << (b % digit_bits);
+}
+
+/* calculate c = a**b using a square-multiply algorithm */
+template<class A, class T>
+void mp_int<A,T>::pow(digit_type b)
+{
+ mp_int g(*this);
+
+ /* set initial result */
+ *this = digit_type(1);
+
+ for (int x = 0; x < digit_bits; ++x)
+ {
+ sqr();
+
+ /* if the bit is set multiply */
+ if (b & (digit_type(1) << (digit_bits - 1)))
+ *this *= g;
+
+ /* shift to next bit */
+ b <<= 1;
+ }
+}
+
+// this is a shell function that calls either the normal or Montgomery
+// modpow functions. Originally the call to the montgomery code was
+// embedded in the normal function but that wasted alot of stack space
+// for nothing (since 99% of the time the Montgomery code would be called)
+//
+// y = g^x mod p
+// *this = *this^exp mod m
+template<class A, class T>
+void mp_int<A,T>::modpow(const mp_int& exp, const mp_int& m)
+{
+ if (m.is_negative())
+ throw std::domain_error("modpow: modulus m must be positive");
+
+ if (exp.is_negative())
+ {
+ // first compute 1 / *this mod m
+ modinv(m);
+
+ // and now compute (1 / *this)**|exp| instead of *this**exp [exp < 0]
+ modpow(abs(exp), m);
+ return;
+ }
+
+ /* modified diminished radix reduction */
+ if (m.reduce_is_2k_l())
+ {
+ //std::cout << "barret_modpow1\n";
+ barret_modpow(exp, m, 1);
+ return;
+ }
+
+ /* is it a DR modulus? */
+ int dr = m.is_dr_modulus();
+
+ /* if not, is it a unrestricted DR modulus? */
+ if (!dr)
+ dr = m.reduce_is_2k() << 1;
+
+ /* if the modulus is odd or dr == true use the montgomery method */
+ if (m.is_odd() || dr)
+ {
+ //std::cout << "fast_modpow dr = " << dr << "\n";
+ fast_modpow(exp, m, dr);
+ }
+ else
+ {
+ //std::cout << "barret_modpow2\n";
+ /* otherwise use the generic Barrett reduction technique */
+ barret_modpow(exp, m, 0);
+ }
+}
+
+template<class A, class T>
+void mp_int<A,T>::barret_modpow(const mp_int& exp, const mp_int& m, int redmode)
+{
+ static const int TAB_SIZE = 256;
+ mp_int M[TAB_SIZE];
+
+ void (mp_int::*redux)(const mp_int&, const mp_int&);
+
+ /* find window size */
+ size_type x = exp.precision();
+ size_type winsize;
+ if (x <= 7)
+ winsize = 2;
+ else if (x <= 36)
+ winsize = 3;
+ else if (x <= 140)
+ winsize = 4;
+ else if (x <= 450)
+ winsize = 5;
+ else if (x <= 1303)
+ winsize = 6;
+ else if (x <= 3529)
+ winsize = 7;
+ else
+ winsize = 8;
+
+ /* create mu, used for Barrett reduction */
+ mp_int mu;
+
+ mp_int mm(m);
+ if (redmode == 0)
+ {
+ mu.reduce_setup(m);
+ //std::cout << "redux = reduce\n";
+ redux = &mp_int::reduce;
+ }
+ else
+ {
+ mu = mm.reduce_2k_l_setup();
+ //std::cout << "redux = reduce_2k_l\n";
+ redux = &mp_int::reduce_2k_l;
+ }
+
+ /* create M table
+ *
+ * The M table contains powers of the base,
+ * e.g. M[x] = G**x mod P
+ *
+ * The first half of the table is not
+ * computed though accept for M[0] and M[1]
+ */
+ M[1] = *this % mm;
+
+
+ /* compute the value at M[1<<(winsize-1)] by squaring
+ * M[1] (winsize-1) times
+ */
+ M[1 << (winsize - 1)] = M[1];
+
+ for (x = 0; x < (winsize - 1); x++)
+ {
+ /* square it */
+ M[1 << (winsize - 1)].sqr();
+ /* reduce modulo P */
+ (M[1 << (winsize - 1)].*redux)(mm, mu);
+ }
+
+ /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+ * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+ */
+ for (x = (1 << (winsize - 1)) + 1; x < (size_type(1) << winsize); ++x)
+ {
+ M[x] = M[x-1] * M[1];
+ (M[x].*redux)(mm, mu);
+ }
+
+ /* setup result */
+ mp_int res = digit_type(1);
+
+ /* set initial mode and bit cnt */
+ int mode = 0;
+ int bitcnt = 1;
+ digit_type buf = 0;
+ int digidx = exp.used_ - 1;
+ size_type bitcpy = 0;
+ int bitbuf = 0;
+
+ for (;;)
+ {
+ /* grab next digit as required */
+ if (--bitcnt == 0)
+ {
+ /* if digidx == -1 we are out of digits */
+ if (digidx == -1)
+ break;
+ /* read next digit and reset the bitcnt */
+ buf = exp.digits_[digidx--];
+ bitcnt = valid_bits;
+ }
+
+ /* grab the next msb from the exponent */
+ int y = (buf >> static_cast<digit_type>(valid_bits - 1)) & 1;
+ buf <<= digit_type(1);
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0)
+ continue;
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0)
+ {
+ res.sqr();
+ (res.*redux)(mm, mu);
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize)
+ {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; ++x)
+ {
+ res.sqr();
+ (res.*redux)(mm, mu);
+ }
+
+ /* then multiply */
+ res *= M[bitbuf];
+ (res.*redux)(mm, mu);
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0)
+ {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; ++x)
+ {
+ res.sqr();
+ (res.*redux)(mm, mu);
+ //mu = res * mm;
+
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0)
+ {
+ /* then multiply */
+ res *= M[1];
+ (res.*redux)(mm, mu);
+ }
+ }
+ }
+
+ swap(res);
+}
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+template<class A, class T>
+void mp_int<A,T>::fast_modpow(const mp_int& exp, const mp_int& m, int redmode)
+{
+ static const int TAB_SIZE = 256;
+ mp_int M[TAB_SIZE];
+
+ /* use a pointer to the reduction algorithm. This allows us to use
+ * one of many reduction algorithms without modding the guts of
+ * the code with if statements everywhere.
+ */
+ void (mp_int::*redux)(const mp_int&, digit_type);
+
+ /* find window size */
+ size_type x = exp.precision();
+ size_type winsize;
+ if (x <= 7)
+ winsize = 2;
+ else if (x <= 36)
+ winsize = 3;
+ else if (x <= 140)
+ winsize = 4;
+ else if (x <= 450)
+ winsize = 5;
+ else if (x <= 1303)
+ winsize = 6;
+ else if (x <= 3529)
+ winsize = 7;
+ else
+ winsize = 8;
+
+ digit_type mp;
+ /* determine and setup reduction code */
+ if (redmode == 0)
+ {
+ /* now setup montgomery */
+ mp = m.montgomery_setup();
+
+ /* automatically pick the comba one if available (saves quite a few calls/ifs) */
+ /*if (((m.used_ * 2 + 1) < mp_warray) &&
+ m.used_ < 1 << ((CHAR_BIT * sizeof(word_type)) - (2 * valid_bits)))
+ {
+ std::cout << "redux = fast_montgomery_reduce\n";
+ redux = &mp_int::fast_montgomery_reduce;
+ }
+ else
+ {*/
+ /* use slower baseline Montgomery method */
+ //std::cout << "redux = montgomery_reduce\n";
+ redux = &mp_int::montgomery_reduce;
+ //}
+ }
+ else if (redmode == 1)
+ {
+ /* setup DR reduction for moduli of the form B**k - b */
+ mp = m.dr_setup();
+ redux = &mp_int::dr_reduce;
+ }
+ else
+ {
+ /* setup DR reduction for moduli of the form 2**k - b */
+ mp = m.reduce_2k_setup();
+ redux = &mp_int::reduce_2k;
+ }
+
+ /* setup result */
+ mp_int res;
+
+ /* create M table
+ *
+ * The first half of the table is not computed though accept for M[0] and M[1]
+ */
+ if (redmode == 0)
+ {
+ /* now we need R mod m */
+ res.montgomery_calc_normalization(m);
+ /* now set M[1] to G * R mod m */
+ M[1] = (*this * res) % m;
+ }
+ else
+ {
+ res = digit_type(1);
+ M[1] = *this % m;
+ }
+
+ /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+ M[1 << (winsize - 1)] = M[1];
+
+ for (x = 0; x < (winsize - 1); ++x)
+ {
+ M[1 << (winsize - 1)].sqr();
+ (M[1 << (winsize - 1)].*redux)(m, mp);
+ }
+
+ /* create upper table */
+ for (x = (1 << (winsize - 1)) + 1; x < (size_type(1) << winsize); ++x)
+ {
+ M[x] = M[x-1] * M[1];
+ (M[x].*redux)(m, mp);
+ }
+
+ /* set initial mode and bit cnt */
+ int mode = 0;
+ int bitcnt = 1;
+ digit_type buf = 0;
+ int digidx = exp.used_ - 1;
+ size_type bitcpy = 0;
+ unsigned int bitbuf = 0;
+
+ for (;;)
+ {
+ /* grab next digit as required */
+ if (--bitcnt == 0)
+ {
+ /* if digidx == -1 we are out of digits so break */
+ if (digidx == -1)
+ break;
+ /* read next digit and reset bitcnt */
+ buf = exp.digits_[digidx--];
+ bitcnt = valid_bits;
+ }
+
+ /* grab the next msb from the exponent */
+ int y = (buf >> (valid_bits - 1)) & 1;
+ buf <<= digit_type(1);
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0)
+ continue;
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0)
+ {
+ res.sqr();
+ (res.*redux)(m, mp);
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize)
+ {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; ++x)
+ {
+ res.sqr();
+ (res.*redux)(m, mp);
+ }
+
+ /* then multiply */
+ res *= M[bitbuf];
+ (res.*redux)(m, mp);
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0)
+ {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; ++x)
+ {
+ res.sqr();
+ (res.*redux)(m, mp);
+
+ /* get next bit of the window */
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0)
+ {
+ /* then multiply */
+ res *= M[1];
+ (res.*redux)(m, mp);
+ }
+ }
+ }
+
+ /* fixup result if Montgomery reduction is used
+ * recall that any value in a Montgomery system is
+ * actually multiplied by R mod n. So we have
+ * to reduce one more time to cancel out the factor
+ * of R.
+ */
+ if (redmode == 0)
+ (res.*redux)(m, mp);
+
+ swap(res);
+}
+
+
+
+template<class A, class T>
+inline mp_int<A,T> pow(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n)
+{
+ mp_int<A,T> tmp(x);
+ tmp.pow(n);
+ return tmp;
+}
+
+template<class A, class T>
+inline mp_int<A,T> modpow(const mp_int<A,T>& base,
+ const mp_int<A,T>& exp,
+ const mp_int<A,T>& mod)
+{
+ mp_int<A,T> tmp(base);
+ tmp.modpow(exp, mod);
+ return tmp;
+}
+
+
+
+

Added: sandbox/mp_math/boost/mp_math/mp_int/prime.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/prime.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,334 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// this one simply divides x by some small primes found in prime_tab
+// returns false if definitely composite, returns true if probably prime
+// this test is to be used to quickly filter out composite numbers
+// for example testing for 2,5,7 will eliminate 54% of all odd numbers
+// testing for all primes less than 100 eliminates 70%, for all primes
+// less than 256 it is 80%.
+struct primality_division_test
+{
+ typedef bool result_type;
+
+ template<class A, class T>
+ bool operator()(const mp_int<A,T>& p) const;
+};
+
+
+template<class A, class T>
+bool primality_division_test::operator()(const mp_int<A,T>& p) const
+{
+ typedef typename mp_int<A,T>::traits_type traits;
+ typedef typename traits::digit_type digit_type;
+ typedef detail::prime_tab<digit_type> prime_tab;
+
+ if (p.is_even())
+ {
+ if (p != digit_type(2))
+ return false;
+ else
+ return true;
+ }
+
+ mp_int<A,T> tmp;
+ for (int i = 0; i < prime_tab::num_primes; ++i)
+ {
+ /* what is x mod prime_tab[i] */
+ tmp = p;
+ const digit_type r =
+ tmp.divide_by_digit(
+ static_cast<digit_type>(prime_tab::values[i]));
+
+ /* is the residue zero? */
+ if (r == 0)
+ {
+ if (p != prime_tab::values[i])
+ return false;
+ else
+ return true; // definitely prime
+ }
+ }
+ return true;
+}
+
+
+
+// fermat primality test:
+// If an integer p is a prime number, then for all integers a,
+// dividing both a p and a by p gives a result with the same remainder.
+//
+// if p is in fact prime then a**p = a (mod p)
+// for all 0 < a < p
+// or alternatively: a**(p-1) = 1 (mod p)
+//
+// returns true if p is probably prime
+// NOTE: may return true for carmichael numbers
+template<
+ class Distribution = uniform_mp_int<>
+>
+class primality_fermat_test
+{
+ const unsigned int rounds_;
+
+public:
+
+ typedef Distribution distribution_type;
+ typedef bool result_type;
+
+ explicit primality_fermat_test(unsigned int rounds)
+ :
+ rounds_(rounds)
+ {}
+
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+};
+
+
+template<class Distribution>
+template<class Engine, class A, class T>
+bool
+primality_fermat_test<Distribution>::operator()
+ (Engine& eng, const mp_int<A,T>& p) const
+{
+ typedef typename mp_int<A,T>::digit_type digit_type;
+
+ const digit_type one = 1;
+ const mp_int<A,T> p1(p-one);
+
+ distribution_type rng(digit_type(2), p1);
+
+ for (unsigned int i = 0; i < rounds_; ++i)
+ {
+ mp_int<A,T> base = rng(eng);
+
+ base.set_least_significant_bit(); // test only odd bases
+
+ const mp_int<A,T> tmp = modpow(base, p1, p);
+
+ if (tmp != one)
+ return false; // definitely composite!
+ }
+
+ return true;
+}
+
+
+// Miller-Rabin test
+// This is an improved version of the Fermat test that will also detect
+// carmichael numbers.
+// The probability that a composite number is reported as prime
+// is less than 1/(4**k) where k is the number of rounds
+template<
+ class Distribution = uniform_mp_int<>
+>
+class primality_miller_rabin_test
+{
+ const unsigned int rounds_;
+
+ static const struct rtable
+ {
+ unsigned k, t;
+ } sizes_[];
+
+public:
+
+ typedef Distribution distribution_type;
+ typedef bool result_type;
+
+ explicit primality_miller_rabin_test(unsigned int rounds = 0)
+ :
+ rounds_(rounds)
+ {}
+
+ // p must be odd
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+
+ // return the recommended number of rounds for numbers of size 'bits'
+ // so that the probability of error is lower than 2^-96
+ static unsigned int recommended_number_of_rounds(unsigned bits);
+};
+
+// This table comes from libtommath, HAC has one too but with slightly lower
+// numbers of rounds.
+template<class Distribution>
+const typename primality_miller_rabin_test<Distribution>::rtable
+primality_miller_rabin_test<Distribution>::sizes_[] =
+{
+ { 128, 28 },
+ { 256, 16 },
+ { 384, 10 },
+ { 512, 7 },
+ { 640, 6 },
+ { 768, 5 },
+ { 896, 4 },
+ { 1024, 4 }
+};
+
+
+template<class Distribution>
+template<class Engine, class A, class T>
+bool
+primality_miller_rabin_test<Distribution>::operator()
+ (Engine& eng, const mp_int<A,T>& p) const
+{
+ assert(p.is_odd());
+
+ unsigned int r;
+ if (rounds_)
+ r = rounds_;
+ else
+ r = recommended_number_of_rounds(p.precision());
+
+ mp_int<A,T> n = abs(p);
+ --n;
+
+ const typename mp_int<A,T>::size_type s = n.count_lsb();
+ n >>= s; // p-1 / 2**s
+
+ const typename mp_int<A,T>::digit_type one = 1;
+ const mp_int<A,T> p_minus_one(p-one);
+ distribution_type rng(one, p_minus_one);
+
+ for (unsigned int i = 0; i < r; ++i)
+ {
+ const mp_int<A,T> base = rng(eng);
+ mp_int<A,T> y = modpow(base,n,p);
+
+ for (typename mp_int<A,T>::size_type j = 0; j < s; ++j)
+ {
+ const bool b = (y != one) && (y != p_minus_one);
+ y.sqr();
+ y %= p;
+ if (b && (y == one))
+ return false;
+ }
+ if (y != one)
+ return false;
+ }
+ return true;
+}
+
+template<class Distribution>
+unsigned int
+primality_miller_rabin_test<Distribution>::recommended_number_of_rounds(
+ unsigned bits)
+{
+ int i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ if (sizes_[i].k == bits)
+ return sizes_[i].t;
+ else if (sizes_[i].k > bits)
+ return (i == 0) ? sizes_[0].t : sizes_[i - 1].t;
+ }
+
+ return sizes_[i-1].t + 1;
+}
+
+
+
+
+template<class A, class T, class PrimalityTest>
+inline bool is_prime(const mp_int<A,T>& x, PrimalityTest f = PrimalityTest())
+{
+ return f(x);
+}
+
+
+template<
+ class PrimalityTest,
+ class Dist = uniform_mp_int_bits<>
+>
+struct prime_generator
+{
+ typedef PrimalityTest primality_test;
+ typedef Dist distribution_type;
+ typedef typename Dist::result_type result_type;
+
+ explicit prime_generator(std::size_t bits,
+ PrimalityTest test = PrimalityTest())
+ :
+ bits_(bits),
+ test_(test)
+ {}
+
+ template<class Engine>
+ result_type operator()(Engine& e) const;
+
+ std::size_t bits_;
+ const primality_test test_;
+};
+
+template<class PrimalityTest, class Dist>
+template<class Engine>
+typename Dist::result_type
+prime_generator<PrimalityTest,Dist>::operator()(Engine& eng) const
+{
+ distribution_type dist(bits_);
+ result_type candidate;
+ do
+ {
+ candidate = dist(eng);
+ candidate.set_least_significant_bit(); // make odd
+ } while (!is_prime(candidate, test_));
+
+ return candidate;
+}
+
+
+// A prime p is called safe if (p-1)/2 is also prime
+template<
+ class PrimalityTest,
+ class Dist = uniform_mp_int_bits<>
+>
+struct safe_prime_generator
+{
+ typedef PrimalityTest primality_test;
+ typedef Dist distribution_type;
+ typedef typename Dist::result_type result_type;
+
+ explicit safe_prime_generator(std::size_t bits,
+ PrimalityTest test = PrimalityTest())
+ :
+ bits_(bits),
+ test_(test)
+ {}
+
+ template<class Engine>
+ result_type operator()(Engine& e) const;
+
+ std::size_t bits_;
+ const primality_test test_;
+};
+
+
+template<class PrimalityTest, class Dist>
+template<class Engine>
+typename Dist::result_type
+safe_prime_generator<PrimalityTest,Dist>::operator()(Engine& eng) const
+{
+ prime_generator<PrimalityTest, Dist> prime_gen(bits_-1, test_);
+ result_type p;
+ do
+ {
+ do
+ {
+ p = prime_gen(eng);
+ p.multiply_by_2();
+ ++p;
+ } while (!is_prime(p, test_));
+ } while (p.precision() > bits_); // catch extremely rare case
+
+ return p;
+}
+
+
+
+
+

Added: sandbox/mp_math/boost/mp_math/mp_int/random.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/random.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,185 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/*#ifndef BOOST_MP_MATH_MP_INT_RANDOM_HPP
+#define BOOST_MP_MATH_MP_INT_RANDOM_HPP
+
+namespace boost {
+namespace mp_math {
+
+template<class A, class T>
+struct mp_int;
+
+*/
+
+// this class is modeled after boost::uniform_int
+// in fact it uses boost::uniform_int internally
+template<class MpInt = mp_int<> >
+struct uniform_mp_int
+{
+ typedef MpInt input_type;
+ typedef MpInt result_type;
+
+ // is min() and max() known at compile time?
+ static const bool has_fixed_range = false;
+
+ uniform_mp_int(const MpInt& min, const MpInt& max)
+ :
+ min_(min),
+ max_(max),
+ d_(0, MpInt::digit_max)
+ {}
+
+ result_type min() const { return min_; }
+ result_type max() const { return max_; }
+
+ void reset() { d_.reset(); }
+
+ template<class Engine>
+ result_type operator()(Engine& e);
+
+private:
+
+ MpInt min_, max_;
+ uniform_int<typename MpInt::digit_type> d_;
+};
+
+template<class MpInt>
+const bool uniform_mp_int<MpInt>::has_fixed_range;
+
+
+template<class MpInt>
+template<class Engine>
+typename uniform_mp_int<MpInt>::result_type
+uniform_mp_int<MpInt>::operator()(Engine& e)
+{
+ result_type tmp;
+ tmp.grow_capacity(max_.size());
+
+ for (typename result_type::size_type i = 0; i < max_.size(); ++i)
+ tmp[i] = d_(e);
+
+ tmp.set_size(max_.size());
+ tmp.clamp();
+
+ if (tmp > max_)
+ tmp %= max_;
+
+ return tmp;
+}
+
+
+template<class MpInt = mp_int<> >
+struct uniform_mp_int_bits
+{
+ typedef MpInt input_type;
+ typedef MpInt result_type;
+
+ static const bool has_fixed_range = false;
+
+ explicit uniform_mp_int_bits(typename MpInt::size_type bits)
+ :
+ d_(0, MpInt::digit_max),
+ bits_(bits)
+ {}
+
+ result_type min() const;
+ result_type max() const;
+
+ typename MpInt::size_type precision() const { return bits_; }
+
+ void reset() { d_.reset(); }
+
+ template<class Engine>
+ result_type operator()(Engine& e);
+
+private:
+
+ uniform_int<typename MpInt::digit_type> d_;
+ typename MpInt::size_type bits_;
+};
+
+template<class MpInt>
+const bool uniform_mp_int_bits<MpInt>::has_fixed_range;
+
+
+template<class MpInt>
+template<class Engine>
+typename uniform_mp_int_bits<MpInt>::result_type
+uniform_mp_int_bits<MpInt>::operator()(Engine& e)
+{
+ result_type tmp;
+
+ const typename MpInt::size_type offset = bits_ / MpInt::valid_bits + 1;
+
+ tmp.grow_capacity(offset);
+
+ for (typename result_type::size_type i = 0; i < offset; ++i)
+ tmp[i] = d_(e);
+
+ tmp.set_size(offset);
+
+ const typename MpInt::digit_type mask =
+ (~typename MpInt::digit_type(0))
+ << (bits_ % MpInt::valid_bits);
+
+ tmp[offset-1] &= ~mask;
+
+ tmp.set_bit(bits_-1); // make exactly bits_ bits long
+
+ return tmp;
+}
+
+template<class MpInt>
+typename uniform_mp_int_bits<MpInt>::result_type
+uniform_mp_int_bits<MpInt>::min() const
+{
+ result_type tmp;
+
+ const typename MpInt::size_type offset =
+ bits_ / MpInt::valid_bits + 1;
+
+ tmp.grow_capacity(offset);
+
+ std::memset(tmp.digits(), 0,
+ offset * sizeof(typename MpInt::digit_type));
+
+ tmp.set_size(offset);
+ tmp.set_bit(bits_ - 1);
+
+ return tmp;
+}
+
+template<class MpInt>
+typename uniform_mp_int_bits<MpInt>::result_type
+uniform_mp_int_bits<MpInt>::max() const
+{
+ result_type tmp;
+ const typename MpInt::size_type offset =
+ bits_ / MpInt::valid_bits + 1;
+
+ tmp.grow_capacity(offset);
+
+ for (typename result_type::size_type i = 0; i < offset; ++i)
+ tmp[i] = MpInt::digit_max;
+
+ tmp.set_size(offset);
+
+ const typename MpInt::digit_type mask =
+ (~typename MpInt::digit_type(0))
+ << (bits_ % MpInt::valid_bits);
+
+ tmp[offset-1] &= ~mask;
+
+ return tmp;
+}
+
+
+/*
+} // namespace boost
+} // namespace mp_math
+
+#endif
+*/

Added: sandbox/mp_math/boost/mp_math/mp_int/root.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/root.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,116 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+mp_int<A,T> sqrt(const mp_int<A,T>& x)
+{
+ /* must be positive */
+ if (x.sign() == -1)
+ throw std::domain_error("sqrt: argument is negative");
+
+ mp_int<A,T> t1;
+
+ /* easy out */
+ if (x.is_zero())
+ {
+ t1.zero();
+ return t1;
+ }
+
+ t1 = x;
+
+ /* First approx. (not very bad for large arg) */
+ t1.shift_digits_right(t1.size()/2);
+
+ /* t1 > 0 */
+ mp_int<A,T> t2 = x / t1;
+
+ t1 += t2;
+ t1.divide_by_2();
+ /* And now t1 > sqrt(arg) */
+ do
+ {
+ t2 = x / t1;
+ t1 += t2;
+ t1.divide_by_2();
+ /* t1 >= sqrt(arg) >= t2 at this point */
+ } while (t1.compare_magnitude(t2) == 1);
+
+ return t1;
+}
+
+
+/* find the n'th root of an integer
+ *
+ * Result found such that (c)**b <= a and (c+1)**b > a
+ *
+ * This algorithm uses Newton's approximation
+ * x[i+1] = x[i] - f(x[i])/f'(x[i])
+ * which will find the root in log(N) time where
+ * each step involves a fair bit. This is not meant to
+ * find huge roots [square and cube, etc].
+ */
+template<class A, class T>
+mp_int<A,T> nth_root(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n)
+{
+ mp_int<A,T> t1, t2, t3;
+
+ /* input must be positive if n is even */
+ if ((n & 1) == 0 && x.is_negative())
+ throw std::domain_error("nth_root: argument must be positive if n is even");
+
+ /* if x is negative fudge the sign but keep track */
+ const int neg = x.sign();
+ const_cast<mp_int<A,T>*>(&x)->set_sign(1);
+
+ /* t2 = 2 */
+ t2 = typename mp_int<A,T>::digit_type(2);
+
+ do
+ {
+ t1 = t2;
+
+ /* t2 = t1 - ((t1**n - x) / (n * t1**(n-1))) */
+
+ /* t3 = t1**(n-1) */
+ t3 = pow(t1, n-1);
+
+ /* numerator */
+ /* t2 = t1**n */
+ t2 = t3 * t1;
+
+ /* t2 = t1**n - x */
+ t2 -= x;
+
+ /* denominator */
+ /* t3 = t1**(n-1) * n */
+ t3.multiply_by_digit(n);
+
+ /* t3 = (t1**n - x)/(n * t1**(n-1)) */
+ t3 = t2 / t3;
+
+ t2 = t1 - t3;
+ } while (t1 != t2);
+
+ /* result can be off by a few so check */
+ for (;;)
+ {
+ t2 = pow(t1, n);
+
+ if (t2 > x)
+ t1.sub_digit(1);
+ else
+ break;
+ }
+
+ /* reset the sign of x first */
+ const_cast<mp_int<A,T>*>(&x)->set_sign(neg);
+
+ /* set the sign of the result */
+ t1.set_sign(neg);
+
+ return t1;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/sqr.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/sqr.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,200 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* squaring using Toom-Cook 3-way algorithm */
+template<class A, class T>
+void mp_int<A,T>::toom_sqr()
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+
+ const size_type B = used_ / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ a0 = *this;
+ a0.modulo_2_to_the_power_of(valid_bits * B);
+
+ a1 = *this;
+ a1.shift_digits_right(B);
+ a1.modulo_2_to_the_power_of(valid_bits * B);
+
+ a2 = *this;
+ a2.shift_digits_right(B * 2);
+
+ /* w0 = a0*a0 */
+ w0 = a0;
+ w0.sqr();
+
+ /* w4 = a2 * a2 */
+ w4 = a2;
+ w4.sqr();
+
+ /* w1 = (a2 + 2(a1 + 2a0))**2 */
+ w1 = a0;
+ w1.multiply_by_2();
+ w1 += a1;
+ w1.multiply_by_2();
+ w1 += a2;
+ w1.sqr();
+
+ /* w3 = (a0 + 2(a1 + 2a2))**2 */
+ w3 = a2;
+ w3.multiply_by_2();
+ w3 += a1;
+ w3.multiply_by_2();
+ w3 += a0;
+ w3.sqr();
+
+ /* w2 = (a2 + a1 + a0)**2 */
+ w2 = a1 + a2;
+ w2 += a0;
+ w2.sqr();
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+ */
+
+ /* r1 - r4 */
+ w1 -= w4;
+ /* r3 - r0 */
+ w3 -= w0;
+ /* r1/2 */
+ w1.divide_by_2();
+ /* r3/2 */
+ w3.divide_by_2();
+ /* r2 - r0 - r4 */
+ w2 -= w0;
+ w2 -= w4;
+ /* r1 - r2 */
+ w1 -= w2;
+ /* r3 - r2 */
+ w3 -= w2;
+ /* r1 - 8r0 */
+ tmp1 = w0;
+ tmp1 <<= 3;
+ w1 -= tmp1;
+ /* r3 - 8r4 */
+ tmp1 = w4;
+ tmp1 <<= 3;
+ w3 -= tmp1;
+ /* 3r2 - r1 - r3 */
+ w2.multiply_by_digit(3);
+ w2 -= w1;
+ w2 -= w3;
+ /* r1 - r2 */
+ w1 -= w2;
+ /* r3 - r2 */
+ w3 -= w2;
+ /* r1/3 */
+ w1.divide_by_3();
+ /* r3/3 */
+ w3.divide_by_3();
+ /* at this point shift W[n] by B*n */
+ w1.shift_digits_left(1 * B);
+ w2.shift_digits_left(2 * B);
+ w3.shift_digits_left(3 * B);
+ w4.shift_digits_left(4 * B);
+ *this = w0 + w1;
+ tmp1 = w2 + w3;
+ tmp1 += w4;
+ *this += tmp1;
+}
+
+/* Karatsuba squaring, computes b = a*a using three
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details. It
+ * is essentially the same algorithm but merely
+ * tuned to perform recursive squarings.
+ */
+// a = x1 * B**n + x0
+// a**2 = x1x1 * B**2n + 2*x0x1 * B**n + x0x0
+// where
+// 2*x0x1 = 1) x1x1 + x0x0 - (x1 - x0)**2 or
+// 2) (x0 + x1)**2 - (x0x0 + x1x1)
+// we use version 1)
+// version 2) may use one less temporary?
+// a**2 = x1x1 * B**2n + (x1x1 + x0x0 - (x1 - x0)**2) * B**n + x0x0
+// TODO revert!
+template<class A, class T>
+void mp_int<A,T>::karatsuba_sqr()
+{
+ mp_int x0, x1, tmp, tmp2, x0x0, x1x1;
+
+ /* min # of digits divided in two */
+ const size_type B = used_ >> 1;
+
+ /* init copy all the temps */
+ x0.grow_capacity(B);
+ x1.grow_capacity(used_ - B);
+
+ /* init temps */
+ x0x0.grow_capacity(B * 2);
+ x1x1.grow_capacity((used_ - B) * 2);
+
+ /* now shift the digits */
+ std::memcpy(x0.digits_, digits_, B * sizeof(digit_type));
+ std::memcpy(x1.digits_, digits_ + B, (used_ - B) * sizeof(digit_type));
+
+ x0.used_ = B;
+ x1.used_ = used_ - B;
+
+ x0.clamp();
+
+ x0x0 = x0;
+ x0x0.sqr();
+ x1x1 = x1;
+ x1x1.sqr();
+
+ tmp = x1x1;
+ tmp.add_magnitude(x0x0);
+
+ tmp2 = x1;
+ tmp2 -= x0;
+ tmp2.sqr();
+
+ tmp.sub_smaller_magnitude(tmp2);
+
+ x1x1.shift_digits_left(B * 2);
+ tmp.shift_digits_left(B);
+
+ x1x1.add_magnitude(tmp);
+ x1x1.add_magnitude(x0x0);
+ swap(x1x1);
+}
+
+template<class A, class T>
+void mp_int<A,T>::comba_sqr()
+{
+ mp_int tmp;
+ tmp.grow_capacity(used_ + used_);
+
+ ops_type::comba_sqr(tmp.digits(), digits(), used_);
+
+ tmp.used_ = used_ + used_;
+
+ tmp.clamp();
+ swap(tmp);
+}
+
+// computes *this = *this * *this
+template<class A, class T>
+void mp_int<A,T>::sqr()
+{
+ if (used_ >= traits_type::toom_sqr_cutoff)
+ toom_sqr();
+ else if (used_ >= traits_type::karatsuba_sqr_cutoff)
+ karatsuba_sqr();
+ else
+ comba_sqr();
+ sign_ = 1;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,309 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+namespace detail
+{
+ template<typename charT>
+ inline int ascii_to_value(const charT c)
+ {
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return c - '0';
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ return c - 'A' + 10;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ return c - 'a' + 10;
+ }
+ return c;
+ }
+}
+
+// low level from string conversion routine
+// Requires:
+// - used_ = 0
+// - first and last must point into string without sign prefix and without base
+// prefix (like 0x)
+// - radix is 8, 10 or 16
+template<class A, class T>
+template<typename Iter>
+void mp_int<A,T>::from_string(Iter first, Iter last, unsigned radix)
+{
+ assert(used_ == 0);
+ assert(first != last);
+
+ const detail::string_conversion_constants<mp_int> sc(radix);
+
+ const size_type length = std::distance(first, last);
+
+ static const char* inv_msg = "mp_int<>::from_string: invalid character";
+
+ const bool is_power_of_two = (radix & (radix - 1)) == 0;
+ if (is_power_of_two)
+ {
+ const size_type required =
+ (length * sc.radix_storage_bits + (valid_bits - 1)) / valid_bits;
+ grow_capacity(required);
+
+ digit_type result = 0;
+ int offset = 0;
+
+ typedef std::reverse_iterator<Iter> reverse_iter_type;
+ for (reverse_iter_type c(last); c != reverse_iter_type(first); ++c)
+ {
+ const digit_type x = static_cast<digit_type>(detail::ascii_to_value(*c));
+
+ if (x >= radix)
+ throw std::invalid_argument(inv_msg);
+
+ result |= x << offset;
+ offset += sc.radix_storage_bits;
+
+ if (offset >= valid_bits)
+ {
+ digits_[used_++] = result;
+ offset -= valid_bits;
+ result = static_cast<digit_type>(x >> (sc.radix_storage_bits - offset));
+ }
+ }
+
+ if (result || !used_)
+ digits_[used_++] = result;
+
+ clamp();
+ if (is_zero())
+ sign_ = 1;
+ }
+ else // radix can only be 10 at this point
+ {
+ size_type required;
+ // approximate log2(10) with 10/3
+ if (length < std::numeric_limits<size_type>::max()/10U)
+ required = (10U * length + 2U) / 3U;
+ else
+ required = length / 3U * 10U;
+ required = (required + (valid_bits - 1)) / valid_bits;
+
+ grow_capacity(required);
+
+ for (size_type i = sc.max_power; i < length; i += sc.max_power)
+ {
+ digit_type result = 0U;
+
+ // first convert a block of decimal digits to radix 10^sc.max_power
+ // which will still fit into a digit_type
+ for (unsigned int j = 0; j < sc.max_power; ++j)
+ {
+ const digit_type x = *first++ - '0';
+ if (x >= 10U)
+ throw std::invalid_argument(inv_msg);
+ result = result * 10U + x;
+ }
+
+ // then use multi precision routines to convert this digit to binary
+ if (used_)
+ {
+ digit_type carry = ops_type::multiply_by_digit(digits_, digits_, used_,
+ sc.max_power_value);
+
+ carry += ops_type::add_single_digit(digits_, digits_, used_, result);
+
+ if (carry)
+ digits_[used_++] = carry;
+ }
+ else
+ digits_[used_++] = result;
+ }
+
+ // one last round for the remaining decimal digits
+ if (first != last)
+ {
+ word_type radix_power = 1U;
+ digit_type result = 0U;
+
+ while (first != last)
+ {
+ const digit_type x = *first++ - '0';
+ if (x >= 10U)
+ throw std::invalid_argument(inv_msg);
+ result = result * 10U + x;
+ radix_power *= 10U;
+ }
+
+ if (used_)
+ {
+ digit_type carry = ops_type::multiply_by_digit(digits_, digits_, used_,
+ static_cast<digit_type>(radix_power));
+
+ carry += ops_type::add_single_digit(digits_, digits_, used_, result);
+
+ if (carry)
+ digits_[used_++] = carry;
+ }
+ else
+ digits_[used_++] = result;
+ }
+ }
+}
+
+
+namespace detail
+{
+ template<typename T, class Alloc>
+ struct scoped_ptr : Alloc
+ {
+ T* ptr;
+ std::size_t size;
+ explicit scoped_ptr(std::size_t s) : size(s) { ptr = this->allocate(size); }
+ ~scoped_ptr() { this->deallocate(ptr,size); }
+ };
+}
+
+
+// TODO use an output iterator then we can easily output to different string
+// types. But keep a high level to_string function to allocate string memory
+// only once.
+template<class A, class T>
+template<class StringT>
+StringT mp_int<A,T>::to_string(std::ios_base::fmtflags f) const
+{
+ typedef typename StringT::value_type char_type;
+
+ StringT s;
+
+ if (!used_)
+ return s;
+
+ digit_type radix;
+
+ if (f & std::ios_base::hex)
+ radix = 16;
+ else if (f & std::ios_base::oct)
+ radix = 8;
+ else if (f & std::ios_base::dec)
+ radix = 10;
+ else
+ throw std::invalid_argument("mp_int<>::to_string: unsupported radix");
+
+ char_type prefix[3];
+ char_type* p = prefix;
+
+ if (is_negative())
+ *p++ = '-';
+ else if (f & std::ios_base::showpos)
+ *p++ = '+';
+
+ if (f & std::ios_base::showbase)
+ {
+ if (radix == 16)
+ {
+ *p++ = '0';
+ if (f & std::ios_base::uppercase)
+ *p++ = 'X';
+ else
+ *p++ = 'x';
+ }
+ else if (radix == 8)
+ *p++ = '0';
+ }
+
+ const int prefix_offset = p - prefix;
+
+ if (is_zero())
+ {
+ s.reserve(prefix_offset + 1);
+ for (int i = 0; i < prefix_offset; ++i)
+ s.push_back(prefix[i]);
+ if (!(f & std::ios_base::oct))
+ s.push_back('0');
+ return s;
+ }
+
+ const detail::string_conversion_constants<mp_int> sc(radix);
+ const bool is_power_of_two = (radix & (radix - 1)) == 0;
+
+ size_type total_bits = precision();
+ // round up to a multiple of sc.radix_storage_bits
+ if (total_bits % sc.radix_storage_bits)
+ total_bits = total_bits - total_bits % sc.radix_storage_bits
+ + sc.radix_storage_bits;
+
+ size_type required;
+ if (is_power_of_two)
+ required = (total_bits + (sc.radix_storage_bits - 1))
+ / sc.radix_storage_bits;
+ // approximate log2(10) with 13/4
+ else if (total_bits < std::numeric_limits<size_type>::max() / 4)
+ required = (total_bits * 4 + 12) / 13;
+ else
+ required = total_bits / 13 * 4;
+
+ required += prefix_offset;
+ detail::scoped_ptr<char_type, typename StringT::allocator_type> sd(required);
+
+ char_type* c = sd.ptr;
+
+ for (int i = 0; i < prefix_offset; ++i)
+ *c++ = prefix[i];
+
+ if (is_power_of_two)
+ {
+ static const char* const lowercase_tab = "0123456789abcdef";
+ static const char* const uppercase_tab = "0123456789ABCDEF";
+
+ const char* const tab = (f & std::ios_base::uppercase)
+ ? uppercase_tab
+ : lowercase_tab;
+
+ const digit_type mask = (1 << sc.radix_storage_bits) - 1;
+
+ int offset = total_bits % valid_bits;
+ if (!offset)
+ offset = valid_bits;
+
+ const_reverse_iterator d = rbegin();
+ for (;;)
+ {
+ offset -= sc.radix_storage_bits;
+ while (offset >= 0)
+ {
+ *c++ = tab[(*d >> offset) & mask];
+ offset -= sc.radix_storage_bits;
+ }
+ const digit_type partial_value = (*d << -offset) & mask;
+ if (++d == rend())
+ break;
+ offset += valid_bits;
+ *c++ = tab[partial_value | (*d >> offset)];
+ }
+ }
+ else
+ {
+ digit_type m = 2;
+ for (digit_type i = 100; i < sc.max_power_value; i *= 10)
+ ++m;
+
+ mp_int tmp = abs(*this);
+
+ while (!tmp.is_zero())
+ {
+ digit_type remainder = tmp.divide_by_digit(sc.max_power_value);
+
+ for (digit_type i = 0; i < m; ++i)
+ {
+ if (remainder || !tmp.is_zero())
+ *c++ = '0' + remainder % 10U;
+ remainder /= 10U;
+ }
+ }
+ std::reverse(sd.ptr + prefix_offset, c);
+ }
+
+ s.assign(sd.ptr, c);
+
+ return s;
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/sub.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/sub.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,43 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<class A, class T>
+void mp_int<A,T>::sub_digit(digit_type b)
+{
+ if (is_negative())
+ {
+ sign_ = 1;
+ add_digit(b);
+ sign_ = -1;
+ return;
+ }
+
+ if (used_ == 1)
+ {
+ if (digits_[0] < b) // example: 2 - 6 = -4
+ {
+ digits_[0] = b - digits_[0];
+ sign_ = -1;
+ }
+ else // example 8 - 7 = 1 or 5 - 5 = 0
+ digits_[0] -= b;
+ }
+ else
+ {
+ ops_type::subtract_single_digit(digits_, digits_, used_, b);
+ if (!digits_[used_-1])
+ --used_;
+ }
+}
+
+// low level subtraction (assumes |*this| >= |rhs|), HAC pp.595 Algorithm 14.9
+template<class A, class T>
+inline void mp_int<A,T>::sub_smaller_magnitude(const mp_int& rhs)
+{
+ ops_type::sub_smaller_magnitude(digits_, digits_, used_, rhs.digits_, rhs.used_);
+
+ clamp();
+}
+

Added: sandbox/mp_math/boost/mp_math/mp_int/traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/mp_int/traits.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,98 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_MP_INT_TRAITS_HPP
+#define BOOST_MP_MATH_MP_INT_TRAITS_HPP
+
+#include <cstddef> // size_t
+#include <boost/config.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/lower_bound.hpp>
+#include <boost/mpl/vector.hpp>
+
+
+namespace boost {
+namespace mp_math {
+
+namespace detail {
+
+typedef mpl::vector<
+ unsigned char,
+ unsigned short,
+ unsigned int,
+ unsigned long int
+ #ifdef BOOST_HAS_LONG_LONG
+ ,
+ unsigned long long int
+ #endif
+> unsigned_type_vec;
+
+template<typename T1, typename T2>
+struct cmp_digits
+:
+mpl::bool_<
+ std::numeric_limits<T1>::digits < std::numeric_limits<T2>::digits/2
+>
+{
+};
+
+// we could also choose unsigned int (since this is propably the
+// fastest unsigned integer type) as digit_type then
+// try to find a larger type as word_type
+// if none exists set unsigned int as word_type and choose next
+// smaller type as digit_type
+struct choose
+{
+ typedef mpl::back<unsigned_type_vec>::type word_type;
+ typedef mpl::deref<
+ mpl::lower_bound<
+ unsigned_type_vec, word_type, cmp_digits<mpl::_1,mpl::_2>
+ >::type
+ >::type digit_type;
+};
+
+} // namespace detail
+
+
+template<
+ typename Digit = detail::choose::digit_type,
+ typename Word = detail::choose::word_type/*,
+ bool debug = false*/
+>
+struct mp_int_traits
+{
+ BOOST_STATIC_ASSERT(
+ std::numeric_limits<Digit>::digits <= std::numeric_limits<Word>::digits/2
+ );
+
+ typedef std::size_t size_type; // TODO should prolly get size_type from allocator_type
+ typedef Digit digit_type;
+ typedef Word word_type;
+
+ static size_type toom_mul_cutoff;
+ static size_type toom_sqr_cutoff;
+ static size_type karatsuba_mul_cutoff;
+ static size_type karatsuba_sqr_cutoff;
+};
+
+
+#define BMPINT_init(S) template<typename D, typename W>\
+ typename mp_int_traits<D,W>::S mp_int_traits<D,W>::
+BMPINT_init(size_type )toom_mul_cutoff = 350;
+BMPINT_init(size_type )toom_sqr_cutoff = 400;
+BMPINT_init(size_type )karatsuba_mul_cutoff = 80;
+BMPINT_init(size_type )karatsuba_sqr_cutoff = 120;
+
+#undef BMPINT_init
+
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/doc/bibliography.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/bibliography.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,21 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Bibliography]
+
+[heading GMP (GNU Multiple Precision Arithmetic Library)]
+* [@http://gmplib.org/]
+
+[heading Handbook of Applied Cryptogtaphy]
+* [@http://www.cacr.math.uwaterloo.ca/hac/]
+
+[heading libtommath]
+* [@http://libtom.org/] `// this link seems to be down lately (10/26/2008)`
+* [@http://math.libtomcrypt.com/] `// this works but is out of date`
+
+[heading Miller-Rabin Primality Test]
+* [@http://www.bitnuts.de/rienhardt/docs/miller_rabin.pdf]
+
+[endsect][/Bibliography]

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/add.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/ctor_dec.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/ctor_hex.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/divide.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/input_vecs.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/modpow.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/modulo.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/multiply.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/square.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/subtract.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/to_dec.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/benchmark_imgs/k7/to_hex.png
==============================================================================
Binary file. No diff available.

Added: sandbox/mp_math/libs/mp_math/doc/html/boostbook.css
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/boostbook.css 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,519 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Distributed under the Boost Software License, Version 1.0. (See accompany-
+ ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+/*=============================================================================
+ Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+ Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+ Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 90%;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+ Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font: 140% }
+ h2 { font: bold 140% }
+ h3 { font: bold 130% }
+ h4 { font: bold 120% }
+ h5 { font: italic 110% }
+ h6 { font: italic 100% }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 120% }
+ h5 tt.computeroutput { font-size: 110% }
+ h6 tt.computeroutput { font-size: 100% }
+
+/*=============================================================================
+ Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+ Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+ Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+ Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+ Table of contents
+=============================================================================*/
+
+ .toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+/*=============================================================================
+ Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+ Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ p.blurb img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+ Variable Lists
+=============================================================================*/
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+ Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+ Colors
+=============================================================================*/
+
+ @media screen
+ {
+ /* Links */
+ a
+ {
+ color: #005a9c;
+ }
+
+ a:visited
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
+
+/*=============================================================================
+ Images
+=============================================================================*/
+
+ span.inlinemediaobject img
+ {
+ vertical-align: middle;
+ }
\ No newline at end of file

Added: sandbox/mp_math/libs/mp_math/doc/html/index.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/index.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,109 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 1. mp_int</title>
+<link rel="stylesheet" href="boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="index.html" title="Chapter 1. mp_int">
+<link rel="next" href="mp_int_/tutorial.html" title="Tutorial">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="mp_int_/tutorial.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div>
+<div><h2 class="title">
+<a name="mp_int"></a>Chapter 1. mp_int </h2></div>
+<div><div class="author"><h3 class="author">
+<span class="firstname">Kevin</span> <span class="surname">Sopp</span>
+</h3></div></div>
+<div><p class="copyright">Copyright © 2008 Kevin Sopp</p></div>
+<div><div class="legalnotice">
+<a name="id2693145"></a><p>
+ All code and documentation is in the public domain
+ </p>
+</div></div>
+</div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="section">Introduction</span></dt>
+<dt><span class="section">Tutorial</span></dt>
+<dd><dl>
+<dt><span class="section">General use</span></dt>
+<dt><span class="section"><a href="mp_int_/tutorial.html#mp_int_.tutorial.random_number_generation">Random number
+ generation</a></span></dt>
+<dt><span class="section">Primality testing</span></dt>
+<dt><span class="section"><a href="mp_int_/tutorial.html#mp_int_.tutorial.prime_number_generation">Prime number
+ generation</a></span></dt>
+</dl></dd>
+<dt><span class="section">Performance</span></dt>
+<dd><dl>
+<dt><span class="section">Tips</span></dt>
+<dt><span class="section">Measurements</span></dt>
+</dl></dd>
+<dt><span class="section">Implementation notes</span></dt>
+<dd><dl>
+<dt><span class="section"><a href="mp_int_/implementation_notes.html#mp_int_.implementation_notes.mp_int_structure">mp_int
+ structure</a></span></dt>
+<dt><span class="section">Semantics</span></dt>
+</dl></dd>
+<dt><span class="section">mp_int reference</span></dt>
+<dt><span class="section">mp_int_traits reference</span></dt>
+<dt><span class="section">uniform_mp_int reference</span></dt>
+<dt><span class="section"><a href="mp_int_/uniform_mp_int_bits_reference.html">uniform_mp_int_bits
+ reference</a></span></dt>
+<dt><span class="section">Primality Tests reference</span></dt>
+<dd><dl>
+<dt><span class="section">primality_division_test</span></dt>
+<dt><span class="section">primality_fermat_test</span></dt>
+<dt><span class="section">primality_miller_rabin_test</span></dt>
+</dl></dd>
+<dt><span class="section">Bibliography</span></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.introduction"></a><a class="link" href="index.html#mp_int_.introduction" title="Introduction">Introduction</a>
+</h2></div></div></div>
+<p>
+ This library provides the <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ class template for arbitrary precision signed integers. These integers grow
+ dynamically as needed. Additionally, special functions which are necessary
+ for the implementation of public key cryptography such as prime generation
+ are provided.
+ </p>
+<a name="mp_int_.introduction.acknowledgement"></a><h4>
+<a name="id2733685"></a>
+ <a class="link" href="index.html#mp_int_.introduction.acknowledgement">Acknowledgement</a>
+ </h4>
+<p>
+ This library originally started as a port of the C code of libtommath. Without
+ the huge amount of work done by its author Tom St. Denis, this library wouldn't
+ have been possible. Not only does he provide free C code, but also a very detailed
+ pdf document of over 200 pages explaining the algorithms used in his code.
+ Both his documentation and his code were placed in the public domain. In the
+ spirit of his work the code of the <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ library and its documentation are placed in the <span class="bold"><strong>public
+ domain</strong></span> as well.
+ </p>
+</div>
+<p>
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><p><small>Last revised: October 06, 2008 at 11:40:14 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="mp_int_/tutorial.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/bibliography.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/bibliography.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,71 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Bibliography</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="primality_tests_reference.html" title="Primality Tests reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="primality_tests_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.bibliography"></a><a class="link" href="bibliography.html" title="Bibliography">Bibliography</a>
+</h2></div></div></div>
+<a name="mp_int_.bibliography.gmp__gnu_multiple_precision_arithmetic_library_"></a><h4>
+<a name="id2791749"></a>
+ <a class="link" href="bibliography.html#mp_int_.bibliography.gmp__gnu_multiple_precision_arithmetic_library_">GMP
+ (GNU Multiple Precision Arithmetic Library)</a>
+ </h4>
+<div class="itemizedlist"><ul type="disc"><li>http://gmplib.org/</li></ul></div>
+<a name="mp_int_.bibliography.handbook_of_applied_cryptogtaphy"></a><h4>
+<a name="id2791785"></a>
+ <a class="link" href="bibliography.html#mp_int_.bibliography.handbook_of_applied_cryptogtaphy">Handbook
+ of Applied Cryptogtaphy</a>
+ </h4>
+<div class="itemizedlist"><ul type="disc"><li>http://www.cacr.math.uwaterloo.ca/hac/</li></ul></div>
+<a name="mp_int_.bibliography.libtommath"></a><h4>
+<a name="id2791820"></a>
+ <a class="link" href="bibliography.html#mp_int_.bibliography.libtommath">libtommath</a>
+ </h4>
+<div class="itemizedlist"><ul type="disc">
+<li>
+http://libtom.org/<code class="computeroutput"><span class="comment">// this link seems to be down lately (10/26/2008)</span></code>
+</li>
+<li>
+http://math.libtomcrypt.com/<code class="computeroutput"><span class="comment">// this works but is out of date</span></code>
+</li>
+</ul></div>
+<a name="mp_int_.bibliography.miller_rabin_primality_test"></a><h4>
+<a name="id2791886"></a>
+ <a class="link" href="bibliography.html#mp_int_.bibliography.miller_rabin_primality_test">Miller-Rabin
+ Primality Test</a>
+ </h4>
+<div class="itemizedlist"><ul type="disc"><li>http://www.bitnuts.de/rienhardt/docs/miller_rabin.pdf</li></ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="primality_tests_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/implementation_notes.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/implementation_notes.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,98 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Implementation notes</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="performance.html" title="Performance">
+<link rel="next" href="mp_int_reference.html" title="mp_int reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="performance.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mp_int_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.implementation_notes"></a><a class="link" href="implementation_notes.html" title="Implementation notes">Implementation notes</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="implementation_notes.html#mp_int_.implementation_notes.mp_int_structure">mp_int
+ structure</a></span></dt>
+<dt><span class="section">Semantics</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.implementation_notes.mp_int_structure"></a><a class="link" href="implementation_notes.html#mp_int_.implementation_notes.mp_int_structure" title="mp_int structure">mp_int
+ structure</a>
+</h3></div></div></div>
+<p>
+ An <code class="computeroutput"><span class="identifier">mp_int</span></code> is handled in a
+ sign plus magnitude representation which looks like this:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">mp_int</span>
+<span class="special">{</span>
+ <span class="identifier">digit_type</span><span class="special">*</span> <span class="identifier">digits_</span><span class="special">;</span>
+ <span class="identifier">size_type</span> <span class="identifier">used_</span><span class="special">,</span> <span class="identifier">capacity_</span><span class="special">;</span>
+ <span class="keyword">int</span> <span class="identifier">sign_</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ The least significant digit of the number always lives at <code class="computeroutput"><span class="identifier">digits_</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code>
+ while the most significant lives at <code class="computeroutput"><span class="identifier">digits_</span><span class="special">[</span><span class="identifier">used_</span> <span class="special">-</span> <span class="number">1</span><span class="special">]</span></code>.
+ </p>
+<p>
+ Libtommath on which this code is ultimately based chose a <code class="computeroutput"><span class="identifier">digit_type</span></code>
+ representation which does not use all of its bits, instead some bits are
+ reserved to hold carries in intermediate results. This allows very fast multiplication
+ routines. I chose a different representation which uses all the bits in the
+ <code class="computeroutput"><span class="identifier">digit_type</span></code> but needs explicit
+ carry handling in the code. This makes normal c++ code a tad slower. However
+ it makes it much easier to write assembler routines since most CPUs provide
+ instructions that allow the handling of carries in place. This is what GMP
+ does as well. It is possible that a <code class="computeroutput"><span class="identifier">digit_type</span></code>
+ representation similar to libtommath's returns someday which can then be
+ enabled via a different <code class="computeroutput"><span class="identifier">mp_int_traits</span></code>
+ class template.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.implementation_notes.semantics"></a><a class="link" href="implementation_notes.html#mp_int_.implementation_notes.semantics" title="Semantics">Semantics</a>
+</h3></div></div></div>
+<div class="itemizedlist"><ul type="disc">
+<li>
+ An integer with a value of zero has a <code class="computeroutput"><span class="identifier">used_</span></code>
+ count of 1 and <code class="computeroutput"><span class="identifier">digits_</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code>
+ holds the value 0.
+ </li>
+<li>
+ An unitialized integer has no value and all operations on it except for
+ initializing or swapping are undefined.
+ </li>
+</ul></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="performance.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mp_int_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_reference.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_reference.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,2123 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>mp_int reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="implementation_notes.html" title="Implementation notes">
+<link rel="next" href="mp_int_traits_reference.html" title="mp_int_traits reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="implementation_notes.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mp_int_traits_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.mp_int_reference"></a><a class="link" href="mp_int_reference.html" title="mp_int reference">mp_int reference</a>
+</h2></div></div></div>
+<a name="mp_int_.mp_int_reference.synopsis"></a><h4>
+<a name="id2745751"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.synopsis">Synopsis</a>
+ </h4>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
+<span class="keyword">namespace</span> <span class="identifier">mp_math</span> <span class="special">{</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span>
+ <span class="keyword">class</span> <span class="identifier">Allocator</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;,</span>
+ <span class="keyword">class</span> <span class="identifier">Traits</span> <span class="special">=</span> <span class="identifier">mp_int_traits</span><span class="special">&lt;&gt;</span>
+<span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">mp_int</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">Allocator</span> <span class="identifier">allocator_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">Traits</span> <span class="identifier">traits_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">size_type</span><span class="special">;</span>
+
+ <span class="comment">// ctor/cctor/dtor/assign
+</span> <span class="identifier">mp_int</span><span class="special">();</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special">&lt;</span><span class="identifier">is_integral</span><span class="special">&lt;</span><span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span><span class="special">*</span> <span class="identifier">dummy</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
+
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">);</span>
+
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">copy</span><span class="special">);</span>
+
+ <span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAS_RVALUE_REFS</span>
+ <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">copy</span><span class="special">);</span>
+ <span class="preprocessor">#endif</span>
+
+ <span class="special">~</span><span class="identifier">mp_int</span><span class="special">();</span>
+
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">);</span>
+
+ <span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAS_RVALUE_REFS</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span><span class="special">);</span>
+ <span class="preprocessor">#endif</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">rhs</span><span class="special">);</span>
+
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+ <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+
+ <span class="comment">// modifiers
+</span> <span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAS_RVALUE_REFS</span>
+ <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
+ <span class="preprocessor">#else</span>
+ <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
+ <span class="preprocessor">#endif</span>
+
+ <span class="comment">// increment/decrement
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">++();</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">--();</span>
+ <span class="identifier">mp_int</span> <span class="keyword">operator</span> <span class="special">++(</span><span class="keyword">int</span><span class="special">);</span>
+ <span class="identifier">mp_int</span> <span class="keyword">operator</span> <span class="special">--(</span><span class="keyword">int</span><span class="special">);</span>
+
+ <span class="comment">// shifting
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&lt;&lt;=</span> <span class="special">(</span><span class="identifier">size_type</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&gt;&gt;=</span> <span class="special">(</span><span class="identifier">size_type</span><span class="special">);</span>
+
+ <span class="comment">// unary negate
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">();</span>
+
+ <span class="comment">// arithmetic operators
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+ <span class="comment">// bitwise operators
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+ <span class="comment">// operators involving integral types
+</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+
+ <span class="comment">// operators involving char strings
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="comment">// operators involving wchar_t strings
+</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="comment">// operators involving std::basic_string
+</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+ <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+
+ <span class="comment">// observers
+</span> <span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">bool</span> <span class="identifier">is_even</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+ <span class="keyword">bool</span> <span class="identifier">is_odd</span> <span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">bool</span> <span class="identifier">is_positive</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+ <span class="keyword">bool</span> <span class="identifier">is_negative</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="identifier">size_type</span> <span class="identifier">precision</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">operator</span> <span class="identifier">unspecified_bool_type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">to_string</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">dec</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+ <span class="identifier">IntegralT</span> <span class="identifier">to_integral</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="comment">// low level access
+</span> <span class="keyword">typedef</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">digit_type</span> <span class="identifier">digit_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">word_type</span> <span class="identifier">word_type</span><span class="special">;</span>
+
+ <span class="keyword">bool</span> <span class="identifier">is_zero</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="identifier">digit_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">);</span>
+ <span class="keyword">const</span> <span class="identifier">digit_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="identifier">digit_type</span><span class="special">&amp;</span> <span class="identifier">at</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">);</span>
+ <span class="keyword">const</span> <span class="identifier">digit_type</span><span class="special">&amp;</span> <span class="identifier">at</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+<span class="special">};</span>
+
+
+<span class="comment">// non-member functions
+</span>
+<span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_HAS_RVALUE_REFS</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;&amp;,</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;&amp;);</span>
+<span class="preprocessor">#else</span>
+<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+<span class="preprocessor">#endif</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">size_type</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&gt;&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">size_type</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">|</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&amp;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">^</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">|</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&amp;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">^</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+
+<span class="comment">// Comparison operators
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="comment">// Comparison between mp_int and std::basic_string
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="comment">// Comparison between std::basic_string and mp_int
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="comment">// Comparison between mp_int and const char*
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="comment">// Comparison between const char* and mp_int
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="comment">// Comparison between mp_int and const wchar_t*
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="comment">// Comparison between const wchar_t* and mp_int
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="comment">// Comparison between mp_int and integral type
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="comment">// Comparison between integral type and mp_int
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+
+<span class="comment">// Stream I/O
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">&gt;</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span>
+<span class="keyword">operator</span> <span class="special">&gt;&gt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">is</span><span class="special">,</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">&gt;</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span>
+<span class="keyword">operator</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+
+<span class="comment">// Special functions
+</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">abs</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">gcd</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">lcm</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">int</span> <span class="identifier">jacobi</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">pow</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digit_type</span> <span class="identifier">n</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">modpow</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">base</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">exp</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span
><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">mod</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">nth_root</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digit_type</span> <span class="identifier">n</span><span class="special">);</span>
+
+
+<span class="special">}</span> <span class="comment">// namespace mp_math
+</span><span class="special">}</span> <span class="comment">// namespace boost
+</span></pre>
+<a name="mp_int_.mp_int_reference.construction_from___assignment_to_a_string_object"></a><h4>
+<a name="id2762818"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.construction_from___assignment_to_a_string_object">Construction
+ from / assignment to a string object</a>
+ </h4>
+<p>
+ In a constructor or assignment operation without the possibility to specify
+ the base of the string argument the base of the number is deduced from the
+ string. If the string starts with <code class="computeroutput"><span class="number">0</span><span class="identifier">x</span></code> or <code class="computeroutput"><span class="number">0</span><span class="identifier">X</span></code> then the number will be treated as hexadecimal
+ value. If the string starts with <code class="computeroutput"><span class="number">0</span></code>
+ then the number will be treated as octal value else it will be treated as decimal
+ value. An optional <code class="computeroutput"><span class="special">-</span></code> sign is allowed
+ as the first character in the string to indicate a negative value.
+ </p>
+<p>
+ In a constructor or assignment operation with the ability to specify the format
+ of the string argument via a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span></code>
+ parameter, possible formatting flags are:
+ </p>
+<div class="itemizedlist"><ul type="disc">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">showbase</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">dec</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">hex</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">oct</span></code></li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.construct_copy_destroy_assign"></a><h4>
+<a name="id2763067"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.construct_copy_destroy_assign">Construct/Copy/Destroy/Assign</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an empty <code class="computeroutput"><span class="identifier">mp_int</span></code> object, such an uninitialized <code class="computeroutput"><span class="identifier">mp_int</span></code> has no value, i.e. it is <span class="emphasis"><em>not</em></span>
+ zero.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special">&lt;</span><span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span><span class="special">*</span> <span class="identifier">dummy</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from an integral type. The value of the object is that of the integral
+ type.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N) where N is the number of
+ bits of IntegralT.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ points to a valid number formatted as string or to an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ contains a valid number formatted as string or <code class="computeroutput"><span class="identifier">s</span></code>
+ is an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">first</span></code>
+ and <code class="computeroutput"><span class="identifier">last</span></code> are iterators into
+ a string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from two iterators.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ points to a valid number formatted according to the flags in <code class="computeroutput"><span class="identifier">f</span></code> or <code class="computeroutput"><span class="identifier">s</span></code>
+ is an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ contains a valid number formatted according to the flags in <code class="computeroutput"><span class="identifier">f</span></code> or <code class="computeroutput"><span class="identifier">s</span></code>
+ is an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">first</span></code>
+ and <code class="computeroutput"><span class="identifier">last</span></code> are iterators into
+ a string formatted according to the formatting flags in <code class="computeroutput"><span class="identifier">f</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from two iterators.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">copy</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs a copy of a given <code class="computeroutput"><span class="identifier">mp_int</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N), where N is the number
+ of digits in <code class="computeroutput"><span class="identifier">copy</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">copy</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ by moving <code class="computeroutput"><span class="identifier">copy</span></code> into <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="special">~</span><span class="identifier">mp_int</span><span class="special">();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Destroys <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Copies the value of <code class="computeroutput"><span class="identifier">rhs</span></code> into <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> obtains the value of <code class="computeroutput"><span class="identifier">rhs</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">rhs</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> obtains the value of <code class="computeroutput"><span class="identifier">rhs</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ points to a valid number formatted as string or to an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">=</span> <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ points to a valid number formatted as string or to an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">=</span> <span class="identifier">mp_int</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+<span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ points to a valid number formatted according to the flags in <code class="computeroutput"><span class="identifier">f</span></code> or <code class="computeroutput"><span class="identifier">s</span></code>
+ is an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">s</span></code>
+ contains a valid number formatted according to the flags in <code class="computeroutput"><span class="identifier">f</span></code> or <code class="computeroutput"><span class="identifier">s</span></code>
+ is an empty string.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from a string.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">RandomAccessIterator</span><span class="special">&gt;</span>
+<span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomAccessIterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">first</span></code>
+ and <code class="computeroutput"><span class="identifier">last</span></code> are iterators into
+ a string formatted according to the formatting flags in <code class="computeroutput"><span class="identifier">f</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs an <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ object from two iterators.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character or if an unrecognized formatting flag was set.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> basic.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.modifiers"></a><h4>
+<a name="id2766915"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.modifiers">Modifiers</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Swaps the value of <code class="computeroutput"><span class="identifier">other</span></code> and <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> nothrow.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Swaps the value of <code class="computeroutput"><span class="identifier">other</span></code> and <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> nothrow.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.increment_decrement"></a><h4>
+<a name="id2767133"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.increment_decrement">Increment/decrement</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">++();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span><pre class="programlisting"><span class="special">*</span><span class="keyword">this</span> <span class="special">+=</span> <span class="number">1</span><span class="special">;</span>
+<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
+</pre>
+</li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> best case is O(1), worst case
+ is O(N) - this happens when the addition causes a carry bit to ripple through
+ all digits subsequently.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">--();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span><pre class="programlisting"><span class="special">*</span><span class="keyword">this</span> <span class="special">-=</span> <span class="number">1</span><span class="special">;</span>
+<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
+</pre>
+</li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> best case is O(1), worst case
+ is O(N) - this happens when the subtraction causes a borrow bit to ripple
+ through all digits subsequently.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span> <span class="keyword">operator</span> <span class="special">++(</span><span class="keyword">int</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span><pre class="programlisting"><span class="identifier">mp_int</span> <span class="identifier">tmp</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
+<span class="special">*</span><span class="keyword">this</span> <span class="special">+=</span> <span class="number">1</span><span class="special">;</span>
+<span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
+</pre>
+</li>
+<li>
+<span class="bold"><strong>Returns:</strong></span> The value of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> before incrementation.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span> <span class="keyword">operator</span> <span class="special">--(</span><span class="keyword">int</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span><pre class="programlisting"><span class="identifier">mp_int</span> <span class="identifier">tmp</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
+<span class="special">*</span><span class="keyword">this</span> <span class="special">-=</span> <span class="number">1</span><span class="special">;</span>
+<span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
+</pre>
+</li>
+<li>
+<span class="bold"><strong>Returns:</strong></span> The value of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> before decrementation.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.shifting"></a><h4>
+<a name="id2767861"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.shifting">Shifting</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&lt;&lt;=</span> <span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Shift <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>
+ bits to the left.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&gt;&gt;=</span> <span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Shift <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>
+ bits to the right.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.unary_negate"></a><h4>
+<a name="id2768196"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.unary_negate">Unary negate</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Negates <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> nothrow.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.arithmetic_operators"></a><h4>
+<a name="id2768321"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.arithmetic_operators">Arithmetic operators</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Adds <code class="computeroutput"><span class="identifier">x</span></code>
+ to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Subtracts <code class="computeroutput"><span class="identifier">x</span></code>
+ from <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Multiplies <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> If <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">x</span> <span class="special">==</span> <span class="keyword">this</span></code>
+ then a squaring algorithm will be used. Different multiplication algorithms
+ are chosen for numbers of different size. The thresholds can be tuned via
+ the <code class="computeroutput"><span class="identifier">mp_int_traits</span></code> class template
+ parameter.
+ <div class="itemizedlist"><ul type="circle">
+<li>
+ Small numbers: Comba algorithm O(N^2).
+ </li>
+<li>
+ Midsize numbers: Karatsuba algorithm O(N^log2(3)) ~ O(N^1.585).
+ </li>
+<li>
+ Large numbers: Toom-Cook algorithm O(N^(log(5)/log(3))) ~ O(N^1.465).
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">x</span>
+ <span class="special">!=</span> <span class="number">0</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Divides <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> if <code class="computeroutput"><span class="identifier">x</span>
+ <span class="special">==</span> <span class="number">0</span></code>.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">x</span>
+ <span class="special">!=</span> <span class="number">0</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Modulus <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> if <code class="computeroutput"><span class="identifier">x</span>
+ <span class="special">==</span> <span class="number">0</span></code>.
+ </li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.bitwise_operators"></a><h4>
+<a name="id2769381"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.bitwise_operators">Bitwise operators</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> OR <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> AND <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> XOR <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.operators_involving_integral_types"></a><h4>
+<a name="id2769904"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.operators_involving_integral_types">Operators
+ involving integral types</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Adds <code class="computeroutput"><span class="identifier">x</span></code>
+ to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Subtracts <code class="computeroutput"><span class="identifier">x</span></code>
+ to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Multiplies <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Divides <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> modulo <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Applies the bitwise or operation
+ on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
+ and the absolute of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Applies the bitwise and operation
+ on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
+ and the absolute of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span> <span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">IntegralT</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Applies the bitwise xor operation
+ on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
+ and the absolute of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.operators_involving_char_wchar_t_strings"></a><h4>
+<a name="id2771318"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.operators_involving_char_wchar_t_strings">Operators
+ involving char/wchar_t strings</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<a name="mp_int_.mp_int_reference.operators_involving_std__basic_string"></a><h4>
+<a name="id2772175"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.operators_involving_std__basic_string">Operators
+ involving std::basic_string</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">-=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">/=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">%=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">|=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">&amp;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">^=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;</span> <span class="identifier">s</span><span class="special">);</span>
+</pre>
+<a name="mp_int_.mp_int_reference.observers"></a><h4>
+<a name="id2773367"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.observers">Observers</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns: </strong></span> A copy of the allocator.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing if allocator copy constructor
+ is nothrow.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">is_even</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">is_odd</span> <span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">is_positive</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">is_negative</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">size_type</span> <span class="identifier">precision</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The number of bits used by the
+ absolute value of *this.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(N).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">operator</span> <span class="identifier">unspecified_bool_type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="number">0</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">to_string</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">dec</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
+ formatting of the string is done according to the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">fmtflags</span></code>
+ parameter. Possible formatting flags are:
+ <div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">showpos</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">showbase</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">dec</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">hex</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">oct</span></code></li>
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">uppercase</span></code></li>
+</ul></div>
+</li>
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> converted to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
+ object.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">IntegralT</span> <span class="identifier">to_integral</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> converted to an object of type <code class="computeroutput"><span class="identifier">IntegralT</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">overflow_error</span></code>
+ if <code class="computeroutput"><span class="identifier">IntegralT</span></code> does not have
+ enough precision to hold the result.
+ </li>
+<li>
+<span class="bold"><strong>Exception safety:</strong></span> strong.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.non_member_functions"></a><h4>
+<a name="id2774432"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.non_member_functions">Non-member functions</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;&amp;,</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">size_type</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&gt;&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">size_type</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">|</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&amp;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">^</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">+</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">-</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">*</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">/</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">%</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">|</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">&amp;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">operator</span> <span class="special">^</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+</pre>
+<p>
+ These functions are implemented in terms of their respective member functions.
+ </p>
+<a name="mp_int_.mp_int_reference.comparison_operators"></a><h4>
+<a name="id2777278"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.comparison_operators">Comparison operators</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> These operators compare the numeric
+ value of their arguments and return a truth value based on that evaluation.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span> Nothing.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the left side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Traits</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">,</span><span class="identifier">Alloc</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the right side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the left side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the right side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the left side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the string argument to
+ an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the right side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">invalid_argument</span></code> if the string contains
+ an invalid character.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span> <span class="identifier">IntegralT</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the integral argument
+ to an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the left side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">IntegralT</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span><span class="identifier">IntegralT</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Effects:</strong></span> Converts the integral argument
+ to an <code class="computeroutput"><span class="identifier">mp_int</span></code> object and compares
+ it to the object on the right side of the expression.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<a name="mp_int_.mp_int_reference.stream_i_o"></a><h4>
+<a name="id2785287"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.stream_i_o">Stream I/O</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">&gt;</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span>
+<span class="keyword">operator</span> <span class="special">&gt;&gt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">is</span><span class="special">,</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span><span class="special">&gt;</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span>
+<span class="keyword">operator</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">&gt;&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<a name="mp_int_.mp_int_reference.special_functions"></a><h4>
+<a name="id2785746"></a>
+ <a class="link" href="mp_int_reference.html#mp_int_.mp_int_reference.special_functions">Special functions</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">abs</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The positive value of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(1).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">gcd</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The greatest common divisor of
+ <code class="computeroutput"><span class="identifier">a</span></code> and <code class="computeroutput"><span class="identifier">b</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O((log2(AB))^2).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">lcm</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The least common multiple of <code class="computeroutput"><span class="identifier">a</span></code> and <code class="computeroutput"><span class="identifier">b</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O((log2(AB))^2).
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">int</span> <span class="identifier">jacobi</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The Jacobi symbol of integer <code class="computeroutput"><span class="identifier">a</span></code> and positive odd integer <code class="computeroutput"><span class="identifier">p</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> if <code class="computeroutput"><span class="identifier">p</span></code>
+ is negative.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">pow</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digit_type</span> <span class="identifier">n</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The <code class="computeroutput"><span class="identifier">n</span></code>th
+ power of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">modpow</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">base</span><span class="special">,</span>
+ <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">exp</span><span class="special">,</span>
+ <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">mod</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns: </strong></span><code class="computeroutput"><span class="special">(</span><span class="identifier">base</span> <span class="special">^</span> <span class="identifier">exp</span><span class="special">)</span> <span class="special">%</span>
+ <span class="identifier">mod</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws: </strong></span><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The square root of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> if <code class="computeroutput"><span class="identifier">x</span></code>
+ is negative.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">nth_root</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">digit_type</span> <span class="identifier">n</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Returns:</strong></span> The <code class="computeroutput"><span class="identifier">n</span></code>th
+ root of <code class="computeroutput"><span class="identifier">x</span></code>.
+ </li>
+<li>
+<span class="bold"><strong>Complexity:</strong></span> O(log(N)).
+ </li>
+<li>
+<span class="bold"><strong>Throws:</strong></span><div class="itemizedlist"><ul type="circle">
+<li><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code></li>
+<li>
+<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code> if <code class="computeroutput"><span class="identifier">x</span></code>
+ is negative and <code class="computeroutput"><span class="identifier">n</span></code> is
+ odd.
+ </li>
+</ul></div>
+</li>
+</ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="implementation_notes.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="mp_int_traits_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_traits_reference.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/mp_int_traits_reference.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>mp_int_traits reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="mp_int_reference.html" title="mp_int reference">
+<link rel="next" href="uniform_mp_int_reference.html" title="uniform_mp_int reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="mp_int_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="uniform_mp_int_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.mp_int_traits_reference"></a><a class="link" href="mp_int_traits_reference.html" title="mp_int_traits reference">mp_int_traits reference</a>
+</h2></div></div></div>
+<p>
+ The second template parameter to mp_int is a type which allows to customize
+ some of mp_int's internal workings.
+ </p>
+<a name="mp_int_.mp_int_traits_reference.synopsis"></a><h4>
+<a name="id2787773"></a>
+ <a class="link" href="mp_int_traits_reference.html#mp_int_.mp_int_traits_reference.synopsis">Synopsis</a>
+ </h4>
+<p>
+
+</p>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int/traits.hpp&gt;
+</span><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
+<span class="keyword">namespace</span> <span class="identifier">mp_math</span> <span class="special">{</span>
+
+<span class="keyword">template</span><span class="special">&lt;</span>
+ <span class="keyword">typename</span> <span class="identifier">Digit</span> <span class="special">=</span> <span class="identifier">implementation</span> <span class="identifier">defined</span><span class="special">,</span>
+ <span class="keyword">typename</span> <span class="identifier">Word</span> <span class="special">=</span> <span class="identifier">implementation</span> <span class="identifier">defined</span>
+<span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">mp_int_traits</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">Digit</span> <span class="identifier">digit_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">Word</span> <span class="identifier">word_type</span><span class="special">;</span>
+
+ <span class="keyword">static</span> <span class="identifier">size_type</span> <span class="identifier">toom_mul_cutoff</span><span class="special">;</span> <span class="comment">// default: 350
+</span> <span class="keyword">static</span> <span class="identifier">size_type</span> <span class="identifier">toom_sqr_cutoff</span><span class="special">;</span> <span class="comment">// default: 400
+</span> <span class="keyword">static</span> <span class="identifier">size_type</span> <span class="identifier">karatsuba_mul_cutoff</span><span class="special">;</span> <span class="comment">// default: 80
+</span> <span class="keyword">static</span> <span class="identifier">size_type</span> <span class="identifier">karatsuba_sqr_cutoff</span><span class="special">;</span> <span class="comment">// default: 120
+</span><span class="special">};</span>
+
+<span class="special">}</span> <span class="comment">// namespace mp_math
+</span><span class="special">}</span> <span class="comment">// namespace boost
+</span></pre>
+<p>
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="mp_int_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="uniform_mp_int_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/performance.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/performance.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,228 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Performance</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="tutorial.html" title="Tutorial">
+<link rel="next" href="implementation_notes.html" title="Implementation notes">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tutorial.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="implementation_notes.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.performance"></a><a class="link" href="performance.html" title="Performance">Performance</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">Tips</span></dt>
+<dt><span class="section">Measurements</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.performance.tips"></a><a class="link" href="performance.html#mp_int_.performance.tips" title="Tips">Tips</a>
+</h3></div></div></div>
+<div class="itemizedlist"><ul type="disc">
+<li>
+ A statement like
+<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span><span class="special">;</span></pre>
+ involves the creation of a temporary <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ inside <code class="computeroutput"><span class="keyword">operator</span> <span class="special">+</span></code>
+ because it is not able to write the result directly into <code class="computeroutput"><span class="identifier">x</span></code> which may already have enough memory
+ allocated to hold the result. Instead rewrite it into
+<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">;</span>
+<span class="identifier">x</span> <span class="special">+=</span> <span class="identifier">b</span><span class="special">;</span>
+</pre>
+ This trick proves to be useful only for simple operations like addition
+ and subtraction.
+ </li>
+<li>
+ In operations involving built in integral types, try to use unsigned types,
+ preferrably unsigned types that are as large or smaller than mp_int&lt;&gt;::digit_type.
+ </li>
+<li>
+ Use hexadecimal digits for input and output. Conversion from/to power of
+ two bases uses a O(n) algorithm which is not possible for base 10.
+ </li>
+</ul></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.performance.measurements"></a><a class="link" href="performance.html#mp_int_.performance.measurements" title="Measurements">Measurements</a>
+</h3></div></div></div>
+<div class="toc"><dl><dt><span class="section"><a href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_">AMD
+ Athlon XP 2000+</a></span></dt></dl></div>
+<p>
+ A benchmark program is supplied with Boost.Mp_math under libs/mp_math/tools/benchmark.
+ This benchmark compares some primitive operations of different multi precision
+ integer libraries. It creates detailed result files and uses gnuplot
+ to create graphs.
+ </p>
+<p>
+ Example invocations:
+ </p>
+<pre class="programlisting">benchmark // runs all benches
+benchmark --help
+benchmark --ops="add subtract multiply" --libs="boost.mp_math libtommath"
+</pre>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_"></a><a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_" title="AMD Athlon XP 2000+">AMD
+ Athlon XP 2000+</a>
+</h4></div></div></div>
+<pre class="programlisting">Operating System: Arch Linux (i686), Kernel 2.6.26, glibc 2.8
+Compiler: gcc-4.3.2
+</pre>
+<p>
+ Libraries being compared:
+ </p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+ Boost.Mp_math-1_36
+ <div class="itemizedlist"><ul type="circle"><li>
+ switches used: -ftemplate-depth-128 -O3 -finline-functions -march=i686
+ -mtune=generic -std=c++0x
+ </li></ul></div>
+</li>
+<li>
+ libtommath-0.41
+ <div class="itemizedlist"><ul type="circle"><li>
+ switches used: -ftemplate-depth-128 -O3 -finline-functions -march=i686
+ -mtune=generic
+ </li></ul></div>
+</li>
+<li>
+ gmp-4.2.2 (precompiled distribution package, uses generic i386 asm and
+ Intel P6 (Pentium Pro) asm where available)
+ <div class="itemizedlist"><ul type="circle"><li>
+ switches used: -march=i686 -mtune=generic -O2
+ </li></ul></div>
+</li>
+</ul></div>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.input_vectors"></a><h4>
+<a name="id2744932"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.input_vectors">Input
+ vectors</a>
+ </h4>
+<p>
+ Operand size is measured in number of bits. I chose to vary the operand
+ size for the benchmarks a little to see how well the operation handles
+ inputs of differing sizes. Benchmarks that use only one operand use operand
+ 1. <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/input_vecs.png" alt="input_vecs"></span>
+ </p>
+<p>
+ While input operand 1 grows linearly, input operand 2's size is determined
+ by a modified sine function.
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.construct_from_decimal_string"></a><h4>
+<a name="id2744980"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.construct_from_decimal_string">Construct
+ from decimal string</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/ctor_dec.png" alt="ctor_dec"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.construct_from_hex_string"></a><h4>
+<a name="id2745020"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.construct_from_hex_string">Construct
+ from hex string</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/ctor_hex.png" alt="ctor_hex"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.conversion_to_decimal_string"></a><h4>
+<a name="id2745059"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.conversion_to_decimal_string">Conversion
+ to decimal string</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/to_dec.png" alt="to_dec"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.conversion_to_hex_string"></a><h4>
+<a name="id2745099"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.conversion_to_hex_string">Conversion
+ to hex string</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/to_hex.png" alt="to_hex"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.add"></a><h4>
+<a name="id2745137"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.add">Add</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/add.png" alt="add"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.subtract"></a><h4>
+<a name="id2745173"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.subtract">Subtract</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/subtract.png" alt="subtract"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.multiply"></a><h4>
+<a name="id2745210"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.multiply">Multiply</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/multiply.png" alt="multiply"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.divide"></a><h4>
+<a name="id2745246"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.divide">Divide</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/divide.png" alt="divide"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.modulo"></a><h4>
+<a name="id2745283"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.modulo">Modulo</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/modulo.png" alt="modulo"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.square"></a><h4>
+<a name="id2745319"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.square">Square</a>
+ </h4>
+<p>
+ <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/square.png" alt="square"></span>
+ </p>
+<a name="mp_int_.performance.measurements.amd_athlon_xp_2000_.modular_power"></a><h4>
+<a name="id2745356"></a>
+ <a class="link" href="performance.html#mp_int_.performance.measurements.amd_athlon_xp_2000_.modular_power">Modular
+ Power</a>
+ </h4>
+<p>
+ The operation looks like this: <code class="computeroutput"><span class="identifier">dest</span>
+ <span class="special">=</span> <span class="special">(</span><span class="identifier">op1</span> <span class="special">^</span> <span class="identifier">op1</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">op2</span></code>.
+ This graph uses a logarithmic scale. <span class="inlinemediaobject"><img src="../benchmark_imgs/k7/modpow.png" alt="modpow"></span>
+ </p>
+</div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tutorial.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="implementation_notes.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/primality_tests_reference.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/primality_tests_reference.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,209 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Primality Tests reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="uniform_mp_int_bits_reference.html" title="uniform_mp_int_bits reference">
+<link rel="next" href="bibliography.html" title="Bibliography">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="uniform_mp_int_bits_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="bibliography.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.primality_tests_reference"></a><a class="link" href="primality_tests_reference.html" title="Primality Tests reference">Primality Tests reference</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">primality_division_test</span></dt>
+<dt><span class="section">primality_fermat_test</span></dt>
+<dt><span class="section">primality_miller_rabin_test</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.primality_tests_reference.primality_division_test"></a><a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_division_test" title="primality_division_test">primality_division_test</a>
+</h3></div></div></div>
+<p>
+ This function object tests a candidate <code class="computeroutput"><span class="identifier">p</span></code>
+ by repeatedly dividing it by small primes (2, 3, 5, 7, 11...). This is a
+ test that should be used before other more complex tests because it quickly
+ sieves out composite numbers. For example, testing for 2, 5, 7 will eliminate
+ 54% of all numbers, testing for all primes less than 100 eliminates 70%,
+ for all primes less than 256 it is 80%.
+ </p>
+<a name="mp_int_.primality_tests_reference.primality_division_test.synopsis"></a><h5>
+<a name="id2789739"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_division_test.synopsis">Synopsis</a>
+ </h5>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">struct</span> <span class="identifier">primality_division_test</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="keyword">bool</span> <span class="identifier">result_type</span><span class="special">;</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+ <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<a name="mp_int_.primality_tests_reference.primality_division_test.members"></a><h4>
+<a name="id2789926"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_division_test.members">Members</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Returns true if <code class="computeroutput"><span class="identifier">p</span></code> is probably prime. Returns false if
+ <code class="computeroutput"><span class="identifier">p</span></code> is definitely composite.
+ </li></ul></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.primality_tests_reference.primality_fermat_test"></a><a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_fermat_test" title="primality_fermat_test">primality_fermat_test</a>
+</h3></div></div></div>
+<p>
+ This test is based on Fermat's little theorem which states that if an integer
+ <code class="computeroutput"><span class="identifier">p</span></code> is prime, then for all
+ integers <code class="computeroutput"><span class="identifier">a</span></code> where 0 &lt;
+ <code class="computeroutput"><span class="identifier">a</span></code> &lt; <code class="computeroutput"><span class="identifier">p</span></code>
+ </p>
+<p>
+ <code class="computeroutput"><span class="identifier">a</span><span class="special">**(</span><span class="identifier">p</span><span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">1</span>
+ <span class="special">(</span><span class="identifier">mod</span>
+ <span class="identifier">p</span><span class="special">)</span></code>
+ </p>
+<p>
+ an alternative formulation is
+ </p>
+<p>
+ <code class="computeroutput"><span class="identifier">a</span><span class="special">**</span><span class="identifier">p</span> <span class="special">=</span> <span class="identifier">a</span>
+ <span class="special">(</span><span class="identifier">mod</span>
+ <span class="identifier">p</span><span class="special">)</span></code>
+ </p>
+<p>
+ For each round the test creates a random base <code class="computeroutput"><span class="identifier">a</span></code>
+ and checks if the condition holds. There is a class of pseudoprimes called
+ carmichael numbers which are less likely though not impossible with enough
+ rounds to be detected by this test.
+ </p>
+<a name="mp_int_.primality_tests_reference.primality_fermat_test.synopsis"></a><h5>
+<a name="id2790306"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_fermat_test.synopsis">Synopsis</a>
+ </h5>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Distribution</span> <span class="special">=</span> <span class="identifier">uniform_mp_int</span><span class="special">&lt;&gt;</span> <span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">primality_fermat_test</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">Distribution</span> <span class="identifier">distribution_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="keyword">bool</span> <span class="identifier">result_type</span><span class="special">;</span>
+
+ <span class="keyword">explicit</span> <span class="identifier">primality_fermat_test</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">rounds</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+ <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<a name="mp_int_.primality_tests_reference.primality_fermat_test.members"></a><h4>
+<a name="id2790631"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_fermat_test.members">Members</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">primality_fermat_test</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">r</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Constructs a <code class="computeroutput"><span class="identifier">primality_fermat_test</span></code>
+ object with the number of test rounds given by <code class="computeroutput"><span class="identifier">r</span></code>.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Returns true if <code class="computeroutput"><span class="identifier">p</span></code> is probably prime. Returns false if
+ <code class="computeroutput"><span class="identifier">p</span></code> is definitely composite.
+ </li></ul></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.primality_tests_reference.primality_miller_rabin_test"></a><a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_miller_rabin_test" title="primality_miller_rabin_test">primality_miller_rabin_test</a>
+</h3></div></div></div>
+<p>
+ This test is an improved version of the Fermat primality test that will also
+ detect carmichael numbers.
+ </p>
+<a name="mp_int_.primality_tests_reference.primality_miller_rabin_test.synopsis"></a><h5>
+<a name="id2790943"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_miller_rabin_test.synopsis">Synopsis</a>
+ </h5>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Distribution</span> <span class="special">=</span> <span class="identifier">uniform_mp_int</span><span class="special">&lt;&gt;</span> <span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">primality_miller_rabin_test</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">Distribution</span> <span class="identifier">distribution_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="keyword">bool</span> <span class="identifier">result_type</span><span class="special">;</span>
+
+ <span class="keyword">explicit</span> <span class="identifier">primality_miller_rabin_test</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">r</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+ <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">static</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">recommended_number_of_rounds</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">bits</span><span class="special">);</span>
+<span class="special">};</span>
+</pre>
+<a name="mp_int_.primality_tests_reference.primality_miller_rabin_test.members"></a><h4>
+<a name="id2791319"></a>
+ <a class="link" href="primality_tests_reference.html#mp_int_.primality_tests_reference.primality_miller_rabin_test.members">Members</a>
+ </h4>
+<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">primality_miller_rabin_test</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">r</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Constructs a <code class="computeroutput"><span class="identifier">primality_miller_rabin_test</span></code>
+ object with the number of test rounds given by <code class="computeroutput"><span class="identifier">r</span></code>.
+ If <code class="computeroutput"><span class="identifier">r</span> <span class="special">==</span>
+ <span class="number">0</span></code> then each invocation of this function
+ object will use the recommended number of rounds.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires:</strong></span><code class="computeroutput"><span class="identifier">p</span></code>
+ is odd.
+ </li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Returns true if <code class="computeroutput"><span class="identifier">p</span></code> is probably prime. Returns false if
+ <code class="computeroutput"><span class="identifier">p</span></code> is definitely composite.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">recommended_number_of_rounds</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">bits</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Returns the recommended number
+ of rounds for a number of precision <code class="computeroutput"><span class="identifier">bits</span></code>
+ so that the probability of error is less than 2^-96.
+ </li></ul></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="uniform_mp_int_bits_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="bibliography.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/tutorial.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/tutorial.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,262 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Tutorial</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="../index.html" title="Chapter 1. mp_int">
+<link rel="next" href="performance.html" title="Performance">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="performance.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
+</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">General use</span></dt>
+<dt><span class="section"><a href="tutorial.html#mp_int_.tutorial.random_number_generation">Random number
+ generation</a></span></dt>
+<dt><span class="section">Primality testing</span></dt>
+<dt><span class="section"><a href="tutorial.html#mp_int_.tutorial.prime_number_generation">Prime number
+ generation</a></span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.tutorial.general_use"></a><a class="link" href="tutorial.html#mp_int_.tutorial.general_use" title="General use">General use</a>
+</h3></div></div></div>
+<p>
+ The only header you need to include to use the library is <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp_math</span><span class="special">/</span><span class="identifier">mp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>.
+ This is a header-only library so deployment is easy. All functions and objects
+ of this library live in namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mp_math</span></code>.
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp_math</span><span class="special">/</span><span class="identifier">mp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+
+<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mp_math</span><span class="special">;</span>
+<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">std</span><span class="special">;</span>
+
+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="comment">// init from string
+</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="string">"93423894782394782347823947289374"</span><span class="special">);</span>
+ <span class="comment">// init from integral type
+</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2340</span><span class="special">;</span>
+ <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">z</span> <span class="special">=</span> <span class="identifier">x</span> <span class="special">*</span> <span class="identifier">y</span><span class="special">;</span>
+
+ <span class="comment">// stream output reacts to stream flags
+</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">z</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="comment">// automatic detection of radix using the base prefix 0x
+</span> <span class="identifier">z</span> <span class="special">=</span> <span class="string">"0xaaaabbbbccccddddeeeeffff222255557777"</span><span class="special">;</span>
+
+ <span class="identifier">z</span> <span class="special">/=</span> <span class="identifier">y</span><span class="special">;</span>
+
+ <span class="comment">// explicit conversion to string according to formatting flags
+</span> <span class="identifier">string</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">.</span><span class="identifier">to_string</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="identifier">ios</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">|</span> <span class="identifier">ios</span><span class="special">::</span><span class="identifier">showbase</span><span class="special">);</span>
+ <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
+
+ <span class="identifier">z</span> <span class="special">-=</span> <span class="identifier">z</span><span class="special">;</span>
+
+ <span class="comment">// explicit conversion to built in integral types - this will throw
+</span> <span class="comment">// std::overflow_error if int does not have enough precision to hold the
+</span> <span class="comment">// result
+</span> <span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">.</span><span class="identifier">to_integral</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;();</span>
+
+ <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ In most cases the <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ type will behave like a built in integral type.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.tutorial.random_number_generation"></a><a class="link" href="tutorial.html#mp_int_.tutorial.random_number_generation" title="Random number generation">Random number
+ generation</a>
+</h3></div></div></div>
+<p>
+ The random number generators have interfaces similar to Boost.Random. Including
+ <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">random</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
+ is not necessary because it is used internally by the <code class="computeroutput"><span class="identifier">mp_int</span></code>
+ random machinery. The random number engine <code class="computeroutput"><span class="identifier">mt19937</span></code>
+ that we use from here on lives in namespace <code class="computeroutput"><span class="identifier">boost</span></code>.
+ </p>
+<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">min</span><span class="special">(</span><span class="number">0U</span><span class="special">);</span>
+<span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">max</span><span class="special">(</span><span class="string">"0x8974651231456456564"</span><span class="special">);</span>
+
+<span class="identifier">uniform_mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">generator</span><span class="special">(</span><span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">);</span>
+
+<span class="comment">// Choose a random number engine.
+</span><span class="identifier">mt19937</span> <span class="identifier">e</span><span class="special">;</span>
+
+<span class="comment">// Now generate a random number.
+</span><span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">generator</span><span class="special">(</span><span class="identifier">e</span><span class="special">);</span>
+</pre>
+<p>
+ Another probably more useful alternative is to generate random numbers of
+ a certain precision measured in bits.
+ </p>
+<pre class="programlisting"><span class="comment">// A generator for 2048 bit integers.
+</span><span class="identifier">uniform_mp_int_bits</span><span class="special">&lt;&gt;</span> <span class="identifier">generator</span><span class="special">(</span><span class="number">2048</span><span class="special">);</span>
+
+<span class="identifier">mt19937</span> <span class="identifier">e</span><span class="special">;</span>
+<span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">generator</span><span class="special">(</span><span class="identifier">e</span><span class="special">);</span>
+</pre>
+<p>
+ Note that the numbers will always be 2048 bits large, i.e. the most significant
+ bit is always set to 1.
+ </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.tutorial.primality_testing"></a><a class="link" href="tutorial.html#mp_int_.tutorial.primality_testing" title="Primality testing">Primality testing</a>
+</h3></div></div></div>
+<p>
+ Currently all primality tests in this library are probabilistic. A probabilistic
+ primality test cannot ascertain that a prime candidate p is really prime.
+ It can however ascertain that it is a composite number.
+ </p>
+<p>
+ Here we will learn how to test a number <code class="computeroutput"><span class="identifier">p</span></code>
+ for primality using the fermat primality test. We use boost::bind to bind
+ the random number engine to the test functor. That is necessary because the
+ test functor's function invocation operator needs the random number engine.
+ The operator looks like this:
+ </p>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<p>
+ We need to bind the random number engine to the first parameter slot. Let's
+ do it!
+ </p>
+<pre class="programlisting"><span class="comment">// Create the fermat test functor with 4 rounds of testing.
+</span><span class="identifier">primality_fermat_test</span><span class="special">&lt;&gt;</span> <span class="identifier">test</span><span class="special">(</span><span class="number">4</span><span class="special">);</span>
+
+<span class="comment">// Create a random number engine.
+</span><span class="identifier">mt19937</span> <span class="identifier">rng</span><span class="special">;</span>
+
+<span class="comment">// Create a random 1024 bit candidate number.
+</span><span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">uniform_mp_int_bits</span><span class="special">&lt;&gt;(</span><span class="number">1024</span><span class="special">)(</span><span class="identifier">rng</span><span class="special">);</span>
+
+<span class="keyword">bool</span> <span class="identifier">is_p_prime</span> <span class="special">=</span> <span class="identifier">is_prime</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">(</span><span class="identifier">test</span><span class="special">,</span> <span class="identifier">rng</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">));</span>
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="mp_int_.tutorial.prime_number_generation"></a><a class="link" href="tutorial.html#mp_int_.tutorial.prime_number_generation" title="Prime number generation">Prime number
+ generation</a>
+</h3></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section">prime_generator</span></dt>
+<dt><span class="section">safe_prime_generator</span></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="mp_int_.tutorial.prime_number_generation.prime_generator"></a><a class="link" href="tutorial.html#mp_int_.tutorial.prime_number_generation.prime_generator" title="prime_generator">prime_generator</a>
+</h4></div></div></div>
+<p>
+ First we will look at how to generate prime numbers using a simple trial
+ division test. What this means is that the prime generator creates a random
+ number and then repeatedly divides it by small primes until it finds a
+ number that passes this test.
+ </p>
+<pre class="programlisting"><span class="comment">// Create a generator for 2048 bit primes.
+</span><span class="identifier">prime_generator</span><span class="special">&lt;</span><span class="identifier">primality_division_test</span><span class="special">&gt;</span> <span class="identifier">generator</span><span class="special">(</span><span class="number">2048</span><span class="special">);</span>
+
+<span class="comment">// Create a random number engine.
+</span><span class="identifier">mt19937</span> <span class="identifier">rng</span><span class="special">;</span>
+
+<span class="comment">// Now create a prime.
+</span><span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">prime</span> <span class="special">=</span> <span class="identifier">generator</span><span class="special">(</span><span class="identifier">rng</span><span class="special">);</span>
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="mp_int_.tutorial.prime_number_generation.safe_prime_generator"></a><a class="link" href="tutorial.html#mp_int_.tutorial.prime_number_generation.safe_prime_generator" title="safe_prime_generator">safe_prime_generator</a>
+</h4></div></div></div>
+<p>
+ A safe prime is a prime <code class="computeroutput"><span class="identifier">p</span></code>
+ for which <code class="computeroutput"><span class="special">(</span><span class="identifier">p</span><span class="special">-</span><span class="number">1</span><span class="special">)/</span><span class="number">2</span></code> is also prime. Such prime numbers are much
+ rarer and thus take longer to generate.
+ </p>
+<p>
+ Now we will look at how to use a more sophisticated primality test like
+ <code class="computeroutput"><span class="identifier">primality_miller_rabin_test</span></code>
+ for prime number generation. It is very useful to combine this test with
+ the <code class="computeroutput"><span class="identifier">primality_division_test</span></code>.
+ This will involve a bit of code, mostly because <code class="computeroutput"><span class="identifier">primality_miller_rabin_test</span></code>
+ and <code class="computeroutput"><span class="identifier">safe_prime_generator</span></code>
+ require a random number generator. The latter needs randomness to create
+ a candidate to test for primality and the miller rabin test needs randomness
+ to test the candidate effectively.
+ </p>
+<pre class="programlisting"><span class="comment">// Define a function object that checks a prime candidate p first with a trial
+</span><span class="comment">// division and then with the miller-rabin algorithm. For ease of use we give
+</span><span class="comment">// it default template arguments.
+</span><span class="comment">// It does not hold a reference to the random number engine because that could
+</span><span class="comment">// lead to lifetime problems.
+</span><span class="keyword">template</span><span class="special">&lt;</span>
+ <span class="keyword">class</span> <span class="identifier">Engine</span> <span class="special">=</span> <span class="identifier">mt19937</span><span class="special">,</span>
+ <span class="keyword">class</span> <span class="identifier">Distribution</span> <span class="special">=</span> <span class="identifier">uniform_mp_int_bits</span><span class="special">&lt;&gt;</span>
+<span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">primality_test</span>
+<span class="special">{</span>
+ <span class="identifier">primality_division_test</span> <span class="identifier">test1</span><span class="special">;</span>
+ <span class="identifier">primality_miller_rabin_test</span><span class="special">&lt;</span><span class="identifier">Distribution</span><span class="special">&gt;</span> <span class="identifier">test2</span><span class="special">;</span>
+ <span class="identifier">Engine</span> <span class="identifier">rng</span><span class="special">;</span>
+
+ <span class="keyword">explicit</span> <span class="identifier">tester</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">Engine</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">rng</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span> <span class="special">{}</span>
+
+ <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;&amp;</span> <span class="identifier">p</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">test1</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="identifier">test2</span><span class="special">(</span><span class="identifier">rng</span><span class="special">,</span> <span class="identifier">p</span><span class="special">);</span>
+ <span class="special">}</span>
+<span class="special">};</span>
+
+<span class="comment">// Create a random number engine that we will feed to the different
+</span><span class="comment">// algorithms.
+</span><span class="identifier">mt19937</span> <span class="identifier">rng</span><span class="special">;</span>
+
+<span class="comment">// Create a generator for safe primes with 128 bits precision.
+</span><span class="keyword">typedef</span> <span class="identifier">safe_prime_generator</span><span class="special">&lt;</span><span class="identifier">primality_test</span><span class="special">&lt;&gt;,</span> <span class="identifier">uniform_mp_int_bits</span><span class="special">&lt;&gt;</span> <span class="special">&gt;</span>
+ <span class="identifier">generator_type</span><span class="special">;</span>
+
+<span class="identifier">generator_type</span> <span class="identifier">generator</span><span class="special">(</span><span class="number">128</span><span class="special">,</span> <span class="identifier">primality_test</span><span class="special">&lt;&gt;(</span><span class="identifier">rng</span><span class="special">));</span>
+
+<span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="identifier">prime</span> <span class="special">=</span> <span class="identifier">generator</span><span class="special">(</span><span class="identifier">rng</span><span class="special">);</span>
+</pre>
+<p>
+ Remember, the generated numbers are <span class="emphasis"><em>probably</em></span> prime.
+ </p>
+</div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="performance.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_bits_reference.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_bits_reference.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,102 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>uniform_mp_int_bits reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="uniform_mp_int_reference.html" title="uniform_mp_int reference">
+<link rel="next" href="primality_tests_reference.html" title="Primality Tests reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="uniform_mp_int_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="primality_tests_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.uniform_mp_int_bits_reference"></a><a class="link" href="uniform_mp_int_bits_reference.html" title="uniform_mp_int_bits reference">uniform_mp_int_bits
+ reference</a>
+</h2></div></div></div>
+<a name="mp_int_.uniform_mp_int_bits_reference.synopsis"></a><h4>
+<a name="id2788984"></a>
+ <a class="link" href="uniform_mp_int_bits_reference.html#mp_int_.uniform_mp_int_bits_reference.synopsis">Synopsis</a>
+ </h4>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MpInt</span> <span class="special">=</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">uniform_mp_int_bits</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">MpInt</span> <span class="identifier">input_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">MpInt</span> <span class="identifier">result_type</span><span class="special">;</span>
+
+ <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">has_fixed_range</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
+
+ <span class="identifier">uniform_mp_int_bits</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">MpInt</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">bits</span><span class="special">);</span>
+
+ <span class="identifier">result_type</span> <span class="identifier">min</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+ <span class="identifier">result_type</span> <span class="identifier">max</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">UniformRandomNumberGenerator</span><span class="special">&gt;</span>
+ <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">UniformRandomNumberGenerator</span><span class="special">&amp;</span> <span class="identifier">urng</span><span class="special">);</span>
+<span class="special">};</span>
+</pre>
+<a name="mp_int_.uniform_mp_int_bits_reference.members"></a><h4>
+<a name="id2789332"></a>
+ <a class="link" href="uniform_mp_int_bits_reference.html#mp_int_.uniform_mp_int_bits_reference.members">Members</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">uniform_mp_int_bits</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">MpInt</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">x</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Constructs a <code class="computeroutput"><span class="identifier">uniform_mp_int_bits</span></code>
+ object. All numbers generated by this object will be <code class="computeroutput"><span class="identifier">x</span></code>
+ bits in size.
+ </li></ul></div>
+<pre class="programlisting"><span class="identifier">result_type</span> <span class="identifier">min</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> The least value of the distribution.
+ </li></ul></div>
+<pre class="programlisting"><span class="identifier">result_type</span> <span class="identifier">max</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> The greatest value of the distribution.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Resets the state of the distribution
+ function.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">UniformRandomNumberGenerator</span><span class="special">&gt;</span>
+<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">UniformRandomNumberGenerator</span><span class="special">&amp;</span> <span class="identifier">urng</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> A uniform random number <code class="computeroutput"><span class="identifier">x</span></code> in the range <code class="computeroutput"><span class="identifier">min</span>
+ <span class="special">&lt;=</span> <span class="identifier">x</span>
+ <span class="special">&lt;=</span> <span class="identifier">max</span></code>.
+ </li></ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="uniform_mp_int_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="primality_tests_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_reference.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/html/mp_int_/uniform_mp_int_reference.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,108 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>uniform_mp_int reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
+<link rel="start" href="../index.html" title="Chapter 1. mp_int">
+<link rel="up" href="../index.html" title="Chapter 1. mp_int">
+<link rel="prev" href="mp_int_traits_reference.html" title="mp_int_traits reference">
+<link rel="next" href="uniform_mp_int_bits_reference.html" title="uniform_mp_int_bits reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="mp_int_traits_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="uniform_mp_int_bits_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="mp_int_.uniform_mp_int_reference"></a><a class="link" href="uniform_mp_int_reference.html" title="uniform_mp_int reference">uniform_mp_int reference</a>
+</h2></div></div></div>
+<a name="mp_int_.uniform_mp_int_reference.synopsis"></a><h4>
+<a name="id2788164"></a>
+ <a class="link" href="uniform_mp_int_reference.html#mp_int_.uniform_mp_int_reference.synopsis">Synopsis</a>
+ </h4>
+<pre class="programlisting"><span class="comment">// &lt;boost/mp_math/mp_int.hpp&gt;
+</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MpInt</span> <span class="special">=</span> <span class="identifier">mp_int</span><span class="special">&lt;&gt;</span> <span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">uniform_mp_int</span>
+<span class="special">{</span>
+ <span class="keyword">typedef</span> <span class="identifier">MpInt</span> <span class="identifier">input_type</span><span class="special">;</span>
+ <span class="keyword">typedef</span> <span class="identifier">MpInt</span> <span class="identifier">result_type</span><span class="special">;</span>
+
+ <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">has_fixed_range</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
+
+ <span class="identifier">uniform_mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MpInt</span><span class="special">&amp;</span> <span class="identifier">min</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">MpInt</span><span class="special">&amp;</span> <span class="identifier">max</span><span class="special">);</span>
+
+ <span class="identifier">result_type</span> <span class="identifier">min</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+ <span class="identifier">result_type</span> <span class="identifier">max</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+
+ <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
+
+ <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">UniformRandomNumberGenerator</span><span class="special">&gt;</span>
+ <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">UniformRandomNumberGenerator</span><span class="special">&amp;</span> <span class="identifier">urng</span><span class="special">);</span>
+<span class="special">};</span>
+</pre>
+<a name="mp_int_.uniform_mp_int_reference.members"></a><h4>
+<a name="id2788532"></a>
+ <a class="link" href="uniform_mp_int_reference.html#mp_int_.uniform_mp_int_reference.members">Members</a>
+ </h4>
+<pre class="programlisting"><span class="identifier">uniform_mp_int</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MpInt</span><span class="special">&amp;</span> <span class="identifier">min</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">MpInt</span><span class="special">&amp;</span> <span class="identifier">max</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<span class="bold"><strong>Requires: </strong></span><code class="computeroutput"><span class="identifier">min</span>
+ <span class="special">&lt;=</span> <span class="identifier">max</span></code>
+</li>
+<li>
+<span class="bold"><strong>Effects:</strong></span> Constructs a <code class="computeroutput"><span class="identifier">uniform_mp_int</span></code>
+ object. <code class="computeroutput"><span class="identifier">min</span></code> and <code class="computeroutput"><span class="identifier">max</span></code> are the parameters of the distribution.
+ </li>
+</ul></div>
+<pre class="programlisting"><span class="identifier">result_type</span> <span class="identifier">min</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> The <code class="computeroutput"><span class="identifier">min</span></code>
+ parameter of the distribution.
+ </li></ul></div>
+<pre class="programlisting"><span class="identifier">result_type</span> <span class="identifier">max</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> The <code class="computeroutput"><span class="identifier">max</span></code>
+ parameter of the distribution.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Effects:</strong></span> Resets the state of the distribution
+ function.
+ </li></ul></div>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">UniformRandomNumberGenerator</span><span class="special">&gt;</span>
+<span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">UniformRandomNumberGenerator</span><span class="special">&amp;</span> <span class="identifier">urng</span><span class="special">);</span>
+</pre>
+<div class="itemizedlist"><ul type="disc"><li>
+<span class="bold"><strong>Returns:</strong></span> A uniform random number <code class="computeroutput"><span class="identifier">x</span></code> in the range <code class="computeroutput"><span class="identifier">min</span>
+ <span class="special">&lt;=</span> <span class="identifier">x</span>
+ <span class="special">&lt;=</span> <span class="identifier">max</span></code>.
+ </li></ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2008 Kevin Sopp<p>
+ All code and documentation is in the public domain
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="mp_int_traits_reference.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="uniform_mp_int_bits_reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: sandbox/mp_math/libs/mp_math/doc/implementation_notes.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/implementation_notes.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,48 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Implementation notes]
+
+[section mp_int structure]
+
+An `mp_int` is handled in a sign plus magnitude representation which looks like
+this:
+
+ struct mp_int
+ {
+ digit_type* digits_;
+ size_type used_, capacity_;
+ int sign_;
+ };
+
+The least significant digit of the number always lives at `digits_[0]` while the
+most significant lives at `digits_[used_ - 1]`.
+
+Libtommath on which this code is ultimately based chose a `digit_type`
+representation which does not use all of its bits, instead some bits are
+reserved to hold carries in intermediate results. This allows very fast
+multiplication routines. I chose a different representation which uses all the
+bits in the `digit_type` but needs explicit carry handling in the code. This
+makes normal c++ code a tad slower. However it makes it much easier to write
+assembler routines since most CPUs provide instructions that allow the handling
+of carries in place. This is what GMP does as well. It is possible that a
+`digit_type` representation similar to libtommath's returns someday which can
+then be enabled via a different `mp_int_traits` class template.
+
+[endsect][/How mp_int structure]
+
+
+[section Semantics]
+
+* An integer with a value of zero has a `used_` count of 1 and `digits_[0]`
+holds the value 0.
+* An unitialized integer has no value and all operations on it except for
+initializing or swapping are undefined.
+
+[endsect][/Semantics]
+
+
+[endsect][/Implementation notes]
+

Added: sandbox/mp_math/libs/mp_math/doc/introduction.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/introduction.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,23 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Introduction]
+This library provides the `mp_int` class template for arbitrary precision signed
+integers. These integers grow dynamically as needed. Additionally, special
+functions which are necessary for the implementation of public key cryptography
+such as prime generation are provided.
+
+[heading Acknowledgement]
+
+This library originally started as a port of the C code of libtommath. Without
+the huge amount of work done by its author Tom St. Denis, this library wouldn't
+have been possible. Not only does he provide free C code, but also a very
+detailed pdf document of over 200 pages explaining the algorithms used in his
+code. Both his documentation and his code were placed in the public domain. In
+the spirit of his work the code of the `mp_int` library and its documentation
+are placed in the [*public domain] as well.
+
+[endsect]
+

Added: sandbox/mp_math/libs/mp_math/doc/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/jamfile.v2 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,28 @@
+# Copyright Kevin Sopp 2008.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
+import quickbook ;
+
+xml mp_int : mp_int.qbk ;
+
+#boostbook standalone
+# :
+# mp_int mp_int
+# ;
+
+boostbook standalone
+ :
+ mp_int
+ :
+ <xsl:param>boost.root=../../../..
+ <xsl:param>boost.libraries=../../../../libs/libraries.htm
+ #<xsl:param>generate.section.toc.level=4
+ #<xsl:param>toc.max.depth=3
+ #<xsl:param>toc.section.depth=4
+ #<xsl:param>chunk.section.depth=1
+ #<xsl:param>chunk.first.sections=1
+ ;
+

Added: sandbox/mp_math/libs/mp_math/doc/mp_int.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/mp_int.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,29 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[library mp_int
+ [quickbook 1.4]
+ [id mp_int]
+ [dirname mp_int]
+ [copyright 2008 Kevin Sopp]
+ [purpose multi precision integer arithmetic]
+ [authors [Sopp, Kevin]]
+ [license Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ [@http://www.boost.org/LICENSE_1_0.txt]
+ [source-mode c++]
+]
+
+[include introduction.qbk]
+[include tutorial.qbk]
+[include performance.qbk]
+[include implementation_notes.qbk]
+[include mp_int_reference.qbk]
+[include mp_int_traits_reference.qbk]
+[include uniform_mp_int_reference.qbk]
+[include uniform_mp_int_bits_reference.qbk]
+[include primality_tests_reference.qbk]
+[include bibliography.qbk]
+

Added: sandbox/mp_math/libs/mp_math/doc/mp_int_reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/mp_int_reference.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,1439 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section mp_int reference]
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ namespace boost {
+ namespace mp_math {
+
+ template<
+ class Allocator = std::allocator<void>,
+ class Traits = mp_int_traits<>
+ >
+ struct mp_int
+ {
+ typedef Allocator allocator_type;
+ typedef Traits traits_type;
+ typedef typename traits_type::size_type size_type;
+
+ // ctor/cctor/dtor/assign
+ mp_int();
+
+ template<typename IntegralT>
+ mp_int(IntegralT x, typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
+
+ mp_int(const char* s);
+ mp_int(const wchar_t* s);
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>& s);
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last);
+
+ mp_int(const char* s, std::ios_base::fmtflags f);
+ mp_int(const wchar_t* s, std::ios_base::fmtflags f);
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>& s, std::ios_base::fmtflags f);
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last, std::ios_base::fmtflags f);
+
+ mp_int(const mp_int& copy);
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ mp_int(mp_int&& copy);
+ #endif
+
+ ~mp_int();
+
+ mp_int& operator = (const mp_int& rhs);
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ mp_int& operator = (mp_int&& rhs);
+ #endif
+
+ template<typename IntegralT>
+ mp_int& operator = (IntegralT rhs);
+
+ mp_int& operator = (const char* s);
+
+ mp_int& operator = (const wchar_t* s);
+
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator = (const std::basic_string<charT,traits,Alloc>& s);
+
+ void assign(const char* s, std::ios_base::fmtflags f);
+
+ void assign(const wchar_t* s, std::ios_base::fmtflags f);
+
+ template<typename charT, class traits, class Alloc>
+ void assign(const std::basic_string<charT,traits,Alloc>& s, std::ios_base::fmtflags f);
+
+ template<typename RandomAccessIterator>
+ void assign(RandomAccessIterator first, RandomAccessIterator last, std::ios_base::fmtflags f);
+
+ // modifiers
+ #ifdef BOOST_HAS_RVALUE_REFS
+ void swap(mp_int&& other);
+ #else
+ void swap(mp_int& other);
+ #endif
+
+ // increment/decrement
+ mp_int& operator ++();
+ mp_int& operator --();
+ mp_int operator ++(int);
+ mp_int operator --(int);
+
+ // shifting
+ mp_int& operator <<= (size_type);
+ mp_int& operator >>= (size_type);
+
+ // unary negate
+ mp_int& operator - ();
+
+ // arithmetic operators
+ mp_int& operator += (const mp_int& x);
+ mp_int& operator -= (const mp_int& x);
+ mp_int& operator *= (const mp_int& x);
+ mp_int& operator /= (const mp_int& x);
+ mp_int& operator %= (const mp_int& x);
+
+ // bitwise operators
+ mp_int& operator |= (const mp_int& x);
+ mp_int& operator &= (const mp_int& x);
+ mp_int& operator ^= (const mp_int& x);
+
+ // operators involving integral types
+ template<typename IntegralT> mp_int& operator += (IntegralT x);
+ template<typename IntegralT> mp_int& operator -= (IntegralT x);
+ template<typename IntegralT> mp_int& operator *= (IntegralT x);
+ template<typename IntegralT> mp_int& operator /= (IntegralT x);
+ template<typename IntegralT> mp_int& operator %= (IntegralT x);
+ template<typename IntegralT> mp_int& operator |= (IntegralT x);
+ template<typename IntegralT> mp_int& operator &= (IntegralT x);
+ template<typename IntegralT> mp_int& operator ^= (IntegralT x);
+
+ // operators involving char strings
+ mp_int& operator += (const char* s);
+ mp_int& operator -= (const char* s);
+ mp_int& operator *= (const char* s);
+ mp_int& operator /= (const char* s);
+ mp_int& operator %= (const char* s);
+ mp_int& operator |= (const char* s);
+ mp_int& operator &= (const char* s);
+ mp_int& operator ^= (const char* s);
+
+ // operators involving wchar_t strings
+ mp_int& operator += (const wchar_t* s);
+ mp_int& operator -= (const wchar_t* s);
+ mp_int& operator *= (const wchar_t* s);
+ mp_int& operator /= (const wchar_t* s);
+ mp_int& operator %= (const wchar_t* s);
+ mp_int& operator |= (const wchar_t* s);
+ mp_int& operator &= (const wchar_t* s);
+ mp_int& operator ^= (const wchar_t* s);
+
+ // operators involving std::basic_string
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator += (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator -= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator *= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator /= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator %= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator |= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator &= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator ^= (const std::basic_string<charT,traits,Alloc>& s);
+
+ // observers
+ allocator_type get_allocator() const;
+
+ bool is_even() const;
+ bool is_odd () const;
+
+ bool is_positive() const;
+ bool is_negative() const;
+
+ size_type precision() const;
+
+ operator unspecified_bool_type() const;
+
+ std::string to_string(std::ios_base::fmtflags f = std::ios_base::dec) const;
+
+ template<typename IntegralT>
+ IntegralT to_integral() const;
+
+ // low level access
+ typedef traits_type::digit_type digit_type;
+ typedef traits_type::word_type word_type;
+
+ bool is_zero() const;
+
+ digit_type& operator[](size_type i);
+ const digit_type& operator[](size_type i) const;
+
+ digit_type& at(size_type i);
+ const digit_type& at(size_type i) const;
+ };
+
+
+ // non-member functions
+
+ #ifdef BOOST_HAS_RVALUE_REFS
+ template<class A, class T>
+ void swap(mp_int<A,T>&&, mp_int<A,T>&&);
+ #else
+ void swap(mp_int<A,T>&, mp_int<A,T>&);
+ #endif
+
+ template<class A, class T>
+ mp_int<A,T> operator << (const mp_int<A,T>&, typename mp_int<A,T>::size_type);
+
+ template<class A, class T>
+ mp_int<A,T> operator >> (const mp_int<A,T>&, typename mp_int<A,T>::size_type);
+
+ template<class A, class T>
+ mp_int<A,T> operator - (const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator + (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator - (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator * (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator / (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator % (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator | (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator & (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator ^ (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator + (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator - (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator * (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator / (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator % (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator | (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator & (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator ^ (const mp_int<A,T>&, IntegralT);
+
+
+ // Comparison operators
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ // Comparison between mp_int and std::basic_string
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator == (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator != (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator < (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator > (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator <= (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator >= (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ // Comparison between std::basic_string and mp_int
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator == (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator != (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator < (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator > (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator <= (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator >= (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ // Comparison between mp_int and const char*
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const char*);
+
+ // Comparison between const char* and mp_int
+
+ template<class A, class T>
+ bool operator == (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const char*, const mp_int<A,T>&);
+
+ // Comparison between mp_int and const wchar_t*
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const wchar_t*);
+
+ // Comparison between const wchar_t* and mp_int
+
+ template<class A, class T>
+ bool operator == (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const wchar_t*, const mp_int<A,T>&);
+
+ // Comparison between mp_int and integral type
+
+ template<class A, class T, typename IntegralT>
+ bool operator == (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator != (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator < (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator > (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator <= (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator >= (const mp_int<A,T>&, IntegralT);
+
+ // Comparison between integral type and mp_int
+
+ template<class A, class T, typename IntegralT>
+ bool operator == (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator != (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator < (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator > (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator <= (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator >= (IntegralT, const mp_int<A,T>&);
+
+
+ // Stream I/O
+
+ template<class A, class T, typename charT, class traits>
+ std::basic_istream<charT, traits>&
+ operator >> (std::basic_istream<charT, traits>& is, mp_int<A,T>& x);
+
+ template<class A, class T, typename charT, class traits>
+ std::basic_ostream<charT, traits>&
+ operator << (std::basic_ostream<charT, traits>& os, const mp_int<A,T>& x);
+
+
+ // Special functions
+
+ template<class A, class T>
+ mp_int<A,T> abs(const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b);
+
+ template<class A, class T>
+ mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b);
+
+ template<class A, class T>
+ int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& p);
+
+ template<class A, class T>
+ mp_int<A,T> pow(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n);
+
+ template<class A, class T>
+ mp_int<A,T> modpow(const mp_int<A,T>& base, const mp_int<A,T>& exp, const mp_int<A,T>& mod);
+
+ template<class A, class T>
+ mp_int<A,T> sqrt(const mp_int<A,T>& x);
+
+ template<class A, class T>
+ mp_int<A,T> nth_root(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n);
+
+
+ } // namespace mp_math
+ } // namespace boost
+
+
+[h3 Construction from / assignment to a string object]
+In a constructor or assignment operation without the possibility to specify the base
+of the string argument the base of the number is deduced from the string. If the
+string starts with `0x` or `0X` then the number will be treated as hexadecimal
+value. If the string starts with `0` then the number will be treated as octal
+value else it will be treated as decimal value. An optional `-` sign is allowed
+as the first character in the string to indicate a negative value.
+
+In a constructor or assignment operation with the ability to specify the format
+of the string argument via a `std::ios_base::fmtflags` parameter, possible
+formatting flags are:
+
+* `std::ios_base::showbase`
+* `std::ios_base::dec`
+* `std::ios_base::hex`
+* `std::ios_base::oct`
+
+
+[heading Construct/Copy/Destroy/Assign]
+
+ mp_int();
+
+* [*Effects:] Constructs an empty `mp_int` object, such an uninitialized
+`mp_int` has no value, i.e. it is /not/ zero.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ template<typename IntegralT>
+ mp_int(IntegralT x, typename enable_if<boost::is_integral<IntegralT> >::type* dummy = 0);
+
+* [*Effects:] Constructs an `mp_int` object from an integral type. The value of
+the object is that of the integral type.
+* [*Complexity:] O(N) where N is the number of bits of IntegralT.
+* [*Throws: ] `std::bad_alloc`.
+
+
+ mp_int(const char* s);
+ mp_int(const wchar_t* s);
+
+* [*Requires: ] `s` points to a valid number formatted as string or to an empty
+string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>& s);
+
+* [*Requires: ] `s` contains a valid number formatted as string or `s` is an
+empty string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last);
+
+* [*Requires: ] `first` and `last` are iterators into a string.
+* [*Effects:] Constructs an `mp_int` object from two iterators.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ mp_int(const char* s, std::ios_base::fmtflags f);
+ mp_int(const wchar_t* s, std::ios_base::fmtflags f);
+
+* [*Requires: ] `s` points to a valid number formatted according to the flags in
+`f` or `s` is an empty string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+
+
+ template<typename charT, class traits, class Alloc>
+ mp_int(const std::basic_string<charT,traits,Alloc>& s, std::ios_base::fmtflags f);
+
+* [*Requires: ] `s` contains a valid number formatted according to the flags in
+`f` or `s` is an empty string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+
+
+ template<typename RandomAccessIterator>
+ mp_int(RandomAccessIterator first, RandomAccessIterator last, std::ios_base::fmtflags f);
+
+* [*Requires: ] `first` and `last` are iterators into a string formatted
+according to the formatting flags in `f`.
+* [*Effects:] Constructs an `mp_int` object from two iterators.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+
+
+ mp_int(const mp_int& copy);
+
+* [*Effects:] Constructs a copy of a given `mp_int`.
+* [*Complexity:] O(N), where N is the number of digits in `copy`.
+* [*Throws: ] `std::bad_alloc`.
+
+
+ mp_int(mp_int&& copy);
+
+* [*Effects:] Constructs an `mp_int` by moving `copy` into `*this`.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ ~mp_int();
+
+* [*Effects:] Destroys `*this`.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ mp_int& operator = (const mp_int& rhs);
+
+* [*Effects:] Copies the value of `rhs` into `*this`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator = (mp_int&& rhs);
+
+* [*Effects: ] `*this` obtains the value of `rhs`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ template<typename IntegralT>
+ mp_int& operator = (IntegralT rhs);
+
+* [*Effects: ] `*this` obtains the value of `rhs`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] basic.
+
+ mp_int& operator = (const char* s);
+ mp_int& operator = (const wchar_t* s);
+
+* [*Requires: ] `s` points to a valid number formatted as string or to an empty
+string.
+* [*Effects:] `*this = mp_int(s);`.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+* [*Exception safety:] basic.
+
+
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator = (const std::basic_string<charT,traits,Alloc>& s);
+
+* [*Requires: ] `s` points to a valid number formatted as string or to an empty
+string.
+* [*Effects:] `*this = mp_int(s);`.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+* [*Exception safety:] basic.
+
+
+ void assign(const char* s, std::ios_base::fmtflags f);
+ void assign(const wchar_t* s, std::ios_base::fmtflags f);
+
+* [*Requires: ] `s` points to a valid number formatted according to the flags in
+`f` or `s` is an empty string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+* [*Exception safety:] basic.
+
+
+ template<typename charT, class traits, class Alloc>
+ void assign(const std::basic_string<charT,traits,Alloc>& s, std::ios_base::fmtflags f);
+
+* [*Requires: ] `s` contains a valid number formatted according to the flags in
+`f` or `s` is an empty string.
+* [*Effects:] Constructs an `mp_int` object from a string.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+* [*Exception safety:] basic.
+
+
+ template<typename RandomAccessIterator>
+ void assign(RandomAccessIterator first, RandomAccessIterator last, std::ios_base::fmtflags f);
+
+* [*Requires: ] `first` and `last` are iterators into a string formatted
+according to the formatting flags in `f`.
+* [*Effects:] Constructs an `mp_int` object from two iterators.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character or if an
+ unrecognized formatting flag was set.
+* [*Exception safety:] basic.
+
+
+[heading Modifiers]
+
+ void swap(mp_int&& other);
+
+* [*Effects:] Swaps the value of `other` and `*this`.
+* [*Complexity:] O(1).
+* [*Exception safety:] nothrow.
+
+
+ void swap(mp_int& other);
+
+* [*Effects:] Swaps the value of `other` and `*this`.
+* [*Complexity:] O(1).
+* [*Exception safety:] nothrow.
+
+
+[heading Increment/decrement]
+
+ mp_int& operator ++();
+
+* [*Effects:]
+``
+*this += 1;
+return *this;
+``
+* [*Returns: ] `*this`.
+* [*Complexity:] best case is O(1), worst case is O(N) - this happens when the
+addition causes a carry bit to ripple through all digits subsequently.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator --();
+
+* [*Effects:]
+``
+*this -= 1;
+return *this;
+``
+* [*Returns: ] `*this`.
+* [*Complexity:] best case is O(1), worst case is O(N) - this happens when the
+subtraction causes a borrow bit to ripple through all digits subsequently.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int operator ++(int);
+
+* [*Effects:]
+``
+mp_int tmp(*this);
+*this += 1;
+return tmp;
+``
+* [*Returns:] The value of `*this` before incrementation.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int operator --(int);
+
+* [*Effects:]
+``
+mp_int tmp(*this);
+*this -= 1;
+return tmp;
+``
+* [*Returns:] The value of `*this` before decrementation.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+[heading Shifting]
+
+ mp_int& operator <<= (size_type x);
+
+* [*Effects:] Shift `*this` by `x` bits to the left.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator >>= (size_type x);
+
+* [*Effects:] Shift `*this` by `x` bits to the right.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+[heading Unary negate]
+
+ mp_int& operator - ();
+
+* [*Effects:] Negates `*this`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(1).
+* [*Exception safety:] nothrow.
+
+
+[heading Arithmetic operators]
+
+ mp_int& operator += (const mp_int& x);
+
+* [*Effects:] Adds `x` to `*this`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator -= (const mp_int& x);
+
+
+* [*Effects:] Subtracts `x` from `*this`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator *= (const mp_int& x);
+
+* [*Effects:] Multiplies `*this` by `x`.
+* [*Returns: ] `*this`.
+* [*Complexity:] If `&x == this` then a squaring algorithm will be used.
+Different multiplication algorithms are chosen for numbers of different size.
+The thresholds can be tuned via the `mp_int_traits` class template parameter.
+ * Small numbers: Comba algorithm O(N^2).
+ * Midsize numbers: Karatsuba algorithm O(N^log2(3)) ~ O(N^1.585).
+ * Large numbers: Toom-Cook algorithm O(N^(log(5)/log(3))) ~ O(N^1.465).
+
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator /= (const mp_int& x);
+
+* [*Requires: ] `x != 0`.
+* [*Effects:] Divides `*this` by `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ]
+ * `std::bad_alloc`
+ * `std::domain_error` if `x == 0`.
+
+* [*Exception safety:] strong.
+
+
+ mp_int& operator %= (const mp_int& x);
+
+* [*Requires: ] `x != 0`.
+* [*Effects:] Modulus `*this` by `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ]
+ * `std::bad_alloc`
+ * `std::domain_error` if `x == 0`.
+
+* [*Exception safety:] strong.
+
+
+[heading Bitwise operators]
+
+ mp_int& operator |= (const mp_int& x);
+
+* [*Effects: ] `*this` OR `x`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator &= (const mp_int& x);
+
+* [*Effects: ] `*this` AND `x`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ mp_int& operator ^= (const mp_int& x);
+
+* [*Effects: ] `*this` XOR `x`.
+* [*Returns: ] `*this`.
+* [*Complexity:] O(N).
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+[heading Operators involving integral types]
+
+ template<typename IntegralT> mp_int& operator += (IntegralT x);
+
+* [*Effects:] Adds `x` to `*this`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator -= (IntegralT x);
+
+* [*Effects:] Subtracts `x` to `*this`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator *= (IntegralT x);
+
+* [*Effects:] Multiplies `*this` by `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator /= (IntegralT x);
+
+* [*Effects:] Divides `*this` by `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator %= (IntegralT x);
+
+* [*Effects: ] `*this` modulo `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator |= (IntegralT x);
+
+* [*Effects:] Applies the bitwise or operation on `*this` and the absolute of `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator &= (IntegralT x);
+
+* [*Effects:] Applies the bitwise and operation on `*this` and the absolute of `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT> mp_int& operator ^= (IntegralT x);
+
+* [*Effects:] Applies the bitwise xor operation on `*this` and the absolute of `x`.
+* [*Returns: ] `*this`.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+[heading Operators involving char/wchar_t strings]
+
+ mp_int& operator += (const char* s);
+ mp_int& operator += (const wchar_t* s);
+ mp_int& operator -= (const char* s);
+ mp_int& operator -= (const wchar_t* s);
+ mp_int& operator *= (const char* s);
+ mp_int& operator *= (const wchar_t* s);
+ mp_int& operator /= (const char* s);
+ mp_int& operator /= (const wchar_t* s);
+ mp_int& operator %= (const char* s);
+ mp_int& operator %= (const wchar_t* s);
+ mp_int& operator |= (const char* s);
+ mp_int& operator |= (const wchar_t* s);
+ mp_int& operator &= (const char* s);
+ mp_int& operator &= (const wchar_t* s);
+ mp_int& operator ^= (const char* s);
+ mp_int& operator ^= (const wchar_t* s);
+
+[heading Operators involving std::basic_string]
+
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator += (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator -= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator *= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator /= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator %= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator |= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator &= (const std::basic_string<charT,traits,Alloc>& s);
+ template<typename charT, class traits, class Alloc>
+ mp_int& operator ^= (const std::basic_string<charT,traits,Alloc>& s);
+
+
+[heading Observers]
+
+ allocator_type get_allocator() const;
+
+* [*Returns: ] A copy of the allocator.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing if allocator copy constructor is nothrow.
+
+
+ bool is_even() const;
+
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ bool is_odd () const;
+
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ bool is_positive() const;
+
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ bool is_negative() const;
+
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ size_type precision() const;
+
+* [*Returns:] The number of bits used by the absolute value of *this.
+* [*Complexity:] O(N).
+* [*Throws:] Nothing.
+
+ operator unspecified_bool_type() const;
+
+* [*Returns: ] `*this != 0`.
+* [*Complexity:] O(1).
+* [*Throws:] Nothing.
+
+
+ std::string to_string(std::ios_base::fmtflags f = std::ios_base::dec) const;
+
+* [*Effects:] Converts `*this` to a `std::string`, formatting of the string is
+done according to the `std::ios_base::fmtflags` parameter. Possible formatting
+flags are:
+ * `std::ios_base::showpos`
+ * `std::ios_base::showbase`
+ * `std::ios_base::dec`
+ * `std::ios_base::hex`
+ * `std::ios_base::oct`
+ * `std::ios_base::uppercase`
+
+* [*Returns: ] `*this` converted to a `std::string` object.
+* [*Throws: ] `std::bad_alloc`.
+* [*Exception safety:] strong.
+
+
+ template<typename IntegralT>
+ IntegralT to_integral() const;
+
+* [*Returns: ] `*this` converted to an object of type `IntegralT`.
+* [*Complexity:] O(1).
+* [*Throws: ] `std::overflow_error` if `IntegralT` does not have enough
+precision to hold the result.
+* [*Exception safety:] strong.
+
+
+
+[heading Non-member functions]
+
+ template<class A, class T>
+ void swap(mp_int<A,T>&&, mp_int<A,T>&&);
+
+ template<class A, class T>
+ mp_int<A,T> operator << (const mp_int<A,T>&, typename mp_int<A,T>::size_type);
+
+ template<class A, class T>
+ mp_int<A,T> operator >> (const mp_int<A,T>&, typename mp_int<A,T>::size_type);
+
+ template<class A, class T>
+ mp_int<A,T> operator - (const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator + (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator - (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator * (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator / (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator % (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator | (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator & (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ mp_int<A,T> operator ^ (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator + (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator - (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator * (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator / (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator % (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator | (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator & (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ mp_int<A,T> operator ^ (const mp_int<A,T>&, IntegralT);
+
+These functions are implemented in terms of their respective member functions.
+
+
+[heading Comparison operators]
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const mp_int<A,T>&);
+
+* [*Effects:] These operators compare the numeric value of their arguments and
+return a truth value based on that evaluation.
+* [*Throws:] Nothing.
+
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator == (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator != (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator < (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator > (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator <= (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator >= (const mp_int<A,T>&, const std::basic_string<charT,Traits,Alloc>&);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the left side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator == (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator != (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator < (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator > (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator <= (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+ template<class A, class T, class charT, class Traits, class Alloc>
+ bool operator >= (const std::basic_string<charT,Traits,Alloc>&, const mp_int<A,T>&);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the right side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const char*);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const char*);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the left side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T>
+ bool operator == (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const char*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const char*, const mp_int<A,T>&);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the right side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T>
+ bool operator == (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator != (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator < (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator > (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator <= (const mp_int<A,T>&, const wchar_t*);
+
+ template<class A, class T>
+ bool operator >= (const mp_int<A,T>&, const wchar_t*);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the left side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T>
+ bool operator == (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator != (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator < (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator > (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator <= (const wchar_t*, const mp_int<A,T>&);
+
+ template<class A, class T>
+ bool operator >= (const wchar_t*, const mp_int<A,T>&);
+
+* [*Effects:] Converts the string argument to an `mp_int` object and compares it
+to the object on the right side of the expression.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::invalid_argument` if the string contains an invalid character.
+
+
+ template<class A, class T, typename IntegralT>
+ bool operator == (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator != (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator < (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator > (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator <= (const mp_int<A,T>&, IntegralT);
+
+ template<class A, class T, typename IntegralT>
+ bool operator >= (const mp_int<A,T>&, IntegralT);
+
+* [*Effects:] Converts the integral argument to an `mp_int` object and compares it
+to the object on the left side of the expression.
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T, typename IntegralT>
+ bool operator == (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator != (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator < (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator > (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator <= (IntegralT, const mp_int<A,T>&);
+
+ template<class A, class T, typename IntegralT>
+ bool operator >= (IntegralT, const mp_int<A,T>&);
+
+* [*Effects:] Converts the integral argument to an `mp_int` object and compares it
+to the object on the right side of the expression.
+* [*Throws: ] `std::bad_alloc`.
+
+
+[heading Stream I/O]
+
+ template<class A, class T, typename charT, class traits>
+ std::basic_istream<charT, traits>&
+ operator >> (std::basic_istream<charT, traits>& is, mp_int<A,T>& x);
+
+ template<class A, class T, typename charT, class traits>
+ std::basic_ostream<charT, traits>&
+ operator << (std::basic_ostream<charT, traits>& os, const mp_int<A,T>& x);
+
+
+[heading Special functions]
+
+ template<class A, class T>
+ mp_int<A,T> abs(const mp_int<A,T>& x);
+
+* [*Returns:] The positive value of `x`.
+* [*Complexity:] O(1).
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T>
+ mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b);
+
+* [*Returns:] The greatest common divisor of `a` and `b`.
+* [*Complexity:] O((log2(AB))^2).
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T>
+ mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b);
+
+* [*Returns:] The least common multiple of `a` and `b`.
+* [*Complexity:] O((log2(AB))^2).
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T>
+ int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& p);
+
+* [*Returns:] The Jacobi symbol of integer `a` and positive odd integer `p`.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::domain_error` if `p` is negative.
+
+
+ template<class A, class T>
+ mp_int<A,T> pow(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n);
+
+* [*Returns:] The `n`th power of `x`.
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T>
+ mp_int<A,T> modpow(const mp_int<A,T>& base,
+ const mp_int<A,T>& exp,
+ const mp_int<A,T>& mod);
+
+
+* [*Returns: ] `(base ^ exp) % mod`.
+* [*Throws: ] `std::bad_alloc`.
+
+
+ template<class A, class T>
+ mp_int<A,T> sqrt(const mp_int<A,T>& x);
+
+* [*Returns:] The square root of `x`.
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::domain_error` if `x` is negative.
+
+
+ template<class A, class T>
+ mp_int<A,T> nth_root(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n);
+
+* [*Returns:] The `n`th root of `x`.
+* [*Complexity:] O(log(N)).
+* [*Throws:]
+ * `std::bad_alloc`
+ * `std::domain_error` if `x` is negative and `n` is odd.
+
+
+[endsect][/mp_int reference]
+

Added: sandbox/mp_math/libs/mp_math/doc/mp_int_traits_reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/mp_int_traits_reference.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,37 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section mp_int_traits reference]
+
+The second template parameter to mp_int is a type which allows to customize some
+of mp_int's internal workings.
+
+[heading Synopsis]
+``
+// <boost/mp_math/mp_int/traits.hpp>
+namespace boost {
+namespace mp_math {
+
+template<
+ typename Digit = implementation defined,
+ typename Word = implementation defined
+>
+struct mp_int_traits
+{
+ typedef std::size_t size_type;
+ typedef Digit digit_type;
+ typedef Word word_type;
+
+ static size_type toom_mul_cutoff; // default: 350
+ static size_type toom_sqr_cutoff; // default: 400
+ static size_type karatsuba_mul_cutoff; // default: 80
+ static size_type karatsuba_sqr_cutoff; // default: 120
+};
+
+} // namespace mp_math
+} // namespace boost
+``
+[endsect][/mp_int_traits reference]
+

Added: sandbox/mp_math/libs/mp_math/doc/performance.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/performance.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,130 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Performance]
+
+[section Tips]
+
+* A statement like
+``x = a + b;``
+involves the creation of a temporary `mp_int` inside `operator +` because it is
+not able to write the result directly into `x` which may already have enough
+memory allocated to hold the result. Instead rewrite it into
+``
+x = a;
+x += b;
+``
+This trick proves to be useful only for simple operations like addition and
+subtraction.
+* In operations involving built in integral types, try to use unsigned types,
+preferrably unsigned types that are as large or smaller than
+mp_int<>::digit_type.
+* Use hexadecimal digits for input and output. Conversion from/to power of two
+bases uses a O(n) algorithm which is not possible for base 10.
+
+[endsect][/Tips]
+
+
+
+
+[section Measurements]
+
+A benchmark program is supplied with Boost.Mp_math under libs\/mp_math\/tools\/benchmark.
+This benchmark compares some primitive operations of different multi precision
+integer libraries. It creates detailed result files and uses
+[@http://www.gnuplot.info/ gnuplot] to create graphs.
+
+Example invocations:
+[pre
+'''benchmark''' // runs all benches
+'''benchmark --help'''
+'''benchmark --ops="add subtract multiply" --libs="boost.mp_math libtommath"'''
+]
+
+
+[section AMD Athlon XP 2000+]
+
+[pre
+'''Operating System: Arch Linux (i686), Kernel 2.6.26, glibc 2.8'''
+'''Compiler: gcc-4.3.2'''
+]
+Libraries being compared:
+
+* Boost.Mp_math-1_37
+ * switches used: -ftemplate-depth-128 -O3 -finline-functions -march=i686 -mtune=generic -std=c++0x
+* libtommath-0.41
+ * switches used: -ftemplate-depth-128 -O3 -finline-functions -march=i686 -mtune=generic
+* gmp-4.2.2 (precompiled distribution package, uses generic i386 asm and Intel
+ P6 (Pentium Pro) asm where available)
+ * switches used: -march=i686 -mtune=generic -O2
+
+[h3 Input vectors]
+Operand size is measured in number of bits.
+I chose to vary the operand size for the benchmarks a little to see how well the
+operation handles inputs of differing sizes. Benchmarks that use only one
+operand use operand 1.
+[$benchmark_imgs/k7/input_vecs.png]
+
+While input operand 1 grows linearly, input operand 2's size is
+determined by a modified sine function.
+
+
+[h3 Construct from decimal string]
+[$benchmark_imgs/k7/ctor_dec.png]
+
+
+[h3 Construct from hex string]
+[$benchmark_imgs/k7/ctor_hex.png]
+
+
+[h3 Conversion to decimal string]
+[$benchmark_imgs/k7/to_dec.png]
+
+
+[h3 Conversion to hex string]
+[$benchmark_imgs/k7/to_hex.png]
+
+
+[h3 Add]
+[$benchmark_imgs/k7/add.png]
+
+
+[h3 Subtract]
+[$benchmark_imgs/k7/subtract.png]
+
+
+[h3 Multiply]
+[$benchmark_imgs/k7/multiply.png]
+
+
+[h3 Divide]
+[$benchmark_imgs/k7/divide.png]
+
+
+[h3 Modulo]
+[$benchmark_imgs/k7/modulo.png]
+
+
+[h3 Square]
+[$benchmark_imgs/k7/square.png]
+
+
+[h3 Modular Power]
+The operation looks like this: `dest = (op1 ^ op1) % op2`.
+This graph uses a logarithmic scale.
+[$benchmark_imgs/k7/modpow.png]
+
+
+[endsect][/AMD K7 Thunderbird 800Mhz]
+
+
+
+[endsect][/Measurements]
+
+
+
+
+
+[endsect][/Performance]

Added: sandbox/mp_math/libs/mp_math/doc/primality_tests_reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/primality_tests_reference.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,136 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Primality Tests reference]
+
+[section primality_division_test]
+
+This function object tests a candidate `p` by repeatedly dividing it by small
+primes (2, 3, 5, 7, 11...). This is a test that should be used before other more
+complex tests because it quickly sieves out composite numbers. For example,
+testing for 2, 5, 7 will eliminate 54% of all numbers, testing for all primes
+less than 100 eliminates 70%, for all primes less than 256 it is 80%.
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ struct primality_division_test
+ {
+ typedef bool result_type;
+
+ template<class A, class T>
+ bool operator()(const mp_int<A,T>& p) const;
+ };
+
+
+[h3 Members]
+
+ template<class A, class T>
+ bool operator()(const mp_int<A,T>& p) const;
+
+* [*Effects:] Returns true if `p` is probably prime. Returns false if `p`
+is definitely composite.
+
+[endsect][/primality_division_test]
+
+
+[section primality_fermat_test]
+
+This test is based on Fermat's little theorem which states that if an integer
+`p` is prime, then for all integers `a` where 0 < `a` < `p`
+
+`a**(p-1) = 1 (mod p)`
+
+an alternative formulation is
+
+`a**p = a (mod p)`
+
+For each round the test creates a random base `a` and checks if the condition
+holds.
+There is a class of pseudoprimes called carmichael numbers which are less likely
+though not impossible with enough rounds to be detected by this test.
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ template<class Distribution = uniform_mp_int<> >
+ struct primality_fermat_test
+ {
+ typedef Distribution distribution_type;
+ typedef bool result_type;
+
+ explicit primality_fermat_test(unsigned int rounds);
+
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+ };
+
+
+[h3 Members]
+
+ explicit primality_fermat_test(unsigned int r);
+
+* [*Effects:] Constructs a `primality_fermat_test` object with the number
+of test rounds given by `r`.
+
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+
+* [*Effects:] Returns true if `p` is probably prime. Returns false if `p`
+is definitely composite.
+
+[endsect][/primality_fermat_test]
+
+
+[section primality_miller_rabin_test]
+
+This test is an improved version of the Fermat primality test that will also
+detect carmichael numbers.
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ template<class Distribution = uniform_mp_int<> >
+ struct primality_miller_rabin_test
+ {
+ typedef Distribution distribution_type;
+ typedef bool result_type;
+
+ explicit primality_miller_rabin_test(unsigned int r = 0);
+
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+
+ static unsigned int recommended_number_of_rounds(unsigned bits);
+ };
+
+
+[h3 Members]
+
+ explicit primality_miller_rabin_test(unsigned int r = 0);
+
+* [*Effects:] Constructs a `primality_miller_rabin_test` object with the number
+of test rounds given by `r`. If `r == 0` then each invocation of this function
+object will use the recommended number of rounds.
+
+ template<class Engine, class A, class T>
+ bool operator()(Engine& e, const mp_int<A,T>& p) const;
+
+* [*Requires:] `p` is odd.
+* [*Effects:] Returns true if `p` is probably prime. Returns false if `p`
+is definitely composite.
+
+
+ unsigned int recommended_number_of_rounds(unsigned bits);
+
+* [*Effects:] Returns the recommended number of rounds for a number of precision
+`bits` so that the probability of error is less than 2^-96.
+
+[endsect][/primality_miller_rabin_test]
+
+
+
+[endsect][/uniform_mp_int_bits reference]
+

Added: sandbox/mp_math/libs/mp_math/doc/tutorial.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/tutorial.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,208 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section Tutorial]
+
+
+[section General use]
+
+The only header you need to include to use the library is
+`<boost/mp_math/mp_int.hpp>`. This is a header-only library so deployment is easy.
+All functions and objects of this library live in namespace `boost::mp_math`.
+
+ #include <iostream>
+ #include <string>
+ #include <boost/mp_math/mp_int.hpp>
+
+ using namespace boost::mp_math;
+ using namespace std;
+
+ int main()
+ {
+ // init from string
+ mp_int<> x("93423894782394782347823947289374");
+ // init from integral type
+ mp_int<> y = 2340;
+ mp_int<> z = x * y;
+
+ // stream output reacts to stream flags
+ cout << hex << z << endl;
+
+ // automatic detection of radix using the base prefix 0x
+ z = "0xaaaabbbbccccddddeeeeffff222255557777";
+
+ z /= y;
+
+ // explicit conversion to string according to formatting flags
+ string s = z.to_string<string>(ios::hex | ios::showbase);
+ cout << s << endl;
+
+ z -= z;
+
+ // explicit conversion to built in integral types - this will throw
+ // std::overflow_error if int does not have enough precision to hold the
+ // result
+ int result = z.to_integral<int>();
+
+ return result;
+ }
+
+In most cases the `mp_int` type will behave like a built in integral type.
+
+[endsect][/General use]
+
+
+[section Random number generation]
+
+The random number generators have interfaces similar to Boost.Random. Including
+`<boost/random.hpp>` is not necessary because it is used internally by the
+`mp_int` random machinery. The random number engine `mt19937` that we use from
+here on lives in namespace `boost`.
+
+
+ const mp_int<> min(0U);
+ const mp_int<> max("0x8974651231456456564");
+
+ uniform_mp_int<> generator(min, max);
+
+ // Choose a random number engine.
+ mt19937 e;
+
+ // Now generate a random number.
+ mp_int<> r = generator(e);
+
+
+Another probably more useful alternative is to generate random numbers of a
+certain precision measured in bits.
+
+
+ // A generator for 2048 bit integers.
+ uniform_mp_int_bits<> generator(2048);
+
+ mt19937 e;
+ mp_int<> r = generator(e);
+
+Note that the numbers will always be 2048 bits large, i.e. the 2048th bit is
+always set to 1.
+
+[endsect][/Random number generation]
+
+
+
+[section Primality testing]
+
+Currently all primality tests in this library are probabilistic. A probabilistic
+primality test cannot ascertain that a prime candidate p is really prime. It can
+however ascertain that it is a composite number.
+
+Here we will learn how to test a number `p` for primality using the fermat
+primality test. We use boost::bind to bind the random number engine to the test
+functor. That is necessary because the test functor's function invocation
+operator needs the random number engine. The operator looks like this:
+
+ bool operator()(Engine& e, const mp_int<>& p) const;
+
+We need to bind the random number engine to the first parameter slot. Let's do
+it!
+
+ // Create the fermat test functor with 4 rounds of testing.
+ primality_fermat_test<> test(4);
+
+ // Create a random number engine.
+ mt19937 rng;
+
+ // Create a random 1024 bit candidate number.
+ mp_int<> p = uniform_mp_int_bits<>(1024)(rng);
+
+ bool is_p_prime = is_prime(p, bind(test, rng, _1));
+
+
+[endsect][/Primality testing]
+
+
+
+[section Prime number generation]
+
+
+[section prime_generator]
+
+First we will look at how to generate prime numbers using a simple trial
+division test. What this means is that the prime generator creates a random
+number and then repeatedly divides it by small primes until it finds a number
+that passes this test.
+
+ // Create a generator for 2048 bit primes.
+ prime_generator<primality_division_test> generator(2048);
+
+ // Create a random number engine.
+ mt19937 rng;
+
+ // Now create a prime.
+ mp_int<> prime = generator(rng);
+
+
+[endsect][/prime_generator]
+
+
+[section safe_prime_generator]
+
+A safe prime is a prime `p` for which `(p-1)/2` is also prime. Such prime numbers
+are much rarer and thus take longer to generate.
+
+Now we will look at how to use a more sophisticated primality test like
+`primality_miller_rabin_test` for prime number generation. It is very useful to
+combine this test with the `primality_division_test`. This will involve a bit of
+code, mostly because `primality_miller_rabin_test` and `safe_prime_generator`
+require a random number generator. The latter needs randomness to create a
+candidate to test for primality and the miller rabin test needs randomness to
+test the candidate effectively.
+
+ // Define a function object that checks a prime candidate p first with a trial
+ // division and then with the miller-rabin algorithm. For ease of use we give
+ // it default template arguments.
+ // It does not hold a reference to the random number engine because that could
+ // lead to lifetime problems.
+ template<
+ class Engine = mt19937,
+ class Distribution = uniform_mp_int_bits<>
+ >
+ struct primality_test
+ {
+ primality_division_test test1;
+ primality_miller_rabin_test<Distribution> test2;
+ Engine rng;
+
+ explicit tester(const Engine& e = Engine()) : rng(e) {}
+
+ bool operator()(const mp_int<>& p)
+ {
+ return test1(p) && test2(rng, p);
+ }
+ };
+
+ // Create a random number engine that we will feed to the different
+ // algorithms.
+ mt19937 rng;
+
+ // Create a generator for safe primes with 128 bits precision.
+ typedef safe_prime_generator<primality_test<>, uniform_mp_int_bits<> >
+ generator_type;
+
+ generator_type generator(128, primality_test<>(rng));
+
+ mp_int<> prime = generator(rng);
+
+Remember, the generated numbers are ['probably] prime.
+
+[endsect][/safe_prime_generator]
+
+
+
+[endsect][/Prime number generation]
+
+
+
+[endsect][/Tutorial]
+

Added: sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_bits_reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_bits_reference.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,60 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section uniform_mp_int_bits reference]
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ template<class MpInt = mp_int<> >
+ struct uniform_mp_int_bits
+ {
+ typedef MpInt input_type;
+ typedef MpInt result_type;
+
+ static const bool has_fixed_range = false;
+
+ uniform_mp_int_bits(typename MpInt::size_type bits);
+
+ result_type min() const;
+ result_type max() const;
+
+ void reset();
+
+ template<class UniformRandomNumberGenerator>
+ result_type operator()(UniformRandomNumberGenerator& urng);
+ };
+
+
+[h3 Members]
+
+ uniform_mp_int_bits(typename MpInt::size_type x);
+
+* [*Effects:] Constructs a `uniform_mp_int_bits` object. All numbers generated
+by this object will be `x` bits in size.
+
+
+ result_type min() const;
+
+* [*Returns:] The least value of the distribution.
+
+
+ result_type max() const;
+
+* [*Returns:] The greatest value of the distribution.
+
+
+ void reset();
+
+* [*Effects:] Resets the state of the distribution function.
+
+
+ template<class UniformRandomNumberGenerator>
+ result_type operator()(UniformRandomNumberGenerator& urng);
+
+* [*Returns:] A uniform random number `x` in the range `min <= x <= max`.
+
+
+[endsect][/uniform_mp_int_bits reference]

Added: sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/doc/uniform_mp_int_reference.qbk 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,61 @@
+[/ Copyright Kevin Sopp 2008.
+ / Distributed under the Boost Software License, Version 1.0.
+ / (See accompanying file LICENSE_1_0.txt or copy at
+ / http://www.boost.org/LICENSE_1_0.txt)]
+
+[section uniform_mp_int reference]
+
+[heading Synopsis]
+
+ // <boost/mp_math/mp_int.hpp>
+ template<class MpInt = mp_int<> >
+ struct uniform_mp_int
+ {
+ typedef MpInt input_type;
+ typedef MpInt result_type;
+
+ static const bool has_fixed_range = false;
+
+ uniform_mp_int(const MpInt& min, const MpInt& max);
+
+ result_type min() const;
+ result_type max() const;
+
+ void reset();
+
+ template<class UniformRandomNumberGenerator>
+ result_type operator()(UniformRandomNumberGenerator& urng);
+ };
+
+
+[h3 Members]
+
+ uniform_mp_int(const MpInt& min, const MpInt& max);
+
+* [*Requires: ] `min <= max`
+* [*Effects:] Constructs a `uniform_mp_int` object. `min` and `max` are the
+parameters of the distribution.
+
+
+ result_type min() const;
+
+* [*Returns:] The `min` parameter of the distribution.
+
+
+ result_type max() const;
+
+* [*Returns:] The `max` parameter of the distribution.
+
+
+ void reset();
+
+* [*Effects:] Resets the state of the distribution function.
+
+
+ template<class UniformRandomNumberGenerator>
+ result_type operator()(UniformRandomNumberGenerator& urng);
+
+* [*Returns:] A uniform random number `x` in the range `min <= x <= max`.
+
+
+[endsect][/uniform_mp_int reference]

Added: sandbox/mp_math/libs/mp_math/index.html
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/index.html 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <title>Boost.Mp_math Documentation</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+ <meta http-equiv="refresh" content="0; URL=doc/index.html" />
+</head>
+
+<body>
+ Automatic redirection failed, please go to <a href=
+ "doc/html/index.html">doc/html/index.html</a>
+</body>
+</html>
+

Added: sandbox/mp_math/libs/mp_math/test/add.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/add.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,217 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("123456");
+ mp_int_type y("987777");
+ mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "1111233");
+ x = 999U;
+ y = 123456U;
+ z = x + y;
+ BOOST_CHECK_EQUAL(z, "124455");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("21474836470");
+ const mp_int_type y("1234567845600");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "1256042682070");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xffffffffffffffff");
+ const mp_int_type y("0xffffffffffffffff");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "0x1fffffffffffffffe");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xffffffffffffffff");
+ const mp_int_type y("0xffffffff");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "0x100000000fffffffe");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456");
+ const mp_int_type y("-987777");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "-1111233");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456");
+ const mp_int_type y("987777");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "864321");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456");
+ const mp_int_type y("-987777");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "-864321");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456");
+ const mp_int_type y("123456");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456");
+ const mp_int_type y("-123456");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1000");
+ const mp_int_type y("-12345678901000");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "-12345678900000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers6, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-12345678901000");
+ const mp_int_type y("1000");
+ const mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "-12345678900000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_small, mp_int_type, mp_int_types)
+{
+ mp_int_type x("123456789");
+ mp_int_type y("123");
+ mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "123456912");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_small_and_large, mp_int_type, mp_int_types)
+{
+ mp_int_type x("123");
+ mp_int_type y("123456789");
+ mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z, "123456912");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_large, mp_int_type, mp_int_types)
+{
+ mp_int_type x(
+ "76563204409879018101322737668344063995824904757312285775560614771886933079"
+ "77822556905976720912850551355328340715074887289899094852653102687850101285"
+ "85715275531977696497398396067715769512450915961775500023723324150851793075"
+ "51871751151095323159497918186624088118225730504044262785072662119470825604"
+ "40835072257208973943520251201155002832786969323087571220195329601804141972"
+ "71293425859967733061169954398382700046379970842289727254846347411792122453"
+ "98890529530611217475343335863666953662801553948341581412563112340543629531"
+ "01094529771464590172847457807673685591148055046712881378811934516545088775"
+ "38198087116656466935095055228728162461388333618793883566996616940381738437"
+ "03453867953392241443573580380271627517797446062394044787118140775664622031"
+ "49144609407766890328547643707523663509662747376486271392344480900673178645"
+ "33198519112197059826509662943577383543858946941049753393431035706592040680"
+ "43848484065292542884106550381079282660840705126574766636237650938379223350"
+ "073087806800887586256085275775217219429527000017403144");
+
+ mp_int_type y(
+ "29156720459736055974643337783563754269574952607968485689453462316428566668"
+ "95504701770860331979649536167161534866285341319360225416010322271645564229"
+ "97610536562445338176729838019564690253931232562709745122032537539983616770"
+ "01864876491464203683664927984801289460556480278145114367860332493722569194"
+ "34026051618152579992400234314328079213866348120156368725488604236521299603"
+ "05243915357553896356662519397274629471920043679673543282319268893065423613"
+ "03777840501083119668898860689222271939900089123195611475211708096094521743"
+ "23436842195705603262202927396682954198215622617086455718070601797199587530"
+ "86110222151397352239086193648500251298495752840008363650931395221675337916"
+ "21665907282124706187656074325458499695895652068822763794228458103499408841"
+ "68233732651102406546734395563663969020820490032431359396293047454261598159"
+ "68165818673838448637209074584819780088546111644065538550490486693301185614"
+ "61602638472505490238203390055056474763248195271964604045005807592301719483"
+ "66411676459481184297663915491569500245585996483678005964410842919747216111"
+ "69086269285356198998091850661544255466466926579668887000118948737207396398"
+ "39189399212362197497646493143022100680619252808094160907526003969639965485"
+ "31238493375062268758735445211914107215235958346264702774326161208396163240"
+ "36339482493382189215697343908873498104516190541170342091008828518924813674"
+ "46253090923280613514725437269574928515018666111820866090440006060807129643"
+ "38626199608899966829344884873038261232122027815715568990196536130996880104"
+ "97887027262726591236620461428328000537452828616386217063092509908555188454"
+ "27278763741671312528892659532960085933913140197210561287118971031419725940"
+ "702202830556069344716729071140147820999566475298895832");
+ mp_int_type z = x + y;
+ BOOST_CHECK_EQUAL(z,
+ "29156720459736055974643337783563754269574952607968485689453462316428566668"
+ "95504701770860331979649536167161534866285341319360225416010322271645564229"
+ "97610536562445338176729838019564690253931232562709745122032537539983616770"
+ "01864876491464203683664927984801289460556480278145114367860332493722569194"
+ "34026051618152579992400234314328079213866348120156368725488604236521299603"
+ "05243915357553896356662519397274629471920043679673543282319268893065423613"
+ "03777840501083119668898860689222271939900089123195611475211708096094521743"
+ "23436842195705603262202927396682954198215622617086455718070601797199587530"
+ "86110222151397352239086193648500251298495752840008363650931395221675337916"
+ "98229111692003724288978811993802563691720556826135049569789072875386341921"
+ "46056289557079127459584946918992309735895377322330454248946150142111699445"
+ "53881094205816145134607470652535549600997027605841038574213810844152978690"
+ "13474389623600813397701308241680562881473925776008866830078469711772545088"
+ "07246748716690158241184166692724503078372965806765577184606172521551358084"
+ "40379695145323932059261805059926955512846897421958614254965296148999518852"
+ "38079928742973414972989829006689054343420806756435742320089116310183595016"
+ "32333023146526858931582903019587792806384013392977584153138095724941252015"
+ "74537569610038656150792399137601660565904524159964225658005445459306552111"
+ "49706958876672854958299017649846556032816112174214910877558146836471751674"
+ "87770809016666857157892528580561924741784775192201840382541017031670058750"
+ "31085546374923651063130124371905384081311775557435970456523545615147229134"
+ "71127247806963855412999209914039368594753845323785327923356621969798949290"
+ "775290637356956930972814346915365040429093475316298976");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("0");
+ for (int i = 0; i < 10; ++i)
+ ++x;
+ BOOST_CHECK_EQUAL(x, "10");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("-4");
+ for (int i = 0; i < 10; ++i)
+ ++x;
+ BOOST_CHECK_EQUAL(x, "6");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment3, mp_int_type, mp_int_types)
+{
+ mp_int_type x("-130");
+ for (int i = 0; i < 10; ++i)
+ ++x;
+ BOOST_CHECK_EQUAL(x, "-120");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment4, mp_int_type, mp_int_types)
+{
+ mp_int_type x("120");
+ for (int i = 0; i < 10; ++i)
+ ++x;
+ BOOST_CHECK_EQUAL(x, "130");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,56 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000f");
+ const mp_int_type y("0xffffffffffff");
+ const mp_int_type z = x & y;
+ BOOST_CHECK_EQUAL(z, x);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000ffffffffff");
+ const mp_int_type y( "0xffffffffffff");
+ const mp_int_type z = x & y;
+ BOOST_CHECK_EQUAL(z, "0xffffffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000f");
+ const mp_int_type y("0xffffffffffff");
+ const mp_int_type z = x | y;
+ BOOST_CHECK_EQUAL(z, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000ffffffffff");
+ const mp_int_type y( "0xaaffffffffff");
+ const mp_int_type z = x | y;
+ BOOST_CHECK_EQUAL(z, "0x00ff00000aaffffffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000f");
+ const mp_int_type y("0xffffffffffff");
+ const mp_int_type z = x ^ y;
+ BOOST_CHECK_EQUAL(z, "0xff00fffffff0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x00ff0000000ffffffffff");
+ const mp_int_type y( "0x33aaffffffff");
+ const mp_int_type z = x ^ y;
+ BOOST_CHECK_EQUAL(z,"0x00ff00000335500000000");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,40 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1");
+ const mp_int_type y("0");
+ BOOST_CHECK_EQUAL(x, true);
+ BOOST_CHECK_EQUAL(y, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_or, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1");
+ const mp_int_type y("0");
+ const bool z = x || y;
+ BOOST_CHECK_EQUAL(z, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1");
+ const mp_int_type y("0");
+ const bool z = x && y;
+ BOOST_CHECK_EQUAL(z, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1");
+ const mp_int_type y("1");
+ const bool z = x && y;
+ BOOST_CHECK_EQUAL(z, true);
+}
+

Added: sandbox/mp_math/libs/mp_math/test/cmp.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/cmp.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,152 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1");
+ const mp_int_type y("-1");
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("12");
+ const mp_int_type y("13");
+ BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1");
+ const mp_int_type y("123456789");
+ BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1");
+ const mp_int_type y("0");
+ BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123");
+ const mp_int_type y("-10");
+ BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456789");
+ const mp_int_type y("123456798");
+ BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type y("0");
+ BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1");
+ const mp_int_type y("0");
+ BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456789");
+ const mp_int_type y("-123456789");
+ BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("11");
+ const mp_int_type y("49941");
+ BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ BOOST_CHECK_EQUAL(x, 0);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("20");
+ BOOST_CHECK_EQUAL(x, 20U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("300");
+ BOOST_CHECK_EQUAL(x, 300);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1");
+ BOOST_CHECK_EQUAL(x, -1);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-32101");
+ BOOST_CHECK_EQUAL(x, -32101);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456789");
+ BOOST_CHECK_LT(x, 123456790);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_unsigned_integral_type, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456789");
+ BOOST_CHECK_LT(x, 123456790U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ BOOST_CHECK_LE(x, 123456789);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("32101");
+ BOOST_CHECK_LE(x, 32102);
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_unsigned_integral_type, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ BOOST_CHECK_LE(x, 32101U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_lt_mp_int, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("32101");
+ BOOST_CHECK_LT(32100, x);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_le_mp_int, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("32101");
+ BOOST_CHECK_LE(x, 32102);
+}
+
+

Added: sandbox/mp_math/libs/mp_math/test/compile_all.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/compile_all.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,96 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Compile all functions in the presence of the cmath header
+
+#include <cmath>
+#include <boost/mp_math/mp_int.hpp>
+
+
+// first explicitly instantiate the class template
+template class boost::mp_math::mp_int<>;
+
+
+
+// a different allocator type used in conjunction with the basic_string class
+// template
+template<typename T>
+struct my_alloc : std::allocator<T>
+{
+ template<typename U> struct rebind { typedef my_alloc<U> other; };
+};
+
+typedef std::basic_string<
+ char, std::char_traits<char>, my_alloc<char> > my_string;
+
+
+
+template<class MpInt>
+MpInt compile_constructors()
+{
+ const std::string a("0x123456789abcdefABCDEF");
+ const std::wstring b(L"012345676543210");
+ const my_string c("0xabcdefabcdef0001");
+
+ // constructors from string
+ MpInt u("0x123456789abcdef");
+ MpInt v(L"0x123456789abcdef");
+ MpInt w(a);
+ MpInt x(a.begin(), a.end());
+ MpInt y(b);
+ MpInt z(c);
+
+ const signed char sc = -100;
+ const unsigned char uc = 200;
+ const int i = -12000;
+ const unsigned int ui = 22000;
+
+ // constructors from integral type
+ MpInt m(sc);
+ MpInt n(uc);
+ MpInt o(i);
+ MpInt p(ui);
+
+ // copy constructor
+ MpInt copy(z);
+
+ return u + v + w + x + y + z + copy + m + n + o + p;
+}
+
+template<class MpInt>
+MpInt compile_assignment_ops()
+{
+ MpInt a = "0xfffffffffffffffffff";
+ MpInt b = "0xabcd";
+ MpInt c = 1000;
+ MpInt d = "07777777777777777777000001";
+
+ a = b;
+ b = d;
+
+ const my_string s("0xa123b566c78e9aafdf");
+ c = s;
+
+ d.assign("-12345678901234", std::ios_base::dec);
+
+ return a + b + c + d;
+}
+
+
+int main(int, char**)
+{
+
+ typedef boost::mp_math::mp_int<> mp_int_type;
+
+ mp_int_type a("0");
+
+ a += compile_constructors<mp_int_type>();
+ a += compile_assignment_ops<mp_int_type>();
+ a = boost::mp_math::pow(a, 3);
+ a = boost::mp_math::abs(a);
+
+ return 0;
+}
+

Added: sandbox/mp_math/libs/mp_math/test/ctors.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/ctors.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,188 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, mp_int_type, mp_int_types)
+{
+ const mp_int_type a;
+ BOOST_CHECK_EQUAL(a.size(), 0U);
+ BOOST_CHECK_EQUAL(a.is_positive(), true);
+ BOOST_CHECK_EQUAL(a.is_negative(), false);
+ BOOST_CHECK_EQUAL(a, "");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("12");
+ BOOST_CHECK_EQUAL(y, "12");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456789");
+ BOOST_CHECK_EQUAL(x, "123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1000000000");
+ BOOST_CHECK_EQUAL(x, "1000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string4, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("0");
+ BOOST_CHECK_EQUAL(y.is_zero(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_positive_decimal_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type z("+1");
+ BOOST_CHECK_EQUAL(z, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type z("-1");
+ BOOST_CHECK_EQUAL(z, "-1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string2, mp_int_type, mp_int_types)
+{
+ const mp_int_type z("-888888");
+ BOOST_CHECK_EQUAL(z, "-888888");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("012");
+ BOOST_CHECK_EQUAL(y, "10");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string2, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(y.is_zero(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0123456777");
+ BOOST_CHECK_EQUAL(x, "21913087");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string4, mp_int_type, mp_int_types)
+{
+ const mp_int_type z("-0777777");
+ BOOST_CHECK_EQUAL(z, "-262143");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("0xF");
+ BOOST_CHECK_EQUAL(y, "15");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string2, mp_int_type, mp_int_types)
+{
+ const mp_int_type y("0xa0");
+ BOOST_CHECK_EQUAL(y, "160");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x123456789abcdef");
+ BOOST_CHECK_EQUAL(x, "0x123456789abcdef");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-0x8F888b");
+ BOOST_CHECK_EQUAL(x, "-0x8F888b");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xA0000000");
+ BOOST_CHECK_EQUAL(x, "2684354560");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_long_string, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
+ BOOST_CHECK_EQUAL(x, "87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_iterators1, mp_int_type, mp_int_types)
+{
+ const std::string s("123456789");
+ const mp_int_type z(s.begin(), s.end());
+ BOOST_CHECK_EQUAL(z, "123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x(9999999U);
+ BOOST_CHECK_EQUAL(x, "9999999");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x(123456U);
+ BOOST_CHECK_EQUAL(x, "123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_signed_char, mp_int_type, mp_int_types)
+{
+ signed char c = -14;
+ const mp_int_type x(c);
+ BOOST_CHECK_EQUAL(x, "-14");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_unsigned_char, mp_int_type, mp_int_types)
+{
+ unsigned char c = 42;
+ const mp_int_type x(c);
+ BOOST_CHECK_EQUAL(x, "42");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_short_int, mp_int_type, mp_int_types)
+{
+ short int c = -14789;
+ const mp_int_type x(c);
+ BOOST_CHECK_EQUAL(x, "-14789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_int, mp_int_type, mp_int_types)
+{
+ int c = -9999;
+ const mp_int_type x(c);
+ BOOST_CHECK_EQUAL(x, "-9999");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_long_int, mp_int_type, mp_int_types)
+{
+ const long int c = -100000000;
+ const mp_int_type x(c);
+ BOOST_CHECK_EQUAL(x, "-100000000");
+}
+
+#ifndef BOOST_NO_CWCHAR
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wchar_t, mp_int_type, mp_int_types)
+{
+ const mp_int_type x(L"0xA0000000");
+ BOOST_CHECK_EQUAL(x, "2684354560");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wstring, mp_int_type, mp_int_types)
+{
+ const std::wstring s(L"0xA0000000");
+ const mp_int_type x(s);
+ BOOST_CHECK_EQUAL(x, "2684354560");
+}
+#endif

Added: sandbox/mp_math/libs/mp_math/test/div.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/div.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,96 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type y("123456");
+ const mp_int_type z = x / y;
+ BOOST_CHECK_EQUAL(z, "8");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type y("-123456");
+ const mp_int_type z = x / y;
+ BOOST_CHECK_EQUAL(z, "-8");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("263825472");
+ const mp_int_type y("123456");
+ const mp_int_type z = x / y;
+ BOOST_CHECK_EQUAL(z, "2137");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("263825472");
+ x.divide_by_2();
+ BOOST_CHECK_EQUAL(x, "131912736");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(shift_right1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("263825472");
+ x >>= 3;
+ BOOST_CHECK_EQUAL(x, "32978184");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type y("123456");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987777");
+ const mp_int_type y("123456");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "-129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type y("-123456");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987777");
+ const mp_int_type y("-123456");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "-129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456");
+ const mp_int_type y("123456");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod6, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type y("5");
+ const mp_int_type z = x % y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+
+

Added: sandbox/mp_math/libs/mp_math/test/gcd.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/gcd.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,32 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("10");
+ const mp_int_type y("2");
+ const mp_int_type z = boost::mp_math::gcd(x,y);
+ BOOST_CHECK_EQUAL(z, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("456489798");
+ const mp_int_type y("987");
+ const mp_int_type z = boost::mp_math::gcd(x,y);
+ BOOST_CHECK_EQUAL(z, "3");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-16384");
+ const mp_int_type y("16384");
+ const mp_int_type z = boost::mp_math::gcd(x,y);
+ BOOST_CHECK_EQUAL(z, "16384");
+}

Added: sandbox/mp_math/libs/mp_math/test/integral_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/integral_ops.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,257 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_min, mp_int_type, mp_int_types)
+{
+ const signed char x = std::numeric_limits<signed char>::min();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_max, mp_int_type, mp_int_types)
+{
+ const signed char x = std::numeric_limits<signed char>::max();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_min, mp_int_type, mp_int_types)
+{
+ const unsigned char x = std::numeric_limits<unsigned char>::min();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_max, mp_int_type, mp_int_types)
+{
+ const unsigned char x = std::numeric_limits<unsigned char>::max();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_min, mp_int_type, mp_int_types)
+{
+ const int x = std::numeric_limits<int>::min();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_max, mp_int_type, mp_int_types)
+{
+ const int x = std::numeric_limits<int>::max();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_min, mp_int_type, mp_int_types)
+{
+ const unsigned int x = std::numeric_limits<unsigned int>::min();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_max, mp_int_type, mp_int_types)
+{
+ const unsigned int x = std::numeric_limits<unsigned int>::max();
+ const mp_int_type y(x);
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x + 1;
+ BOOST_CHECK_EQUAL(z, "987778");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x + (-1);
+ BOOST_CHECK_EQUAL(z, "987776");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_unsigned_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("9999999");
+ const mp_int_type z = x + 1U;
+ BOOST_CHECK_EQUAL(z, "10000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_min, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type z = x + std::numeric_limits<signed char>::min();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_max, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type z = x + std::numeric_limits<signed char>::max();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_min, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type z = x + std::numeric_limits<int>::min();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_max, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const mp_int_type z = x + std::numeric_limits<int>::max();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x - 12345;
+ BOOST_CHECK_EQUAL(z, "975432");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("98000");
+ const mp_int_type z = x - (-1);
+ BOOST_CHECK_EQUAL(z, "98001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("125642682070");
+ const long y = 2147483647;
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "123495198423");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_unsigned_char1, mp_int_type, mp_int_types)
+{
+ const unsigned char y = 14;
+ const mp_int_type x("987777");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "987763");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x * 12345;
+ BOOST_CHECK_EQUAL(z, "12194107065");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x * -12345;
+ BOOST_CHECK_EQUAL(z, "-12194107065");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987777");
+ const mp_int_type z = x * -12345;
+ BOOST_CHECK_EQUAL(z, "12194107065");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_unsigned_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1256");
+ const mp_int_type z = x * 100U;
+ mp_int_type w("125600");
+ BOOST_CHECK_EQUAL(z, "125600");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-9877234234252377");
+ const mp_int_type z = x * 0;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_negative_zero1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-9877234234252377");
+ const mp_int_type z = x * -0;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("786432");
+ const mp_int_type z = x / 12;
+ BOOST_CHECK_EQUAL(z, "65536");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("786432");
+ const mp_int_type z = x % 12;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987777");
+ const mp_int_type z = x % 123456;
+ BOOST_CHECK_EQUAL(z, "-129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987777");
+ const mp_int_type z = x % -123456;
+ BOOST_CHECK_EQUAL(z, "129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987777");
+ const mp_int_type z = x % -123456;
+ BOOST_CHECK_EQUAL(z, "-129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987771");
+ const mp_int_type z = x % 16U;
+ BOOST_CHECK_EQUAL(z, "11");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-987771");
+ const mp_int_type z = x % 16U;
+ BOOST_CHECK_EQUAL(z, "-11");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("786432");
+ const mp_int_type z = x | 1;
+ BOOST_CHECK_EQUAL(z, "786433");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("786432");
+ const mp_int_type z = x | -1;
+ BOOST_CHECK_EQUAL(z, "786433");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_unsigned_integral1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("786432");
+ const mp_int_type z = x | 1U;
+ BOOST_CHECK_EQUAL(z, "786433");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/jacobi.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/jacobi.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,32 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1236");
+ const mp_int_type y("20003");
+ const int z = boost::mp_math::jacobi(x,y);
+ BOOST_CHECK_EQUAL(z, 1);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("987897");
+ const mp_int_type y("987");
+ const int z = boost::mp_math::jacobi(x,y);
+ BOOST_CHECK_EQUAL(z, 0);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("610");
+ const mp_int_type y("987");
+ const int z = boost::mp_math::jacobi(x,y);
+ BOOST_CHECK_EQUAL(z, -1);
+}

Added: sandbox/mp_math/libs/mp_math/test/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/jamfile.v2 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,44 @@
+# Copyright Kevin Sopp 2008.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+alias boost_test
+: $(BOOST_ROOT)/libs/test/build//boost_unit_test_framework/<link>shared ;
+
+alias boost_serialization
+: $(BOOST_ROOT)/libs/serialization/build//boost_serialization/<link>shared ;
+
+project
+ : requirements
+ <include>../../..
+ <link>static
+ <define>BOOST_TEST_DYN_LINK
+ <define>BOOST_TEST_MAIN
+ #<define>BOOST_MP_MATH_MP_INT_USE_ASM
+ ;
+
+unit-test add : add.cpp boost_test ;
+unit-test bitwise_ops : bitwise_ops.cpp boost_test ;
+unit-test bool_conversion : bool_conversion.cpp boost_test ;
+unit-test cmp : cmp.cpp boost_test ;
+unit-test ctors : ctors.cpp boost_test ;
+unit-test div : div.cpp boost_test ;
+unit-test gcd : gcd.cpp boost_test ;
+unit-test integral_ops : integral_ops.cpp boost_test ;
+unit-test jacobi : jacobi.cpp boost_test ;
+unit-test mul : mul.cpp boost_test ;
+unit-test pow : pow.cpp boost_test ;
+unit-test prime : prime.cpp boost_test ;
+unit-test random : random.cpp boost_test ;
+unit-test root : root.cpp boost_test ;
+unit-test serialization : serialization.cpp boost_test boost_serialization ;
+unit-test shift : shift.cpp boost_test ;
+unit-test sqr : sqr.cpp boost_test ;
+unit-test sub : sub.cpp boost_test ;
+unit-test stream_io : stream_io.cpp boost_test ;
+unit-test string_ops : string_ops.cpp boost_test ;
+unit-test to_integral : to_integral.cpp boost_test ;
+unit-test traits : traits.cpp boost_test ;
+#unit-test compile_all : compile_all.cpp boost_test ;
+

Added: sandbox/mp_math/libs/mp_math/test/mul.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/mul.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,368 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("12");
+ const mp_int_type y("22459455");
+ const mp_int_type z = x * y;
+ BOOST_CHECK_EQUAL(z, "269513460");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("280708");
+ const mp_int_type y("2245945");
+ const mp_int_type z = x * y;
+ BOOST_CHECK_EQUAL(z, "630454729060");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("65536");
+ const mp_int_type y("65536");
+ const mp_int_type z = x * y;
+ BOOST_CHECK_EQUAL(z, "4294967296");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1234567890123456789");
+ const mp_int_type y("9877771234567890123");
+ const mp_int_type z = x * y;
+ BOOST_CHECK_EQUAL(z, "12194779192182653090000267987090395047");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("789456120556882111687894651457623561325656871513");
+ const mp_int_type y("54564563128978513215");
+ const mp_int_type z = x * y;
+ BOOST_CHECK_EQUAL(z, "43076328327684465744675616648356768900793087398990591539995027544295");
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul6, mp_int_type, mp_int_types)
+{
+ // this tests karatsuba multiplication for 8, 16 and 32 bit digit_type
+ const mp_int_type x(
+ "87500402519005030061267904448809305029512439942506161234260852587645856336"
+ "94640987107484273728362553552515383304557585868121651546490330517814007487"
+ "34682745159208158750835203309620570274592666481348052963762094268695162425"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "59441070673981642057711662497893572913873133654626566743289483229067287310"
+ "16863866837882738076436342057320810154710294295605465397209378421688020320"
+ "35702406032061642794728883255642074744145228324022219347019013411158803532"
+ "45994041206565648683544493690427219798945006072652042753387791345064784511"
+ "50227920502852884378111055250850357557404795594025600468996407045934090727"
+ "08041078777870387730504");
+ const mp_int_type y(
+ "87500402519005030061267904448809305029512439942506161234260852587645856336"
+ "94640987107484273728362553552515383304557585868121651546490330517814007487"
+ "34682745159208158750835203309620570274592666481348052963762094268695162425"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "59441070673981642057711662497893572913873133654626566743289483229067287310"
+ "16863866837882738076436342057320810154710294295605465397209378421688020320"
+ "35702406032061642794728883255642074744145228324022219347019013411158803532"
+ "45994041206565648683544493690427219798945006072652042753387791345064784511"
+ "50227920502852884378111055250850357557404795594025600468996407045934090727"
+ "08041078777870387730504938308922524767076619493071600607096868205642593777"
+ "83064672064693123083586511497969514956199763260628691421422356349215807298"
+ "53893432372651287096347803705731068491268031212879821570628466049198139563"
+ "07225373203247341492567070512742515269237115281940442618925655326204507165"
+ "43018685973456180521304052296263372550548657267007681462726186588489921154"
+ "03738735312309811855295260282588410141887442245474311543699839300870263148"
+ "89969642893224272388306131900850182843780525186002406202200057400419364041"
+ "12480917884571681605871307558328122948240801747503773233227317344565943160"
+ "78184811118761000119446172201197213166958413376441353073591860771242469526"
+ "34162171790217465073689788174652534961638870987430329380376975097234424950"
+ "28626203467171261194438985008578074151902043501430333019202385199270557942"
+ "82069487032265791643884311563532673152911052140807076806223793474752085674"
+ "51690168224265201474031350018449280412602665727006489664736651532321662145"
+ "22395731894311806382965185156526606660906262290677223798531105431808835740"
+ "80068277468617762211054331907328141344243411630209274782352265433366236954"
+ "62340796945506470082986574244652633468578747126384423018749343237426427830"
+ "62597495610006322516869046617226177792891514414040880511098169575819779926"
+ "53267511946096311413217967853431922008343789549408902117132966444741997352"
+ "58418657379544687590177580275674377304583931111620683151992749560156615440"
+ "09956001573216294273550652829235006290995819615078227235050765818475452342"
+ "95118077784320900839083926375344280915278665450149678774001364483022411118"
+ "86989210613864536835695555040115554865868694788922281253334356037168116291"
+ "99227045413249316876243936449829162763370534672670641521910718921661373160"
+ "93948899172794003245737017747952580428164207428777214495975431645589773283"
+ "12391742034637254884903040666536846003583703264118132242307521988982264762"
+ "13953490712153270721924306359669195669881431604926261623147833800912453474"
+ "06542388952383807976431616628717886593805647129190060659586374949333503420"
+ "5241703455510726935");
+
+ const mp_int_type z = x * y;
+
+ const mp_int_type w(
+ "76563204409879018101322737668344063995824904757312285775560614771886933079"
+ "77822556905976720912850551355328340715074887289899094852653102687850101285"
+ "85715275531977696497398396067715769512450915961775500023723324150851793075"
+ "51871751151095323159497918186624088118225730504044262785072662119470825604"
+ "40835072257208973943520251201155002832786969323087571220195329601804141972"
+ "71293425859967733061169954398382700046379970842289727254846347411792122453"
+ "98890529530611217475343335863666953662801553948341581412563112340543629531"
+ "01094529771464590172847457807673685591148055046712881378811934516545088775"
+ "38198087116656466935095055228728162461388333618793883566996616940381738437"
+ "03453867953392241443573580380271627517797446062394044787118140775664622031"
+ "49144609407766890328547643707523663509662747376486271392344480900673178645"
+ "33198519112197059826509662943577383543858946941049753393431035706592040680"
+ "43848484065292542884106550381079282660840705126574766636237650938379223350"
+ "07308780680088758625608527577521721942952700001740314426688555136034651920"
+ "92948869415921251533176579828351648585255631612516166131530519177426817087"
+ "53127165191235539369253485175856164884318259457319518574027800748530624722"
+ "30999853784133144744590149844870058500033133557974954747400058296439058233"
+ "59080109028703731380219724583279605028258137468666258706566102379192203551"
+ "90274426910716106736469216457355540125186992654301008720830993368763363204"
+ "11036960264301276622450044075944548104639523605502445335712149154791061273"
+ "09156720459736055974643337783563754269574952607968485689453462316428566668"
+ "95504701770860331979649536167161534866285341319360225416010322271645564229"
+ "97610536562445338176729838019564690253931232562709745122032537539983616770"
+ "01864876491464203683664927984801289460556480278145114367860332493722569194"
+ "34026051618152579992400234314328079213866348120156368725488604236521299603"
+ "05243915357553896356662519397274629471920043679673543282319268893065423613"
+ "03777840501083119668898860689222271939900089123195611475211708096094521743"
+ "23436842195705603262202927396682954198215622617086455718070601797199587530"
+ "86110222151397352239086193648500251298495752840008363650931395221675337916"
+ "21665907282124706187656074325458499695895652068822763794228458103499408841"
+ "68233732651102406546734395563663969020820490032431359396293047454261598159"
+ "68165818673838448637209074584819780088546111644065538550490486693301185614"
+ "61602638472505490238203390055056474763248195271964604045005807592301719483"
+ "66411676459481184297663915491569500245585996483678005964410842919747216111"
+ "69086269285356198998091850661544255466466926579668887000118948737207396398"
+ "39189399212362197497646493143022100680619252808094160907526003969639965485"
+ "31238493375062268758735445211914107215235958346264702774326161208396163240"
+ "36339482493382189215697343908873498104516190541170342091008828518924813674"
+ "46253090923280613514725437269574928515018666111820866090440006060807129643"
+ "38626199608899966829344884873038261232122027815715568990196536130996880104"
+ "97887027262726591236620461428328000537452828616386217063092509908555188454"
+ "27278763741671312528892659532960085933913140197210561287118971031419725940"
+ "70220283055606934471672907114014782099956647529889583250740029484462218658"
+ "62960901244568848989478467720707250809806379509214397878558772543587967635"
+ "96161034019645060913914198361071023036142203589230741296078930717247341831"
+ "26204308310630181474853421564903407641109879794777661716811159608177803322"
+ "61170286373919980640839261570604290919653466216587527613203517128403418424"
+ "791614399508711582164287714644181913925240");
+
+ BOOST_CHECK_EQUAL(z, w);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul7, mp_int_type, mp_int_types)
+{
+ // this tests toom cook multiplication for 8, 16 and 32 bit digit_type
+ const mp_int_type x(
+ "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
+ "34682745159208158750835203309620570274592666481348052963762094268695162425"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
+ "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "59441070673981642057711662497893572913873133654626566743289483229067287310"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "16863866837882738076436342057320810154710294295605465397209378421688020320"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
+ const mp_int_type y(
+ "0x875aa402519005030061267904ccc8809d0502243994250616123426085258764585633a"
+ "94640987107484273728362553552515383304557585868121651546490330517814007487"
+ "34682745159208158750835203309620570274592666481348052963762094268695162425"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "59441070673981642057711662497893572913873133654626566743289483229067287310"
+ "16863866837882738076436342057320810154710294295605465397209378421688020320"
+ "357024060320616427947288832ff6420747dd145228324022219347019013411158803532"
+ "45994041206565648683544493690427219798945006072652042753387791345064784511"
+ "50227920502852884378111055250850357557404795594025600468996407045934090727"
+ "08041078777870387730504938308922524767076619493071600607096868205642593777"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "83064672064693123083586511497969514956199763260628691421422356349215807298"
+ "53893432372651287096347803705731068491268031212879821570628466049198139563"
+ "07225373203247341492562497b8b93568861230addd281940442618925655326204507165"
+ "43018685973456180521304052296263372550548657267007681462726186588489921154"
+ "03738735312309811855295260282588410141887442245474311543699839300870263148"
+ "cdd69642893224272388306131f0a850182843780525186002406202200057400419364041"
+ "12480917884571681605871307558328122948240801747503773233227317344565943160"
+ "78184811118761000119446172201197213166958413376441353073591860771242469526"
+ "34162171790217465073689788174652534961638870987430329380376975097234424950"
+ "286262034671712611944389850085780a4151902043501430333019202385199270557942"
+ "82069487032265791643884311563532673152911052140807076806223793474752085674"
+ "51690168224265201474031350018449280412602665727006489664736651532321662145"
+ "22395731894311806382965185156526606660906262290677223798531105431808835740"
+ "80068277468617762211054331907328141344243411630209274782352265433366236954"
+ "62340796945506470082986574244652633468578747126384423018749343237426427830"
+ "62597495610006322516869046617226177792891514414040880511098169575819779926"
+ "53267511946096311413217967853431922008343789549408902117132966444741997352"
+ "5841865737954468759a177580275674377304583931111620683151992749560156615440"
+ "09956001573216294273550652829235006290995819615078227235050765818475452342"
+ "95118077784320900839083926375344280915278665450149678774001364483022411118"
+ "86989210613864536835695555040115554865868694788922281253334356037168116291"
+ "99227045413249316876243936449829162763370534672670641521910718921661373160"
+ "93948899172794003245737017747952580428164207428777214495975431645589773283"
+ "12391742034637254884903040666536846003583703264118132242307521988982264762"
+ "13953490712153270721924306359669195669881431604926261623147833800912453474"
+ "06542388952383807976431616628717886593805647129190060659586374949333503420"
+ "ffab023789d7d78f78a45a45fee789001a1a");
+
+ const mp_int_type z = x * y;
+
+ const mp_int_type w(
+ "0x2a4ec67dcaf1afdd14bf63d7cd883f269ca00be2cae5c539545352050e33af7bb008713c"
+ "63587bc02911b0cb1fb807d94cd4a937f6e19801a28500f45ba1dc90a548e8e15e0c31536b"
+ "39f3940191a76b6fd96fda83c7aa9aa675f536633917587fbdb4990f73dc4650e19af67392"
+ "712b0a94aeec78f21523bd2ae92cee0b5d42ce2ead649060ff8134dbca0790f051b132b8fd"
+ "2f0bbe66f3226f7fe7a80c0be18fcd0238ff0100e4353f4973c1cb72c40e83804192fbd008"
+ "1e3d4dfe03e1d4c8d1ed4ba8ffe7cf5d00237598de949ab89cd6f95cbc3545a4d797e425f9"
+ "041fbe52955af28221505ce3e53cb5bc12d8d9a13f39704463db4db21aaea4fc29643a2746"
+ "2e6d3b40f9eb621106bda6223bf2aaa4f027e037acb45406cd39b242c90df3b4fae1bf788a"
+ "1529dac1ce1b77f4d1557e2aa8a4adf9c6b3b0c364ce68300b5f65efc8166dae1b2e0f8443"
+ "76975b12b72c36f2dfc4a533adca3db43955265d91d15232bcfd712e46dd4cd4f63981317b"
+ "31be8e9fc0a56275da498e8a4c13419eb8560fa05d73373ff238787b77c0b45c0b44b6b042"
+ "365bfb3b3a4d96cdb3ad7cb9b9248498a02b43a16206db5cc3f52c4cdf2c58807a68a6d1b0"
+ "f24bf8daa4eaf6ffdd3e781fd52b5fe609678d045944d7ea6a6689954b82a737b136a86d32"
+ "e8de0c6b88e66300487b83deb53038fc298c2b1d1ffe64ab7ebf0e7682b285bb567c3ad4bc"
+ "69c0e0216f5c8df2681a3e84435b39dbd4a3cd5dcdf0b776bc0b5281f8806155318e70d237"
+ "4267ca699ebdc5df58e282f7a6d2a7401a3544193741e9597df7fb92c7a0c87128b53ae873"
+ "14aacf233fc20cba4ac4835579bd82b6efcadd591dbf826d470795d64bb698202e3fc5bbd3"
+ "9ca2249167520764d448a95c7a7ed00f43d2f36f4158fccacf2f5738878099da8a323e7d2c"
+ "57579da5e348b45aabe59366085532c73c2388b3a2672b08758bdaae3746364b49d0217b27"
+ "5d22b2b4916628afd5009e103803f4ba5241413200d85e119ceb4dc876c1521047a8be7650"
+ "767b0d83fcbf991c6b04a51213692867fe4c9e452b2800fe5fc57df9d8f75cab72609a49af"
+ "92b1e2407b64ea424344a626b2e86eacdf18af6a000af8c5607019df1d670307a65df3e4bf"
+ "51e9809212a3288001e1df69a6070558e24f686ff34b50e7b2daf5f3f7abc7be88fff8fb5d"
+ "f0aab1f952f91eec5c5ff7e25d2babb61db263e7381fbe40ad81b3494c323a35d3333fcadd"
+ "d6b057c88fe2f43ec1bf754de9fdbc768457d7fc44c90c2e44f79c32849f56d7d2152b96d1"
+ "4b7735e8eae29d8e9ccdd61be1f73f7d1d2e16732505448a33145a5b1d5c342f0990a0a731"
+ "a5e034cb3c0f5658e20b8ac7f4e93c249ec9badb93c4e064b59c34b11e4327d0dacb0951ac"
+ "1c13831520a06deee884613bce16fe5b92e1e0776caf6aa1a7aadccad11a741e7c08512816"
+ "e1c4a0f8910c35450a7448c180528decdc54a9af2cf5b5244c03d088be6d8b6978f2e90baa"
+ "3ce9f85456b51768f7b2d2261785f7680e62cdc420d0e62e41aba012a391c250d3579665ec"
+ "06a0e137c8d3da6ec07be1c2f0599dcbd1f6a801a06a062734ec34889edcd57ca99bc35d5b"
+ "9686b7fc073aa06d9d052ae7d762a7dbc5740e73ef730b478acdb54455d4db80e80b03bc61"
+ "aa013ab9c0b9ece6a00e4e46c16068a2771d0c9c42432f4ef1279481886c6cf890d656a8fa"
+ "e248c9c17bedb151ea802c3b8d7918296dc38a71f173c0b6fceb72611bc817429271ff1d1f"
+ "9fc29780727dbab824eb6ff07e552c8a6679c667bbb20925b7920c7307e3f553c64e1f8962"
+ "e556168cef58af8f406f9f6847719addd6083d19e351b2281bb6f8f64789cdab8f29915f71"
+ "128cd2152ba95124b935770dda3231973037cb7c1e8d22ee4bd10331c91d4db53c291cb16c"
+ "f498366646a27bc18df39aeb5790ba6e02c9904b0fe7e6127dd412daaafdc9b1548727eb05"
+ "57e191893e391f038797139cdf054dab4a208b00dbea79313c3952bcaf8384882456dace78"
+ "117550a133acd3cc883c036e2ecb133eaca4f6df4c002589436f529f3975fde6c779ab3038"
+ "85b1decf3f9b625dd31d634e98410486ba3e3dfff5e90da22c1734fbf9b52b92db6b44af70"
+ "da57859ca38220d8a24dca3251f9f65a1abfcbd2386732f3919c88af189efeb31ee6da9deb"
+ "f70e85bbaa928abb1d2ba86d3b038c1eea98c1a36d0e783a79e578cbc3b98d9a9f4a9c0392"
+ "bf51fcb31325c1b9131f762cd31583c231d786190dc92752781192a72ff75c3c8c297706a0"
+ "4d14571575e076dc13c8bf2c3202bb468ef6f20f6ae27ba91a0182af2c73a40477a9e1d23d"
+ "60fc5f57e9f3a86315b11ea7dc922ba70d38a24c18e1552e15239b2a29d6fc7517f5aabdd5"
+ "e0c800178beeac9b582c44af59f7c2cee341813eb13220d4bee3ef07e9ab8d35ccc0f684e9"
+ "902affb65f87cee827e6bd42fbc433df0070dc210d078fdc92fb7f559b577150e28f21f64a"
+ "c0edc61da523858e62cca0c85b8c16b8bd784f7ed8efb96314e75b3b9bd26ea93bdfc45565"
+ "85ea59cda0c92be16321ed27d93b9a05980574fc99dcb079e6145a0b0ab0c4cbebdc0e51af"
+ "2825278224922511ab721f412589b8a160fa95c3bc9038a3af4a330f5e796d30bf60017921"
+ "bc01a0200e87c26a0afedc292ff05a3e9d564323d0e0c738bcbf24f226d9aa59944abc109a"
+ "9916f57dad39fd1c928da18c32184a230be2eef814c47cea0baea02241c34fae2c8d025a02"
+ "0ab4faf8409cbc467333b807af12473f5dc3be988bb9ef61a60ff1672e07de7f5f6bf99583"
+ "f876305337ca3bbc6b2cc1f562d9f4b90cd9e54d85e04b8aa47dcb4dd5efb271f2a1d61922"
+ "cefdabcad5c3565f3f65a3e421e688b53c15a568c368eeed28d546e47dd53afc3944bfce69"
+ "94841555ac1a1968412a5504d68ae69b2067aaf3c8516a993ffb0657f82cfcb4950e6da431"
+ "de09b4a1d104e3190af9518bd2d10921ee2a3cbba8c25e1ef98606121d60cb48dbe91994f6"
+ "afceb6ea5187fdbd6d943b24c6a2584516d014ca5549828b1c5dcb80016f5dbe91667d03c0"
+ "ed9db277261ff9a7fe77886bb1c9c7d3e95e8a4204b984115323b3a8895ae102921e807294"
+ "131b5554246e6004541e11d1e449f017f1590b18c695ab79b098683f4693e0c6d87836feae"
+ "3db0bceca8b11f9b2190b8f61d77fdad0687ce678c31059af3771bc54170fad3171efa5eaa"
+ "39a4dc3d3fa837e868d1cd704de7c1877e4b77cd9fa44d500b74d0a52cf1b9c5ca6f031005"
+ "c6362066e930694a5d8063a2f27c899a78dd4f79f89e47c46e24c454efcb034105824c009f"
+ "9ce5f9b0eb6998ee1a61a2b83ed878ac81e50ffa48f6c5eaf225a56c9cbca51312808c0c51"
+ "7f49f131c12ecb7094f389228b77db2a305a01f69975138aa67dce71b80285fa1f21993189"
+ "b38898d0e2c5e6fddb644101107f610ac20ab744140addc41021fbf68b041b80fa3c1a3851"
+ "65038651ac3a07ef76368658c5a984d28e149981a7ab931e6fa1d87aa8756331927c54443a"
+ "54177cb8617bd8f54aba47a06af8f41f28cc47d71bd153d821c0c45adbad135170cfe68429"
+ "683a0bc06e4e7a06bd060a87fb8309e4f14c31a3732eada80079072e55fc26cb02ac710791"
+ "0a95d32111198ac6c07625c117acf23fefbbff59fb4c84bc6ac1a3fde905cf1d75693caaf7"
+ "7d2728e7c66d6005a236176e85cb3b282fb7a577e5e4c617c23b2af879810b560882c93552"
+ "27ee9670073d5288c4af9e57a0c81c7af0142670dbb0a18a2f79fe3ae3791739e732784600"
+ "fe9a9a4475ad985499e81ce7a06a04368fbdd007ddb2a222a0268c086252e73f18ef9b165a"
+ "c044c5f42af698b80eba1c1b4423c3b8d010d31ea85831fae7bbb74efe9a22283c1e238d09"
+ "6ae5d00ded7ae17744925d316b3d1c92861c58e1e6668dd52f4932c1e891ed5441f29786fd"
+ "d41a78b75730b8cc193ed85ac5a667a86ba4bbc1ad45aeddc56d32e16f410ad06f5cd2e6b8"
+ "2a31feb6585cfe987b8db1dc8dfdd3a4a8b09518f341fac8f8c7aeb8052cec62bf23eab8a1"
+ "b35cab3e3ed3acc3b64e29c1cc4d7cdeaefcd61f06c61b8a48b90a838ee0aac2cc76a2e56f"
+ "d8dda42e2ff863f75132ff39dd4241ac3ac1aa21845a66bdd02b77b4c38dd5ada02e3863e0"
+ "12b5bf5ad2eae7f6b1b85b4fdf960b915c257dc2be810ce92bb82c58bc478994a71332502c"
+ "ea5e5cf5bfc2ba0480d53dd2dec046f718001eba5088463e6598488dbca8cf07024102458c"
+ "abac35a14188323195f0bcc8a4d7b006467ad4ee46e6cc61f91243e311e0a775582ca3be74"
+ "9193f6044b573435eb7185c437ce3abb6b232f7d85d5beb68ebe859b9af9d6216a5c1a236c"
+ "499c661d705e9df96466429370c573b7c02d6b66c9725f39550e9bd8f63b69dd1d91ae3b7d"
+ "daf6e53f36111e43f185b2a19e6969c95441159ab96ba7928d9a8c66a81d8cb2967d90f5b8"
+ "65bf2b0986e7e10275476faf729ff6ff275347c3afb647cfaf80b76a7d51c1530e5e305241"
+ "e46f992416baa5e204ed1ccc29ab615e71ee06a21d29fabf1c114bcb0262a5031bbb8bf5d5"
+ "a4fcf004f0276eb27cb4007eb0cfc99fc515e858170e135707b07b5f0839f602d1f1ce9eb7"
+ "a41e02aea4c95a499f9ade35d8f1de41791d62ee88fac1e74828aa5025efa0444425f58edc"
+ "1158f0c1afa86f9cf062ef973eb852fe203a48a8cc6f9ef89bbd76e5602aa93c3af0cab8e0"
+ "0433b8beaf63024c36d652dfc1065c483ce480e6b36250d8bf4c3e8500ca1ab6457fa02206"
+ "6592d25f38e376a4e9d7b1dec77b378b6daf4a3e33e5aac75ff2a93808b163e738b62d6f32"
+ "c8526d92795fa623217fcb8c4450bd0ed300742327457928fb0ac0d9a1a47c490db6d3eb56"
+ "900e091c8e047e6f618acac52dea702c4ca72acd001f2c056291d71e8e7e49ea13afae0d3f"
+ "66a7d7dd8d6a264ca4be9eb02549bf40e61f1e2e4f01fe4ceafd7855686747eb1b1acd2c96"
+ "92fcedc94");
+
+ BOOST_CHECK_EQUAL(z, w);
+}
+
+

Added: sandbox/mp_math/libs/mp_math/test/pow.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/pow.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,104 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_1, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x.pow2(0);
+ BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_2, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x.pow2(1);
+ BOOST_CHECK_EQUAL(x, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_3, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x.pow2(64);
+ BOOST_CHECK_EQUAL(x, "18446744073709551616");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow_1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("2");
+ x.pow(0);
+ BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow_2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("2");
+ x.pow(1);
+ BOOST_CHECK_EQUAL(x, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow_3, mp_int_type, mp_int_types)
+{
+ mp_int_type x("2");
+ x.pow(64);
+ BOOST_CHECK_EQUAL(x, "18446744073709551616");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("2");
+ const mp_int_type exp("14");
+ const mp_int_type m("8");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("4");
+ const mp_int_type exp("13");
+ const mp_int_type m("497");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "445");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow3, mp_int_type, mp_int_types)
+{
+ mp_int_type x("2395422");
+ const mp_int_type exp("2424832");
+ const mp_int_type m("2424833");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow4, mp_int_type, mp_int_types)
+{
+ mp_int_type x("184");
+ const mp_int_type exp("560");
+ const mp_int_type m("561");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow5, mp_int_type, mp_int_types)
+{
+ mp_int_type x("997028168093060821869770104094480850560519901475");
+ const mp_int_type exp("7455602825647884208337395736200454918783366342656");
+ const mp_int_type m("7455602825647884208337395736200454918783366342657");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow6, mp_int_type, mp_int_types)
+{
+ mp_int_type x("184");
+ const mp_int_type exp("5600");
+ const mp_int_type m("2668");
+ x.modpow(exp, m);
+ BOOST_CHECK_EQUAL(x, "552");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/prerequisite.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/prerequisite.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,39 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/mp_math/mp_int.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/unique.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+//typedef boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t> traits_type;
+//typedef boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t> traits_type;
+//typedef boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t> traits_type;
+//typedef boost::mp_math::mp_int_traits<> traits_type;
+
+//typedef boost::mp_math::mp_int<std::allocator<void>, traits_type> mp_int_type;
+
+
+typedef boost::mpl::vector<
+ boost::mp_math::mp_int<
+ std::allocator<void>,
+ boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t>
+ >,
+ boost::mp_math::mp_int<
+ std::allocator<void>,
+ boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t>
+ >,
+ boost::mp_math::mp_int<
+ std::allocator<void>,
+ boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t>
+ >,
+ boost::mp_math::mp_int<>
+> some_mp_int_types;
+
+typedef boost::mpl::unique<
+ some_mp_int_types, boost::is_same<boost::mpl::_1, boost::mpl::_2>
+>::type mp_int_types;
+
+

Added: sandbox/mp_math/libs/mp_math/test/prime.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/prime.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,243 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/bind.hpp>
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+template<class MpInt>
+struct fixture
+{
+ std::vector<MpInt> primes;
+ std::vector<MpInt> composites;
+ std::vector<MpInt> carmichaels;
+
+ fixture();
+};
+
+template<class MpInt>
+fixture<MpInt>::fixture()
+{
+ // from http://primes.utm.edu/
+ primes.push_back("2424833");
+ primes.push_back("5915587277");
+ primes.push_back("48112959837082048697");
+ primes.push_back("671998030559713968361666935769");
+ primes.push_back("2425967623052370772757633156976982469681");
+ primes.push_back("22953686867719691230002707821868552601124472329079");
+ primes.push_back("31353958997402666638501031970734176101289470405573395248411"
+ "3");
+ primes.push_back("46695238499321305088763925547134075213191172396379432249800"
+ "15676156491");
+ primes.push_back("18532395500947174450709383384936679868383424444311405679463"
+ "280782405796233163977");
+ primes.push_back("28275548353370728705475218432112134576686148069744870344385"
+ "7012153264407439766013042402571");
+ primes.push_back("20747222467734852078216952221076085874809964747211172927529"
+ "92589912196684750549658310084416732550077");
+ primes.push_back("35201546659608842026088328007565866231962578784643756647773"
+ "109869245232364730066609837018108561065242031153677");
+ primes.push_back("49949091806585030192119760356408111278062369027342098434296"
+ "86905940646121085912172293044610060051708652944665271663688"
+ "51");
+ primes.push_back("54522121518442644531155217703627128153004567880738702606371"
+ "72006414987479914150831821202259862091373741738511579629040"
+ "732909194883");
+ primes.push_back("11116154175595527770308362725647119128773382144932530406518"
+ "51655768643786825585565208246254887946100346011818823101363"
+ "6706338524913578946637");
+ primes.push_back("65669205018189751363824155419918192392295592176092883676630"
+ "41617905539892282237934618347035068727470717051679959727072"
+ "53940099469869516422893633357693");
+ primes.push_back("51665668390920744584663348665715976941144605703879863575380"
+ "48450432901440804868689337999823161841839689242893622491638"
+ "917313351308387294478994745350551549126803");
+ primes.push_back("27218343798190233889779431662111815254174074647423987223301"
+ "82099632472829888864333146379225493741435309651830476334589"
+ "6749125106775048493507719412795029690510090142402163");
+ primes.push_back("27834442010031021673804244175247010833232390861821952548705"
+ "37102073847719982865971352904187195267023851783658963402109"
+ "57041552257518693488098683242070746473230980005141419410511"
+ "409");
+ primes.push_back("50774619156173716518115936073898485346139106651602235699024"
+ "04065418076795944656510340577164207672426574638345121648036"
+ "69334456133986869450012704680852639785739151463455742734197"
+ "2391976756821");
+ primes.push_back("58021664585639791181184025950440248398226136069516938232493"
+ "68750582247183653682429882273371034225069773999682593823264"
+ "19406708576245141031259861340509976971601273015479957884681"
+ "37887651823707102007839");
+ primes.push_back("7455602825647884208337395736200454918783366342657");
+
+ // composites with small factors
+ composites.push_back("2530121");
+
+ // composites with large factors
+ // from http://web.mit.edu/kenta/www/three/prime/composites.html.gz
+ /*composites.push_back("241999944999997");
+ composites.push_back("9247999997483999999981");
+ composites.push_back("9247999999996395999999999973");
+ composites.push_back("2738000000000000184999999999998407");
+ composites.push_back("172979999999999999711699999999999999867");
+ composites.push_back("3920000000000000000000000000000071399999999999999999999"
+ "999999994969");
+ composites.push_back("6479999999999999999999999999999999999995877999999999999"
+ "9999999999999999999999947559");
+ composites.push_back("1458000000000000000000000000000000000000000000000000000"
+ "0000000006749999999999999999999999999999999999999999999"
+ "99999999999999998367");
+ composites.push_back("1095200000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000003329999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "99999999999433");
+ composites.push_back("1999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999772999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999960081");
+ composites.push_back("7937999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999960"
+ "7509999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999222"
+ "63");
+ composites.push_back("6727999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999996154599999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "999999999999999999999999999999999999999999447193");
+ composites.push_back("4231999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999977321999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "999999999999999999999999999999999921103");
+ composites.push_back("1729799999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999383409999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "9999999999999999999999999999999999999999999999999999999"
+ "999999610793");*/
+
+ // from http://de.wikibooks.org/wiki/Pseudoprimzahlen:_Tabelle_Carmichael-Zahlen
+ carmichaels.push_back("294409");
+ carmichaels.push_back("825265"); // 5*7*17*19*73
+ carmichaels.push_back("1152271");
+ carmichaels.push_back("23382529");
+ carmichaels.push_back("62756641");
+ carmichaels.push_back("114910489");
+ carmichaels.push_back("1407548341");
+ carmichaels.push_back("11346205609");
+ carmichaels.push_back("173032371289");
+ carmichaels.push_back("2199733160881");
+ carmichaels.push_back("84154807001953");
+ carmichaels.push_back("973694665856161");
+ carmichaels.push_back("9746347772161"); // 7*11*13*17*19*31*37*41*641
+}
+
+
+// primality tests
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_is_divisible1, mp_int_type, mp_int_types)
+{
+ using namespace boost::mp_math;
+
+ fixture<mp_int_type> f;
+ typedef typename std::vector<mp_int_type>::const_iterator iter;
+
+ for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
+ BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), true);
+
+ for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
+ BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), false);
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_fermat_test1, mp_int_type, mp_int_types)
+{
+ using namespace boost;
+
+ mp_math::primality_fermat_test<
+ mp_math::uniform_mp_int<mp_int_type>
+ > fermat_test(1);
+
+ mt19937 rng;
+
+ fixture<mp_int_type> f;
+ typedef typename std::vector<mp_int_type>::const_iterator iter;
+
+ for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
+ BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), true);
+
+ for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
+ BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), false);
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_miller_rabin_test1, mp_int_type, mp_int_types)
+{
+ using namespace boost;
+
+ mp_math::primality_miller_rabin_test<
+ mp_math::uniform_mp_int<mp_int_type>
+ > mr_test;
+
+ mt19937 rng;
+
+ fixture<mp_int_type> f;
+ typedef typename std::vector<mp_int_type>::const_iterator iter;
+ for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
+ BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), true);
+
+ for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
+ BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
+
+ for (iter i = f.carmichaels.begin(); i != f.carmichaels.end(); ++i)
+ BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
+}
+
+
+// prime generation
+template<class Engine, class Distribution>
+struct tester
+{
+ boost::mp_math::primality_division_test test1;
+ boost::mp_math::primality_miller_rabin_test<Distribution> test2;
+ Engine rng;
+
+ explicit tester(const Engine& e) : rng(e) {}
+
+ template<class A, class T>
+ bool operator()(const boost::mp_math::mp_int<A,T>& p)
+ {
+ return test1(p) && test2(rng, p);
+ }
+};
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(generate_safe_prime_128bits, mp_int_type, mp_int_types)
+{
+ typedef tester<boost::mt19937, boost::mp_math::uniform_mp_int<mp_int_type> > tester_type;
+ typedef boost::mp_math::uniform_mp_int_bits<mp_int_type> distribution_type;
+
+ boost::mt19937 rng;
+
+ boost::mp_math::safe_prime_generator<tester_type, distribution_type>
+ generator(128U, tester_type(rng));
+
+ const mp_int_type safe_prime = generator(rng);
+
+ BOOST_CHECK_EQUAL(safe_prime.precision(), 128U);
+}

Added: sandbox/mp_math/libs/mp_math/test/random.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/random.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,79 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int1, mp_int_type, mp_int_types)
+{
+ const mp_int_type min(0), max(128);
+ boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
+ boost::mt19937 e;
+ for (int i = 0; i < 128; ++i)
+ {
+ const mp_int_type x = g(e);
+ BOOST_REQUIRE_GE(x, min);
+ BOOST_REQUIRE_LE(x, max);
+ }
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int2, mp_int_type, mp_int_types)
+{
+ const mp_int_type min(11), max("26546549");
+ boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
+ boost::mt19937 e;
+ for (int i = 0; i < 1000; ++i)
+ {
+ const mp_int_type x = g(e);
+ BOOST_REQUIRE_GE(x, min);
+ BOOST_REQUIRE_LE(x, max);
+ }
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits1, mp_int_type, mp_int_types)
+{
+ BOOST_CHECK_EQUAL(
+ boost::mp_math::uniform_mp_int_bits<mp_int_type>::has_fixed_range, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits2, mp_int_type, mp_int_types)
+{
+ boost::mp_math::uniform_mp_int_bits<mp_int_type> g(512);
+ boost::mt19937 e;
+ const mp_int_type x = g(e);
+ BOOST_CHECK_EQUAL(x.precision(), 512U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits3, mp_int_type, mp_int_types)
+{
+ boost::mp_math::uniform_mp_int_bits<mp_int_type> g(71);
+ boost::mt19937 e;
+ const mp_int_type x = g(e);
+ BOOST_CHECK_EQUAL(x.precision(), 71U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits4, mp_int_type, mp_int_types)
+{
+ boost::mp_math::uniform_mp_int_bits<mp_int_type> g(1001);
+ boost::mt19937 e;
+ const mp_int_type x = g(e);
+ BOOST_CHECK_EQUAL(x.precision(), 1001U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits5, mp_int_type, mp_int_types)
+{
+ boost::mp_math::uniform_mp_int_bits<mp_int_type> g(8);
+ BOOST_CHECK_EQUAL(g.min(), 128U);
+ BOOST_CHECK_EQUAL(g.max(), 255U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits6, mp_int_type, mp_int_types)
+{
+ boost::mp_math::uniform_mp_int_bits<mp_int_type> g(11);
+ BOOST_CHECK_EQUAL(g.min(), 1024U);
+ BOOST_CHECK_EQUAL(g.max(), 2047U);
+}
+
+

Added: sandbox/mp_math/libs/mp_math/test/root.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/root.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,29 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("279841");
+ const mp_int_type y = sqrt(x);
+ BOOST_CHECK_EQUAL(y, "529");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("78310985281");
+ const mp_int_type y = sqrt(x);
+ BOOST_CHECK_EQUAL(y, "279841");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("85766121");
+ const mp_int_type y = nth_root(x, 3);
+ BOOST_CHECK_EQUAL(y, "441");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/serialization.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/serialization.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,27 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <sstream>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_serialization1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("0x123456789abcdef257");
+ mp_int_type y;
+
+ std::stringstream s;
+
+ boost::archive::text_oarchive oa(s);
+ oa << x;
+
+ boost::archive::text_iarchive ia(s);
+ ia >> y;
+
+ BOOST_CHECK_EQUAL(x, y);
+}
+

Added: sandbox/mp_math/libs/mp_math/test/shift.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/shift.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,42 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+ x <<= 2;
+ const mp_int_type y(
+ "986226271566049499158044949826379182595649292855440000031396");
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+ x <<= 99;
+ const mp_int_type y(
+ "156273790638943927367154966864556037925514287264587565911690950563681284"
+ "261029491729498112");
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+ x >>= 17;
+ mp_int_type y(
+ "1881077330715273855510797404911764493171022973738555908");
+ BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("0");
+ x >>= 17;
+ BOOST_CHECK_EQUAL(x, "0");
+}

Added: sandbox/mp_math/libs/mp_math/test/sqr.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/sqr.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,202 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456789");
+ const mp_int_type y = x * x;
+ BOOST_CHECK_EQUAL(y, "15241578750190521");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("25");
+ const mp_int_type y = x * x;
+ BOOST_CHECK_EQUAL(y, "625");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("300");
+ const mp_int_type y = x * x;
+ const mp_int_type z("90000");
+ BOOST_CHECK_EQUAL(y, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("2228218");
+ const mp_int_type y = x * x;
+ BOOST_CHECK_EQUAL(y, "4964955455524");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("999998000001");
+ const mp_int_type y = x * x;
+ const mp_int_type z("999996000005999996000001");
+ BOOST_CHECK_EQUAL(y, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr6, mp_int_type, mp_int_types)
+{
+ // this tests toom squaring and karatsuba squaring for 8, 16 and 32 bit
+ // digit_type
+ const mp_int_type x(
+ "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
+ "34682745159208158750835203309620570274592666481348052963762094268695162425"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
+ "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "18850320172906096781969070339129822281355221058882087466637338881223511228"
+ "63144016884857141834687376804878770495858121023810198067988560350169566260"
+ "59441070673981642057711662497893572913873133654626566743289483229067287310"
+ "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+ "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+ "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+ "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+ "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+ "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+ "16863866837882738076436342057320810154710294295605465397209378421688020320"
+ "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+ "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+ "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+ "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
+
+ const mp_int_type y = x * x;
+
+ const mp_int_type z(
+ "0x1902e5887a586c505ed49b0ef0db72e959da458fbfe7f7f1738b9da657ebc6b4f3eeda8f3"
+ "45f86a9439fb0a314af8a6d54e9002f6b9778bc217f31e1c2af869b890e50b105f2a6c8f6d4"
+ "d9f7ce008697c1ef9f6b1b3d58089517db9a209f0951f3843c9f5dd81da8082a4e79771c9fe"
+ "c7a967defed9c1d7229a9e6a78226389976caba3a3419a68d1376d7b67eb20136d1c47b480f"
+ "446428ec425ddeb779492e6e40c2318633e6783066d046486a419676066b0fcacf9c9da24ef"
+ "bb6ae2a639af668b9c732ed3ba74f4e73f28cffbc415d3a086decd149e1dd1f4265ede8666c"
+ "2963f2ef61b190fb094730110586e73afc7656f6e8e3188767ee075b98cceff2de2959b3c51"
+ "eb0cd03b5d277846536a3d5fa2baaff03d2ff90785581d170ad264d845d6e3522921afae94f"
+ "13eda75f99694a961beff0495830b53f1b282d4fc5fa665a402cc253d71aa411a16c7cf3825"
+ "6ff351d8e7f6c476d01ca3d39947a71703488cc0c85f7ce9ae7521e22ce4cb99e14dcaaaa69"
+ "d8f1390f8c8275c899e8ec14b2fb9100bd8c4e44bc2d531f049a31583e11d73070a815efad7"
+ "0e28caa18cd89a7e4bb1a17a961ae011511fe3ef495ae1c8e44653a73c6434ee77b242f7d9a"
+ "462613b92a5809da93c6d687222abf79b09a718fdf7787c7aff48b1e529da53898273abab56"
+ "00d67781a15c06e3741c79948cecbd3cd24414d40b0087844c9271bae8d470571a4e87309f9"
+ "ba510ef32c2def3e29f0f342f9a6f50fb00ee16159d0de74dfc85baf97c861a1ae63aca48b7"
+ "b2c3830ae11aa818f6da2a3cc74b5c2d0c635c9dd6d9fc5b9d35e46f8a53b93724e112a140e"
+ "cdee10eeaefa830d4678d06e1f3426abba1c9f76415ed479bee5160a8a5fcf9d5803552ca5a"
+ "810ea290fab7df557d9687af8782413fd04bf41454eae63c470ab231186c7aaf88b7e8de2ef"
+ "5e04cc8f9738f42ab5c8f993d13f8051765d4369709e54d24ec5e14138d1fe7ac81b311eb42"
+ "b0c35deebd10a3f5a60535870eeebd8662d11844ae4b39507232787d04e3c214e5b73b7b280"
+ "3395fd5a5c0c373cf2dbe76a2972e3bbaf6ff166c8134ad831ed000a4c4d5e615b74d697f8c"
+ "2be9fd8326e1aa352bcdb5ba460a0d34f750de03701e98ea43969c5b3b9de3e7bb562a320de"
+ "b10d1c8671b523611ffe7c2da353a1d3b86cf1c4d34d3347d02337e0656b9b39c8fe1f961f3"
+ "b5919df4469e895d3869590c042d6f881d9781c413613f6c5a22fd9cd24c906582e143b04b7"
+ "a09aefeed701bbf92687e995cc56578784b96c5a7a648d5c166c3b7c9a0c2df9c0166bf00b8"
+ "55c1f6e236ac96484638733eb9e84ccc4ccb33a49399e5057bd2d96ca51133496d5283a2085"
+ "56aa7f2b3264678f99f7cf5380bd61180230870ae35c00d272ec73d960ead550b29730a42a1"
+ "051e825890ec2283cf0de984af072a2125fd4ff692e47ef620b24a952c37ea379444061869c"
+ "aec75d2836afff972e54255daa9069f4c51f5bdb8ada41d3907fb5581dc7289d50577663616"
+ "464fc8b3f99676dd67bb93358a897feadd7a92336a0f4af44c9325fc53ba1d87f7b914e4847"
+ "462109cba84ad8498cd717c503d4c363b8ff405df44fa84bc9c8bed141c7f91954098b2ecb8"
+ "b59fc457ec86022bf6c395bb382f6a193e3387d52f3e1978af4576153fa7fb60d5b896cef43"
+ "e628045ec0577971b78e7ab1b3a9fa9ea6cc8e4a04f141e744f70fe0c800ce5dd3c748729c6"
+ "efa085877a7d9296ad489883ee966117e5db61bafbcd55284dc8d470646473761ec606357bb"
+ "fed899cd7c69e027656ef30b12e8a9e63868048bae95c7b67d26a843c94cec551ed5093542b"
+ "ff7437316a830e3c48f19491a81fb37aef5d89ee08b507b881e65fbf8dd3343e58b63ea3a2b"
+ "d465e02c5cb673e5c8cced17f5d3f9fad8307cd6c3abf9111e063fb197df4db52eac6092229"
+ "64e157a1b172004c1817162e688b55245c598cbdc5fd9f74db4911484feb5a390c27d0efeb3"
+ "a8bc21ff9dec02808fad5f882580facb5324a4f3a21b75c23cc311be7afe003895351fd07fa"
+ "c037d67718cc11aa5942837ee9048882e2564b625689ee3bd9487c4ec43f562508bbcd0671c"
+ "18434ca6ae92725d905210060d80e2524eb38ed600aeaf486d7b2b690a9f567d86444c35fd9"
+ "8bdf6b665dbf7e43557b281a792400274ca21fec996e5e6142780f8a7adcddbae4a2e9474a1"
+ "38931c19f96368bb2bc40aace10616bef5c975feca3c7f3e1122b41a39df9202a7a6405c647"
+ "d032f8c692e1e89838fc1dacb291d9e2d8ee90d88b6f598947d085289f9c4247548628a9e3f"
+ "6ea8ac5980e290749e39a9417b20f39dbbbed20209584a741747771020b2287007b37d17779"
+ "21303e3b7a9ee49db7b14dda965d9241548387e610758507c946eee0c49b67efaeedbe64e6b"
+ "114e3b4ddff5edd2050322d8298ae66388b1fb64435fa064364f41f129ce83a0cc563f8796e"
+ "1dd09be1a03bc5567caed9326df5714f6cf88ca247826ce93add7d17332d6870b1d0613a4fd"
+ "fd4c7d8185db385687d735d0bf22e87a045ad2a397db9c4ee0908a047f087a0fb49a27f65d0"
+ "e6e6ef0ef506d1411788ac027c29be3e93253e61ee76f951d3ce721c825bf5b883471f91f68"
+ "a37ca36d198adf93063e220a16b94e9aaca5c4691590ff2a696c1663b5ca69e3f3a11409cf9"
+ "727cf409a1f87a0a5e4805008c7488b7c9e23c42e33bfb0fab7e4f59e482ec50aa1b4d64996"
+ "4e7232c26acb75217ef1b200ebde38169d6ce7aeb2746aa29249d61af1e168a256e1848cb33"
+ "873c5457afd48194f77c786bcd8ce842605117c66b003abc05fb9b74869cc832c88df506e0e"
+ "79ebb0436443fb467269e42840a0486b3f35acca04b000876b9bf2c6a7f09ec6ff7ce198f8f"
+ "584e3e22b4a2e8279c1a043899fe0d2e5180ec1738b1cb23032374069b33a471fdd8e5f5be2"
+ "a4ff945697d9dc540878bc6a6704cb8b866914fbce94021bc2e6743dc7e160a8780912a90ff"
+ "732a81b060d97f777713881e9214474e1196ff13f07361385e19e5c5ffa24aa6b00f473cfd3"
+ "e71c42ed1c31eb9b5ec91635bf8c77e7aff696009da2163c7e1621bea9b30479a8e10906d3e"
+ "1ba06f3e64e776a62164238d18cebaf9684427fe8e5930fbd8892851c8cfa4e2c729558b909"
+ "a665f57919565d834fbebb0d64ba1721b083ca6fe55dab07546df6c1e60ab41f4836f64c27c"
+ "4f715764a472f01d947cbf8d3cd8e011129edecca4334b095edf3d37e27b7c30900eac3702c"
+ "3e09179a53462cda8dece1ecdda223d6cc32c9363f5123982b071367609b01bcfccfd4a0120"
+ "23b4dfacb5993d04434aac5a95e0192770206b4a3bdcb3a75013daedf68ed40cfca0e4bd802"
+ "4906ff8cc816d7bf556898545965b846f2b1dda3216d17d236e4ba5d2427ee799696c60297a"
+ "c720adacd63da47e2e3aeeb99c136e1b5de50cfe523823a87f94b1b4b8f6be2162ea40441dc"
+ "2f9af466c7642d0ef34429a986ae96e962e4a2cd9c12a41d71398ac03c990a15364c38a3bd9"
+ "af6605d1c9b807babd942bd66d2f6e4ccfaa2131354cf78aa09ffcec32258c9c3b53fbcc755"
+ "5bfeb11152332bef6420b08528d43f6865c5d53ade958d3b58dfe2f34391ea8d2d8fb35c32e"
+ "6a8f569d6cc9d456ff5b78fae829cc171f95f5389373a0dee3565a428237ec4e68b6e6efc3c"
+ "a5bd220699eb80bd498d2ea90d43b901881567e9c18898caea36334008b4a08e3e6cbda4e17"
+ "db7f5187d6f3284eca8c1a03faa28a2a23b27d560690642db0ea485e4be8c1c8b4441234f39"
+ "f31a6c9fe5cc7e50c777acd0746bbfb7399ee262a36a54a8ee25c334e503dcd6e00f7e9ac3a"
+ "80495156af9f9aaac62fe02c4c2373cc03d32c4be1b077d97f6167413661403a38b0df999d0"
+ "24701c5f17e5e5701cf9b9eccd9417af7637139473aab760b7ecafa863e7f049a6b98be603b"
+ "6bf0132b211b80123246c657cfdbb4b5dff7be43c364be943b5cdf03db86a6cd56a96187cb4"
+ "5b6acbf37383ca3fe7c9cc3b65a57c9ea6f4d686222801ce6d1463bb92ff5f2599619388660"
+ "99365474bbcba180f940ede8a02777bcf55d3549cfcd819aca8f055074d81af6472c3c9beaa"
+ "67b8f89066f1e02d1502aa13a4c872b9b1dc4e2a2b6d58eaa869c9e62a9f7e01efc2c87eb6a"
+ "9bc80d29c9c48a10edec1e5a799aeff2a580736525357ae40d677aa4fb6533c15b4afed1fde"
+ "f6e0e4c0a548c5be8751da42ffd8b409dcd77487437a16d769e232c95d0b780a46395ea0023"
+ "6cf19b1fafbda1c8c75aee09e06bcf0383816d0f9c364baa95a09fe2e2894693fc66166a16a"
+ "e152a24dfc5ca3646ce2cafe40a7ffbeb561ae4db74dc7ff045e85a9126a25152f0342d1f87"
+ "3ecb21bc411771eb7589f3df1be59fa97156ca5d3c93a7df10b90c525e25df36e7947614770"
+ "1f9ab2a368b179428ad005c7af2fb500fac032f0f1ff3f9694412d3c164fcc444075135fd9d"
+ "a58e2fab3ebf7b5fcaaf20256052e64b59c92db1cd3c2e0c2df41b06a540a754d349a284fa1"
+ "45a13795674240616f433d174fc67dda102db9e9e3bf23d4a8816ad130bca720ef707606206"
+ "7ab36f2061261981528dfdcaa3e21787f164e6ba318bb018f3974540ae8559790284852d31a"
+ "d8c77066f8620345f099606eced7f93e465b3a31a7b196b24e76a44d7ec6f597fb4a3a9a1a8"
+ "ba5611156e20c294b90cdde30166ee59c0c80936e992e5f3185c6396756194a7c8f1971a0b8"
+ "27477b2060dfe721fd0c2e725e25cc99d1227c6db9d5452dd70dbb0c2db67187a4e93c9bcfa"
+ "0049fad1289773ea6ffdcf6e6680a44cd577223b8f86eae3568ee5cd0b2f45a17f7b6d7531c"
+ "925e2c22b4004fd8e12ab70e2392e190dab556c0227b660cc226f5db558668bcb426a8153bc"
+ "32af18b8c7dbe3c2ad210300582f823fc5fd7aadc653c2c0b59b3e5362b158793485e56c7c4"
+ "c4");
+
+ BOOST_CHECK_EQUAL(y, z);
+}
+

Added: sandbox/mp_math/libs/mp_math/test/stream_io.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/stream_io.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,124 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "1024");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output_w_showbase, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::showbase);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "1024");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::oct, std::ios_base::basefield);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "2000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output_w_showbase, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::oct, std::ios_base::basefield);
+ os.setf(std::ios_base::showbase);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "02000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::hex, std::ios_base::basefield);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::hex, std::ios_base::basefield);
+ os.setf(std::ios_base::showbase);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "0x400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_uppercase, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xabcdef0");
+ std::ostringstream os;
+ os.setf(std::ios_base::hex, std::ios_base::basefield);
+ os.setf(std::ios_base::showbase | std::ios_base::uppercase);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "0XABCDEF0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_showpos, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ std::ostringstream os;
+ os.setf(std::ios_base::hex, std::ios_base::basefield);
+ os.setf(std::ios_base::showbase | std::ios_base::showpos);
+ os << x;
+ BOOST_CHECK_EQUAL(os.str(), "+0x400");
+}
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input1, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ std::stringstream s;
+ s << "-123456";
+ s >> x;
+ BOOST_CHECK_EQUAL(x, "-123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input2, mp_int_type, mp_int_types)
+{
+ mp_int_type x, y;
+ std::stringstream s;
+ s << "-123456";
+ s << " " << "987654321";
+ s >> x;
+ BOOST_CHECK_EQUAL(x, "-123456");
+ BOOST_REQUIRE(s.good());
+ s >> y;
+ BOOST_CHECK_EQUAL(y, "987654321");
+ BOOST_CHECK(s.good());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_input, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ std::stringstream s;
+ s << "0123456";
+ s >> x;
+ BOOST_CHECK_EQUAL(x, "0123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_input, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ std::stringstream s;
+ s << "0xFFFFAB01";
+ s >> x;
+ BOOST_CHECK_EQUAL(x, "0xFFFFAB01");
+}

Added: sandbox/mp_math/libs/mp_math/test/string_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/string_ops.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,151 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xabcdef123456789");
+ const std::string s =
+ x.template to_string<std::string>(std::ios::hex | std::ios::showbase);
+ BOOST_CHECK_EQUAL(s, "0xabcdef123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("12345678901234567890");
+ const std::string s = x.template to_string<std::string>();
+ BOOST_CHECK_EQUAL(s, "12345678901234567890");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xabcdef123456789");
+ const std::string s = x.template to_string<std::string>(
+ std::ios::hex | std::ios::showbase | std::ios::uppercase);
+ BOOST_CHECK_EQUAL(s, "0XABCDEF123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("76484675");
+ const std::string s = x.template to_string<std::string>(std::ios::oct);
+ BOOST_CHECK_EQUAL(s, "443610103");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1024");
+ const std::string s = x.template to_string<std::string>(std::ios::oct);
+ BOOST_CHECK_EQUAL(s, "2000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string6, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const std::string s =
+ x.template to_string<std::string>(
+ std::ios_base::dec | std::ios_base::showbase | std::ios_base::showpos);
+ BOOST_CHECK_EQUAL(s, "+0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string7, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0");
+ const std::string s =
+ x.template to_string<std::string>(
+ std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
+ BOOST_CHECK_EQUAL(s, "+0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string8, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-0");
+ const std::string s =
+ x.template to_string<std::string>(
+ std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
+ BOOST_CHECK_EQUAL(s, "+0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string9, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1");
+ const std::string s =
+ x.template to_string<std::string>(
+ std::ios_base::hex | std::ios_base::showbase | std::ios_base::showpos);
+ BOOST_CHECK_EQUAL(s, "-0x1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string10, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x95a6801ce5292b9a8410e1a59dd29967");
+ const std::string s =
+ x.template to_string<std::string>(std::ios_base::hex);
+ BOOST_CHECK_EQUAL(s, "95a6801ce5292b9a8410e1a59dd29967");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string11, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0x12471fa56d6");
+ const std::string s = x.template to_string<std::string>();
+ BOOST_CHECK_EQUAL(s, "1256042682070");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign1, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x = "269513460";
+ BOOST_CHECK_EQUAL(x, "269513460");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign2, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x = "0xabcdef123456789";
+ BOOST_CHECK_EQUAL(x, "0xabcdef123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign3, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x = "012345676543210000001";
+ BOOST_CHECK_EQUAL(x, "012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign4, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x = "0";
+ BOOST_CHECK_EQUAL(x.is_zero(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign5, mp_int_type, mp_int_types)
+{
+ mp_int_type x("0xabcedf03030303");
+ x = "-012345676543210000001";
+ BOOST_CHECK_EQUAL(x, "-012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign1, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x.assign("123456789876543210000001", std::ios::dec);
+ BOOST_CHECK_EQUAL(x, "123456789876543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign2, mp_int_type, mp_int_types)
+{
+ mp_int_type x;
+ x.assign("abcdefabcdef1234567890", std::ios::hex);
+ BOOST_CHECK_EQUAL(x, "0xabcdefabcdef1234567890");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign3, mp_int_type, mp_int_types)
+{
+ mp_int_type x("-564897123123456456789789789897");
+ x.assign("1234567000000000000000000000000077", std::ios::oct);
+ BOOST_CHECK_EQUAL(x, "01234567000000000000000000000000077");
+}

Added: sandbox/mp_math/libs/mp_math/test/sub.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/sub.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,132 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub1, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("123456");
+ const mp_int_type y("987777");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "-864321");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub2, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("955588990000001");
+ const mp_int_type y("9801");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "955588989990200");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub3, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("99999991");
+ const mp_int_type y("987654321000123456789");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "-987654321000023456798");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub4, mp_int_type, mp_int_types)
+{
+ const mp_int_type x(
+ "49144609407766890328547643707523663509662747376486271392344480900673178645"
+ "33198519112197059826509662943577383543858946941049753393431035706592040680"
+ "43848484065292542884106550381079282660840705126574766636237650938379223350"
+ "073087806800887586256085275775217219429527000017403144");
+ const mp_int_type y(
+ "49144609407766890328547643707523663509662747376486271392344480900673178645"
+ "33198519112197059826509662943577383543858946941049753393431035706592040680"
+ "43848484065292542884106550381079282660840705126574766636237650938379223350"
+ "073087806800887586256085275775217219429527000017403144");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub5, mp_int_type, mp_int_types)
+{
+ const mp_int_type x(
+ "21665907282124706187656074325458499695895652068822763794228458103499408841");
+ const mp_int_type y(
+ "173087806800887586256085275775299999999889978789789");
+ const mp_int_type z = x - y;
+ const mp_int_type w(
+ "21665907282124706187655901237651698808309395983546988494228458213520619052");
+ BOOST_CHECK_EQUAL(z, w);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub6, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("0xff");
+ const mp_int_type y("0x1000ff0000000");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "-0x1000fefffff01");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub7, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("1000000");
+ const mp_int_type y("-1000000");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "2000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub8, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1000000");
+ const mp_int_type y("1000000");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "-2000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub9, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-123456789");
+ const mp_int_type y("-123456789");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub10, mp_int_type, mp_int_types)
+{
+ const mp_int_type x("-1000000");
+ const mp_int_type y("-2500000");
+ const mp_int_type z = x - y;
+ BOOST_CHECK_EQUAL(z, "1500000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("0");
+ for (int i = 0; i < 10; ++i)
+ --x;
+ BOOST_CHECK_EQUAL(x, "-10");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("4");
+ for (int i = 0; i < 10; ++i)
+ --x;
+ BOOST_CHECK_EQUAL(x, "-6");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement3, mp_int_type, mp_int_types)
+{
+ mp_int_type x("-120");
+ for (int i = 0; i < 10; ++i)
+ --x;
+ BOOST_CHECK_EQUAL(x, "-130");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement4, mp_int_type, mp_int_types)
+{
+ mp_int_type x("130");
+ for (int i = 0; i < 10; ++i)
+ --x;
+ BOOST_CHECK_EQUAL(x, "120");
+}
+

Added: sandbox/mp_math/libs/mp_math/test/to_integral.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/to_integral.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,136 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char1, mp_int_type, mp_int_types)
+{
+ mp_int_type x("123");
+ char z = x.template to_integral<char>();
+ BOOST_CHECK_EQUAL(z, 123);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char2, mp_int_type, mp_int_types)
+{
+ mp_int_type x("-123");
+ char z = x.template to_integral<char>();
+ BOOST_CHECK_EQUAL(z, -123);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<char>::min());
+ char z = x.template to_integral<char>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<char>::max());
+ int z = x.template to_integral<char>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned char>::min());
+ unsigned char z = x.template to_integral<unsigned char>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned char>::max());
+ unsigned char z = x.template to_integral<unsigned char>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<int>::min());
+ int z = x.template to_integral<int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<int>::max());
+ int z = x.template to_integral<int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned int>::min());
+ unsigned int z = x.template to_integral<unsigned int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned int>::max());
+ unsigned int z = x.template to_integral<unsigned int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<long int>::min());
+ long int z = x.template to_integral<long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<long int>::max());
+ long int z = x.template to_integral<long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned long int>::min());
+ unsigned long int z = x.template to_integral<unsigned long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned long int>::max());
+ unsigned long int z = x.template to_integral<unsigned long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::max());
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<long long int>::min());
+ long long int z = x.template to_integral<long long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<long long int>::max());
+ long long int z = x.template to_integral<long long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_min, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned long long int>::min());
+ unsigned long long int z = x.template to_integral<unsigned long long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_max, mp_int_type, mp_int_types)
+{
+ mp_int_type x(std::numeric_limits<unsigned long long int>::max());
+ unsigned long long int z = x.template to_integral<unsigned long long int>();
+ BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::max());
+}
+#endif
+

Added: sandbox/mp_math/libs/mp_math/test/traits.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/traits.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,39 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <vector>
+#include <boost/test/unit_test.hpp>
+#include <boost/mp_math/mp_int.hpp>
+
+BOOST_AUTO_TEST_CASE(check_digit_type_and_word_type)
+{
+ typedef boost::mp_math::mp_int<> mp_int_type;
+
+ std::vector<int> x;
+ x.push_back(std::numeric_limits<unsigned char>::digits);
+ x.push_back(std::numeric_limits<unsigned short>::digits);
+ x.push_back(std::numeric_limits<unsigned int>::digits);
+ x.push_back(std::numeric_limits<unsigned long int>::digits);
+ #ifdef BOOST_HAS_LONG_LONG
+ x.push_back(std::numeric_limits<unsigned long long int>::digits);
+ #endif
+
+ const int word_type_digits = x.back();
+
+ std::vector<int>::const_reverse_iterator it;
+ for (it = x.rbegin(); it != x.rend(); ++it)
+ {
+ if (*it <= word_type_digits / 2)
+ break;
+ }
+
+ const int digit_type_digits = *it;
+
+ BOOST_CHECK_EQUAL(digit_type_digits,
+ std::numeric_limits<mp_int_type::digit_type>::digits);
+ BOOST_CHECK_EQUAL(word_type_digits,
+ std::numeric_limits<mp_int_type::word_type>::digits);
+}
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,123 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "benchmark.hpp"
+#include <iostream>
+#include <stdexcept>
+#include <boost/random.hpp>
+
+std::string create_random_hex_string(int size_in_bits)
+{
+ std::string s;
+ boost::mt19937 r;
+ boost::uniform_smallint<char> u(0,15);
+ boost::variate_generator<boost::mt19937&, boost::uniform_smallint<char> > vg(r, u);
+ // one hex digit can occupy 4 bits
+ for (int i = 0; i < size_in_bits/4; ++i)
+ {
+ char tmp = vg();
+ if (tmp < 10)
+ tmp = '0' + tmp;
+ else
+ tmp = 'a' + (tmp-10);
+ s.push_back(tmp);
+ }
+ return s;
+}
+
+std::string create_random_dec_string(int size_in_digits)
+{
+ std::string s;
+ boost::mt19937 r;
+ boost::uniform_smallint<char> u(0,9);
+ boost::variate_generator<boost::mt19937&, boost::uniform_smallint<char> > vg(r, u);
+
+ for (int i = 0; i < size_in_digits; ++i)
+ s.push_back('0' + vg());
+
+ return s;
+}
+
+
+const char* to_string(op_type op)
+{
+ switch (op)
+ {
+ case op_ctor_dec: return "ctor_dec";
+ case op_ctor_hex: return "ctor_hex";
+ case op_to_dec: return "to_dec";
+ case op_to_hex: return "to_hex";
+ case op_add: return "add";
+ case op_subtract: return "subtract";
+ case op_multiply: return "multiply";
+ case op_divide: return "divide";
+ case op_modulo: return "modulo";
+ case op_square: return "square";
+ case op_modpow: return "modpow";
+ default:
+ return "unknown op";
+ }
+}
+
+
+benchmark_base::benchmark_base(const std::string& name, const std::string& version)
+:
+ name_(name),
+ version_(version),
+ num_input_samples_(0)
+{}
+
+benchmark_base::~benchmark_base()
+{}
+
+void benchmark_base::run(benchmark_result& r, const std::string& op, double sample_time)
+{
+ std::cout << "executing "
+ << name_ << "->" << op << " ops";
+ std::cout.flush();
+
+ if (op == "ctor_dec") ctor_dec(r, sample_time);
+ else if (op == "ctor_hex") ctor_hex(r, sample_time);
+ else if (op == "to_dec" ) to_dec (r, sample_time);
+ else if (op == "to_hex" ) to_hex (r, sample_time);
+ else if (op == "add" ) add (r, sample_time);
+ else if (op == "subtract") subtract(r, sample_time);
+ else if (op == "multiply") multiply(r, sample_time);
+ else if (op == "divide" ) divide (r, sample_time);
+ else if (op == "modulo" ) modulo (r, sample_time);
+ else if (op == "square" ) square (r, sample_time);
+ else if (op == "modpow" ) modpow (r, sample_time);
+ else
+ {
+ std::cout << "unknown op: " << op << std::endl;
+ throw std::runtime_error("benchmark_base::run: unknown op");
+ }
+
+ std::cout << '\t' << r.total_time << " sec" << std::endl;
+}
+
+
+void benchmark_manager::add(const benchmark_ptr& p)
+{
+ b_.push_back(p);
+};
+
+const benchmark_ptr& benchmark_manager::get(const std::string name) const
+{
+ for (b_set::const_iterator i = b_.begin(); i != b_.end(); ++i)
+ if ((*i)->name() == name)
+ return *i;
+ throw std::runtime_error("unknown library");
+}
+
+void benchmark_manager::print_available_libs(std::ostream& out) const
+{
+ for (b_set::const_iterator it = b_.begin(); it != b_.end(); ++it)
+ out << (*it)->name() << "\n";
+}
+
+
+
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,190 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_HPP
+#define BOOST_MP_MATH_TOOLS_BENCHMARK_HPP
+
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/timer.hpp>
+
+
+std::string create_random_hex_string(int size_in_bits);
+std::string create_random_dec_string(int size_in_digits);
+
+
+enum op_type
+{
+ op_ctor_dec,
+ op_ctor_hex,
+ op_to_dec,
+ op_to_hex,
+ op_add,
+ op_subtract,
+ op_multiply,
+ op_divide,
+ op_modulo,
+ op_square,
+ op_modpow
+};
+
+const char* to_string(op_type op);
+
+
+struct benchmark_result
+{
+ std::string libname;
+ std::string op;
+
+ double sample_time;
+ double total_time;
+ // time for a single op execution in milliseconds
+ std::vector<double> ops;
+
+ bool operator < (const benchmark_result& r) const { return op < r.op; }
+
+ void clear()
+ {
+ total_time = 0;
+ ops.clear();
+ }
+};
+
+
+struct benchmark_base
+{
+ typedef std::vector<std::string> string_vec;
+
+ benchmark_base(const std::string& name, const std::string& version);
+
+ virtual ~benchmark_base();
+
+ virtual void set_num_input_samples(unsigned int num)
+ {
+ num_input_samples_ = num;
+ }
+
+ void run(benchmark_result& r, const std::string& op, double sample_time);
+
+ // these need to be invoked because we need these for all other benchmarks
+ virtual void construct_operand_1(const std::string& src, unsigned int i) = 0;
+ virtual void construct_operand_2(const std::string& src, unsigned int i) = 0;
+
+ //virtual bool has_op(op_type) = 0;
+
+ // now come the individual benchmarks
+ virtual void ctor_dec(benchmark_result&, double sample_time) = 0;
+ virtual void ctor_hex(benchmark_result&, double sample_time) = 0;
+ virtual void to_dec (benchmark_result&, double sample_time) = 0;
+ virtual void to_hex (benchmark_result&, double sample_time) = 0;
+ virtual void add (benchmark_result&, double sample_time) = 0;
+ virtual void subtract(benchmark_result&, double sample_time) = 0;
+ virtual void multiply(benchmark_result&, double sample_time) = 0;
+ virtual void divide (benchmark_result&, double sample_time) = 0;
+ virtual void modulo (benchmark_result&, double sample_time) = 0;
+ virtual void square (benchmark_result&, double sample_time) = 0;
+ virtual void modpow (benchmark_result&, double sample_time) = 0;
+
+ const std::string& name () const { return name_; }
+ const std::string& version() const { return version_; }
+
+ string_vec dec_str; // inputs for ctor_dec
+ string_vec hex_str; // inputs for ctor_hex
+
+protected:
+
+ const std::string name_;
+ const std::string version_;
+ unsigned int num_input_samples_;
+};
+
+
+template<class MPInt>
+struct benchmark
+:
+ benchmark_base
+{
+ typedef MPInt mp_int_type;
+ typedef std::vector<mp_int_type> mp_int_vec;
+
+ benchmark(const std::string& name, const std::string& version)
+ :
+ benchmark_base(name, version)
+ {}
+
+ virtual ~benchmark();
+
+ virtual void clear_dst_vector() = 0;
+
+ virtual void set_num_input_samples(unsigned int num);
+
+ template<class F>
+ void do_bench(F f, benchmark_result& r, double sample_time);
+ template<class F>
+ void do_bench2(F f, benchmark_result& r, double sample_time);
+
+ mp_int_vec dst; // destination vector
+ mp_int_vec src1; // operand 1 vector
+ mp_int_vec src2; // operand 2 vector
+ std::string str; // holds result of to_dec, to_hex string conversions
+};
+
+
+template<class MPInt>
+benchmark<MPInt>::~benchmark()
+{}
+
+template<class MPInt>
+void benchmark<MPInt>::set_num_input_samples(unsigned int num)
+{
+ dst.resize(num);
+ src1.resize(num);
+ src2.resize(num);
+ benchmark_base::set_num_input_samples(num);
+}
+
+template<class MPInt>
+template<class BenchFunctor>
+void benchmark<MPInt>::do_bench(BenchFunctor f, benchmark_result& r, double sample_time)
+{
+ boost::timer total;
+ boost::timer op_time;
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ unsigned long num_ops_executed = 0;
+ op_time.restart();
+ for (; op_time.elapsed() < sample_time; ++num_ops_executed)
+ f(i);
+ // push the number of ops per millisecond
+ r.ops.push_back(1.0/(op_time.elapsed() * 1000.0 / num_ops_executed));
+ }
+ r.total_time = total.elapsed();
+ // clear dst vector for next test
+ clear_dst_vector();
+}
+
+
+typedef boost::shared_ptr<benchmark_base> benchmark_ptr;
+
+
+// This class simply holds all available benchmark libraries
+struct benchmark_manager
+{
+ typedef std::vector<benchmark_ptr> b_set;
+
+ void add(const benchmark_ptr& p);
+
+ const benchmark_ptr& get(const std::string name) const;
+
+ void print_available_libs(std::ostream& out) const;
+
+ b_set b_;
+};
+
+
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,53 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "benchmark_gmp.hpp"
+#include <boost/timer.hpp>
+
+benchmark_gmp::benchmark_gmp()
+:
+ base(std::string("gmp"), gmp_version)
+{
+ // init dst vector
+ std::fill(dst.begin(), dst.end(), mpz_class());
+}
+
+benchmark_gmp::~benchmark_gmp()
+{}
+
+void benchmark_gmp::clear_dst_vector()
+{
+ std::fill(dst.begin(), dst.end(), mpz_class());
+}
+
+void benchmark_gmp::construct_operand_1(const std::string& src, unsigned int i)
+{
+ src1[i] = mpz_class(src, 16);
+}
+
+void benchmark_gmp::construct_operand_2(const std::string& src, unsigned int i)
+{
+ src2[i] = mpz_class(src, 16);
+}
+
+#define bench_function_def(f) \
+void benchmark_gmp::f(benchmark_result& r, double sample_time) \
+{ do_bench(f##_op(*this), r, sample_time); }
+
+bench_function_def(ctor_dec)
+bench_function_def(ctor_hex)
+bench_function_def(to_dec)
+bench_function_def(to_hex)
+bench_function_def(add)
+bench_function_def(subtract)
+bench_function_def(multiply)
+bench_function_def(divide)
+bench_function_def(modulo)
+bench_function_def(square)
+bench_function_def(modpow)
+
+#undef bench_function_def
+
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,107 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_GMP_HPP
+#define BOOST_MP_MATH_TOOLS_BENCHMARK_GMP_HPP
+
+#include <gmpxx.h>
+#include "benchmark.hpp"
+
+
+struct benchmark_gmp : benchmark<mpz_class>
+{
+ typedef benchmark<mpz_class> base;
+
+ benchmark_gmp();
+ ~benchmark_gmp();
+
+ void clear_dst_vector();
+
+ void construct_operand_1(const std::string& src, unsigned int i);
+ void construct_operand_2(const std::string& src, unsigned int i);
+
+ void ctor_dec(benchmark_result&, double sample_time);
+ void ctor_hex(benchmark_result&, double sample_time);
+ void to_dec (benchmark_result&, double sample_time);
+ void to_hex (benchmark_result&, double sample_time);
+ void add (benchmark_result&, double sample_time);
+ void subtract(benchmark_result&, double sample_time);
+ void multiply(benchmark_result&, double sample_time);
+ void divide (benchmark_result&, double sample_time);
+ void modulo (benchmark_result&, double sample_time);
+ void square (benchmark_result&, double sample_time);
+ void modpow (benchmark_result&, double sample_time);
+
+ struct ctor_dec_op
+ {
+ base& b;
+ explicit ctor_dec_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.dst[i] = mpz_class(b.dec_str[i], 10); }
+ };
+
+ struct ctor_hex_op
+ {
+ base& b;
+ explicit ctor_hex_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.dst[i] = mpz_class(b.hex_str[i], 16); }
+ };
+
+ struct to_dec_op
+ {
+ base& b;
+ explicit to_dec_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.str = b.src1[i].get_str(10); }
+ };
+
+ struct to_hex_op
+ {
+ base& b;
+ explicit to_hex_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.str = b.src1[i].get_str(16); }
+ };
+
+ #define bench_functor(name,op) \
+ struct name##_op { \
+ base& b; \
+ explicit name##_op(base& ba) : b(ba) {} \
+ void operator()(unsigned int i) const \
+ { b.dst[i] = b.src1[i] op b.src2[i]; } \
+ }
+
+ bench_functor(add,+);
+ bench_functor(subtract,-);
+ bench_functor(multiply,*);
+ bench_functor(divide,/);
+ bench_functor(modulo,%);
+
+ #undef bench_functor
+
+ struct square_op
+ {
+ base& b;
+ explicit square_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const
+ {
+ mpz_pow_ui(b.dst[i].get_mpz_t(), b.src1[i].get_mpz_t(), 2);
+ }
+ };
+
+ struct modpow_op
+ {
+ base& b;
+ explicit modpow_op(base& ba) : b (ba) {}
+ void operator()(unsigned int i) const
+ {
+ mpz_powm(
+ b.dst[i].get_mpz_t(),
+ b.src1[i].get_mpz_t(), b.src1[i].get_mpz_t(), b.src2[i].get_mpz_t());
+ }
+ };
+};
+
+
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,65 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "benchmark_libtom.hpp"
+
+const char* ltm_version = "0.41";
+
+benchmark_libtom::benchmark_libtom()
+:
+ base("libtommath", ltm_version)
+{
+ // init vectors
+ for (mp_int_vec::iterator it = dst.begin(); it != dst.end(); ++it)
+ mp_init(&*it);
+ for (mp_int_vec::iterator it = src1.begin(); it != src1.end(); ++it)
+ mp_init(&*it);
+ for (mp_int_vec::iterator it = src2.begin(); it != src2.end(); ++it)
+ mp_init(&*it);
+}
+
+benchmark_libtom::~benchmark_libtom()
+{
+ for (mp_int_vec::iterator it = dst.begin(); it != dst.end(); ++it)
+ mp_clear(&*it);
+}
+
+void benchmark_libtom::clear_dst_vector()
+{
+ for (mp_int_vec::iterator it = dst.begin(); it != dst.end(); ++it)
+ {
+ mp_clear(&*it);
+ mp_init(&*it);
+ }
+}
+
+void benchmark_libtom::construct_operand_1(const std::string& src, unsigned int i)
+{
+ mp_read_radix(&src1[i], src.c_str(), 16);
+}
+
+void benchmark_libtom::construct_operand_2(const std::string& src, unsigned int i)
+{
+ mp_read_radix(&src2[i], src.c_str(), 16);
+}
+
+#define bench_function_def(f) \
+void benchmark_libtom::f(benchmark_result& r, double sample_time) \
+{ do_bench(f##_op(*this), r, sample_time); }
+
+bench_function_def(ctor_dec)
+bench_function_def(ctor_hex)
+bench_function_def(to_dec)
+bench_function_def(to_hex)
+bench_function_def(add)
+bench_function_def(subtract)
+bench_function_def(multiply)
+bench_function_def(divide)
+bench_function_def(modulo)
+bench_function_def(square)
+bench_function_def(modpow)
+
+#undef bench_function_def
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_libtom.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,132 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_LIBTOM_HPP
+#define BOOST_MP_MATH_TOOLS_BENCHMARK_LIBTOM_HPP
+
+#include "benchmark.hpp"
+#include "tommath.h"
+
+extern const char* ltm_version;
+
+struct benchmark_libtom : benchmark<mp_int>
+{
+ typedef benchmark<mp_int> base;
+
+ benchmark_libtom();
+ ~benchmark_libtom();
+
+ void clear_dst_vector();
+
+ void construct_operand_1(const std::string& src, unsigned int i);
+ void construct_operand_2(const std::string& src, unsigned int i);
+
+ void ctor_dec(benchmark_result&, double sample_time);
+ void ctor_hex(benchmark_result&, double sample_time);
+ void to_dec (benchmark_result&, double sample_time);
+ void to_hex (benchmark_result&, double sample_time);
+ void add (benchmark_result&, double sample_time);
+ void subtract(benchmark_result&, double sample_time);
+ void multiply(benchmark_result&, double sample_time);
+ void divide (benchmark_result&, double sample_time);
+ void modulo (benchmark_result&, double sample_time);
+ void square (benchmark_result&, double sample_time);
+ void modpow (benchmark_result&, double sample_time);
+
+ struct ctor_dec_op
+ {
+ base& b;
+ explicit ctor_dec_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { mp_read_radix(&b.dst[i], b.dec_str[i].c_str(), 10); }
+ };
+
+ struct ctor_hex_op
+ {
+ base& b;
+ explicit ctor_hex_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { mp_read_radix(&b.dst[i], b.hex_str[i].c_str(), 16); }
+ };
+
+ struct to_dec_op
+ {
+ base& b;
+ char* tmp;
+ unsigned size;
+
+ explicit to_dec_op(base& ba) : b(ba), tmp(0), size(0) {}
+ ~to_dec_op() { delete[] tmp; }
+
+ void operator()(unsigned int i)
+ {
+ const unsigned needed = b.src1[i].used * DIGIT_BIT / 3;
+ if (size < needed)
+ tmp = new char[needed];
+ mp_toradix(&b.src1[i], tmp, 10);
+ b.str = tmp;
+ }
+ };
+
+ struct to_hex_op
+ {
+ base& b;
+ char* tmp;
+ unsigned size;
+
+ explicit to_hex_op(base& ba) : b(ba), tmp(0), size(0) {}
+ ~to_hex_op() { delete[] tmp; }
+
+ void operator()(unsigned int i)
+ {
+ const unsigned needed = b.src1[i].used * DIGIT_BIT / 4 + 1;
+ if (size < needed)
+ tmp = new char[needed];
+ mp_toradix(&b.src1[i], tmp, 16);
+ b.str = tmp;
+ }
+ };
+
+ static void mp_div_wrapper(mp_int* x, mp_int* y, mp_int* dst)
+ {
+ mp_div(x, y, dst, NULL);
+ }
+
+ #define bench_functor(name,op,func) \
+ struct name##_op { \
+ base& b; \
+ explicit name##_op(base& ba) : b(ba) {} \
+ void operator()(unsigned int i) const \
+ { func(&b.src1[i],&b.src2[i],&b.dst[i]); } \
+ }
+
+ bench_functor(add,+,mp_add);
+ bench_functor(subtract,-,mp_sub);
+ bench_functor(multiply,*,mp_mul);
+ bench_functor(divide,/,mp_div_wrapper);
+ bench_functor(modulo,%,mp_mod);
+
+ #undef bench_functor
+
+ struct square_op
+ {
+ base& b;
+ explicit square_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { mp_sqr(&b.src1[i], &b.dst[i]); }
+ };
+
+ struct modpow_op
+ {
+ base& b;
+ explicit modpow_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const
+ {
+ mp_exptmod(&b.src1[i], &b.src1[i], &b.src2[i], &b.dst[i]);
+ }
+ };
+};
+
+
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,53 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/version.hpp>
+#include "benchmark_mp_math.hpp"
+
+
+benchmark_mp_math::benchmark_mp_math()
+:
+ base("boost.mp_math", BOOST_LIB_VERSION)
+{
+ // init dst vector
+ std::fill(dst.begin(), dst.end(), mp_int_type());
+}
+
+benchmark_mp_math::~benchmark_mp_math()
+{}
+
+void benchmark_mp_math::clear_dst_vector()
+{
+ std::fill(dst.begin(), dst.end(), mp_int_type());
+}
+
+void benchmark_mp_math::construct_operand_1(const std::string& src, unsigned int i)
+{
+ src1[i].assign(src, std::ios::hex);
+}
+
+void benchmark_mp_math::construct_operand_2(const std::string& src, unsigned int i)
+{
+ src2[i].assign(src, std::ios::hex);
+}
+
+#define bench_function_def(f) \
+void benchmark_mp_math::f(benchmark_result& r, double sample_time) \
+{ do_bench(f##_op(*this), r, sample_time); }
+
+bench_function_def(ctor_dec)
+bench_function_def(ctor_hex)
+bench_function_def(to_dec)
+bench_function_def(to_hex)
+bench_function_def(add)
+bench_function_def(subtract)
+bench_function_def(multiply)
+bench_function_def(divide)
+bench_function_def(modulo)
+bench_function_def(square)
+bench_function_def(modpow)
+
+#undef bench_function_def
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,106 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_MP_MATH_HPP
+#define BOOST_MP_MATH_TOOLS_BENCHMARK_MP_MATH_HPP
+
+#include <boost/mp_math/mp_int.hpp>
+#include "benchmark.hpp"
+
+
+struct benchmark_mp_math : benchmark<boost::mp_math::mp_int<> >
+{
+ typedef benchmark<boost::mp_math::mp_int<> > base;
+
+ benchmark_mp_math();
+ virtual ~benchmark_mp_math();
+
+ void clear_dst_vector();
+
+ void construct_operand_1(const std::string& src, unsigned int i);
+ void construct_operand_2(const std::string& src, unsigned int i);
+
+ void ctor_dec(benchmark_result&, double sample_time);
+ void ctor_hex(benchmark_result&, double sample_time);
+ void to_dec (benchmark_result&, double sample_time);
+ void to_hex (benchmark_result&, double sample_time);
+ void add (benchmark_result&, double sample_time);
+ void subtract(benchmark_result&, double sample_time);
+ void multiply(benchmark_result&, double sample_time);
+ void divide (benchmark_result&, double sample_time);
+ void modulo (benchmark_result&, double sample_time);
+ void square (benchmark_result&, double sample_time);
+ void modpow (benchmark_result&, double sample_time);
+
+ struct ctor_dec_op
+ {
+ base& b;
+ explicit ctor_dec_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.dst[i].assign(b.dec_str[i], std::ios::dec); }
+ };
+
+ struct ctor_hex_op
+ {
+ base& b;
+ explicit ctor_hex_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.dst[i].assign(b.hex_str[i], std::ios::hex); }
+ };
+
+ struct to_dec_op
+ {
+ base& b;
+ explicit to_dec_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.str = b.src1[i].to_string<std::string>(std::ios::dec); }
+ };
+
+ struct to_hex_op
+ {
+ base& b;
+ explicit to_hex_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const { b.str = b.src1[i].to_string<std::string>(std::ios::hex); }
+ };
+
+ #define bench_functor(name,op) \
+ struct name##_op { \
+ base& b; \
+ explicit name##_op(base& ba) : b(ba) {} \
+ void operator()(unsigned int i) const \
+ { b.dst[i] = b.src1[i]; b.dst[i] op##= b.src2[i]; } \
+ }
+
+ bench_functor(add,+);
+ bench_functor(subtract,-);
+ bench_functor(multiply,*);
+ bench_functor(divide,/);
+ bench_functor(modulo,%);
+
+ #undef bench_functor
+
+ struct square_op
+ {
+ base& b;
+ explicit square_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const
+ {
+ b.dst[i] = b.src1[i];
+ b.dst[i].sqr();
+ }
+ };
+
+ struct modpow_op
+ {
+ base& b;
+ explicit modpow_op(base& ba) : b(ba) {}
+ void operator()(unsigned int i) const
+ {
+ b.dst[i] = boost::mp_math::modpow(b.src1[i], b.src1[i], b.src2[i]);
+ }
+ };
+};
+
+
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_result.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,85 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+struct benchmark_result
+{
+ std::string libname;
+ std::string op;
+
+ double total_time;
+ unsigned long total_ops;
+ std::vector<unsigned long> ops;
+
+ bool operator < (const benchmark_result& r) const { return op < r.op; }
+
+ void clear()
+ {}
+};
+
+
+
+struct benchmark_summary
+{
+ typedef std::vector<std::string> string_list;
+ // TODO need a list and a set view of op_result
+ typedef std::set<benchmark_result> result_list;
+ typedef result_list::const_iterator const_result_iterator;
+
+
+ result_list results;
+
+ void write_data_files(const string_list&);
+ void write_gnuplot_scripts();
+ void write_summary_file();
+
+ bool results_for_op_exist(const std::string& opname) const;
+};
+
+
+
+void benchmark_summary::write_data_files(const string_list& ops) const
+{
+ typedef std::vector<std::string> string_list;
+ for (string_list::const_iterator op = ops.begin(); op != ops.end(); ++op)
+ {
+ if (!results_for_op_exist(op))
+ continue;
+
+ const std::string filename(std::string(to_string(op)) + ".dat");
+ std::ofstream file(filename.c_str());
+ if (!file.is_open())
+ throw std::runtime_error("couldn't open data file");
+
+ const unsigned int num_ops = results.count(op);
+ const_result_iterator first = results.lower_bound(op);
+ const_result_iterator last = results.upper_bound(op);
+
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ while (first != last)
+ {
+ file << first->ops.at(i);
+
+ if (++first != last)
+ file << "\t";
+ }
+ file << "\n";
+ }
+ }
+}
+
+bool benchmark_summary::results_for_op_exist(const std::string& opname) const
+{
+ return results.find(benchmark_result("", opname)) != results.end();
+}
+
+
+
+
+benchmark_runner::get_benchmark_result();
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,350 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cmath>
+#include <fstream>
+#include <iostream>
+#include <numeric> // accumulate
+#include <stdexcept>
+#include <sstream>
+#include "benchmark_runner.hpp"
+
+
+void benchmark_runner::run(const std::vector<std::string>& ops,
+ double sample_time)
+{
+ init_libs();
+
+ for (std::vector<std::string>::const_iterator op = ops.begin(); op != ops.end(); ++op)
+ execute_bench_op(*op, sample_time);
+
+ std::cout << "creating data files..." << std::endl;
+ create_data_files();
+}
+
+unsigned long
+benchmark_runner::get_operand1_size(unsigned int sample_number) const
+{
+ // linear growth
+ const double m = static_cast<double>(end_ - beg_) /
+ static_cast<double>(num_input_samples_);
+ return (m * sample_number) + beg_;
+}
+
+unsigned long
+benchmark_runner::get_operand2_size(unsigned int sample_number) const
+{
+ // modified sine curve
+ const double pi = 3.141592654;
+ const double sample_num_to_rad = num_input_samples_ / (4.5 * pi);
+
+ // scale sample_number into the range [0...4.5*PI]
+ const double x = sample_number / sample_num_to_rad;
+
+ const double y_val = std::sin(x) + 1.0;
+
+ const double y_top = get_operand1_size(sample_number);
+ const double p0 = pi;
+ double y_bottom;
+ if (x <= p0)
+ y_bottom = y_top / (x / p0 * 2.0 + 1.0) + 1.0;
+ else
+ y_bottom = y_top / 3.0;
+
+ // we want to scale the curve at the point p1 to be above y_top at x = 2.5*pi
+ const double p1 = 2.5 * pi;
+
+ // here we use a function of the form y = -ax^2 + b to scale the curve at (and
+ // around) p1
+ const double a = 1.0/(p1 * p1);
+ double adjust = -a * ((x-p1) * (x-p1)) + 1.0;
+ // scale to be 10% above p1
+ adjust *= 1.1;
+ // stop scaling once we're past p1 and 'adjust' falls below 1.0
+ if (x > p1 && adjust < 1.0)
+ adjust = 1.0;
+
+ return static_cast<unsigned long>(y_bottom * adjust * y_val + y_bottom);
+}
+
+benchmark_runner::benchmark_runner(unsigned int num_input_samples,
+ unsigned long operand_size_beg,
+ unsigned long operand_size_end)
+:
+ num_input_samples_(num_input_samples),
+ beg_(operand_size_beg ? operand_size_beg : 1), // zero length not allowed
+ end_(operand_size_end)
+{
+}
+
+void benchmark_runner::add_library(const boost::shared_ptr<benchmark_base>& b)
+{
+ libs_.push_back(b);
+}
+
+void benchmark_runner::create_input_vectors(unsigned long min, unsigned long max)
+{
+ std::ofstream iv_file("input_vecs.dat");
+ if (!iv_file.is_open())
+ throw std::runtime_error("couldn't open file input_vecs.dat");
+
+ std::cout << "Creating " << num_input_samples_
+ << " operand indices for numbers between "
+ << min << " and " << max << " bits."
+ << std::endl;
+
+ const std::string rn = create_random_hex_string(max);
+
+ std::cout << "creating input vectors";
+ std::cout.flush();
+
+ // create input vector where number size is determined by the sine function
+ const unsigned int stepsize = num_input_samples_ / 10;
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ const unsigned long size1 = get_operand1_size(i);
+ const unsigned long size2 = get_operand2_size(i);
+
+ // divide by 4 because rn has max/4 hex digits
+ string_vec1_.push_back(rn.substr(0, size1/4));
+ string_vec2_.push_back(rn.substr(0, size2/4));
+
+ // output the input sizes for a graph here
+ iv_file << size1 << "\t" << size2 << "\n";
+
+ if (((i+1) % stepsize) == 0)
+ {
+ std::cout << ".";
+ std::cout.flush();
+ }
+ }
+
+ std::cout << std::endl;
+
+ iv_file.close();
+}
+
+void benchmark_runner::write_input_vector_plotfile(unsigned int x, unsigned int y) const
+{
+ std::ofstream pf("input_vecs.plt");
+ if (!pf.is_open())
+ throw std::runtime_error("couldn't open plotfile");
+ pf << "set term png size " << x << "," << y << "\n"
+ "set output \"input_vecs.png\"\n"
+ "set title \"input size of operands\"\n"
+ "set key left\n"
+ "set xlabel \"operand number\"\n"
+ "set ylabel \"size in bits\"\n"
+ "plot \"input_vecs.dat\" using 0:1 title \"operand 1 size\" with lines,\\\n"
+ " \"input_vecs.dat\" using 0:2 title \"operand 2 size\" with lines";
+}
+
+void benchmark_runner::init_libs()
+{
+ const unsigned long min_size =
+ std::min(get_operand1_size(0),
+ get_operand2_size(0));
+
+ const unsigned long max_size =
+ std::max(get_operand1_size(num_input_samples_),
+ get_operand2_size(num_input_samples_));
+
+ create_input_vectors(min_size, max_size);
+
+ const unsigned int stepsize = num_input_samples_ / 10;
+ for (library_vec::iterator lib = libs_.begin(); lib != libs_.end(); ++lib)
+ {
+ (*lib)->set_num_input_samples(num_input_samples_);
+
+ // init ctor strings
+ std::string hex_s = create_random_hex_string(max_size);
+ std::string dec_s = create_random_dec_string(max_size);
+
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ (*lib)->hex_str.push_back(hex_s.substr(0, get_operand1_size(i)/4));
+ (*lib)->dec_str.push_back(dec_s.substr(0, get_operand1_size(i)));
+ }
+
+
+ std::cout << (*lib)->name() << "->"
+ << "constructing operand 1 input vector";
+ std::cout.flush();
+
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ (*lib)->construct_operand_1(string_vec1_[i], i);
+ if (((i+1) % stepsize) == 0)
+ {
+ std::cout << ".";
+ std::cout.flush();
+ }
+ }
+ std::cout << std::endl;
+
+ std::cout << (*lib)->name() << "->"
+ << "constructing operand 2 input vector";
+ std::cout.flush();
+
+ for (unsigned int i = 0; i < num_input_samples_; ++i)
+ {
+ (*lib)->construct_operand_2(string_vec2_[i], i);
+ if (((i+1) % stepsize) == 0)
+ {
+ std::cout << ".";
+ std::cout.flush();
+ }
+ }
+ std::cout << std::endl;
+ }
+}
+
+void benchmark_runner::execute_bench_op(const std::string& op, double sample_time)
+{
+ for (library_vec::iterator lib = libs_.begin(); lib != libs_.end(); ++lib)
+ {
+ benchmark_result r;
+
+ r.libname = (*lib)->name() + "-" + (*lib)->version();
+ r.op = op;
+ r.sample_time = sample_time;
+
+ (*lib)->run(r, op, sample_time);
+
+ results_.push_back(r);
+ }
+}
+
+void benchmark_runner::create_data_files()
+{
+ result_list::const_iterator r = results_.begin();
+
+ // expects result list to be sorted by op name
+ while (r != results_.end())
+ {
+ data_file d;
+ result_list::const_iterator cur = r;
+ while (r != results_.end() && r->op == cur->op)
+ {
+ data_file::column c;
+
+ c.libname = r->libname;
+ c.data = r->ops;
+
+ // scale from ops per sample_time_ to ops per second
+ /*const double scale = 1.0 / r->sample_time;
+ for (std::vector<double>::iterator it = c.data.begin();
+ it != c.data.end(); ++it)
+ *it *= scale;*/
+
+ c.total_ops = std::accumulate(r->ops.begin(), r->ops.end(), 0.);
+ d.cols.push_back(c);
+ ++r;
+ }
+
+ d.op = cur->op;
+
+ d.cols.sort();
+ dfiles_.push_back(d);
+ }
+}
+
+void benchmark_runner::write_data_files() const
+{
+ for (std::list<data_file>::const_iterator it = dfiles_.begin();
+ it != dfiles_.end(); ++it)
+ it->write();
+}
+
+void benchmark_runner::write_gnuplot_scripts(unsigned int x, unsigned int y) const
+{
+ write_input_vector_plotfile(x, y);
+ for (std::list<data_file>::const_iterator it = dfiles_.begin();
+ it != dfiles_.end(); ++it)
+ it->write_gnuplot_script(x, y);
+}
+
+void benchmark_runner::write_summary_file() const
+{
+ std::ostringstream s;
+ for (std::list<data_file>::const_iterator d = dfiles_.begin();
+ d != dfiles_.end(); ++d)
+ {
+ s << d->op << "\n";
+ for (std::list<data_file::column>::const_iterator c = d->cols.begin();
+ c != d->cols.end(); ++ c)
+ {
+ s << c->libname << " total ops = " << c->total_ops << "\n";
+ }
+ }
+
+ std::cout << s.str();
+
+ std::ofstream file("summary.txt");
+ if (!file.is_open())
+ throw std::runtime_error("couldn't open summary.txt file");
+ file << s.str();
+}
+
+void benchmark_runner::write_results(unsigned int x, unsigned int y) const
+{
+ std::cout << "writing data files..." << std::endl;
+ write_data_files();
+ std::cout << "writing gnuplot scripts..." << std::endl;
+ write_gnuplot_scripts(x, y);
+ write_summary_file();
+}
+
+
+void data_file::write() const
+{
+ const std::string filename(op + ".dat");
+ std::ofstream file(filename.c_str());
+ if (!file.is_open())
+ throw std::runtime_error("couldn't open data file");
+
+ const unsigned int col_len = cols.front().data.size();
+ for (unsigned int i = 0; i < col_len; ++i)
+ {
+ std::list<column>::const_iterator it = cols.begin();
+
+ while (it != cols.end())
+ {
+ file << it->data.at(i);
+
+ if (++it != cols.end())
+ file << "\t";
+ }
+ file << "\n";
+ }
+}
+
+void data_file::write_gnuplot_script(unsigned int x, unsigned int y) const
+{
+ const std::string filename(op + ".plt");
+ std::ofstream file(filename.c_str());
+ if (!file.is_open())
+ throw std::runtime_error("couldn't open plot file");
+
+ file << "set title \"" << op << "\"\n"
+ "set xlabel " << "\"operand index\"\n"
+ "set ylabel " << "\"ops/msec\"\n"
+ "set autoscale\n"
+ "set term png size " << x << "," << y << "\n"
+ "set output \"" << op << ".png\"\n";
+ file << "plot \\\n";
+
+ std::list<column>::const_iterator it = cols.begin();
+ int count = 1;
+ while (it != cols.end())
+ {
+ file << '"' << op << ".dat\" using 0:" << count++ << " title \""
+ << it->libname << "\" with lines";
+ if (++it != cols.end())
+ file << ",\\\n";
+ }
+ file << std::endl;
+}
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_runner.hpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,80 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_RUNNER_HPP
+#define BOOST_MP_MATH_TOOLS_BENCHMARK_RUNNER_HPP
+
+#include <list>
+#include "benchmark.hpp"
+
+
+struct data_file
+{
+ struct column
+ {
+ std::string libname;
+ std::vector<double> data;
+ double total_ops;
+ bool operator < (const column& rhs) const { return libname < rhs.libname; }
+ };
+
+ std::string op;
+
+ std::list<column> cols;
+
+ void write() const;
+ void write_gnuplot_script(unsigned int x, unsigned int y) const;
+};
+
+
+struct benchmark_runner
+{
+ benchmark_runner(unsigned int num_input_samples,
+ unsigned long operand_size_beg,
+ unsigned long operand_size_end);
+
+ // add a library
+ void add_library(const boost::shared_ptr<benchmark_base>& b);
+
+ // benches all operations given in ops
+ void run(const std::vector<std::string>& ops, double sample_time);
+
+ void write_data_files() const;
+ void write_gnuplot_scripts(unsigned int x, unsigned int y) const;
+ void write_summary_file() const;
+
+ void write_results(unsigned int x, unsigned int y) const;
+
+ void execute_bench_op(const std::string& op, double sample_time);
+
+private:
+
+ void init_libs();
+
+ void create_data_files();
+
+ void create_input_vectors(unsigned long min, unsigned long max);
+ void write_input_vector_plotfile(unsigned int x, unsigned int y) const;
+
+ unsigned long get_operand1_size(unsigned int) const;
+ unsigned long get_operand2_size(unsigned int) const;
+
+ typedef std::vector<boost::shared_ptr<benchmark_base> > library_vec;
+ typedef std::list<benchmark_result> result_list;
+
+ const unsigned int num_input_samples_;
+ const unsigned long beg_;
+ const unsigned long end_;
+ std::vector<std::string> string_vec1_;
+ std::vector<std::string> string_vec2_;
+ library_vec libs_;
+ result_list results_;
+
+ std::list<data_file> dfiles_;
+};
+
+
+#endif
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,45 @@
+# Copyright Kevin Sopp 2008.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+alias boost_fs : $(BOOST_ROOT)/libs/filesystem/build//boost_filesystem/<link>shared ;
+alias boost_po : $(BOOST_ROOT)/libs/program_options/build//boost_program_options/<link>shared ;
+
+project
+ :
+ requirements
+ <include>../../../..
+ <include>.
+ <link>static
+ <toolset>gcc:<cxxflags>"-march=i686 -mtune=generic"
+ ;
+
+
+
+# GMP (GNU Multiple Precision Arithmetic, http://gmplib.org/) library need to be
+# installed for the benchmark to work
+# gmpxx is the library for the C++ bindings of gmp
+lib gmpxx : : <name>gmpxx ;
+lib gmp : : <name>gmp ;
+
+lib tommath : tommath.cpp : <variant>release ;
+
+exe benchmark
+ :
+ benchmark.cpp
+ benchmark_runner.cpp
+ benchmark_mp_math.cpp
+ benchmark_libtom.cpp
+ benchmark_gmp.cpp
+ main.cpp
+ tommath
+ gmpxx gmp
+ boost_fs
+ boost_po
+ :
+ <variant>release
+ <toolset>gcc:<cxxflags>-std=c++0x #-DBOOST_MP_MATH_MP_INT_USE_ASM"
+ ;
+
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,325 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+
+#include <boost/filesystem.hpp>
+#include <boost/program_options.hpp>
+#include <boost/tokenizer.hpp>
+
+#include "benchmark_runner.hpp"
+
+#include "benchmark_mp_math.hpp"
+#include "benchmark_libtom.hpp"
+#include "benchmark_gmp.hpp"
+
+
+const char* version = "0.3";
+
+
+struct config
+{
+ unsigned int graph_x, graph_y;
+ unsigned int num_input_samples;
+ double max_error;
+ double sample_time;
+ std::pair<unsigned int, unsigned int> range;
+
+ typedef std::vector<std::string> string_list;
+ // we receive these two strings from the cmdline and need to tokenize them
+ std::string ops_string;
+ std::string libs_string;
+ // the tokenized result
+ string_list ops; // ops that we shall execute
+ string_list libs; // libs that we shall benchmark
+
+ config();
+
+ void show_available_ops (std::ostream&) const;
+
+ const string_list& available_ops () const { return available_ops_; }
+
+ double estimated_run_time() const;
+
+private:
+
+ string_list available_ops_;
+};
+
+
+config::config()
+{
+ available_ops_.push_back("ctor_dec");
+ available_ops_.push_back("ctor_hex");
+ available_ops_.push_back("to_dec");
+ available_ops_.push_back("to_hex");
+ available_ops_.push_back("add");
+ available_ops_.push_back("subtract");
+ available_ops_.push_back("multiply");
+ available_ops_.push_back("divide");
+ available_ops_.push_back("modulo");
+ available_ops_.push_back("square");
+ available_ops_.push_back("modpow");
+}
+
+
+
+void config::show_available_ops(std::ostream& os) const
+{
+ string_list::const_iterator op;
+ for (op = available_ops_.begin(); op != available_ops_.end(); ++op)
+ os << *op << "\n";
+}
+
+double config::estimated_run_time() const
+{
+ return sample_time * num_input_samples * ops.size() * libs.size();
+}
+
+
+double calibrate_sample_time(double max_error)
+{
+ const int vec_length = 10;
+ long vec[vec_length];
+ double st = 0.01;
+
+ int verified = 0;
+ while (true)
+ {
+ for (int k = 0; k < vec_length; ++k)
+ {
+ boost::timer t;
+ boost::timer inner;
+ long count = 0;
+ while (inner.elapsed() < st)
+ ++count;
+ vec[k] = count;
+ }
+ // calculate error
+ long average_value = 0;
+ for (int i = 0; i < vec_length; ++i)
+ average_value += vec[i];
+ average_value /= vec_length;
+
+ long average_deviation = 0;
+ for (int i = 0; i < vec_length; ++i)
+ average_deviation += std::abs(average_value - vec[i]);
+ average_deviation /= vec_length;
+
+ const double error = (double)average_deviation / (double)average_value;
+
+ std::cout << "sample-time = " << st
+ << ", current error = " << error;
+ if (verified)
+ std::cout << " (verifying)";
+ std::cout << std::endl;
+
+ if (error < max_error)
+ {
+ if (verified == 2)
+ return st;
+ ++verified;
+ continue;
+ }
+ else
+ verified = 0;
+ if (error / max_error > 2.0)
+ st += 0.01;
+ else
+ st += 0.002;
+ if (st >= 0.05)
+ return 0.05;
+ }
+}
+
+
+
+
+int main(int argc, char** argv)
+{
+ typedef config::string_list string_list;
+
+ std::ios::sync_with_stdio(false);
+
+ try
+ {
+
+ benchmark_manager bmgr;
+ bmgr.add(benchmark_ptr(new benchmark_mp_math()));
+ bmgr.add(benchmark_ptr(new benchmark_libtom()));
+ bmgr.add(benchmark_ptr(new benchmark_gmp()));
+
+ config c;
+
+ using namespace boost::program_options;
+
+ options_description opts
+ ("This program benchmarks different multiprecision integer "
+ "libraries and outputs data files for use with gnuplot "
+ "(http://www.gnuplot.com).\n"
+ "options"
+ );
+
+ opts.add_options()
+ ("help,h", "show this message")
+
+ ("version,v", "print version")
+
+ ("num-input-samples,n",
+ value(&c.num_input_samples)->default_value(1000),
+ "number of input samples to create")
+
+ ("max-error,e",
+ value(&c.max_error)->default_value(0.1, "0.1"),
+ "this value is used to calculate the sample time, you should not "
+ "need to modify it")
+
+ ("sample-time,s",
+ value(&c.sample_time)->default_value(0.035, "0.035"),
+ "directly specify the sample time in seconds, it is used to reduce "
+ "the error of the measurements")
+
+ ("range-beg,a",
+ value(&c.range.first)->default_value(32),
+ "range of numbers, measured in bits")
+
+ ("range-end,b",
+ value(&c.range.second)->default_value(3072),
+ "range of numbers, measured in bits")
+
+ ("ops",
+ value(&c.ops_string),
+ "the operations to benchmark")
+
+ ("libs",
+ value(&c.libs_string),
+ "the libraries to benchmark")
+
+ ("list-ops", "lists available operations")
+
+ ("list-libs", "lists available libraries")
+
+ ("x",
+ value(&c.graph_x)->default_value(1024),
+ "width of graphs created by gnuplot")
+ ("y",
+ value(&c.graph_y)->default_value(768),
+ "height of graphs created by gnuplot")
+ ;
+
+ variables_map vm;
+
+ store(parse_command_line(argc, argv, opts), vm);
+
+ notify(vm);
+
+ if (vm.count("help"))
+ {
+ std::cout << opts << std::endl;
+ return 0;
+ }
+ if (vm.count("version"))
+ {
+ std::cout << version << std::endl;
+ return 0;
+ }
+ if (vm.count("list-ops"))
+ {
+ c.show_available_ops(std::cout);
+ return 0;
+ }
+ if (vm.count("list-libs"))
+ {
+ bmgr.print_available_libs(std::cout);
+ return 0;
+ }
+ if (!vm.count("ops"))
+ c.ops = c.available_ops();
+ else
+ {
+ boost::char_separator<char> sep(" ,");
+ boost::tokenizer<boost::char_separator<char> > tokens(c.ops_string, sep);
+ std::copy(tokens.begin(), tokens.end(), std::back_inserter(c.ops));
+ }
+
+ std::cout << "Ops that we are about to benchmark:\n";
+ for (string_list::const_iterator it = c.ops.begin(); it != c.ops.end(); ++it)
+ std::cout << "- " << *it << std::endl;
+
+ if (!vm.count("libs"))
+ {
+ for (benchmark_manager::b_set::const_iterator it = bmgr.b_.begin();
+ it != bmgr.b_.end(); ++it)
+ c.libs.push_back((*it)->name());
+ }
+ else
+ {
+ boost::char_separator<char> sep(" ,");
+ boost::tokenizer<boost::char_separator<char> > tokens(c.libs_string, sep);
+ std::copy(tokens.begin(), tokens.end(), std::back_inserter(c.libs));
+ }
+
+
+ // switch to a new subdir to store the benchmark results
+ const std::time_t time = std::time(0);
+ char timestring[32];
+ std::strftime(timestring, 32, "%Y %m %d %H:%M", std::localtime(&time));
+
+ boost::filesystem::create_directory(timestring);
+ boost::filesystem::current_path(timestring);
+
+
+ benchmark_runner b_runner(c.num_input_samples, c.range.first, c.range.second);
+
+ std::cout << "Libraries that we are about to benchmark:\n";
+ for (string_list::const_iterator lib = c.libs.begin();
+ lib != c.libs.end(); ++lib)
+ {
+ const benchmark_ptr p(bmgr.get(*lib));
+ std::cout << "- " << p->name() << "\n";
+ b_runner.add_library(p);
+ }
+
+ if (!vm.count("sample-time"))
+ {
+ std::cout << "calibrating sample time..." << std::endl;
+ c.sample_time = calibrate_sample_time(c.max_error);
+ }
+
+ std::cout << "Sample time is: " << c.sample_time << " sec" << std::endl;
+
+ const double runtime = c.estimated_run_time();
+ std::cout << "Estimated run time of benchmark is at least "
+ << (long)(runtime/60.0) << " minutes, but could be much longer for "
+ << "very large numbers." << std::endl;
+
+ b_runner.run(c.ops, c.sample_time);
+ b_runner.write_results(c.graph_x, c.graph_y);
+
+ std::cout << "done with benchmarking!" << std::endl;
+
+ std::cout << "creating graphs via gnuplot...\n";
+ std::cout << "calling \'gnuplot *.plt\'" << std::endl;
+ const int ret = std::system("gnuplot *.plt");
+ if (ret)
+ std::cout << "something went wrong, received the error code " << ret
+ << std::endl;
+ else
+ std::cout << "done" << std::endl;
+
+ if (boost::filesystem::is_empty(boost::filesystem::current_path()))
+ boost::filesystem::remove(boost::filesystem::current_path());
+
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "caught exception: " << e.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.cpp 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,9524 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* Start: bn_error.c */
+#include "tommath.h"
+#ifdef BN_ERROR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+static const struct {
+ int code;
+ const char *msg;
+} msgs[] = {
+ { MP_OKAY, "Successful" },
+ { MP_MEM, "Out of heap" },
+ { MP_VAL, "Value out of range" }
+};
+
+/* return a char * string for a given code */
+const char *mp_error_to_string(int code)
+{
+ int x;
+
+ /* scan the lookup table for the given message */
+ for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
+ if (msgs[x].code == code) {
+ return msgs[x].msg;
+ }
+ }
+
+ /* generic reply for invalid code */
+ return "Invalid error code";
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_error.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_error.c */
+
+/* Start: bn_fast_mp_invmod.c */
+#include "tommath.h"
+#ifdef BN_FAST_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes the modular inverse via binary extended euclidean algorithm,
+ * that is c = 1/a mod b
+ *
+ * Based on slow invmod except this is optimized for the case where b is
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x, y, u, v, B, D;
+ int res, neg;
+
+ /* 2. [modified] b must be odd */
+ if (mp_iseven (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* init all our temps */
+ if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* x == modulus, y == value to invert */
+ if ((res = mp_copy (b, &x)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* we need y = |a| */
+ if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ mp_set (&D, 1);
+
+top:
+ /* 4. while u is even do */
+ while (mp_iseven (&u) == 1) {
+ /* 4.1 u = u/2 */
+ if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 4.2 if B is odd then */
+ if (mp_isodd (&B) == 1) {
+ if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* B = B/2 */
+ if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 5. while v is even do */
+ while (mp_iseven (&v) == 1) {
+ /* 5.1 v = v/2 */
+ if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 5.2 if D is odd then */
+ if (mp_isodd (&D) == 1) {
+ /* D = (D-x)/2 */
+ if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* D = D/2 */
+ if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 6. if u >= v then */
+ if (mp_cmp (&u, &v) != MP_LT) {
+ /* u = u - v, B = B - D */
+ if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ } else {
+ /* v - v - u, D = D - B */
+ if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* if not zero goto step 4 */
+ if (mp_iszero (&u) == 0) {
+ goto top;
+ }
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (mp_cmp_d (&v, 1) != MP_EQ) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* b is now the inverse */
+ neg = a->sign;
+ while (D.sign == MP_NEG) {
+ if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ mp_exch (&D, c);
+ c->sign = neg;
+ res = MP_OKAY;
+
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_fast_mp_invmod.c */
+
+/* Start: bn_fast_mp_montgomery_reduce.c */
+#include "tommath.h"
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+ int ix, res, olduse;
+ mp_word W[MP_WARRAY];
+
+ /* get old used count */
+ olduse = x->used;
+
+ /* grow a as required */
+ if (x->alloc < n->used + 1) {
+ if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* first we have to get the digits of the input into
+ * an array of double precision words W[...]
+ */
+ {
+ register mp_word *_W;
+ register mp_digit *tmpx;
+
+ /* alias for the W[] array */
+ _W = W;
+
+ /* alias for the digits of x*/
+ tmpx = x->dp;
+
+ /* copy the digits of a into W[0..a->used-1] */
+ for (ix = 0; ix < x->used; ix++) {
+ *_W++ = *tmpx++;
+ }
+
+ /* zero the high words of W[a->used..m->used*2] */
+ for (; ix < n->used * 2 + 1; ix++) {
+ *_W++ = 0;
+ }
+ }
+
+ /* now we proceed to zero successive digits
+ * from the least significant upwards
+ */
+ for (ix = 0; ix < n->used; ix++) {
+ /* mu = ai * m' mod b
+ *
+ * We avoid a double precision multiplication (which isn't required)
+ * by casting the value down to a mp_digit. Note this requires
+ * that W[ix-1] have the carry cleared (see after the inner loop)
+ */
+ register mp_digit mu;
+ mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
+
+ /* a = a + mu * m * b**i
+ *
+ * This is computed in place and on the fly. The multiplication
+ * by b**i is handled by offseting which columns the results
+ * are added to.
+ *
+ * Note the comba method normally doesn't handle carries in the
+ * inner loop In this case we fix the carry from the previous
+ * column since the Montgomery reduction requires digits of the
+ * result (so far) [see above] to work. This is
+ * handled by fixing up one carry after the inner loop. The
+ * carry fixups are done in order so after these loops the
+ * first m->used words of W[] have the carries fixed
+ */
+ {
+ register int iy;
+ register mp_digit *tmpn;
+ register mp_word *_W;
+
+ /* alias for the digits of the modulus */
+ tmpn = n->dp;
+
+ /* Alias for the columns set by an offset of ix */
+ _W = W + ix;
+
+ /* inner loop */
+ for (iy = 0; iy < n->used; iy++) {
+ *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
+ }
+ }
+
+ /* now fix carry for next digit, W[ix+1] */
+ W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
+ }
+
+ /* now we have to propagate the carries and
+ * shift the words downward [all those least
+ * significant digits we zeroed].
+ */
+ {
+ register mp_digit *tmpx;
+ register mp_word *_W, *_W1;
+
+ /* nox fix rest of carries */
+
+ /* alias for current word */
+ _W1 = W + ix;
+
+ /* alias for next word, where the carry goes */
+ _W = W + ++ix;
+
+ for (; ix <= n->used * 2 + 1; ix++) {
+ *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
+ }
+
+ /* copy out, A = A/b**n
+ *
+ * The result is A/b**n but instead of converting from an
+ * array of mp_word to mp_digit than calling mp_rshd
+ * we just copy them in the right order
+ */
+
+ /* alias for destination word */
+ tmpx = x->dp;
+
+ /* alias for shifted double precision result */
+ _W = W + n->used;
+
+ for (ix = 0; ix < n->used + 1; ix++) {
+ *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
+ }
+
+ /* zero oldused digits, if the input a was larger than
+ * m->used+1 we'll have to clear the digits
+ */
+ for (; ix < olduse; ix++) {
+ *tmpx++ = 0;
+ }
+ }
+
+ /* set the max used and clamp */
+ x->used = n->used + 1;
+ mp_clamp (x);
+
+ /* if A >= m then A = A - m */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ return s_mp_sub (x, n, x);
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_fast_mp_montgomery_reduce.c */
+
+/* Start: bn_fast_s_mp_mul_digs.c */
+#include "tommath.h"
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier. It is
+ * designed to compute the columns of the product first
+ * then handle the carries afterwards. This has the effect
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of
+ * digits of output so if say only a half-product is required
+ * you don't have to compute the upper half (a feature
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY];
+ register mp_word _W;
+
+ /* grow the destination as required */
+ if (c->alloc < digs) {
+ if ((res = mp_grow (c, digs)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ pa = MIN(digs, a->used + b->used);
+
+ /* clear the carry */
+ _W = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty;
+ int iy;
+ mp_digit *tmpx, *tmpy;
+
+ /* get offsets into the two bignums */
+ ty = MIN(b->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = b->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; ++iz) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+ }
+
+ /* store term */
+ W[ix] = ((mp_digit)_W) & MP_MASK;
+
+ /* make next carry */
+ _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = c->used;
+ c->used = pa;
+
+ {
+ register mp_digit *tmpc;
+ tmpc = c->dp;
+ for (ix = 0; ix < pa+1; ix++) {
+ /* now extract the previous digit [below the carry] */
+ *tmpc++ = W[ix];
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpc++ = 0;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_digs.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_fast_s_mp_mul_digs.c */
+
+/* Start: bn_fast_s_mp_mul_high_digs.c */
+#include "tommath.h"
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* this is a modified version of fast_s_mul_digs that only produces
+ * output digits *above* digs. See the comments for fast_s_mul_digs
+ * to see how it works.
+ *
+ * This is used in the Barrett reduction since for one of the multiplications
+ * only the higher digits were needed. This essentially halves the work.
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ */
+int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY];
+ mp_word _W;
+
+ /* grow the destination as required */
+ pa = a->used + b->used;
+ if (c->alloc < pa) {
+ if ((res = mp_grow (c, pa)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ pa = a->used + b->used;
+ _W = 0;
+ for (ix = digs; ix < pa; ix++) {
+ int tx, ty, iy;
+ mp_digit *tmpx, *tmpy;
+
+ /* get offsets into the two bignums */
+ ty = MIN(b->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = b->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially its
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+ }
+
+ /* store term */
+ W[ix] = ((mp_digit)_W) & MP_MASK;
+
+ /* make next carry */
+ _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = c->used;
+ c->used = pa;
+
+ {
+ register mp_digit *tmpc;
+
+ tmpc = c->dp + digs;
+ for (ix = digs; ix < pa; ix++) {
+ /* now extract the previous digit [below the carry] */
+ *tmpc++ = W[ix];
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpc++ = 0;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_fast_s_mp_mul_high_digs.c */
+
+/* Start: bn_fast_s_mp_sqr.c */
+#include "tommath.h"
+#ifdef BN_FAST_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that
+ * starts closer to zero] can't equal the offset of tmpy.
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens. You double all those
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY], *tmpx;
+ mp_word W1;
+
+ /* grow the destination as required */
+ pa = a->used + a->used;
+ if (b->alloc < pa) {
+ if ((res = mp_grow (b, pa)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ W1 = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty, iy;
+ mp_word _W;
+ mp_digit *tmpy;
+
+ /* clear counter */
+ _W = 0;
+
+ /* get offsets into the two bignums */
+ ty = MIN(a->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = a->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* now for squaring tx can never equal ty
+ * we halve the distance since they approach at a rate of 2x
+ * and we have to round because odd cases need to be executed
+ */
+ iy = MIN(iy, (ty-tx+1)>>1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+ }
+
+ /* double the inner product and add carry */
+ _W = _W + _W + W1;
+
+ /* even columns have the square term in them */
+ if ((ix&1) == 0) {
+ _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+ }
+
+ /* store it */
+ W[ix] = (mp_digit)(_W & MP_MASK);
+
+ /* make next carry */
+ W1 = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = b->used;
+ b->used = a->used+a->used;
+
+ {
+ mp_digit *tmpb;
+ tmpb = b->dp;
+ for (ix = 0; ix < pa; ix++) {
+ *tmpb++ = W[ix] & MP_MASK;
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpb++ = 0;
+ }
+ }
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_fast_s_mp_sqr.c */
+
+/* Start: bn_mp_2expt.c */
+#include "tommath.h"
+#ifdef BN_MP_2EXPT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes a = 2**b
+ *
+ * Simple algorithm which zeroes the int, grows it then just sets one bit
+ * as required.
+ */
+int
+mp_2expt (mp_int * a, int b)
+{
+ int res;
+
+ /* zero a as per default */
+ mp_zero (a);
+
+ /* grow a to accomodate the single bit */
+ if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* set the used count of where the bit will go */
+ a->used = b / DIGIT_BIT + 1;
+
+ /* put the single bit in its place */
+ a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_2expt.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_2expt.c */
+
+/* Start: bn_mp_abs.c */
+#include "tommath.h"
+#ifdef BN_MP_ABS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* b = |a|
+ *
+ * Simple function copies the input and fixes the sign to positive
+ */
+int
+mp_abs (mp_int * a, mp_int * b)
+{
+ int res;
+
+ /* copy a to b */
+ if (a != b) {
+ if ((res = mp_copy (a, b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* force the sign of b to positive */
+ b->sign = MP_ZPOS;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_abs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_abs.c */
+
+/* Start: bn_mp_add.c */
+#include "tommath.h"
+#ifdef BN_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ /* get sign of both inputs */
+ sa = a->sign;
+ sb = b->sign;
+
+ /* handle two cases, not four */
+ if (sa == sb) {
+ /* both positive or both negative */
+ /* add their magnitudes, copy the sign */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* one positive, the other negative */
+ /* subtract the one with the greater magnitude from */
+ /* the one of the lesser magnitude. The result gets */
+ /* the sign of the one with the greater magnitude. */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ c->sign = sb;
+ res = s_mp_sub (b, a, c);
+ } else {
+ c->sign = sa;
+ res = s_mp_sub (a, b, c);
+ }
+ }
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_add.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_add.c */
+
+/* Start: bn_mp_add_d.c */
+#include "tommath.h"
+#ifdef BN_MP_ADD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* single digit addition */
+int
+mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, ix, oldused;
+ mp_digit *tmpa, *tmpc, mu;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative and |a| >= b, call c = |a| - b */
+ if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+ /* temporarily fix sign of a */
+ a->sign = MP_ZPOS;
+
+ /* c = |a| - b */
+ res = mp_sub_d(a, b, c);
+
+ /* fix sign */
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* old number of used digits in c */
+ oldused = c->used;
+
+ /* sign always positive */
+ c->sign = MP_ZPOS;
+
+ /* source alias */
+ tmpa = a->dp;
+
+ /* destination alias */
+ tmpc = c->dp;
+
+ /* if a is positive */
+ if (a->sign == MP_ZPOS) {
+ /* add digit, after this we're propagating
+ * the carry.
+ */
+ *tmpc = *tmpa++ + b;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+
+ /* now handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ + mu;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+ }
+ /* set final carry */
+ ix++;
+ *tmpc++ = mu;
+
+ /* setup size */
+ c->used = a->used + 1;
+ } else {
+ /* a was negative and |a| < b */
+ c->used = 1;
+
+ /* the result is a single digit */
+ if (a->used == 1) {
+ *tmpc++ = b - a->dp[0];
+ } else {
+ *tmpc++ = b;
+ }
+
+ /* setup count so the clearing of oldused
+ * can fall through correctly
+ */
+ ix = 1;
+ }
+
+ /* now zero to oldused */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_add_d.c */
+
+/* Start: bn_mp_addmod.c */
+#include "tommath.h"
+#ifdef BN_MP_ADDMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* d = a + b (mod c) */
+int
+mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_add (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_addmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_addmod.c */
+
+/* Start: bn_mp_and.c */
+#include "tommath.h"
+#ifdef BN_MP_AND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* AND two ints together */
+int
+mp_and (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] &= x->dp[ix];
+ }
+
+ /* zero digits above the last from the smallest mp_int */
+ for (; ix < t.used; ix++) {
+ t.dp[ix] = 0;
+ }
+
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_and.c */
+
+/* Start: bn_mp_clamp.c */
+#include "tommath.h"
+#ifdef BN_MP_CLAMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* trim unused digits
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast. Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+ /* decrease used while the most significant digit is
+ * zero.
+ */
+ while (a->used > 0 && a->dp[a->used - 1] == 0) {
+ --(a->used);
+ }
+
+ /* reset the sign flag if used == 0 */
+ if (a->used == 0) {
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clamp.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_clamp.c */
+
+/* Start: bn_mp_clear.c */
+#include "tommath.h"
+#ifdef BN_MP_CLEAR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* clear one (frees) */
+void
+mp_clear (mp_int * a)
+{
+ int i;
+
+ /* only do anything if a hasn't been freed previously */
+ if (a->dp != NULL) {
+ /* first zero the digits */
+ for (i = 0; i < a->used; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* free ram */
+ XFREE(a->dp);
+
+ /* reset members to make debugging easier */
+ a->dp = NULL;
+ a->alloc = a->used = 0;
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clear.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_clear.c */
+
+/* Start: bn_mp_clear_multi.c */
+#include "tommath.h"
+#ifdef BN_MP_CLEAR_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+#include <stdarg.h>
+
+void mp_clear_multi(mp_int *mp, ...)
+{
+ mp_int* next_mp = mp;
+ va_list args;
+ va_start(args, mp);
+ while (next_mp != NULL) {
+ mp_clear(next_mp);
+ next_mp = va_arg(args, mp_int*);
+ }
+ va_end(args);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clear_multi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_clear_multi.c */
+
+/* Start: bn_mp_cmp.c */
+#include "tommath.h"
+#ifdef BN_MP_CMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* compare two ints (signed)*/
+int
+mp_cmp (mp_int * a, mp_int * b)
+{
+ /* compare based on sign */
+ if (a->sign != b->sign) {
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ } else {
+ return MP_GT;
+ }
+ }
+
+ /* compare digits */
+ if (a->sign == MP_NEG) {
+ /* if negative compare opposite direction */
+ return mp_cmp_mag(b, a);
+ } else {
+ return mp_cmp_mag(a, b);
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_cmp.c */
+
+/* Start: bn_mp_cmp_d.c */
+#include "tommath.h"
+#ifdef BN_MP_CMP_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* compare a digit */
+int mp_cmp_d(mp_int * a, mp_digit b)
+{
+ /* compare based on sign */
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ }
+
+ /* compare based on magnitude */
+ if (a->used > 1) {
+ return MP_GT;
+ }
+
+ /* compare the only digit of a to b */
+ if (a->dp[0] > b) {
+ return MP_GT;
+ } else if (a->dp[0] < b) {
+ return MP_LT;
+ } else {
+ return MP_EQ;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_cmp_d.c */
+
+/* Start: bn_mp_cmp_mag.c */
+#include "tommath.h"
+#ifdef BN_MP_CMP_MAG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (mp_int * a, mp_int * b)
+{
+ int n;
+ mp_digit *tmpa, *tmpb;
+
+ /* compare based on # of non-zero digits */
+ if (a->used > b->used) {
+ return MP_GT;
+ }
+
+ if (a->used < b->used) {
+ return MP_LT;
+ }
+
+ /* alias for a */
+ tmpa = a->dp + (a->used - 1);
+
+ /* alias for b */
+ tmpb = b->dp + (a->used - 1);
+
+ /* compare based on digits */
+ for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+ if (*tmpa > *tmpb) {
+ return MP_GT;
+ }
+
+ if (*tmpa < *tmpb) {
+ return MP_LT;
+ }
+ }
+ return MP_EQ;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_mag.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_cmp_mag.c */
+
+/* Start: bn_mp_cnt_lsb.c */
+#include "tommath.h"
+#ifdef BN_MP_CNT_LSB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+static const int lnz[16] = {
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a)
+{
+ int x;
+ mp_digit q, qq;
+
+ /* easy out */
+ if (mp_iszero(a) == 1) {
+ return 0;
+ }
+
+ /* scan lower digits until non-zero */
+ for (x = 0; x < a->used && a->dp[x] == 0; x++);
+ q = a->dp[x];
+ x *= DIGIT_BIT;
+
+ /* now scan this digit until a 1 is found */
+ if ((q & 1) == 0) {
+ do {
+ qq = q & 15;
+ x += lnz[qq];
+ q >>= 4;
+ } while (qq == 0);
+ }
+ return x;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cnt_lsb.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_cnt_lsb.c */
+
+/* Start: bn_mp_copy.c */
+#include "tommath.h"
+#ifdef BN_MP_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* copy, b = a */
+int
+mp_copy (mp_int * a, mp_int * b)
+{
+ int res, n;
+
+ /* if dst == src do nothing */
+ if (a == b) {
+ return MP_OKAY;
+ }
+
+ /* grow dest */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* zero b and copy the parameters over */
+ {
+ register mp_digit *tmpa, *tmpb;
+
+ /* pointer aliases */
+
+ /* source */
+ tmpa = a->dp;
+
+ /* destination */
+ tmpb = b->dp;
+
+ /* copy all the digits */
+ for (n = 0; n < a->used; n++) {
+ *tmpb++ = *tmpa++;
+ }
+
+ /* clear high digits */
+ for (; n < b->used; n++) {
+ *tmpb++ = 0;
+ }
+ }
+
+ /* copy used count and sign */
+ b->used = a->used;
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_copy.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_copy.c */
+
+/* Start: bn_mp_count_bits.c */
+#include "tommath.h"
+#ifdef BN_MP_COUNT_BITS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (mp_int * a)
+{
+ int r;
+ mp_digit q;
+
+ /* shortcut */
+ if (a->used == 0) {
+ return 0;
+ }
+
+ /* get number of digits and add that */
+ r = (a->used - 1) * DIGIT_BIT;
+
+ /* take the last digit and count the bits in it */
+ q = a->dp[a->used - 1];
+ while (q > ((mp_digit) 0)) {
+ ++r;
+ q >>= ((mp_digit) 1);
+ }
+ return r;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_count_bits.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_count_bits.c */
+
+/* Start: bn_mp_div.c */
+#include "tommath.h"
+#ifdef BN_MP_DIV_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+#ifdef BN_MP_DIV_SMALL
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int ta, tb, tq, q;
+ int res, n, n2;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ /* init our temps */
+ if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
+ return res;
+ }
+
+
+ mp_set(&tq, 1);
+ n = mp_count_bits(a) - mp_count_bits(b);
+ if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+ ((res = mp_abs(b, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+
+ while (n-- >= 0) {
+ if (mp_cmp(&tb, &ta) != MP_GT) {
+ if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+ ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+ if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+ ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* now q == quotient and ta == remainder */
+ n = a->sign;
+ n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+ if (c != NULL) {
+ mp_exch(c, &q);
+ c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+ }
+ if (d != NULL) {
+ mp_exch(d, &ta);
+ d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+ }
+LBL_ERR:
+ mp_clear_multi(&ta, &tb, &tq, &q, NULL);
+ return res;
+}
+
+#else
+
+/* integer signed division.
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly
+ * incomplete. For example, it doesn't consider
+ * the case where digits are removed from 'x' in
+ * the inner loop. It also doesn't consider the
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int q, x, y, t1, t2;
+ int res, n, t, i, norm, neg;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
+ return res;
+ }
+ q.used = a->used + 2;
+
+ if ((res = mp_init (&t1)) != MP_OKAY) {
+ goto LBL_Q;
+ }
+
+ if ((res = mp_init (&t2)) != MP_OKAY) {
+ goto LBL_T1;
+ }
+
+ if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
+ goto LBL_T2;
+ }
+
+ if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
+ goto LBL_X;
+ }
+
+ /* fix the sign */
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+ x.sign = y.sign = MP_ZPOS;
+
+ /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+ norm = mp_count_bits(&y) % DIGIT_BIT;
+ if (norm < (int)(DIGIT_BIT-1)) {
+ norm = (DIGIT_BIT-1) - norm;
+ if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ } else {
+ norm = 0;
+ }
+
+ /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+ n = x.used - 1;
+ t = y.used - 1;
+
+ /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+ if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
+ goto LBL_Y;
+ }
+
+ while (mp_cmp (&x, &y) != MP_LT) {
+ ++(q.dp[n - t]);
+ if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ }
+
+ /* reset y by shifting it back down */
+ mp_rshd (&y, n - t);
+
+ /* step 3. for i from n down to (t + 1) */
+ for (i = n; i >= (t + 1); i--) {
+ if (i > x.used) {
+ continue;
+ }
+
+ /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
+ * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+ if (x.dp[i] == y.dp[t]) {
+ q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
+ } else {
+ mp_word tmp;
+ tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
+ tmp |= ((mp_word) x.dp[i - 1]);
+ tmp /= ((mp_word) y.dp[t]);
+ if (tmp > (mp_word) MP_MASK)
+ tmp = MP_MASK;
+ q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
+ }
+
+ /* while (q{i-t-1} * (yt * b + y{t-1})) >
+ xi * b**2 + xi-1 * b + xi-2
+
+ do q{i-t-1} -= 1;
+ */
+ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
+ do {
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
+
+ /* find left hand */
+ mp_zero (&t1);
+ t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+ t1.dp[1] = y.dp[t];
+ t1.used = 2;
+ if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* find right hand */
+ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+ t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+ t2.dp[2] = x.dp[i];
+ t2.used = 3;
+ } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+ /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+ if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+ if (x.sign == MP_NEG) {
+ if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
+ }
+ }
+
+ /* now q is the quotient and x is the remainder
+ * [which we have to normalize]
+ */
+
+ /* get sign before writing to c */
+ x.sign = x.used == 0 ? MP_ZPOS : a->sign;
+
+ if (c != NULL) {
+ mp_clamp (&q);
+ mp_exch (&q, c);
+ c->sign = neg;
+ }
+
+ if (d != NULL) {
+ mp_div_2d (&x, norm, &x, NULL);
+ mp_exch (&x, d);
+ }
+
+ res = MP_OKAY;
+
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+LBL_Q:mp_clear (&q);
+ return res;
+}
+
+#endif
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_div.c */
+
+/* Start: bn_mp_div_2.c */
+#include "tommath.h"
+#ifdef BN_MP_DIV_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* copy */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* source alias */
+ tmpa = a->dp + b->used - 1;
+
+ /* dest alias */
+ tmpb = b->dp + b->used - 1;
+
+ /* carry */
+ r = 0;
+ for (x = b->used - 1; x >= 0; x--) {
+ /* get the carry for the next iteration */
+ rr = *tmpa & 1;
+
+ /* shift the current digit, add in carry and store */
+ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+ /* forward carry to next iteration */
+ r = rr;
+ }
+
+ /* zero excess digits */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_2.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_div_2.c */
+
+/* Start: bn_mp_div_2d.c */
+#include "tommath.h"
+#ifdef BN_MP_DIV_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
+int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
+{
+ mp_digit D, r, rr;
+ int x, res;
+ mp_int t;
+
+
+ /* if the shift count is <= 0 then we do no work */
+ if (b <= 0) {
+ res = mp_copy (a, c);
+ if (d != NULL) {
+ mp_zero (d);
+ }
+ return res;
+ }
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ /* get the remainder */
+ if (d != NULL) {
+ if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ mp_rshd (c, b / DIGIT_BIT);
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ D = (mp_digit) (b % DIGIT_BIT);
+ if (D != 0) {
+ register mp_digit *tmpc, mask, shift;
+
+ /* mask */
+ mask = (((mp_digit)1) << D) - 1;
+
+ /* shift for lsb */
+ shift = DIGIT_BIT - D;
+
+ /* alias */
+ tmpc = c->dp + (c->used - 1);
+
+ /* carry */
+ r = 0;
+ for (x = c->used - 1; x >= 0; x--) {
+ /* get the lower bits of this word in a temp */
+ rr = *tmpc & mask;
+
+ /* shift the current word and mix in the carry bits from the previous word */
+ *tmpc = (*tmpc >> D) | (r << shift);
+ --tmpc;
+
+ /* set the carry to the carry bits of the current word found above */
+ r = rr;
+ }
+ }
+ mp_clamp (c);
+ if (d != NULL) {
+ mp_exch (&t, d);
+ }
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_div_2d.c */
+
+/* Start: bn_mp_div_3.c */
+#include "tommath.h"
+#ifdef BN_MP_DIV_3_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w, t;
+ mp_digit b;
+ int res, ix;
+
+ /* b = 2**DIGIT_BIT / 3 */
+ b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= 3) {
+ /* multiply w by [1/3] */
+ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+ /* now subtract 3 * [w/3] from w, to get the remainder */
+ w -= t+t+t;
+
+ /* fixup the remainder as required since
+ * the optimization is not exact.
+ */
+ while (w >= 3) {
+ t += 1;
+ w -= 3;
+ }
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ /* [optional] store the remainder */
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ /* [optional] store the quotient */
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_div_3.c */
+
+/* Start: bn_mp_div_d.c */
+#include "tommath.h"
+#ifdef BN_MP_DIV_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+ int x;
+
+ /* fast return if no power of two */
+ if ((b==0) || (b & (b-1))) {
+ return 0;
+ }
+
+ for (x = 0; x < DIGIT_BIT; x++) {
+ if (b == (((mp_digit)1)<<x)) {
+ *p = x;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w;
+ mp_digit t;
+ int res, ix;
+
+ /* cannot divide by zero */
+ if (b == 0) {
+ return MP_VAL;
+ }
+
+ /* quick outs */
+ if (b == 1 || mp_iszero(a) == 1) {
+ if (d != NULL) {
+ *d = 0;
+ }
+ if (c != NULL) {
+ return mp_copy(a, c);
+ }
+ return MP_OKAY;
+ }
+
+ /* power of two ? */
+ if (s_is_power_of_two(b, &ix) == 1) {
+ if (d != NULL) {
+ *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+ }
+ if (c != NULL) {
+ return mp_div_2d(a, ix, c, NULL);
+ }
+ return MP_OKAY;
+ }
+
+#ifdef BN_MP_DIV_3_C
+ /* three? */
+ if (b == 3) {
+ return mp_div_3(a, c, d);
+ }
+#endif
+
+ /* no easy answer [c'est la vie]. Just division */
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= b) {
+ t = (mp_digit)(w / b);
+ w -= ((mp_word)t) * ((mp_word)b);
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_d.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2007/01/09 04:44:32 $ */
+
+/* End: bn_mp_div_d.c */
+
+/* Start: bn_mp_dr_is_modulus.c */
+#include "tommath.h"
+#ifdef BN_MP_DR_IS_MODULUS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines if a number is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a)
+{
+ int ix;
+
+ /* must be at least two digits */
+ if (a->used < 2) {
+ return 0;
+ }
+
+ /* must be of the form b**k - a [a <= b] so all
+ * but the first digit must be equal to -1 (mod b).
+ */
+ for (ix = 1; ix < a->used; ix++) {
+ if (a->dp[ix] != MP_MASK) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_is_modulus.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_dr_is_modulus.c */
+
+/* Start: bn_mp_dr_reduce.c */
+#include "tommath.h"
+#ifdef BN_MP_DR_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ * Chae Hoon Lim, Pil Joong Lee,
+ * POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input x must be in the range 0 <= x <= (n-1)**2
+ */
+int
+mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+{
+ int err, i, m;
+ mp_word r;
+ mp_digit mu, *tmpx1, *tmpx2;
+
+ /* m = digits in modulus */
+ m = n->used;
+
+ /* ensure that "x" has at least 2m digits */
+ if (x->alloc < m + m) {
+ if ((err = mp_grow (x, m + m)) != MP_OKAY) {
+ return err;
+ }
+ }
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+ /* aliases for digits */
+ /* alias for lower half of x */
+ tmpx1 = x->dp;
+
+ /* alias for upper half of x, or x/B**m */
+ tmpx2 = x->dp + m;
+
+ /* set carry to zero */
+ mu = 0;
+
+ /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+ for (i = 0; i < m; i++) {
+ r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+ *tmpx1++ = (mp_digit)(r & MP_MASK);
+ mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
+ }
+
+ /* set final carry */
+ *tmpx1++ = mu;
+
+ /* zero words above m */
+ for (i = m + 1; i < x->used; i++) {
+ *tmpx1++ = 0;
+ }
+
+ /* clamp, sub and return */
+ mp_clamp (x);
+
+ /* if x >= n then subtract and reduce again
+ * Each successive "recursion" makes the input smaller and smaller.
+ */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ s_mp_sub(x, n, x);
+ goto top;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_dr_reduce.c */
+
+/* Start: bn_mp_dr_setup.c */
+#include "tommath.h"
+#ifdef BN_MP_DR_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines the setup value */
+void mp_dr_setup(mp_int *a, mp_digit *d)
+{
+ /* the casts are required if DIGIT_BIT is one less than
+ * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+ */
+ *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
+ ((mp_word)a->dp[0]));
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_dr_setup.c */
+
+/* Start: bn_mp_exch.c */
+#include "tommath.h"
+#ifdef BN_MP_EXCH_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* swap the elements of two integers, for cases where you can't simply swap the
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+ mp_int t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exch.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_exch.c */
+
+/* Start: bn_mp_expt_d.c */
+#include "tommath.h"
+#ifdef BN_MP_EXPT_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* calculate c = a**b using a square-multiply algorithm */
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, x;
+ mp_int g;
+
+ if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* set initial result */
+ mp_set (c, 1);
+
+ for (x = 0; x < (int) DIGIT_BIT; x++) {
+ /* square */
+ if ((res = mp_sqr (c, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+
+ /* if the bit is set multiply */
+ if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
+ if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+ }
+
+ /* shift to next bit */
+ b <<= 1;
+ }
+
+ mp_clear (&g);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_expt_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_expt_d.c */
+
+/* Start: bn_mp_exptmod.c */
+#include "tommath.h"
+#ifdef BN_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+
+/* this is a shell function that calls either the normal or Montgomery
+ * exptmod functions. Originally the call to the montgomery code was
+ * embedded in the normal function but that wasted alot of stack space
+ * for nothing (since 99% of the time the Montgomery code would be called)
+ */
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+{
+ int dr;
+
+ /* modulus P must be positive */
+ if (P->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* if exponent X is negative we have to recurse */
+ if (X->sign == MP_NEG) {
+#ifdef BN_MP_INVMOD_C
+ mp_int tmpG, tmpX;
+ int err;
+
+ /* first compute 1/G mod P */
+ if ((err = mp_init(&tmpG)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+ mp_clear(&tmpG);
+ return err;
+ }
+
+ /* now get |X| */
+ if ((err = mp_init(&tmpX)) != MP_OKAY) {
+ mp_clear(&tmpG);
+ return err;
+ }
+ if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+ mp_clear_multi(&tmpG, &tmpX, NULL);
+ return err;
+ }
+
+ /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+ err = mp_exptmod(&tmpG, &tmpX, P, Y);
+ mp_clear_multi(&tmpG, &tmpX, NULL);
+ return err;
+#else
+ /* no invmod */
+ return MP_VAL;
+#endif
+ }
+
+/* modified diminished radix reduction */
+#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
+ if (mp_reduce_is_2k_l(P) == MP_YES) {
+ return s_mp_exptmod(G, X, P, Y, 1);
+ }
+#endif
+
+#ifdef BN_MP_DR_IS_MODULUS_C
+ /* is it a DR modulus? */
+ dr = mp_dr_is_modulus(P);
+#else
+ /* default to no */
+ dr = 0;
+#endif
+
+#ifdef BN_MP_REDUCE_IS_2K_C
+ /* if not, is it a unrestricted DR modulus? */
+ if (dr == 0) {
+ dr = mp_reduce_is_2k(P) << 1;
+ }
+#endif
+
+ /* if the modulus is odd or dr != 0 use the montgomery method */
+#ifdef BN_MP_EXPTMOD_FAST_C
+ if (mp_isodd (P) == 1 || dr != 0) {
+ return mp_exptmod_fast (G, X, P, Y, dr);
+ } else {
+#endif
+#ifdef BN_S_MP_EXPTMOD_C
+ /* otherwise use the generic Barrett reduction technique */
+ return s_mp_exptmod (G, X, P, Y, 0);
+#else
+ /* no exptmod for evens */
+ return MP_VAL;
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+ }
+#endif
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_exptmod.c */
+
+/* Start: bn_mp_exptmod_fast.c */
+#include "tommath.h"
+#ifdef BN_MP_EXPTMOD_FAST_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+
+#ifdef MP_LOW_MEM
+ #define TAB_SIZE 32
+#else
+ #define TAB_SIZE 256
+#endif
+
+int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+ mp_int M[TAB_SIZE], res;
+ mp_digit buf, mp;
+ int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+
+ /* use a pointer to the reduction algorithm. This allows us to use
+ * one of many reduction algorithms without modding the guts of
+ * the code with if statements everywhere.
+ */
+ int (*redux)(mp_int*,mp_int*,mp_digit);
+
+ /* find window size */
+ x = mp_count_bits (X);
+ if (x <= 7) {
+ winsize = 2;
+ } else if (x <= 36) {
+ winsize = 3;
+ } else if (x <= 140) {
+ winsize = 4;
+ } else if (x <= 450) {
+ winsize = 5;
+ } else if (x <= 1303) {
+ winsize = 6;
+ } else if (x <= 3529) {
+ winsize = 7;
+ } else {
+ winsize = 8;
+ }
+
+#ifdef MP_LOW_MEM
+ if (winsize > 5) {
+ winsize = 5;
+ }
+#endif
+
+ /* init M array */
+ /* init first cell */
+ if ((err = mp_init(&M[1])) != MP_OKAY) {
+ return err;
+ }
+
+ /* now init the second half of the array */
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ if ((err = mp_init(&M[x])) != MP_OKAY) {
+ for (y = 1<<(winsize-1); y < x; y++) {
+ mp_clear (&M[y]);
+ }
+ mp_clear(&M[1]);
+ return err;
+ }
+ }
+
+ /* determine and setup reduction code */
+ if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+ /* now setup montgomery */
+ if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
+ goto LBL_M;
+ }
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+
+ /* automatically pick the comba one if available (saves quite a few calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+ if (((P->used * 2 + 1) < MP_WARRAY) &&
+ P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ redux = fast_mp_montgomery_reduce;
+ } else
+#endif
+ {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+ /* use slower baseline Montgomery method */
+ redux = mp_montgomery_reduce;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ }
+ } else if (redmode == 1) {
+#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
+ /* setup DR reduction for moduli of the form B**k - b */
+ mp_dr_setup(P, &mp);
+ redux = mp_dr_reduce;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ } else {
+#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
+ /* setup DR reduction for moduli of the form 2**k - b */
+ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
+ goto LBL_M;
+ }
+ redux = mp_reduce_2k;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ }
+
+ /* setup result */
+ if ((err = mp_init (&res)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ /* create M table
+ *
+
+ *
+ * The first half of the table is not computed though accept for M[0] and M[1]
+ */
+
+ if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+ /* now we need R mod m */
+ if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+#else
+ err = MP_VAL;
+ goto LBL_RES;
+#endif
+
+ /* now set M[1] to G * R mod m */
+ if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ } else {
+ mp_set(&res, 1);
+ if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+ if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ for (x = 0; x < (winsize - 1); x++) {
+ if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* create upper table */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+ if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* set initial mode and bit cnt */
+ mode = 0;
+ bitcnt = 1;
+ buf = 0;
+ digidx = X->used - 1;
+ bitcpy = 0;
+ bitbuf = 0;
+
+ for (;;) {
+ /* grab next digit as required */
+ if (--bitcnt == 0) {
+ /* if digidx == -1 we are out of digits so break */
+ if (digidx == -1) {
+ break;
+ }
+ /* read next digit and reset bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int)DIGIT_BIT;
+ }
+
+ /* grab the next msb from the exponent */
+ y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
+ buf <<= (mp_digit)1;
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0) {
+ continue;
+ }
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize) {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0) {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* get next bit of the window */
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0) {
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+ }
+ }
+
+ if (redmode == 0) {
+ /* fixup result if Montgomery reduction is used
+ * recall that any value in a Montgomery system is
+ * actually multiplied by R mod n. So we have
+ * to reduce one more time to cancel out the factor
+ * of R.
+ */
+ if ((err = redux(&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* swap res with Y */
+ mp_exch (&res, Y);
+ err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_M:
+ mp_clear(&M[1]);
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ mp_clear (&M[x]);
+ }
+ return err;
+}
+#endif
+
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod_fast.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_exptmod_fast.c */
+
+/* Start: bn_mp_exteuclid.c */
+#include "tommath.h"
+#ifdef BN_MP_EXTEUCLID_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Extended euclidean algorithm of (a, b) produces
+ a*u1 + b*u2 = u3
+ */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+{
+ mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
+ int err;
+
+ if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
+ return err;
+ }
+
+ /* initialize, (u1,u2,u3) = (1,0,a) */
+ mp_set(&u1, 1);
+ if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
+
+ /* initialize, (v1,v2,v3) = (0,1,b) */
+ mp_set(&v2, 1);
+ if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
+
+ /* loop while v3 != 0 */
+ while (mp_iszero(&v3) == MP_NO) {
+ /* q = u3/v3 */
+ if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
+
+ /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+ if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
+
+ /* (u1,u2,u3) = (v1,v2,v3) */
+ if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
+
+ /* (v1,v2,v3) = (t1,t2,t3) */
+ if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
+ }
+
+ /* make sure U3 >= 0 */
+ if (u3.sign == MP_NEG) {
+ mp_neg(&u1, &u1);
+ mp_neg(&u2, &u2);
+ mp_neg(&u3, &u3);
+ }
+
+ /* copy result out */
+ if (U1 != NULL) { mp_exch(U1, &u1); }
+ if (U2 != NULL) { mp_exch(U2, &u2); }
+ if (U3 != NULL) { mp_exch(U3, &u3); }
+
+ err = MP_OKAY;
+_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_exteuclid.c */
+
+/* Start: bn_mp_fread.c */
+#include "tommath.h"
+#ifdef BN_MP_FREAD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* read a bigint from a file stream in ASCII */
+int mp_fread(mp_int *a, int radix, FILE *stream)
+{
+ int err, ch, neg, y;
+
+ /* clear a */
+ mp_zero(a);
+
+ /* if first digit is - then set negative */
+ ch = fgetc(stream);
+ if (ch == '-') {
+ neg = MP_NEG;
+ ch = fgetc(stream);
+ } else {
+ neg = MP_ZPOS;
+ }
+
+ for (;;) {
+ /* find y in the radix map */
+ for (y = 0; y < radix; y++) {
+ if (mp_s_rmap[y] == ch) {
+ break;
+ }
+ }
+ if (y == radix) {
+ break;
+ }
+
+ /* shift up and add */
+ if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
+ return err;
+ }
+
+ ch = fgetc(stream);
+ }
+ if (mp_cmp_d(a, 0) != MP_EQ) {
+ a->sign = neg;
+ }
+
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_fread.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_fread.c */
+
+/* Start: bn_mp_fwrite.c */
+#include "tommath.h"
+#ifdef BN_MP_FWRITE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+int mp_fwrite(mp_int *a, int radix, FILE *stream)
+{
+ char *buf;
+ int err, len, x;
+
+ if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+ return err;
+ }
+
+ buf = OPT_CAST(char) XMALLOC (len);
+ if (buf == NULL) {
+ return MP_MEM;
+ }
+
+ if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
+ XFREE (buf);
+ return err;
+ }
+
+ for (x = 0; x < len; x++) {
+ if (fputc(buf[x], stream) == EOF) {
+ XFREE (buf);
+ return MP_VAL;
+ }
+ }
+
+ XFREE (buf);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_fwrite.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_fwrite.c */
+
+/* Start: bn_mp_gcd.c */
+#include "tommath.h"
+#ifdef BN_MP_GCD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Greatest Common Divisor using the binary method */
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int u, v;
+ int k, u_lsb, v_lsb, res;
+
+ /* either zero than gcd is the largest */
+ if (mp_iszero (a) == MP_YES) {
+ return mp_abs (b, c);
+ }
+ if (mp_iszero (b) == MP_YES) {
+ return mp_abs (a, c);
+ }
+
+ /* get copies of a and b we can modify */
+ if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
+ goto LBL_U;
+ }
+
+ /* must be positive for the remainder of the algorithm */
+ u.sign = v.sign = MP_ZPOS;
+
+ /* B1. Find the common power of two for u and v */
+ u_lsb = mp_cnt_lsb(&u);
+ v_lsb = mp_cnt_lsb(&v);
+ k = MIN(u_lsb, v_lsb);
+
+ if (k > 0) {
+ /* divide the power of two out */
+ if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+
+ if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ /* divide any remaining factors of two out */
+ if (u_lsb != k) {
+ if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ if (v_lsb != k) {
+ if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ while (mp_iszero(&v) == 0) {
+ /* make sure v is the largest */
+ if (mp_cmp_mag(&u, &v) == MP_GT) {
+ /* swap u and v to make sure v is >= u */
+ mp_exch(&u, &v);
+ }
+
+ /* subtract smallest from largest */
+ if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+ goto LBL_V;
+ }
+
+ /* Divide out all factors of two */
+ if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ /* multiply by 2**k which we divided out at the beginning */
+ if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ c->sign = MP_ZPOS;
+ res = MP_OKAY;
+LBL_V:mp_clear (&u);
+LBL_U:mp_clear (&v);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_gcd.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_gcd.c */
+
+/* Start: bn_mp_get_int.c */
+#include "tommath.h"
+#ifdef BN_MP_GET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* get the lower 32-bits of an mp_int */
+unsigned long mp_get_int(mp_int * a)
+{
+ int i;
+ unsigned long res;
+
+ if (a->used == 0) {
+ return 0;
+ }
+
+ /* get number of digits of the lsb we have to read */
+ i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
+
+ /* get most significant digit of result */
+ res = DIGIT(a,i);
+
+ while (--i >= 0) {
+ res = (res << DIGIT_BIT) | DIGIT(a,i);
+ }
+
+ /* force result to 32-bits always so it is consistent on non 32-bit platforms */
+ return res & 0xFFFFFFFFUL;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_get_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_get_int.c */
+
+/* Start: bn_mp_grow.c */
+#include "tommath.h"
+#ifdef BN_MP_GROW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+ int i;
+ mp_digit *tmp;
+
+ /* if the alloc size is smaller alloc more ram */
+ if (a->alloc < size) {
+ /* ensure there are always at least MP_PREC digits extra on top */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* reallocate the array a->dp
+ *
+ * We store the return in a temporary variable
+ * in case the operation failed we don't want
+ * to overwrite the dp member of a.
+ */
+ tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
+ if (tmp == NULL) {
+ /* reallocation failed but "a" is still valid [can be freed] */
+ return MP_MEM;
+ }
+
+ /* reallocation succeeded so set a->dp */
+ a->dp = tmp;
+
+ /* zero excess digits */
+ i = a->alloc;
+ a->alloc = size;
+ for (; i < a->alloc; i++) {
+ a->dp[i] = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_grow.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_grow.c */
+
+/* Start: bn_mp_init.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+ int i;
+
+ /* allocate memory required and clear it */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the digits to zero */
+ for (i = 0; i < MP_PREC; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* set the used to zero, allocated digits to the default precision
+ * and sign to positive */
+ a->used = 0;
+ a->alloc = MP_PREC;
+ a->sign = MP_ZPOS;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init.c */
+
+/* Start: bn_mp_init_copy.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+ int res;
+
+ if ((res = mp_init (a)) != MP_OKAY) {
+ return res;
+ }
+ return mp_copy (b, a);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_copy.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init_copy.c */
+
+/* Start: bn_mp_init_multi.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+#include <stdarg.h>
+
+int mp_init_multi(mp_int *mp, ...)
+{
+ mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
+ int n = 0; /* Number of ok inits */
+ mp_int* cur_arg = mp;
+ va_list args;
+
+ va_start(args, mp); /* init args to next argument from caller */
+ while (cur_arg != NULL) {
+ if (mp_init(cur_arg) != MP_OKAY) {
+ /* Oops - error! Back-track and mp_clear what we already
+ succeeded in init-ing, then return error.
+ */
+ va_list clean_args;
+
+ /* end the current list */
+ va_end(args);
+
+ /* now start cleaning up */
+ cur_arg = mp;
+ va_start(clean_args, mp);
+ while (n--) {
+ mp_clear(cur_arg);
+ cur_arg = va_arg(clean_args, mp_int*);
+ }
+ va_end(clean_args);
+ res = MP_MEM;
+ break;
+ }
+ n++;
+ cur_arg = va_arg(args, mp_int*);
+ }
+ va_end(args);
+ return res; /* Assumed ok, if error flagged above. */
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_multi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init_multi.c */
+
+/* Start: bn_mp_init_set.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ mp_set(a, b);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_set.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init_set.c */
+
+/* Start: bn_mp_init_set_int.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* initialize and set a digit */
+int mp_init_set_int (mp_int * a, unsigned long b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ return mp_set_int(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_set_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init_set_int.c */
+
+/* Start: bn_mp_init_size.c */
+#include "tommath.h"
+#ifdef BN_MP_INIT_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+ int x;
+
+ /* pad size so there are always extra digits */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* alloc mem */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the members */
+ a->used = 0;
+ a->alloc = size;
+ a->sign = MP_ZPOS;
+
+ /* zero the digits */
+ for (x = 0; x < size; x++) {
+ a->dp[x] = 0;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_init_size.c */
+
+/* Start: bn_mp_invmod.c */
+#include "tommath.h"
+#ifdef BN_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ /* b cannot be negative */
+ if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ return MP_VAL;
+ }
+
+#ifdef BN_FAST_MP_INVMOD_C
+ /* if the modulus is odd we can use a faster routine instead */
+ if (mp_isodd (b) == 1) {
+ return fast_mp_invmod (a, b, c);
+ }
+#endif
+
+#ifdef BN_MP_INVMOD_SLOW_C
+ return mp_invmod_slow(a, b, c);
+#endif
+
+ return MP_VAL;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_invmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_invmod.c */
+
+/* Start: bn_mp_invmod_slow.c */
+#include "tommath.h"
+#ifdef BN_MP_INVMOD_SLOW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x, y, u, v, A, B, C, D;
+ int res;
+
+ /* b cannot be negative */
+ if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ return MP_VAL;
+ }
+
+ /* init temps */
+ if ((res = mp_init_multi(&x, &y, &u, &v,
+ &A, &B, &C, &D, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* x = a, y = b */
+ if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (b, &y)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* 2. [modified] if x,y are both even then return an error! */
+ if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ mp_set (&A, 1);
+ mp_set (&D, 1);
+
+top:
+ /* 4. while u is even do */
+ while (mp_iseven (&u) == 1) {
+ /* 4.1 u = u/2 */
+ if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 4.2 if A or B is odd then */
+ if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+ /* A = (A+y)/2, B = (B-x)/2 */
+ if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* A = A/2, B = B/2 */
+ if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 5. while v is even do */
+ while (mp_iseven (&v) == 1) {
+ /* 5.1 v = v/2 */
+ if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 5.2 if C or D is odd then */
+ if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+ /* C = (C+y)/2, D = (D-x)/2 */
+ if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* C = C/2, D = D/2 */
+ if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 6. if u >= v then */
+ if (mp_cmp (&u, &v) != MP_LT) {
+ /* u = u - v, A = A - C, B = B - D */
+ if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ } else {
+ /* v - v - u, C = C - A, D = D - B */
+ if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* if not zero goto step 4 */
+ if (mp_iszero (&u) == 0)
+ goto top;
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (mp_cmp_d (&v, 1) != MP_EQ) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* if its too low */
+ while (mp_cmp_d(&C, 0) == MP_LT) {
+ if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* too big */
+ while (mp_cmp_mag(&C, b) != MP_LT) {
+ if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* C is now the inverse */
+ mp_exch (&C, c);
+ res = MP_OKAY;
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_invmod_slow.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_invmod_slow.c */
+
+/* Start: bn_mp_is_square.c */
+#include "tommath.h"
+#ifdef BN_MP_IS_SQUARE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Check if remainders are possible squares - fast exclude non-squares */
+static const char rem_128[128] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
+};
+
+static const char rem_105[105] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
+};
+
+/* Store non-zero to ret if arg is square, and zero if not */
+int mp_is_square(mp_int *arg,int *ret)
+{
+ int res;
+ mp_digit c;
+ mp_int t;
+ unsigned long r;
+
+ /* Default to Non-square :) */
+ *ret = MP_NO;
+
+ if (arg->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* digits used? (TSD) */
+ if (arg->used == 0) {
+ return MP_OKAY;
+ }
+
+ /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
+ if (rem_128[127 & DIGIT(arg,0)] == 1) {
+ return MP_OKAY;
+ }
+
+ /* Next check mod 105 (3*5*7) */
+ if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
+ return res;
+ }
+ if (rem_105[c] == 1) {
+ return MP_OKAY;
+ }
+
+
+ if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
+ return res;
+ }
+ if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+ r = mp_get_int(&t);
+ /* Check for other prime modules, note it's not an ERROR but we must
+ * free "t" so the easiest way is to goto ERR. We know that res
+ * is already equal to MP_OKAY from the mp_mod call
+ */
+ if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
+ if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
+ if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
+ if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
+ if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
+ if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
+ if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
+
+ /* Final check - is sqr(sqrt(arg)) == arg ? */
+ if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
+ERR:mp_clear(&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_is_square.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_is_square.c */
+
+/* Start: bn_mp_jacobi.c */
+#include "tommath.h"
+#ifdef BN_MP_JACOBI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ */
+int mp_jacobi (mp_int * a, mp_int * p, int *c)
+{
+ mp_int a1, p1;
+ int k, s, r, res;
+ mp_digit residue;
+
+ /* if p <= 0 return MP_VAL */
+ if (mp_cmp_d(p, 0) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* step 1. if a == 0, return 0 */
+ if (mp_iszero (a) == 1) {
+ *c = 0;
+ return MP_OKAY;
+ }
+
+ /* step 2. if a == 1, return 1 */
+ if (mp_cmp_d (a, 1) == MP_EQ) {
+ *c = 1;
+ return MP_OKAY;
+ }
+
+ /* default */
+ s = 0;
+
+ /* step 3. write a = a1 * 2**k */
+ if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init (&p1)) != MP_OKAY) {
+ goto LBL_A1;
+ }
+
+ /* divide out larger power of two */
+ k = mp_cnt_lsb(&a1);
+ if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+
+ /* step 4. if e is even set s=1 */
+ if ((k & 1) == 0) {
+ s = 1;
+ } else {
+ /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+ residue = p->dp[0] & 7;
+
+ if (residue == 1 || residue == 7) {
+ s = 1;
+ } else if (residue == 3 || residue == 5) {
+ s = -1;
+ }
+ }
+
+ /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+ if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
+ s = -s;
+ }
+
+ /* if a1 == 1 we're done */
+ if (mp_cmp_d (&a1, 1) == MP_EQ) {
+ *c = s;
+ } else {
+ /* n1 = n mod a1 */
+ if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+ if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+ *c = s * r;
+ }
+
+ /* done */
+ res = MP_OKAY;
+LBL_P1:mp_clear (&p1);
+LBL_A1:mp_clear (&a1);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_jacobi.c */
+
+/* Start: bn_mp_karatsuba_mul.c */
+#include "tommath.h"
+#ifdef BN_MP_KARATSUBA_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* c = |a| * |b| using Karatsuba Multiplication using
+ * three half size multiplications
+ *
+ * Let B represent the radix [e.g. 2**DIGIT_BIT] and
+ * let n represent half of the number of digits in
+ * the min(a,b)
+ *
+ * a = a1 * B**n + a0
+ * b = b1 * B**n + b0
+ *
+ * Then, a * b =>
+ a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
+ *
+ * Note that a1b1 and a0b0 are used twice and only need to be
+ * computed once. So in total three half size (half # of
+ * digit) multiplications are performed, a0b0, a1b1 and
+ * (a1+b1)(a0+b0)
+ *
+ * Note that a multiplication of half the digits requires
+ * 1/4th the number of single precision multiplications so in
+ * total after one call 25% of the single precision multiplications
+ * are saved. Note also that the call to mp_mul can end up back
+ * in this function if the a0, a1, b0, or b1 are above the threshold.
+ * This is known as divide-and-conquer and leads to the famous
+ * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
+ * the standard O(N**2) that the baseline/comba methods use.
+ * Generally though the overhead of this method doesn't pay off
+ * until a certain size (N ~ 80) is reached.
+ */
+int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
+ int B, err;
+
+ /* default the return code to an error */
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = MIN (a->used, b->used);
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+ if (mp_init_size (&y0, B) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&y1, b->used - B) != MP_OKAY)
+ goto Y0;
+
+ /* init temps */
+ if (mp_init_size (&t1, B * 2) != MP_OKAY)
+ goto Y1;
+ if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
+ goto X0Y0;
+
+ /* now shift the digits */
+ x0.used = y0.used = B;
+ x1.used = a->used - B;
+ y1.used = b->used - B;
+
+ {
+ register int x;
+ register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
+
+ /* we copy the digits directly instead of using higher level functions
+ * since we also need to shift the digits
+ */
+ tmpa = a->dp;
+ tmpb = b->dp;
+
+ tmpx = x0.dp;
+ tmpy = y0.dp;
+ for (x = 0; x < B; x++) {
+ *tmpx++ = *tmpa++;
+ *tmpy++ = *tmpb++;
+ }
+
+ tmpx = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *tmpx++ = *tmpa++;
+ }
+
+ tmpy = y1.dp;
+ for (x = B; x < b->used; x++) {
+ *tmpy++ = *tmpb++;
+ }
+ }
+
+ /* only need to clamp the lower words since by definition the
+ * upper words x1/y1 must have a known number of digits
+ */
+ mp_clamp (&x0);
+ mp_clamp (&y0);
+
+ /* now calc the products x0y0 and x1y1 */
+ /* after this x0 is no longer required, free temp [x0==t2]! */
+ if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
+ goto X1Y1; /* x0y0 = x0*y0 */
+ if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1*y1 */
+
+ /* now calc x1+x0 and y1+y0 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x1 - x0 */
+ if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = y1 - y0 */
+ if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
+
+ /* add x0y0 */
+ if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = x0y0 + x1y1 */
+ if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+ if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1y1 << 2*B */
+
+ if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 */
+ if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
+
+ /* Algorithm succeeded set the return code to MP_OKAY */
+ err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_mul.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_karatsuba_mul.c */
+
+/* Start: bn_mp_karatsuba_sqr.c */
+#include "tommath.h"
+#ifdef BN_MP_KARATSUBA_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Karatsuba squaring, computes b = a*a using three
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details. It
+ * is essentially the same algorithm but merely
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+ mp_int x0, x1, t1, t2, x0x0, x1x1;
+ int B, err;
+
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = a->used;
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+
+ /* init temps */
+ if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
+ goto T2;
+ if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
+ goto X0X0;
+
+ {
+ register int x;
+ register mp_digit *dst, *src;
+
+ src = a->dp;
+
+ /* now shift the digits */
+ dst = x0.dp;
+ for (x = 0; x < B; x++) {
+ *dst++ = *src++;
+ }
+
+ dst = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *dst++ = *src++;
+ }
+ }
+
+ x0.used = B;
+ x1.used = a->used - B;
+
+ mp_clamp (&x0);
+
+ /* now calc the products x0*x0 and x1*x1 */
+ if (mp_sqr (&x0, &x0x0) != MP_OKAY)
+ goto X1X1; /* x0x0 = x0*x0 */
+ if (mp_sqr (&x1, &x1x1) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1*x1 */
+
+ /* now calc (x1+x0)**2 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x1 - x0 */
+ if (mp_sqr (&t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
+
+ /* add x0y0 */
+ if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
+ goto X1X1; /* t2 = x0x0 + x1x1 */
+ if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
+ if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1x1 << 2*B */
+
+ if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 */
+ if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
+
+ err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_karatsuba_sqr.c */
+
+/* Start: bn_mp_lcm.c */
+#include "tommath.h"
+#ifdef BN_MP_LCM_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res;
+ mp_int t1, t2;
+
+
+ if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* t1 = get the GCD of the two inputs */
+ if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+ goto LBL_T;
+ }
+
+ /* divide the smallest by the GCD */
+ if (mp_cmp_mag(a, b) == MP_LT) {
+ /* store quotient in t2 such that t2 * b is the LCM */
+ if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(b, &t2, c);
+ } else {
+ /* store quotient in t2 such that t2 * a is the LCM */
+ if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(a, &t2, c);
+ }
+
+ /* fix the sign to positive */
+ c->sign = MP_ZPOS;
+
+LBL_T:
+ mp_clear_multi (&t1, &t2, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_lcm.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_lcm.c */
+
+/* Start: bn_mp_lshd.c */
+#include "tommath.h"
+#ifdef BN_MP_LSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+ int x, res;
+
+ /* if its less than zero return */
+ if (b <= 0) {
+ return MP_OKAY;
+ }
+
+ /* grow to fit the new digits */
+ if (a->alloc < a->used + b) {
+ if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ {
+ register mp_digit *top, *bottom;
+
+ /* increment the used by the shift amount then copy upwards */
+ a->used += b;
+
+ /* top */
+ top = a->dp + a->used - 1;
+
+ /* base */
+ bottom = a->dp + a->used - 1 - b;
+
+ /* much like mp_rshd this is implemented using a sliding window
+ * except the window goes the otherway around. Copying from
+ * the bottom to the top. see bn_mp_rshd.c for more info.
+ */
+ for (x = a->used - 1; x >= b; x--) {
+ *top-- = *bottom--;
+ }
+
+ /* zero the lower digits */
+ top = a->dp;
+ for (x = 0; x < b; x++) {
+ *top++ = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_lshd.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_lshd.c */
+
+/* Start: bn_mp_mod.c */
+#include "tommath.h"
+#ifdef BN_MP_MOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int t;
+ int res;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ if (t.sign != b->sign) {
+ res = mp_add (b, &t, c);
+ } else {
+ res = MP_OKAY;
+ mp_exch (&t, c);
+ }
+
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mod.c */
+
+/* Start: bn_mp_mod_2d.c */
+#include "tommath.h"
+#ifdef BN_MP_MOD_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (mp_int * a, int b, mp_int * c)
+{
+ int x, res;
+
+ /* if b is <= 0 then zero the int */
+ if (b <= 0) {
+ mp_zero (c);
+ return MP_OKAY;
+ }
+
+ /* if the modulus is larger than the value than return */
+ if (b >= (int) (a->used * DIGIT_BIT)) {
+ res = mp_copy (a, c);
+ return res;
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+
+ /* zero digits above the last digit of the modulus */
+ for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+ c->dp[x] = 0;
+ }
+ /* clear the digit that is not completely outside/inside the modulus */
+ c->dp[b / DIGIT_BIT] &=
+ (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mod_2d.c */
+
+/* Start: bn_mp_mod_d.c */
+#include "tommath.h"
+#ifdef BN_MP_MOD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+int
+mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+{
+ return mp_div_d(a, b, NULL, c);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mod_d.c */
+
+/* Start: bn_mp_montgomery_calc_normalization.c */
+#include "tommath.h"
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b. This saves alot of multiple precision shifting.
+ */
+int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+{
+ int x, bits, res;
+
+ /* how many bits of last digit does b use */
+ bits = mp_count_bits (b) % DIGIT_BIT;
+
+ if (b->used > 1) {
+ if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
+ return res;
+ }
+ } else {
+ mp_set(a, 1);
+ bits = 1;
+ }
+
+
+ /* now compute C = A * B mod b */
+ for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
+ if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
+ return res;
+ }
+ if (mp_cmp_mag (a, b) != MP_LT) {
+ if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
+ return res;
+ }
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_montgomery_calc_normalization.c */
+
+/* Start: bn_mp_montgomery_reduce.c */
+#include "tommath.h"
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+int
+mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+ int ix, res, digs;
+ mp_digit mu;
+
+ /* can the fast reduction [comba] method be used?
+ *
+ * Note that unlike in mul you're safely allowed *less*
+ * than the available columns [255 per default] since carries
+ * are fixed up in the inner loop.
+ */
+ digs = n->used * 2 + 1;
+ if ((digs < MP_WARRAY) &&
+ n->used <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_mp_montgomery_reduce (x, n, rho);
+ }
+
+ /* grow the input as required */
+ if (x->alloc < digs) {
+ if ((res = mp_grow (x, digs)) != MP_OKAY) {
+ return res;
+ }
+ }
+ x->used = digs;
+
+ for (ix = 0; ix < n->used; ix++) {
+ /* mu = ai * rho mod b
+ *
+ * The value of rho must be precalculated via
+ * montgomery_setup() such that
+ * it equals -1/n0 mod b this allows the
+ * following inner loop to reduce the
+ * input one digit at a time
+ */
+ mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
+
+ /* a = a + mu * m * b**i */
+ {
+ register int iy;
+ register mp_digit *tmpn, *tmpx, u;
+ register mp_word r;
+
+ /* alias for digits of the modulus */
+ tmpn = n->dp;
+
+ /* alias for the digits of x [the input] */
+ tmpx = x->dp + ix;
+
+ /* set the carry to zero */
+ u = 0;
+
+ /* Multiply and add in place */
+ for (iy = 0; iy < n->used; iy++) {
+ /* compute product and sum */
+ r = ((mp_word)mu) * ((mp_word)*tmpn++) +
+ ((mp_word) u) + ((mp_word) * tmpx);
+
+ /* get carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+ /* fix digit */
+ *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
+ }
+ /* At this point the ix'th digit of x should be zero */
+
+
+ /* propagate carries upwards as required*/
+ while (u) {
+ *tmpx += u;
+ u = *tmpx >> DIGIT_BIT;
+ *tmpx++ &= MP_MASK;
+ }
+ }
+ }
+
+ /* at this point the n.used'th least
+ * significant digits of x are all zero
+ * which means we can shift x to the
+ * right by n.used digits and the
+ * residue is unchanged.
+ */
+
+ /* x = x/b**n.used */
+ mp_clamp(x);
+ mp_rshd (x, n->used);
+
+ /* if x >= n then x = x - n */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ return s_mp_sub (x, n, x);
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_montgomery_reduce.c */
+
+/* Start: bn_mp_montgomery_setup.c */
+#include "tommath.h"
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* setups the montgomery reduction stuff */
+int
+mp_montgomery_setup (mp_int * n, mp_digit * rho)
+{
+ mp_digit x, b;
+
+/* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
+ * => 2*X*A - X*X*A*A = 1
+ * => 2*(1) - (1) = 1
+ */
+ b = n->dp[0];
+
+ if ((b & 1) == 0) {
+ return MP_VAL;
+ }
+
+ x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**8 */
+#if !defined(MP_8BIT)
+ x *= 2 - b * x; /* here x*a==1 mod 2**16 */
+#endif
+#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
+ x *= 2 - b * x; /* here x*a==1 mod 2**32 */
+#endif
+#ifdef MP_64BIT
+ x *= 2 - b * x; /* here x*a==1 mod 2**64 */
+#endif
+
+ /* rho = -1/m mod b */
+ *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_setup.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_montgomery_setup.c */
+
+/* Start: bn_mp_mul.c */
+#include "tommath.h"
+#ifdef BN_MP_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, neg;
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+ /* use Toom-Cook? */
+#ifdef BN_MP_TOOM_MUL_C
+ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
+ res = mp_toom_mul(a, b, c);
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+ /* use Karatsuba? */
+ if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+ res = mp_karatsuba_mul (a, b, c);
+ } else
+#endif
+ {
+ /* can we use the fast multiplier?
+ *
+ * The fast multiplier can be used if the output will
+ * have less than MP_WARRAY digits and the number of
+ * digits won't affect carry propagation
+ */
+ int digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+ if ((digs < MP_WARRAY) &&
+ MIN(a->used, b->used) <=
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ res = fast_s_mp_mul_digs (a, b, c, digs);
+ } else
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+ res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+ res = MP_VAL;
+#endif
+
+ }
+ c->sign = (c->used > 0) ? neg : MP_ZPOS;
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mul.c */
+
+/* Start: bn_mp_mul_2.c */
+#include "tommath.h"
+#ifdef BN_MP_MUL_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* grow to accomodate result */
+ if (b->alloc < a->used + 1) {
+ if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* alias for source */
+ tmpa = a->dp;
+
+ /* alias for dest */
+ tmpb = b->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < a->used; x++) {
+
+ /* get what will be the *next* carry bit from the
+ * MSB of the current digit
+ */
+ rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+
+ /* now shift up this digit, add in the carry [from the previous] */
+ *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+
+ /* copy the carry that would be from the source
+ * digit into the next iteration
+ */
+ r = rr;
+ }
+
+ /* new leading digit? */
+ if (r != 0) {
+ /* add a MSB which is always 1 at this point */
+ *tmpb = 1;
+ ++(b->used);
+ }
+
+ /* now zero any excess digits on the destination
+ * that we didn't write to
+ */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mul_2.c */
+
+/* Start: bn_mp_mul_2d.c */
+#include "tommath.h"
+#ifdef BN_MP_MUL_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* shift left by a certain bit count */
+int mp_mul_2d (mp_int * a, int b, mp_int * c)
+{
+ mp_digit d;
+ int res;
+
+ /* copy */
+ if (a != c) {
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+ if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ d = (mp_digit) (b % DIGIT_BIT);
+ if (d != 0) {
+ register mp_digit *tmpc, shift, mask, r, rr;
+ register int x;
+
+ /* bitmask for carries */
+ mask = (((mp_digit)1) << d) - 1;
+
+ /* shift for msbs */
+ shift = DIGIT_BIT - d;
+
+ /* alias */
+ tmpc = c->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < c->used; x++) {
+ /* get the higher bits of the current word */
+ rr = (*tmpc >> shift) & mask;
+
+ /* shift the current word and OR in the carry */
+ *tmpc = ((*tmpc << d) | r) & MP_MASK;
+ ++tmpc;
+
+ /* set the carry to the carry bits of the current word */
+ r = rr;
+ }
+
+ /* set final carry */
+ if (r != 0) {
+ c->dp[(c->used)++] = r;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mul_2d.c */
+
+/* Start: bn_mp_mul_d.c */
+#include "tommath.h"
+#ifdef BN_MP_MUL_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit u, *tmpa, *tmpc;
+ mp_word r;
+ int ix, res, olduse;
+
+ /* make sure c is big enough to hold a*b */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get the original destinations used count */
+ olduse = c->used;
+
+ /* set the sign */
+ c->sign = a->sign;
+
+ /* alias for a->dp [source] */
+ tmpa = a->dp;
+
+ /* alias for c->dp [dest] */
+ tmpc = c->dp;
+
+ /* zero carry */
+ u = 0;
+
+ /* compute columns */
+ for (ix = 0; ix < a->used; ix++) {
+ /* compute product and carry sum for this term */
+ r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+ /* mask off higher bits to get a single digit */
+ *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* send carry into next iteration */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+
+ /* store final carry [if any] and increment ix offset */
+ *tmpc++ = u;
+ ++ix;
+
+ /* now zero digits above the top */
+ while (ix++ < olduse) {
+ *tmpc++ = 0;
+ }
+
+ /* set used count */
+ c->used = a->used + 1;
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mul_d.c */
+
+/* Start: bn_mp_mulmod.c */
+#include "tommath.h"
+#ifdef BN_MP_MULMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* d = a * b (mod c) */
+int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mulmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_mulmod.c */
+
+/* Start: bn_mp_n_root.c */
+#include "tommath.h"
+#ifdef BN_MP_N_ROOT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* find the n'th root of an integer
+ *
+ * Result found such that (c)**b <= a and (c+1)**b > a
+ *
+ * This algorithm uses Newton's approximation
+ * x[i+1] = x[i] - f(x[i])/f'(x[i])
+ * which will find the root in log(N) time where
+ * each step involves a fair bit. This is not meant to
+ * find huge roots [square and cube, etc].
+ */
+int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_int t1, t2, t3;
+ int res, neg;
+
+ /* input must be positive if b is even */
+ if ((b & 1) == 0 && a->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ if ((res = mp_init (&t1)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init (&t2)) != MP_OKAY) {
+ goto LBL_T1;
+ }
+
+ if ((res = mp_init (&t3)) != MP_OKAY) {
+ goto LBL_T2;
+ }
+
+ /* if a is negative fudge the sign but keep track */
+ neg = a->sign;
+ a->sign = MP_ZPOS;
+
+ /* t2 = 2 */
+ mp_set (&t2, 2);
+
+ do {
+ /* t1 = t2 */
+ if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
+
+ /* t3 = t1**(b-1) */
+ if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* numerator */
+ /* t2 = t1**b */
+ if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t2 = t1**b - a */
+ if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* denominator */
+ /* t3 = t1**(b-1) * b */
+ if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t3 = (t1**b - a)/(b * t1**(b-1)) */
+ if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+ } while (mp_cmp (&t1, &t2) != MP_EQ);
+
+ /* result can be off by a few so check */
+ for (;;) {
+ if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ if (mp_cmp (&t2, a) == MP_GT) {
+ if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+ } else {
+ break;
+ }
+ }
+
+ /* reset the sign of a first */
+ a->sign = neg;
+
+ /* set the result */
+ mp_exch (&t1, c);
+
+ /* set the sign of the result */
+ c->sign = neg;
+
+ res = MP_OKAY;
+
+LBL_T3:mp_clear (&t3);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_n_root.c */
+
+/* Start: bn_mp_neg.c */
+#include "tommath.h"
+#ifdef BN_MP_NEG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* b = -a */
+int mp_neg (mp_int * a, mp_int * b)
+{
+ int res;
+ if (a != b) {
+ if ((res = mp_copy (a, b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (mp_iszero(b) != MP_YES) {
+ b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ } else {
+ b->sign = MP_ZPOS;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_neg.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_neg.c */
+
+/* Start: bn_mp_or.c */
+#include "tommath.h"
+#ifdef BN_MP_OR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* OR two ints together */
+int mp_or (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] |= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_or.c */
+
+/* Start: bn_mp_prime_fermat.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_FERMAT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* performs one Fermat test.
+ *
+ * If "a" were prime then b**a == b (mod a) since the order of
+ * the multiplicative sub-group would be phi(a) = a-1. That means
+ * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
+ *
+ * Sets result to 1 if the congruence holds, or zero otherwise.
+ */
+int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+{
+ mp_int t;
+ int err;
+
+ /* default to composite */
+ *result = MP_NO;
+
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* init t */
+ if ((err = mp_init (&t)) != MP_OKAY) {
+ return err;
+ }
+
+ /* compute t = b**a mod a */
+ if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
+ goto LBL_T;
+ }
+
+ /* is it equal to b? */
+ if (mp_cmp (&t, b) == MP_EQ) {
+ *result = MP_YES;
+ }
+
+ err = MP_OKAY;
+LBL_T:mp_clear (&t);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_fermat.c */
+
+/* Start: bn_mp_prime_is_divisible.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines if an integers is divisible by one
+ * of the first PRIME_SIZE primes or not
+ *
+ * sets result to 0 if not, 1 if yes
+ */
+int mp_prime_is_divisible (mp_int * a, int *result)
+{
+ int err, ix;
+ mp_digit res;
+
+ /* default to not */
+ *result = MP_NO;
+
+ for (ix = 0; ix < PRIME_SIZE; ix++) {
+ /* what is a mod LBL_prime_tab[ix] */
+ if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
+ return err;
+ }
+
+ /* is the residue zero? */
+ if (res == 0) {
+ *result = MP_YES;
+ return MP_OKAY;
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_divisible.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_is_divisible.c */
+
+/* Start: bn_mp_prime_is_prime.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_IS_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* performs a variable number of rounds of Miller-Rabin
+ *
+ * Probability of error after t rounds is no more than
+
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+{
+ mp_int b;
+ int ix, err, res;
+
+ /* default to no */
+ *result = MP_NO;
+
+ /* valid value of t? */
+ if (t <= 0 || t > PRIME_SIZE) {
+ return MP_VAL;
+ }
+
+ /* is the input equal to one of the primes in the table? */
+ for (ix = 0; ix < PRIME_SIZE; ix++) {
+ if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+ *result = 1;
+ return MP_OKAY;
+ }
+ }
+
+ /* first perform trial division */
+ if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+ return err;
+ }
+
+ /* return if it was trivially divisible */
+ if (res == MP_YES) {
+ return MP_OKAY;
+ }
+
+ /* now perform the miller-rabin rounds */
+ if ((err = mp_init (&b)) != MP_OKAY) {
+ return err;
+ }
+
+ for (ix = 0; ix < t; ix++) {
+ /* set the prime */
+ mp_set (&b, ltm_prime_tab[ix]);
+
+ if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+ goto LBL_B;
+ }
+
+ if (res == MP_NO) {
+ goto LBL_B;
+ }
+ }
+
+ /* passed the test */
+ *result = MP_YES;
+LBL_B:mp_clear (&b);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_prime.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_is_prime.c */
+
+/* Start: bn_mp_prime_miller_rabin.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_MILLER_RABIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Miller-Rabin test of "a" to the base of "b" as described in
+ * HAC pp. 139 Algorithm 4.24
+ *
+ * Sets result to 0 if definitely composite or 1 if probably prime.
+ * Randomly the chance of error is no more than 1/4 and often
+ * very much lower.
+ */
+int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+{
+ mp_int n1, y, r;
+ int s, j, err;
+
+ /* default */
+ *result = MP_NO;
+
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* get n1 = a - 1 */
+ if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
+ goto LBL_N1;
+ }
+
+ /* set 2**s * r = n1 */
+ if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
+ goto LBL_N1;
+ }
+
+ /* count the number of least significant bits
+ * which are zero
+ */
+ s = mp_cnt_lsb(&r);
+
+ /* now divide n - 1 by 2**s */
+ if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
+ goto LBL_R;
+ }
+
+ /* compute y = b**r mod a */
+ if ((err = mp_init (&y)) != MP_OKAY) {
+ goto LBL_R;
+ }
+ if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if y != 1 and y != n1 do */
+ if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
+ j = 1;
+ /* while j <= s-1 and y != n1 */
+ while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
+ if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if y == 1 then composite */
+ if (mp_cmp_d (&y, 1) == MP_EQ) {
+ goto LBL_Y;
+ }
+
+ ++j;
+ }
+
+ /* if y != n1 then composite */
+ if (mp_cmp (&y, &n1) != MP_EQ) {
+ goto LBL_Y;
+ }
+ }
+
+ /* probably prime now */
+ *result = MP_YES;
+LBL_Y:mp_clear (&y);
+LBL_R:mp_clear (&r);
+LBL_N1:mp_clear (&n1);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_miller_rabin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_miller_rabin.c */
+
+/* Start: bn_mp_prime_next_prime.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_NEXT_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
+{
+ int err, res, x, y;
+ mp_digit res_tab[PRIME_SIZE], step, kstep;
+ mp_int b;
+
+ /* ensure t is valid */
+ if (t <= 0 || t > PRIME_SIZE) {
+ return MP_VAL;
+ }
+
+ /* force positive */
+ a->sign = MP_ZPOS;
+
+ /* simple algo if a is less than the largest prime in the table */
+ if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
+ /* find which prime it is bigger than */
+ for (x = PRIME_SIZE - 2; x >= 0; x--) {
+ if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
+ if (bbs_style == 1) {
+ /* ok we found a prime smaller or
+ * equal [so the next is larger]
+ *
+ * however, the prime must be
+ * congruent to 3 mod 4
+ */
+ if ((ltm_prime_tab[x + 1] & 3) != 3) {
+ /* scan upwards for a prime congruent to 3 mod 4 */
+ for (y = x + 1; y < PRIME_SIZE; y++) {
+ if ((ltm_prime_tab[y] & 3) == 3) {
+ mp_set(a, ltm_prime_tab[y]);
+ return MP_OKAY;
+ }
+ }
+ }
+ } else {
+ mp_set(a, ltm_prime_tab[x + 1]);
+ return MP_OKAY;
+ }
+ }
+ }
+ /* at this point a maybe 1 */
+ if (mp_cmp_d(a, 1) == MP_EQ) {
+ mp_set(a, 2);
+ return MP_OKAY;
+ }
+ /* fall through to the sieve */
+ }
+
+ /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
+ if (bbs_style == 1) {
+ kstep = 4;
+ } else {
+ kstep = 2;
+ }
+
+ /* at this point we will use a combination of a sieve and Miller-Rabin */
+
+ if (bbs_style == 1) {
+ /* if a mod 4 != 3 subtract the correct value to make it so */
+ if ((a->dp[0] & 3) != 3) {
+ if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
+ }
+ } else {
+ if (mp_iseven(a) == 1) {
+ /* force odd */
+ if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
+ return err;
+ }
+ }
+ }
+
+ /* generate the restable */
+ for (x = 1; x < PRIME_SIZE; x++) {
+ if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
+ return err;
+ }
+ }
+
+ /* init temp used for Miller-Rabin Testing */
+ if ((err = mp_init(&b)) != MP_OKAY) {
+ return err;
+ }
+
+ for (;;) {
+ /* skip to the next non-trivially divisible candidate */
+ step = 0;
+ do {
+ /* y == 1 if any residue was zero [e.g. cannot be prime] */
+ y = 0;
+
+ /* increase step to next candidate */
+ step += kstep;
+
+ /* compute the new residue without using division */
+ for (x = 1; x < PRIME_SIZE; x++) {
+ /* add the step to each residue */
+ res_tab[x] += kstep;
+
+ /* subtract the modulus [instead of using division] */
+ if (res_tab[x] >= ltm_prime_tab[x]) {
+ res_tab[x] -= ltm_prime_tab[x];
+ }
+
+ /* set flag if zero */
+ if (res_tab[x] == 0) {
+ y = 1;
+ }
+ }
+ } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
+
+ /* add the step */
+ if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* if didn't pass sieve and step == MAX then skip test */
+ if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
+ continue;
+ }
+
+ /* is this prime? */
+ for (x = 0; x < t; x++) {
+ mp_set(&b, ltm_prime_tab[t]);
+ if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if (res == MP_NO) {
+ break;
+ }
+ }
+
+ if (res == MP_YES) {
+ break;
+ }
+ }
+
+ err = MP_OKAY;
+LBL_ERR:
+ mp_clear(&b);
+ return err;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_next_prime.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_next_prime.c */
+
+/* Start: bn_mp_prime_rabin_miller_trials.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+
+static const struct {
+ int k, t;
+} sizes[] = {
+{ 128, 28 },
+{ 256, 16 },
+{ 384, 10 },
+{ 512, 7 },
+{ 640, 6 },
+{ 768, 5 },
+{ 896, 4 },
+{ 1024, 4 }
+};
+
+/* returns # of RM trials required for a given bit size */
+int mp_prime_rabin_miller_trials(int size)
+{
+ int x;
+
+ for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
+ if (sizes[x].k == size) {
+ return sizes[x].t;
+ } else if (sizes[x].k > size) {
+ return (x == 0) ? sizes[0].t : sizes[x - 1].t;
+ }
+ }
+ return sizes[x-1].t + 1;
+}
+
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_rabin_miller_trials.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_rabin_miller_trials.c */
+
+/* Start: bn_mp_prime_random_ex.c */
+#include "tommath.h"
+#ifdef BN_MP_PRIME_RANDOM_EX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ *
+ * LTM_PRIME_BBS - make prime congruent to 3 mod 4
+ * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+
+/* This is possibly the mother of all prime generation functions, muahahahahaha! */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
+{
+ unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
+ int res, err, bsize, maskOR_msb_offset;
+
+ /* sanity check the input */
+ if (size <= 1 || t <= 0) {
+ return MP_VAL;
+ }
+
+ /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
+ if (flags & LTM_PRIME_SAFE) {
+ flags |= LTM_PRIME_BBS;
+ }
+
+ /* calc the byte size */
+ bsize = (size>>3) + ((size&7)?1:0);
+
+ /* we need a buffer of bsize bytes */
+ tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
+ if (tmp == NULL) {
+ return MP_MEM;
+ }
+
+ /* calc the maskAND value for the MSbyte*/
+ maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
+
+ /* calc the maskOR_msb */
+ maskOR_msb = 0;
+ maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
+ if (flags & LTM_PRIME_2MSB_ON) {
+ maskOR_msb |= 0x80 >> ((9 - size) & 7);
+ }
+
+ /* get the maskOR_lsb */
+ maskOR_lsb = 1;
+ if (flags & LTM_PRIME_BBS) {
+ maskOR_lsb |= 3;
+ }
+
+ do {
+ /* read the bytes */
+ if (cb(tmp, bsize, dat) != bsize) {
+ err = MP_VAL;
+ goto error;
+ }
+
+ /* work over the MSbyte */
+ tmp[0] &= maskAND;
+ tmp[0] |= 1 << ((size - 1) & 7);
+
+ /* mix in the maskORs */
+ tmp[maskOR_msb_offset] |= maskOR_msb;
+ tmp[bsize-1] |= maskOR_lsb;
+
+ /* read it in */
+ if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
+
+ /* is it prime? */
+ if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
+ if (res == MP_NO) {
+ continue;
+ }
+
+ if (flags & LTM_PRIME_SAFE) {
+ /* see if (a-1)/2 is prime */
+ if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
+ if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
+
+ /* is it prime? */
+ if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
+ }
+ } while (res == MP_NO);
+
+ if (flags & LTM_PRIME_SAFE) {
+ /* restore a to the original value */
+ if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
+ if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
+ }
+
+ err = MP_OKAY;
+error:
+ XFREE(tmp);
+ return err;
+}
+
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_random_ex.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_prime_random_ex.c */
+
+/* Start: bn_mp_radix_size.c */
+#include "tommath.h"
+#ifdef BN_MP_RADIX_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* returns size of ASCII reprensentation */
+int mp_radix_size (mp_int * a, int radix, int *size)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+
+ *size = 0;
+
+ /* special case for binary */
+ if (radix == 2) {
+ *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+ return MP_OKAY;
+ }
+
+ /* make sure the radix is in range */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ if (mp_iszero(a) == MP_YES) {
+ *size = 2;
+ return MP_OKAY;
+ }
+
+ /* digs is the digit count */
+ digs = 0;
+
+ /* if it's negative add one for the sign */
+ if (a->sign == MP_NEG) {
+ ++digs;
+ }
+
+ /* init a copy of the input */
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* force temp to positive */
+ t.sign = MP_ZPOS;
+
+ /* fetch out all of the digits */
+ while (mp_iszero (&t) == MP_NO) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ ++digs;
+ }
+ mp_clear (&t);
+
+ /* return digs + 1, the 1 is for the NULL byte that would be required. */
+ *size = digs + 1;
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_radix_size.c */
+
+/* Start: bn_mp_radix_smap.c */
+#include "tommath.h"
+#ifdef BN_MP_RADIX_SMAP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_radix_smap.c */
+
+/* Start: bn_mp_rand.c */
+#include "tommath.h"
+#ifdef BN_MP_RAND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* makes a pseudo-random int of a given size */
+int
+mp_rand (mp_int * a, int digits)
+{
+ int res;
+ mp_digit d;
+
+ mp_zero (a);
+ if (digits <= 0) {
+ return MP_OKAY;
+ }
+
+ /* first place a random non-zero digit */
+ do {
+ d = ((mp_digit) abs (rand ())) & MP_MASK;
+ } while (d == 0);
+
+ if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
+ return res;
+ }
+
+ while (--digits > 0) {
+ if ((res = mp_lshd (a, 1)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_rand.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_rand.c */
+
+/* Start: bn_mp_read_radix.c */
+#include "tommath.h"
+#ifdef BN_MP_READ_RADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+ int y, res, neg;
+ char ch;
+
+ /* zero the digit bignum */
+ mp_zero(a);
+
+ /* make sure the radix is ok */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* if the leading digit is a
+ * minus set the sign to negative.
+ */
+ if (*str == '-') {
+ ++str;
+ neg = MP_NEG;
+ } else {
+ neg = MP_ZPOS;
+ }
+
+ /* set the integer to the default of zero */
+ mp_zero (a);
+
+ /* process each digit of the string */
+ while (*str) {
+ /* if the radix < 36 the conversion is case insensitive
+ * this allows numbers like 1AB and 1ab to represent the same value
+ * [e.g. in hex]
+ */
+ ch = (char) ((radix < 36) ? toupper (*str) : *str);
+ for (y = 0; y < 64; y++) {
+ if (ch == mp_s_rmap[y]) {
+ break;
+ }
+ }
+
+ /* if the char was found in the map
+ * and is less than the given radix add it
+ * to the number, otherwise exit the loop.
+ */
+ if (y < radix) {
+ if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+ return res;
+ }
+ if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+ return res;
+ }
+ } else {
+ break;
+ }
+ ++str;
+ }
+
+ /* set the sign only if a != 0 */
+ if (mp_iszero(a) != 1) {
+ a->sign = neg;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_read_radix.c */
+
+/* Start: bn_mp_read_signed_bin.c */
+#include "tommath.h"
+#ifdef BN_MP_READ_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* read signed bin, big endian, first byte is 0==positive or 1==negative */
+int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
+{
+ int res;
+
+ /* read magnitude */
+ if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* first byte is 0 for positive, non-zero for negative */
+ if (b[0] == 0) {
+ a->sign = MP_ZPOS;
+ } else {
+ a->sign = MP_NEG;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_signed_bin.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_read_signed_bin.c */
+
+/* Start: bn_mp_read_unsigned_bin.c */
+#include "tommath.h"
+#ifdef BN_MP_READ_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
+{
+ int res;
+
+ /* make sure there are at least two digits */
+ if (a->alloc < 2) {
+ if ((res = mp_grow(a, 2)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* zero the int */
+ mp_zero (a);
+
+ /* read the bytes in */
+ while (c-- > 0) {
+ if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
+ return res;
+ }
+
+#ifndef MP_8BIT
+ a->dp[0] |= *b++;
+ a->used += 1;
+#else
+ a->dp[0] = (*b & MP_MASK);
+ a->dp[1] |= ((*b++ >> 7U) & 1);
+ a->used += 2;
+#endif
+ }
+ mp_clamp (a);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_unsigned_bin.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_read_unsigned_bin.c */
+
+/* Start: bn_mp_reduce.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reduces x mod m, assumes 0 < x < m**2, mu is
+ * precomputed via mp_reduce_setup.
+ * From HAC pp.604 Algorithm 14.42
+ */
+int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
+{
+ mp_int q;
+ int res, um = m->used;
+
+ /* q = x */
+ if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
+ return res;
+ }
+
+ /* q1 = x / b**(k-1) */
+ mp_rshd (&q, um - 1);
+
+ /* according to HAC this optimization is ok */
+ if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
+ if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+ } else {
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+ if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+ if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+#else
+ {
+ res = MP_VAL;
+ goto CLEANUP;
+ }
+#endif
+ }
+
+ /* q3 = q2 / b**(k+1) */
+ mp_rshd (&q, um + 1);
+
+ /* x = x mod b**(k+1), quick (no division) */
+ if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* q = q * m mod b**(k+1), quick (no division) */
+ if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* x = x - q */
+ if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* If x < 0, add b**(k+1) to it */
+ if (mp_cmp_d (x, 0) == MP_LT) {
+ mp_set (&q, 1);
+ if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
+ goto CLEANUP;
+ if ((res = mp_add (x, &q, x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ /* Back off if it's too big */
+ while (mp_cmp (x, m) != MP_LT) {
+ if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+ }
+
+CLEANUP:
+ mp_clear (&q);
+
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce.c */
+
+/* Start: bn_mp_reduce_2k.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
+{
+ mp_int q;
+ int p, res;
+
+ if ((res = mp_init(&q)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(n);
+top:
+ /* q = a/2**p, a = a mod 2**p */
+ if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (d != 1) {
+ /* q = q * d */
+ if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
+ goto ERR;
+ }
+ }
+
+ /* a = a + q */
+ if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (mp_cmp_mag(a, n) != MP_LT) {
+ s_mp_sub(a, n, a);
+ goto top;
+ }
+
+ERR:
+ mp_clear(&q);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_2k.c */
+
+/* Start: bn_mp_reduce_2k_l.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d
+ This differs from reduce_2k since "d" can be larger
+ than a single digit.
+*/
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
+{
+ mp_int q;
+ int p, res;
+
+ if ((res = mp_init(&q)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(n);
+top:
+ /* q = a/2**p, a = a mod 2**p */
+ if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* q = q * d */
+ if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* a = a + q */
+ if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (mp_cmp_mag(a, n) != MP_LT) {
+ s_mp_sub(a, n, a);
+ goto top;
+ }
+
+ERR:
+ mp_clear(&q);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_2k_l.c */
+
+/* Start: bn_mp_reduce_2k_setup.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_2K_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
+{
+ int res, p;
+ mp_int tmp;
+
+ if ((res = mp_init(&tmp)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(a);
+ if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ *d = tmp.dp[0];
+ mp_clear(&tmp);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_2k_setup.c */
+
+/* Start: bn_mp_reduce_2k_setup_l.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_2K_SETUP_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
+{
+ int res;
+ mp_int tmp;
+
+ if ((res = mp_init(&tmp)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear(&tmp);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_2k_setup_l.c */
+
+/* Start: bn_mp_reduce_is_2k.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_IS_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines if mp_reduce_2k can be used */
+int mp_reduce_is_2k(mp_int *a)
+{
+ int ix, iy, iw;
+ mp_digit iz;
+
+ if (a->used == 0) {
+ return MP_NO;
+ } else if (a->used == 1) {
+ return MP_YES;
+ } else if (a->used > 1) {
+ iy = mp_count_bits(a);
+ iz = 1;
+ iw = 1;
+
+ /* Test every bit from the second digit up, must be 1 */
+ for (ix = DIGIT_BIT; ix < iy; ix++) {
+ if ((a->dp[iw] & iz) == 0) {
+ return MP_NO;
+ }
+ iz <<= 1;
+ if (iz > (mp_digit)MP_MASK) {
+ ++iw;
+ iz = 1;
+ }
+ }
+ }
+ return MP_YES;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_is_2k.c */
+
+/* Start: bn_mp_reduce_is_2k_l.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_IS_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* determines if reduce_2k_l can be used */
+int mp_reduce_is_2k_l(mp_int *a)
+{
+ int ix, iy;
+
+ if (a->used == 0) {
+ return MP_NO;
+ } else if (a->used == 1) {
+ return MP_YES;
+ } else if (a->used > 1) {
+ /* if more than half of the digits are -1 we're sold */
+ for (iy = ix = 0; ix < a->used; ix++) {
+ if (a->dp[ix] == MP_MASK) {
+ ++iy;
+ }
+ }
+ return (iy >= (a->used/2)) ? MP_YES : MP_NO;
+
+ }
+ return MP_NO;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_is_2k_l.c */
+
+/* Start: bn_mp_reduce_setup.c */
+#include "tommath.h"
+#ifdef BN_MP_REDUCE_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+int mp_reduce_setup (mp_int * a, mp_int * b)
+{
+ int res;
+
+ if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
+ return res;
+ }
+ return mp_div (a, b, a, NULL);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_reduce_setup.c */
+
+/* Start: bn_mp_rshd.c */
+#include "tommath.h"
+#ifdef BN_MP_RSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+ int x;
+
+ /* if b <= 0 then ignore it */
+ if (b <= 0) {
+ return;
+ }
+
+ /* if b > used then simply zero it and return */
+ if (a->used <= b) {
+ mp_zero (a);
+ return;
+ }
+
+ {
+ register mp_digit *bottom, *top;
+
+ /* shift the digits down */
+
+ /* bottom */
+ bottom = a->dp;
+
+ /* top [offset into digits] */
+ top = a->dp + b;
+
+ /* this is implemented as a sliding window where
+ * the window is b-digits long and digits from
+ * the top of the window are copied to the bottom
+ *
+ * e.g.
+
+ b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
+ /\ | ---->
+ \-------------------/ ---->
+ */
+ for (x = 0; x < (a->used - b); x++) {
+ *bottom++ = *top++;
+ }
+
+ /* zero the top digits */
+ for (; x < a->used; x++) {
+ *bottom++ = 0;
+ }
+ }
+
+ /* remove excess digits */
+ a->used -= b;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_rshd.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_rshd.c */
+
+/* Start: bn_mp_set.c */
+#include "tommath.h"
+#ifdef BN_MP_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+ mp_zero (a);
+ a->dp[0] = b & MP_MASK;
+ a->used = (a->dp[0] != 0) ? 1 : 0;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_set.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_set.c */
+
+/* Start: bn_mp_set_int.c */
+#include "tommath.h"
+#ifdef BN_MP_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+ int x, res;
+
+ mp_zero (a);
+
+ /* set four bits at a time */
+ for (x = 0; x < 8; x++) {
+ /* shift the number up four bits */
+ if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* OR in the top four bits of the source */
+ a->dp[0] |= (b >> 28) & 15;
+
+ /* shift the source up to the next four bits */
+ b <<= 4;
+
+ /* ensure that digits are not clamped off */
+ a->used += 1;
+ }
+ mp_clamp (a);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_set_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_set_int.c */
+
+/* Start: bn_mp_shrink.c */
+#include "tommath.h"
+#ifdef BN_MP_SHRINK_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* shrink a bignum */
+int mp_shrink (mp_int * a)
+{
+ mp_digit *tmp;
+ if (a->alloc != a->used && a->used > 0) {
+ if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
+ return MP_MEM;
+ }
+ a->dp = tmp;
+ a->alloc = a->used;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_shrink.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_shrink.c */
+
+/* Start: bn_mp_signed_bin_size.c */
+#include "tommath.h"
+#ifdef BN_MP_SIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* get the size for an signed equivalent */
+int mp_signed_bin_size (mp_int * a)
+{
+ return 1 + mp_unsigned_bin_size (a);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_signed_bin_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_signed_bin_size.c */
+
+/* Start: bn_mp_sqr.c */
+#include "tommath.h"
+#ifdef BN_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+ int res;
+
+#ifdef BN_MP_TOOM_SQR_C
+ /* use Toom-Cook? */
+ if (a->used >= TOOM_SQR_CUTOFF) {
+ res = mp_toom_sqr(a, b);
+ /* Karatsuba? */
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+if (a->used >= KARATSUBA_SQR_CUTOFF) {
+ res = mp_karatsuba_sqr (a, b);
+ } else
+#endif
+ {
+#ifdef BN_FAST_S_MP_SQR_C
+ /* can we use the fast comba multiplier? */
+ if ((a->used * 2 + 1) < MP_WARRAY &&
+ a->used <
+ (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+ res = fast_s_mp_sqr (a, b);
+ } else
+#endif
+#ifdef BN_S_MP_SQR_C
+ res = s_mp_sqr (a, b);
+#else
+ res = MP_VAL;
+#endif
+ }
+ b->sign = MP_ZPOS;
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_sqr.c */
+
+/* Start: bn_mp_sqrmod.c */
+#include "tommath.h"
+#ifdef BN_MP_SQRMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* c = a * a (mod b) */
+int
+mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_sqr (a, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, b, c);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqrmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_sqrmod.c */
+
+/* Start: bn_mp_sqrt.c */
+#include "tommath.h"
+#ifdef BN_MP_SQRT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* this function is less generic than mp_n_root, simpler and faster */
+int mp_sqrt(mp_int *arg, mp_int *ret)
+{
+ int res;
+ mp_int t1,t2;
+
+ /* must be positive */
+ if (arg->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* easy out */
+ if (mp_iszero(arg) == MP_YES) {
+ mp_zero(ret);
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init(&t2)) != MP_OKAY) {
+ goto E2;
+ }
+
+ /* First approx. (not very bad for large arg) */
+ mp_rshd (&t1,t1.used/2);
+
+ /* t1 > 0 */
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* And now t1 > sqrt(arg) */
+ do {
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* t1 >= sqrt(arg) >= t2 at this point */
+ } while (mp_cmp_mag(&t1,&t2) == MP_GT);
+
+ mp_exch(&t1,ret);
+
+E1: mp_clear(&t2);
+E2: mp_clear(&t1);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_sqrt.c */
+
+/* Start: bn_mp_sub.c */
+#include "tommath.h"
+#ifdef BN_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ sa = a->sign;
+ sb = b->sign;
+
+ if (sa != sb) {
+ /* subtract a negative from a positive, OR */
+ /* subtract a positive from a negative. */
+ /* In either case, ADD their magnitudes, */
+ /* and use the sign of the first number. */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* subtract a positive from a positive, OR */
+ /* subtract a negative from a negative. */
+ /* First, take the difference between their */
+ /* magnitudes, then... */
+ if (mp_cmp_mag (a, b) != MP_LT) {
+ /* Copy the sign from the first */
+ c->sign = sa;
+ /* The first has a larger or equal magnitude */
+ res = s_mp_sub (a, b, c);
+ } else {
+ /* The result has the *opposite* sign from */
+ /* the first number. */
+ c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ /* The second has a larger magnitude */
+ res = s_mp_sub (b, a, c);
+ }
+ }
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sub.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_sub.c */
+
+/* Start: bn_mp_sub_d.c */
+#include "tommath.h"
+#ifdef BN_MP_SUB_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* single digit subtraction */
+int
+mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit *tmpa, *tmpc, mu;
+ int res, ix, oldused;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative just do an unsigned
+ * addition [with fudged signs]
+ */
+ if (a->sign == MP_NEG) {
+ a->sign = MP_ZPOS;
+ res = mp_add_d(a, b, c);
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* setup regs */
+ oldused = c->used;
+ tmpa = a->dp;
+ tmpc = c->dp;
+
+ /* if a <= b simply fix the single digit */
+ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+ if (a->used == 1) {
+ *tmpc++ = b - *tmpa;
+ } else {
+ *tmpc++ = b;
+ }
+ ix = 1;
+
+ /* negative/1digit */
+ c->sign = MP_NEG;
+ c->used = 1;
+ } else {
+ /* positive/size */
+ c->sign = MP_ZPOS;
+ c->used = a->used;
+
+ /* subtract first digit */
+ *tmpc = *tmpa++ - b;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+
+ /* handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ - mu;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* zero excess digits */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_sub_d.c */
+
+/* Start: bn_mp_submod.c */
+#include "tommath.h"
+#ifdef BN_MP_SUBMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* d = a - b (mod c) */
+int
+mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_submod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_submod.c */
+
+/* Start: bn_mp_to_signed_bin.c */
+#include "tommath.h"
+#ifdef BN_MP_TO_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin (mp_int * a, unsigned char *b)
+{
+ int res;
+
+ if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
+ return res;
+ }
+ b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_to_signed_bin.c */
+
+/* Start: bn_mp_to_signed_bin_n.c */
+#include "tommath.h"
+#ifdef BN_MP_TO_SIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+ if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
+ return MP_VAL;
+ }
+ *outlen = mp_signed_bin_size(a);
+ return mp_to_signed_bin(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin_n.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_to_signed_bin_n.c */
+
+/* Start: bn_mp_to_unsigned_bin.c */
+#include "tommath.h"
+#ifdef BN_MP_TO_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+ int x, res;
+ mp_int t;
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ x = 0;
+ while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+ b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+ b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+ if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+ bn_reverse (b, x);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_to_unsigned_bin.c */
+
+/* Start: bn_mp_to_unsigned_bin_n.c */
+#include "tommath.h"
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+ if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
+ return MP_VAL;
+ }
+ *outlen = mp_unsigned_bin_size(a);
+ return mp_to_unsigned_bin(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin_n.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_to_unsigned_bin_n.c */
+
+/* Start: bn_mp_toom_mul.c */
+#include "tommath.h"
+#ifdef BN_MP_TOOM_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* multiplication using the Toom-Cook 3-way algorithm
+ *
+ * Much more complicated than Karatsuba but has a lower
+ * asymptotic running time of O(N**1.464). This algorithm is
+ * only particularly useful on VERY large inputs
+ * (we're talking 1000s of digits here...).
+*/
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = MIN(a->used, b->used) / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* b = b2 * B**2 + b1 * B + b0 */
+ if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(b, &b1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b1, B);
+ mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
+
+ if ((res = mp_copy(b, &b2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b2, B*2);
+
+ /* w0 = a0*b0 */
+ if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * b2 */
+ if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts,
+ 2 small divisions and 1 small multiplication
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toom_mul.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_toom_mul.c */
+
+/* Start: bn_mp_toom_sqr.c */
+#include "tommath.h"
+#ifdef BN_MP_TOOM_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* squaring using Toom-Cook 3-way algorithm */
+int
+mp_toom_sqr(mp_int *a, mp_int *b)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = a->used / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* w0 = a0*a0 */
+ if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * a2 */
+ if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))**2 */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))**2 */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)**2 */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_toom_sqr.c */
+
+/* Start: bn_mp_toradix.c */
+#include "tommath.h"
+#ifdef BN_MP_TORADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int * a, char *str, int radix)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the radix */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == 1) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ ++_s;
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == 0) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [exluding the sign] of the number]
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_toradix.c */
+
+/* Start: bn_mp_toradix_n.c */
+#include "tommath.h"
+#ifdef BN_MP_TORADIX_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64)
+ *
+ * Stores upto maxlen-1 chars and always a NULL byte
+ */
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the maxlen, radix */
+ if (maxlen < 2 || radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == MP_YES) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ /* we have to reverse our digits later... but not the - sign!! */
+ ++_s;
+
+ /* store the flag and mark the number as positive */
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+
+ /* subtract a char */
+ --maxlen;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == 0) {
+ if (--maxlen < 1) {
+ /* no more room */
+ break;
+ }
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [exluding the sign] of the number
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_toradix_n.c */
+
+/* Start: bn_mp_unsigned_bin_size.c */
+#include "tommath.h"
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+ int size = mp_count_bits (a);
+ return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_unsigned_bin_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_unsigned_bin_size.c */
+
+/* Start: bn_mp_xor.c */
+#include "tommath.h"
+#ifdef BN_MP_XOR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* XOR two ints together */
+int
+mp_xor (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] ^= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_xor.c */
+
+/* Start: bn_mp_zero.c */
+#include "tommath.h"
+#ifdef BN_MP_ZERO_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+ int n;
+ mp_digit *tmp;
+
+ a->sign = MP_ZPOS;
+ a->used = 0;
+
+ tmp = a->dp;
+ for (n = 0; n < a->alloc; n++) {
+ *tmp++ = 0;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_mp_zero.c */
+
+/* Start: bn_prime_tab.c */
+#include "tommath.h"
+#ifdef BN_PRIME_TAB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+const mp_digit ltm_prime_tab[] = {
+ 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+ 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+ 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+ 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+#ifndef MP_8BIT
+ 0x0083,
+ 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+ 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+ 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+ 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+ 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+ 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+ 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+ 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+ 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+ 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+ 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+ 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+ 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+ 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+ 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+ 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+ 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+ 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+ 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+ 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+ 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+ 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+ 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+ 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+ 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+ 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+ 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+ 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+#endif
+};
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_prime_tab.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_prime_tab.c */
+
+/* Start: bn_reverse.c */
+#include "tommath.h"
+#ifdef BN_REVERSE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* reverse an array, used for radix code */
+void
+bn_reverse (unsigned char *s, int len)
+{
+ int ix, iy;
+ unsigned char t;
+
+ ix = 0;
+ iy = len - 1;
+ while (ix < iy) {
+ t = s[ix];
+ s[ix] = s[iy];
+ s[iy] = t;
+ ++ix;
+ --iy;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_reverse.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_reverse.c */
+
+/* Start: bn_s_mp_add.c */
+#include "tommath.h"
+#ifdef BN_S_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int *x;
+ int olduse, res, min, max;
+
+ /* find sizes, we let |a| <= |b| which means we have to sort
+ * them. "x" will point to the input with the most digits
+ */
+ if (a->used > b->used) {
+ min = b->used;
+ max = a->used;
+ x = a;
+ } else {
+ min = a->used;
+ max = b->used;
+ x = b;
+ }
+
+ /* init result */
+ if (c->alloc < max + 1) {
+ if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get old used digit count and set new one */
+ olduse = c->used;
+ c->used = max + 1;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+
+ /* first input */
+ tmpa = a->dp;
+
+ /* second input */
+ tmpb = b->dp;
+
+ /* destination */
+ tmpc = c->dp;
+
+ /* zero the carry */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+ *tmpc = *tmpa++ + *tmpb++ + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, that is in A+B
+ * if A or B has more digits add those in
+ */
+ if (min != max) {
+ for (; i < max; i++) {
+ /* T[i] = X[i] + U */
+ *tmpc = x->dp[i] + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* add carry */
+ *tmpc++ = u;
+
+ /* clear digits above oldused */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_add.c */
+
+/* Start: bn_s_mp_exptmod.c */
+#include "tommath.h"
+#ifdef BN_S_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+#ifdef MP_LOW_MEM
+ #define TAB_SIZE 32
+#else
+ #define TAB_SIZE 256
+#endif
+
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+ mp_int M[TAB_SIZE], res, mu;
+ mp_digit buf;
+ int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+ int (*redux)(mp_int*,mp_int*,mp_int*);
+
+ /* find window size */
+ x = mp_count_bits (X);
+ if (x <= 7) {
+ winsize = 2;
+ } else if (x <= 36) {
+ winsize = 3;
+ } else if (x <= 140) {
+ winsize = 4;
+ } else if (x <= 450) {
+ winsize = 5;
+ } else if (x <= 1303) {
+ winsize = 6;
+ } else if (x <= 3529) {
+ winsize = 7;
+ } else {
+ winsize = 8;
+ }
+
+#ifdef MP_LOW_MEM
+ if (winsize > 5) {
+ winsize = 5;
+ }
+#endif
+
+ /* init M array */
+ /* init first cell */
+ if ((err = mp_init(&M[1])) != MP_OKAY) {
+ return err;
+ }
+
+ /* now init the second half of the array */
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ if ((err = mp_init(&M[x])) != MP_OKAY) {
+ for (y = 1<<(winsize-1); y < x; y++) {
+ mp_clear (&M[y]);
+ }
+ mp_clear(&M[1]);
+ return err;
+ }
+ }
+
+ /* create mu, used for Barrett reduction */
+ if ((err = mp_init (&mu)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ if (redmode == 0) {
+ if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ redux = mp_reduce;
+ } else {
+ if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ redux = mp_reduce_2k_l;
+ }
+
+ /* create M table
+ *
+ * The M table contains powers of the base,
+ * e.g. M[x] = G**x mod P
+ *
+ * The first half of the table is not
+ * computed though accept for M[0] and M[1]
+ */
+ if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ /* compute the value at M[1<<(winsize-1)] by squaring
+ * M[1] (winsize-1) times
+ */
+ if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ for (x = 0; x < (winsize - 1); x++) {
+ /* square it */
+ if ((err = mp_sqr (&M[1 << (winsize - 1)],
+ &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ /* reduce modulo P */
+ if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ }
+
+ /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+ * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+ */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+ if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ }
+
+ /* setup result */
+ if ((err = mp_init (&res)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ mp_set (&res, 1);
+
+ /* set initial mode and bit cnt */
+ mode = 0;
+ bitcnt = 1;
+ buf = 0;
+ digidx = X->used - 1;
+ bitcpy = 0;
+ bitbuf = 0;
+
+ for (;;) {
+ /* grab next digit as required */
+ if (--bitcnt == 0) {
+ /* if digidx == -1 we are out of digits */
+ if (digidx == -1) {
+ break;
+ }
+ /* read next digit and reset the bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int) DIGIT_BIT;
+ }
+
+ /* grab the next msb from the exponent */
+ y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
+ buf <<= (mp_digit)1;
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0) {
+ continue;
+ }
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize) {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0) {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0) {
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+ }
+ }
+
+ mp_exch (&res, Y);
+ err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_MU:mp_clear (&mu);
+LBL_M:
+ mp_clear(&M[1]);
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ mp_clear (&M[x]);
+ }
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_exptmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_exptmod.c */
+
+/* Start: bn_s_mp_mul_digs.c */
+#include "tommath.h"
+#ifdef BN_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12 Modified so you can control how
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ mp_int t;
+ int res, pa, pb, ix, iy;
+ mp_digit u;
+ mp_word r;
+ mp_digit tmpx, *tmpt, *tmpy;
+
+ /* can we use the fast multiplier? */
+ if (((digs) < MP_WARRAY) &&
+ MIN (a->used, b->used) <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_s_mp_mul_digs (a, b, c, digs);
+ }
+
+ if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+ return res;
+ }
+ t.used = digs;
+
+ /* compute the digits of the product directly */
+ pa = a->used;
+ for (ix = 0; ix < pa; ix++) {
+ /* set the carry to zero */
+ u = 0;
+
+ /* limit ourselves to making digs digits of output */
+ pb = MIN (b->used, digs - ix);
+
+ /* setup some aliases */
+ /* copy of the digit from a used within the nested loop */
+ tmpx = a->dp[ix];
+
+ /* an alias for the destination shifted ix places */
+ tmpt = t.dp + ix;
+
+ /* an alias for the digits of b */
+ tmpy = b->dp;
+
+ /* compute the columns of the output and propagate the carry */
+ for (iy = 0; iy < pb; iy++) {
+ /* compute the column as a mp_word */
+ r = ((mp_word)*tmpt) +
+ ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+ ((mp_word) u);
+
+ /* the new column is the lower part of the result */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry word from the result */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+ /* set carry if it is placed below digs */
+ if (ix + iy < digs) {
+ *tmpt = u;
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, c);
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_digs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_mul_digs.c */
+
+/* Start: bn_s_mp_mul_high_digs.c */
+#include "tommath.h"
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* multiplies |a| * |b| and does not compute the lower digs digits
+ * [meant to get the higher part of the product]
+ */
+int
+s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ mp_int t;
+ int res, pa, pb, ix, iy;
+ mp_digit u;
+ mp_word r;
+ mp_digit tmpx, *tmpt, *tmpy;
+
+ /* can we use the fast multiplier? */
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ if (((a->used + b->used + 1) < MP_WARRAY)
+ && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_s_mp_mul_high_digs (a, b, c, digs);
+ }
+#endif
+
+ if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ t.used = a->used + b->used + 1;
+
+ pa = a->used;
+ pb = b->used;
+ for (ix = 0; ix < pa; ix++) {
+ /* clear the carry */
+ u = 0;
+
+ /* left hand side of A[ix] * B[iy] */
+ tmpx = a->dp[ix];
+
+ /* alias to the address of where the digits will be stored */
+ tmpt = &(t.dp[digs]);
+
+ /* alias for where to read the right hand side from */
+ tmpy = b->dp + (digs - ix);
+
+ for (iy = digs - ix; iy < pb; iy++) {
+ /* calculate the double precision result */
+ r = ((mp_word)*tmpt) +
+ ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+ ((mp_word) u);
+
+ /* get the lower part */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* carry the carry */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+ *tmpt = u;
+ }
+ mp_clamp (&t);
+ mp_exch (&t, c);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_high_digs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_mul_high_digs.c */
+
+/* Start: bn_s_mp_sqr.c */
+#include "tommath.h"
+#ifdef BN_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+ mp_int t;
+ int res, ix, iy, pa;
+ mp_word r;
+ mp_digit u, tmpx, *tmpt;
+
+ pa = a->used;
+ if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* default used is maximum possible size */
+ t.used = 2*pa + 1;
+
+ for (ix = 0; ix < pa; ix++) {
+ /* first calculate the digit at 2*ix */
+ /* calculate double precision result */
+ r = ((mp_word) t.dp[2*ix]) +
+ ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+ /* store lower part in result */
+ t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+ /* left hand side of A[ix] * A[iy] */
+ tmpx = a->dp[ix];
+
+ /* alias for where to store the results */
+ tmpt = t.dp + (2*ix + 1);
+
+ for (iy = ix + 1; iy < pa; iy++) {
+ /* first calculate the product */
+ r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+ /* now calculate the double precision result, note we use
+ * addition instead of *2 since it's easier to optimize
+ */
+ r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+ /* store lower part */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ /* propagate upwards */
+ while (u != ((mp_digit) 0)) {
+ r = ((mp_word) *tmpt) + ((mp_word) u);
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, b);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_sqr.c */
+
+/* Start: bn_s_mp_sub.c */
+#include "tommath.h"
+#ifdef BN_S_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int olduse, res, min, max;
+
+ /* find sizes */
+ min = b->used;
+ max = a->used;
+
+ /* init result */
+ if (c->alloc < max) {
+ if ((res = mp_grow (c, max)) != MP_OKAY) {
+ return res;
+ }
+ }
+ olduse = c->used;
+ c->used = max;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+ tmpa = a->dp;
+ tmpb = b->dp;
+ tmpc = c->dp;
+
+ /* set carry to zero */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* T[i] = A[i] - B[i] - U */
+ *tmpc = *tmpa++ - *tmpb++ - u;
+
+ /* U = carry bit of T[i]
+ * Note this saves performing an AND operation since
+ * if a carry does occur it will propagate all the way to the
+ * MSB. As a result a single shift is enough to get the carry
+ */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, e.g. if A has more digits than B */
+ for (; i < max; i++) {
+ /* T[i] = A[i] - U */
+ *tmpc = *tmpa++ - u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* clear digits above used (since we may not have grown result above) */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_sub.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bn_s_mp_sub.c */
+
+/* Start: bncore.c */
+#include "tommath.h"
+#ifdef BNCORE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://libtom.org
+ */
+
+/* Known optimal configurations
+
+ CPU /Compiler /MUL CUTOFF/SQR CUTOFF
+-------------------------------------------------------------
+ Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
+ AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
+
+*/
+
+int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
+ KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
+
+ TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
+ TOOM_SQR_CUTOFF = 400;
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bncore.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
+
+/* End: bncore.c */
+
+
+/* EOF */

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.h
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/tommath.h 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,589 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis_at_[hidden], http://math.libtomcrypt.com
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include "tommath_class.h"
+
+#ifndef MIN
+ #define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+ #define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define OPT_CAST(x) (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(__x86_64__)
+ #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+ #define MP_64BIT
+ #endif
+#endif
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+ typedef unsigned char mp_digit;
+ typedef unsigned short mp_word;
+#elif defined(MP_16BIT)
+ typedef unsigned short mp_digit;
+ typedef unsigned long mp_word;
+#elif defined(MP_64BIT)
+ /* for GCC only on supported platforms */
+#ifndef CRYPT
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef unsigned long mp_word __attribute__ ((mode(TI)));
+
+ #define DIGIT_BIT 60
+#else
+ /* this is the default case, 28-bit digits */
+
+ /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+ #if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef unsigned __int64 ulong64;
+ typedef signed __int64 long64;
+ #else
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+ #endif
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef ulong64 mp_word;
+
+#ifdef MP_31BIT
+ /* this is an extension that uses 31-bit digits */
+ #define DIGIT_BIT 31
+#else
+ /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
+ #define DIGIT_BIT 28
+ #define MP_28BIT
+#endif
+#endif
+
+/* define heap macros */
+#ifndef CRYPT
+ /* default to libc stuff */
+ #ifndef XMALLOC
+ #define XMALLOC malloc
+ #define XFREE free
+ #define XREALLOC realloc
+ #define XCALLOC calloc
+ #else
+ /* prototypes for our heap functions */
+ extern void *XMALLOC(size_t n);
+ extern void *XREALLOC(void *p, size_t n);
+ extern void *XCALLOC(size_t n, size_t s);
+ extern void XFREE(void *p);
+ #endif
+#endif
+
+
+/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
+#ifndef DIGIT_BIT
+ #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT DIGIT_BIT
+#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX MP_MASK
+
+/* equalities */
+#define MP_LT -1 /* less than */
+#define MP_EQ 0 /* equal to */
+#define MP_GT 1 /* greater than */
+
+#define MP_ZPOS 0 /* positive integer */
+#define MP_NEG 1 /* negative */
+
+#define MP_OKAY 0 /* ok result */
+#define MP_MEM -2 /* out of mem */
+#define MP_VAL -3 /* invalid input */
+#define MP_RANGE MP_VAL
+
+#define MP_YES 1 /* yes response */
+#define MP_NO 0 /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
+
+typedef int mp_err;
+
+/* you'll have to tune these... */
+extern int KARATSUBA_MUL_CUTOFF,
+ KARATSUBA_SQR_CUTOFF,
+ TOOM_MUL_CUTOFF,
+ TOOM_SQR_CUTOFF;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+ #ifndef MP_LOW_MEM
+ #define MP_PREC 32 /* default digits of precision */
+ #else
+ #define MP_PREC 8 /* default digits of precision */
+ #endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
+#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+typedef struct {
+ int used, alloc, sign;
+ mp_digit *dp;
+} mp_int;
+
+/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m) ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m) ((m)->sign)
+
+/* error code to char* string */
+const char *mp_error_to_string(int code);
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+int mp_init(mp_int *a);
+
+/* free a bignum */
+void mp_clear(mp_int *a);
+
+/* init a null terminated series of arguments */
+int mp_init_multi(mp_int *mp, ...);
+
+/* clear a null terminated series of arguments */
+void mp_clear_multi(mp_int *mp, ...);
+
+/* exchange two ints */
+void mp_exch(mp_int *a, mp_int *b);
+
+/* shrink ram required for a bignum */
+int mp_shrink(mp_int *a);
+
+/* grow an int to a given size */
+int mp_grow(mp_int *a, int size);
+
+/* init to a given number of digits */
+int mp_init_size(mp_int *a, int size);
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+
+/* set to zero */
+void mp_zero(mp_int *a);
+
+/* set to a digit */
+void mp_set(mp_int *a, mp_digit b);
+
+/* set a 32-bit const */
+int mp_set_int(mp_int *a, unsigned long b);
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b);
+
+/* initialize and set 32-bit value */
+int mp_init_set_int (mp_int * a, unsigned long b);
+
+/* copy, b = a */
+int mp_copy(mp_int *a, mp_int *b);
+
+/* inits and copies, a = b */
+int mp_init_copy(mp_int *a, mp_int *b);
+
+/* trim unused digits */
+void mp_clamp(mp_int *a);
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+void mp_rshd(mp_int *a, int b);
+
+/* left shift by "b" digits */
+int mp_lshd(mp_int *a, int b);
+
+/* c = a / 2**b */
+int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
+
+/* b = a/2 */
+int mp_div_2(mp_int *a, mp_int *b);
+
+/* c = a * 2**b */
+int mp_mul_2d(mp_int *a, int b, mp_int *c);
+
+/* b = a*2 */
+int mp_mul_2(mp_int *a, mp_int *b);
+
+/* c = a mod 2**d */
+int mp_mod_2d(mp_int *a, int b, mp_int *c);
+
+/* computes a = 2**b */
+int mp_2expt(mp_int *a, int b);
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a);
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+int mp_rand(mp_int *a, int digits);
+
+/* ---> binary operations <--- */
+/* c = a XOR b */
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a OR b */
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a AND b */
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+int mp_neg(mp_int *a, mp_int *b);
+
+/* b = |a| */
+int mp_abs(mp_int *a, mp_int *b);
+
+/* compare a to b */
+int mp_cmp(mp_int *a, mp_int *b);
+
+/* compare |a| to |b| */
+int mp_cmp_mag(mp_int *a, mp_int *b);
+
+/* c = a + b */
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a - b */
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a * b */
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+
+/* b = a*a */
+int mp_sqr(mp_int *a, mp_int *b);
+
+/* a/b => cb + d == a */
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+int mp_cmp_d(mp_int *a, mp_digit b);
+
+/* c = a + b */
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a - b */
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a * b */
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* a/b => cb + d == a */
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+
+/* a/3 => 3c + d == a */
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+
+/* c = a**b */
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a * b (mod c) */
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a * a (mod b) */
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = 1/a (mod b) */
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = (a, b) */
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
+/* c = [a, b] or (a*b)/(a, b) */
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+
+/* special sqrt algo */
+int mp_sqrt(mp_int *arg, mp_int *ret);
+
+/* is number a square? */
+int mp_is_square(mp_int *arg, int *ret);
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+
+/* used to setup the Barrett reduction for a given modulus b */
+int mp_reduce_setup(mp_int *a, mp_int *b);
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+
+/* setups the montgomery reduction */
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+
+/* returns 1 if a is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a);
+
+/* sets the value of "d" required for mp_dr_reduce */
+void mp_dr_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b using the Diminished Radix method */
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+
+/* returns true if a can be reduced with mp_reduce_2k */
+int mp_reduce_is_2k(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+
+/* returns true if a can be reduced with mp_reduce_2k_l */
+int mp_reduce_is_2k_l(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+
+/* d = a**b (mod c) */
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+ #define PRIME_SIZE 31
+#else
+ #define PRIME_SIZE 256
+#endif
+
+/* table of first PRIME_SIZE primes */
+extern const mp_digit ltm_prime_tab[];
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+int mp_prime_is_divisible(mp_int *a, int *result);
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96
+ */
+int mp_prime_rabin_miller_trials(int size);
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases. Also performs an initial sieve of trial
+ * division. Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ *
+ * LTM_PRIME_BBS - make prime congruent to 3 mod 4
+ * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+
+/* ---> radix conversion <--- */
+int mp_count_bits(mp_int *a);
+
+int mp_unsigned_bin_size(mp_int *a);
+int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a, unsigned char *b);
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_read_radix(mp_int *a, const char *str, int radix);
+int mp_toradix(mp_int *a, char *str, int radix);
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+int mp_radix_size(mp_int *a, int radix, int *size);
+
+int mp_fread(mp_int *a, int radix, FILE *stream);
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp) mp_signed_bin_size(mp)
+#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S) mp_toradix((M), (S), 16)
+
+/* lowlevel functions, do not call! */
+int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_sqr(mp_int *a, mp_int *b);
+int s_mp_sqr(mp_int *a, mp_int *b);
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+int mp_toom_sqr(mp_int *a, mp_int *b);
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
+void bn_reverse(unsigned char *s, int len);
+
+extern const char *mp_s_rmap;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtommath/tommath.h,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2006/03/31 14:18:44 $ */

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_class.h
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_class.h 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,1004 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
+#if defined(LTM2)
+#define LTM3
+#endif
+#if defined(LTM1)
+#define LTM2
+#endif
+#define LTM1
+
+#if defined(LTM_ALL)
+#define BN_ERROR_C
+#define BN_FAST_MP_INVMOD_C
+#define BN_FAST_MP_MONTGOMERY_REDUCE_C
+#define BN_FAST_S_MP_MUL_DIGS_C
+#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+#define BN_FAST_S_MP_SQR_C
+#define BN_MP_2EXPT_C
+#define BN_MP_ABS_C
+#define BN_MP_ADD_C
+#define BN_MP_ADD_D_C
+#define BN_MP_ADDMOD_C
+#define BN_MP_AND_C
+#define BN_MP_CLAMP_C
+#define BN_MP_CLEAR_C
+#define BN_MP_CLEAR_MULTI_C
+#define BN_MP_CMP_C
+#define BN_MP_CMP_D_C
+#define BN_MP_CMP_MAG_C
+#define BN_MP_CNT_LSB_C
+#define BN_MP_COPY_C
+#define BN_MP_COUNT_BITS_C
+#define BN_MP_DIV_C
+#define BN_MP_DIV_2_C
+#define BN_MP_DIV_2D_C
+#define BN_MP_DIV_3_C
+#define BN_MP_DIV_D_C
+#define BN_MP_DR_IS_MODULUS_C
+#define BN_MP_DR_REDUCE_C
+#define BN_MP_DR_SETUP_C
+#define BN_MP_EXCH_C
+#define BN_MP_EXPT_D_C
+#define BN_MP_EXPTMOD_C
+#define BN_MP_EXPTMOD_FAST_C
+#define BN_MP_EXTEUCLID_C
+#define BN_MP_FREAD_C
+#define BN_MP_FWRITE_C
+#define BN_MP_GCD_C
+#define BN_MP_GET_INT_C
+#define BN_MP_GROW_C
+#define BN_MP_INIT_C
+#define BN_MP_INIT_COPY_C
+#define BN_MP_INIT_MULTI_C
+#define BN_MP_INIT_SET_C
+#define BN_MP_INIT_SET_INT_C
+#define BN_MP_INIT_SIZE_C
+#define BN_MP_INVMOD_C
+#define BN_MP_INVMOD_SLOW_C
+#define BN_MP_IS_SQUARE_C
+#define BN_MP_JACOBI_C
+#define BN_MP_KARATSUBA_MUL_C
+#define BN_MP_KARATSUBA_SQR_C
+#define BN_MP_LCM_C
+#define BN_MP_LSHD_C
+#define BN_MP_MOD_C
+#define BN_MP_MOD_2D_C
+#define BN_MP_MOD_D_C
+#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+#define BN_MP_MONTGOMERY_REDUCE_C
+#define BN_MP_MONTGOMERY_SETUP_C
+#define BN_MP_MUL_C
+#define BN_MP_MUL_2_C
+#define BN_MP_MUL_2D_C
+#define BN_MP_MUL_D_C
+#define BN_MP_MULMOD_C
+#define BN_MP_N_ROOT_C
+#define BN_MP_NEG_C
+#define BN_MP_OR_C
+#define BN_MP_PRIME_FERMAT_C
+#define BN_MP_PRIME_IS_DIVISIBLE_C
+#define BN_MP_PRIME_IS_PRIME_C
+#define BN_MP_PRIME_MILLER_RABIN_C
+#define BN_MP_PRIME_NEXT_PRIME_C
+#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+#define BN_MP_PRIME_RANDOM_EX_C
+#define BN_MP_RADIX_SIZE_C
+#define BN_MP_RADIX_SMAP_C
+#define BN_MP_RAND_C
+#define BN_MP_READ_RADIX_C
+#define BN_MP_READ_SIGNED_BIN_C
+#define BN_MP_READ_UNSIGNED_BIN_C
+#define BN_MP_REDUCE_C
+#define BN_MP_REDUCE_2K_C
+#define BN_MP_REDUCE_2K_L_C
+#define BN_MP_REDUCE_2K_SETUP_C
+#define BN_MP_REDUCE_2K_SETUP_L_C
+#define BN_MP_REDUCE_IS_2K_C
+#define BN_MP_REDUCE_IS_2K_L_C
+#define BN_MP_REDUCE_SETUP_C
+#define BN_MP_RSHD_C
+#define BN_MP_SET_C
+#define BN_MP_SET_INT_C
+#define BN_MP_SHRINK_C
+#define BN_MP_SIGNED_BIN_SIZE_C
+#define BN_MP_SQR_C
+#define BN_MP_SQRMOD_C
+#define BN_MP_SQRT_C
+#define BN_MP_SUB_C
+#define BN_MP_SUB_D_C
+#define BN_MP_SUBMOD_C
+#define BN_MP_TO_SIGNED_BIN_C
+#define BN_MP_TO_SIGNED_BIN_N_C
+#define BN_MP_TO_UNSIGNED_BIN_C
+#define BN_MP_TO_UNSIGNED_BIN_N_C
+#define BN_MP_TOOM_MUL_C
+#define BN_MP_TOOM_SQR_C
+#define BN_MP_TORADIX_C
+#define BN_MP_TORADIX_N_C
+#define BN_MP_UNSIGNED_BIN_SIZE_C
+#define BN_MP_XOR_C
+#define BN_MP_ZERO_C
+#define BN_PRIME_TAB_C
+#define BN_REVERSE_C
+#define BN_S_MP_ADD_C
+#define BN_S_MP_EXPTMOD_C
+#define BN_S_MP_MUL_DIGS_C
+#define BN_S_MP_MUL_HIGH_DIGS_C
+#define BN_S_MP_SQR_C
+#define BN_S_MP_SUB_C
+#define BNCORE_C
+#endif
+
+#if defined(BN_ERROR_C)
+ #define BN_MP_ERROR_TO_STRING_C
+#endif
+
+#if defined(BN_FAST_MP_INVMOD_C)
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_COPY_C
+ #define BN_MP_MOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_SQR_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_2EXPT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_ABS_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_ADD_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_ADD_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_ADDMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_AND_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CLAMP_C)
+#endif
+
+#if defined(BN_MP_CLEAR_C)
+#endif
+
+#if defined(BN_MP_CLEAR_MULTI_C)
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CMP_C)
+ #define BN_MP_CMP_MAG_C
+#endif
+
+#if defined(BN_MP_CMP_D_C)
+#endif
+
+#if defined(BN_MP_CMP_MAG_C)
+#endif
+
+#if defined(BN_MP_CNT_LSB_C)
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_COPY_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_COUNT_BITS_C)
+#endif
+
+#if defined(BN_MP_DIV_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_ABS_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_2_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_DIV_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_DIV_3_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_D_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DR_IS_MODULUS_C)
+#endif
+
+#if defined(BN_MP_DR_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_DR_SETUP_C)
+#endif
+
+#if defined(BN_MP_EXCH_C)
+#endif
+
+#if defined(BN_MP_EXPT_D_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SET_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MUL_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ABS_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_REDUCE_IS_2K_L_C
+ #define BN_S_MP_EXPTMOD_C
+ #define BN_MP_DR_IS_MODULUS_C
+ #define BN_MP_REDUCE_IS_2K_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_EXPTMOD_FAST_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_FAST_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MONTGOMERY_SETUP_C
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_DR_SETUP_C
+ #define BN_MP_DR_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_C
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_EXTEUCLID_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_NEG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_FREAD_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CMP_D_C
+#endif
+
+#if defined(BN_MP_FWRITE_C)
+ #define BN_MP_RADIX_SIZE_C
+ #define BN_MP_TORADIX_C
+#endif
+
+#if defined(BN_MP_GCD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ABS_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_GET_INT_C)
+#endif
+
+#if defined(BN_MP_GROW_C)
+#endif
+
+#if defined(BN_MP_INIT_C)
+#endif
+
+#if defined(BN_MP_INIT_COPY_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_INIT_MULTI_C)
+ #define BN_MP_ERR_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_INIT_SET_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+#endif
+
+#if defined(BN_MP_INIT_SET_INT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_INT_C
+#endif
+
+#if defined(BN_MP_INIT_SIZE_C)
+ #define BN_MP_INIT_C
+#endif
+
+#if defined(BN_MP_INVMOD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ISODD_C
+ #define BN_FAST_MP_INVMOD_C
+ #define BN_MP_INVMOD_SLOW_C
+#endif
+
+#if defined(BN_MP_INVMOD_SLOW_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_IS_SQUARE_C)
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_SET_INT_C
+ #define BN_MP_MOD_C
+ #define BN_MP_GET_INT_C
+ #define BN_MP_SQRT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_JACOBI_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_MUL_C)
+ #define BN_MP_MUL_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SQR_C
+ #define BN_MP_SUB_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_LCM_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_GCD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_LSHD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+#endif
+
+#if defined(BN_MP_MOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_MOD_2D_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MOD_D_C)
+ #define BN_MP_DIV_D_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_SET_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_REDUCE_C)
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_SETUP_C)
+#endif
+
+#if defined(BN_MP_MUL_C)
+ #define BN_MP_TOOM_MUL_C
+ #define BN_MP_KARATSUBA_MUL_C
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_S_MP_MUL_C
+ #define BN_S_MP_MUL_DIGS_C
+#endif
+
+#if defined(BN_MP_MUL_2_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_MUL_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_GROW_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MUL_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MULMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_N_ROOT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_EXPT_D_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_NEG_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_OR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_FERMAT_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
+ #define BN_MP_MOD_D_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_PRIME_IS_DIVISIBLE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_MILLER_RABIN_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SQRMOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_NEXT_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
+#endif
+
+#if defined(BN_MP_PRIME_RANDOM_EX_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+ #define BN_MP_PRIME_IS_PRIME_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_D_C
+#endif
+
+#if defined(BN_MP_RADIX_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_RADIX_SMAP_C)
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_RAND_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_LSHD_C
+#endif
+
+#if defined(BN_MP_READ_RADIX_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_RADIX_SMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_READ_SIGNED_BIN_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_READ_UNSIGNED_BIN_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_REDUCE_C)
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_MUL_HIGH_DIGS_C
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_MOD_2D_C
+ #define BN_S_MP_MUL_DIGS_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CMP_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_CLEAR_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_C)
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_L_C)
+#endif
+
+#if defined(BN_MP_REDUCE_SETUP_C)
+ #define BN_MP_2EXPT_C
+ #define BN_MP_DIV_C
+#endif
+
+#if defined(BN_MP_RSHD_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_INT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SHRINK_C)
+#endif
+
+#if defined(BN_MP_SIGNED_BIN_SIZE_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+#endif
+
+#if defined(BN_MP_SQR_C)
+ #define BN_MP_TOOM_SQR_C
+ #define BN_MP_KARATSUBA_SQR_C
+ #define BN_FAST_S_MP_SQR_C
+ #define BN_S_MP_SQR_C
+#endif
+
+#if defined(BN_MP_SQRMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_SQRT_C)
+ #define BN_MP_N_ROOT_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_DIV_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_SUB_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_SUB_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SUBMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_C)
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_N_C)
+ #define BN_MP_SIGNED_BIN_SIZE_C
+ #define BN_MP_TO_SIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TOOM_MUL_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TOOM_SQR_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TORADIX_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_TORADIX_N_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_XOR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_ZERO_C)
+#endif
+
+#if defined(BN_PRIME_TAB_C)
+#endif
+
+#if defined(BN_REVERSE_C)
+#endif
+
+#if defined(BN_S_MP_ADD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_S_MP_EXPTMOD_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_L_C
+ #define BN_MP_REDUCE_2K_L_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SET_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_S_MP_MUL_DIGS_C)
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SUB_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BNCORE_C)
+#endif
+
+#ifdef LTM3
+#define LTM_LAST
+#endif
+#include "tommath_superclass.h"
+#include "tommath_class.h"
+#else
+#define LTM_LAST
+#endif
+
+/* $Source: /cvs/libtom/libtommath/tommath_class.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/07/28 11:59:32 $ */

Added: sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_superclass.h
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/tommath_superclass.h 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,81 @@
+// Copyright Kevin Sopp 2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/* super class file for PK algos */
+
+/* default ... include all MPI */
+#define LTM_ALL
+
+/* RSA only (does not support DH/DSA/ECC) */
+/* #define SC_RSA_1 */
+
+/* For reference.... On an Athlon64 optimizing for speed...
+
+ LTM's mpi.o with all functions [striped] is 142KiB in size.
+
+*/
+
+/* Works for RSA only, mpi.o is 68KiB */
+#ifdef SC_RSA_1
+ #define BN_MP_SHRINK_C
+ #define BN_MP_LCM_C
+ #define BN_MP_PRIME_RANDOM_EX_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_GCD_C
+ #define BN_MP_MOD_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_ADDMOD_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_SET_INT_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+ #define BN_REVERSE_C
+ #define BN_PRIME_TAB_C
+
+ /* other modifiers */
+ #define BN_MP_DIV_SMALL /* Slower division, not critical */
+
+ /* here we are on the last pass so we turn things off. The functions classes are still there
+ * but we remove them specifically from the build. This also invokes tweaks in functions
+ * like removing support for even moduli, etc...
+ */
+#ifdef LTM_LAST
+ #undef BN_MP_TOOM_MUL_C
+ #undef BN_MP_TOOM_SQR_C
+ #undef BN_MP_KARATSUBA_MUL_C
+ #undef BN_MP_KARATSUBA_SQR_C
+ #undef BN_MP_REDUCE_C
+ #undef BN_MP_REDUCE_SETUP_C
+ #undef BN_MP_DR_IS_MODULUS_C
+ #undef BN_MP_DR_SETUP_C
+ #undef BN_MP_DR_REDUCE_C
+ #undef BN_MP_REDUCE_IS_2K_C
+ #undef BN_MP_REDUCE_2K_SETUP_C
+ #undef BN_MP_REDUCE_2K_C
+ #undef BN_S_MP_EXPTMOD_C
+ #undef BN_MP_DIV_3_C
+ #undef BN_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_MP_INVMOD_C
+
+ /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
+ * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
+ * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
+ * trouble.
+ */
+ #undef BN_S_MP_MUL_DIGS_C
+ #undef BN_S_MP_SQR_C
+ #undef BN_MP_MONTGOMERY_REDUCE_C
+#endif
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/tommath_superclass.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/14 13:29:17 $ */

Added: sandbox/mp_math/project-root.jam
==============================================================================
--- (empty file)
+++ sandbox/mp_math/project-root.jam 2008-10-24 14:49:35 EDT (Fri, 24 Oct 2008)
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2006 João Abecasis
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+##
+## IMPORTANT NOTE: This file MUST NOT be copied over a boost installation
+##
+
+path-constant top : . ;
+
+import modules ;
+import path ;
+
+local boost-root = [ modules.peek : BOOST_ROOT ] ;
+local math-header-include = $(top)/../.. ;
+
+if ! $(boost-root)
+{
+ local boost-search-dirs = [ modules.peek : BOOST_BUILD_PATH ] ;
+
+ for local dir in $(boost-search-dirs)
+ {
+ if [ path.glob $(dir)/../../../ : boost/version.hpp ]
+ {
+ boost-root += $(dir)/../../../ ;
+ }
+ }
+
+ if $(boost-root)
+ {
+ boost-root = [ path.make $(boost-root[1]) ] ;
+ }
+ else
+ {
+ ECHO "Warning: couldn't find BOOST_ROOT in" $(boost-root) ;
+ }
+}
+
+use-project /boost/unit_test : $(boost-root)/libs/test/build ;
+
+project
+ : requirements
+ <include>.
+ <include>$(boost-root)
+ : # build everything in ./bin.v2
+ build-dir bin.v2
+ ;
+
+path-constant BOOST_ROOT : $(boost-root) ;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk