|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r60963 - sandbox/xint/boost/xint/src
From: pbristow_at_[hidden]
Date: 2010-03-31 09:25:58
Author: pbristow
Date: 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
New Revision: 60963
URL: http://svn.boost.org/trac/boost/changeset/60963
Log:
Chad updates from xint2.zip
Text files modified:
sandbox/xint/boost/xint/src/compare.cpp | 6
sandbox/xint/boost/xint/src/data_t.cpp | 27 ++--
sandbox/xint/boost/xint/src/gcd.cpp | 10 +
sandbox/xint/boost/xint/src/integer.cpp | 18 +-
sandbox/xint/boost/xint/src/modular.cpp | 8
sandbox/xint/boost/xint/src/monty.cpp | 8
sandbox/xint/boost/xint/src/operators.cpp | 24 ++-
sandbox/xint/boost/xint/src/powers.cpp | 8
sandbox/xint/boost/xint/src/primes.cpp | 2
sandbox/xint/boost/xint/src/primitives.cpp | 75 +++++-------
sandbox/xint/boost/xint/src/random.cpp | 234 ++++++++++++++++++---------------------
sandbox/xint/boost/xint/src/roots.cpp | 7 +
12 files changed, 207 insertions(+), 220 deletions(-)
Modified: sandbox/xint/boost/xint/src/compare.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/compare.cpp (original)
+++ sandbox/xint/boost/xint/src/compare.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -38,7 +38,7 @@
if (b1data->mLength != b2data->mLength) {
answer=((b1data->mLength < b2data->mLength) ? -1 : 1);
} else {
- for (int x = b1data->mLength - 1; x >= 0; --x) {
+ for (int x = int(b1data->mLength) - 1; x >= 0; --x) {
if (b1data->digits[x] != b2data->digits[x]) {
answer=((b1data->digits[x] < b2data->digits[x]) ? -1 : 1);
break;
@@ -49,8 +49,6 @@
return answer;
}
-} // namespace xint
-
bool operator!(const xint::integer &num1) { return num1.sign()==0; }
bool operator==(const xint::integer &num1, const xint::integer &num2) { return xint::compare(num1, num2)==0; }
bool operator!=(const xint::integer& num1, const xint::integer& num2) { return xint::compare(num1, num2)!=0; }
@@ -58,3 +56,5 @@
bool operator>(const xint::integer& num1, const xint::integer& num2) { return xint::compare(num1, num2)>0; }
bool operator<=(const xint::integer& num1, const xint::integer& num2) { return xint::compare(num1, num2)<=0; }
bool operator>=(const xint::integer& num1, const xint::integer& num2) { return xint::compare(num1, num2)>=0; }
+
+} // namespace xint
Modified: sandbox/xint/boost/xint/src/data_t.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/data_t.cpp (original)
+++ sandbox/xint/boost/xint/src/data_t.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -45,7 +45,7 @@
digits=&mStorage[0];
#endif
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
}
memcpy(digits, c->digits, mLength*sizeof(digit_t));
@@ -82,7 +82,7 @@
skipLeadingZeros();
}
-void data_t::alloc(int newcount, bool copydigits) {
+void data_t::alloc(size_t newcount, bool copydigits) {
if (digits==mQuickDigits && newcount<=QuickDigits::count) {
if (!copydigits) zero(digits, QuickDigits::count);
else zero(digits+mLength, (newcount-mLength));
@@ -112,7 +112,7 @@
#endif
} catch (std::bad_alloc&) {
digits=mQuickDigits; // Might allow for recovery in some cases
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
memcpy(digits, mQuickDigits, mLength*sizeof(digit_t));
@@ -123,7 +123,7 @@
try {
newDigits=new digit_t[newcount];
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
if (copydigits) {
@@ -140,7 +140,7 @@
try {
mStorage.resize(newcount);
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
digits=&mStorage[0];
if (!copydigits) zero(digits, newcount);
@@ -150,7 +150,7 @@
}
}
-void data_t::copy(const data_t *c, int extraDigits) {
+void data_t::copy(const data_t *c, size_t extraDigits) {
alloc(c->mLength+extraDigits);
mLength=c->mLength;
@@ -205,7 +205,7 @@
// Now add the digits, starting at the least-significant digit.
digit_t carry=0;
- int x=0;
+ size_t x=0;
for (; x<addend.mLength; ++x) {
doubledigit_t t=doubledigit_t(digits[x])+addend.digits[x]+carry;
if (t>=digit_overflowbit) { carry=1; t-=digit_overflowbit; } else carry=0;
@@ -230,7 +230,8 @@
// size of the longest operand, so we've already got enough room.
// Now subtract the digits, starting at the least-significant one.
- int borrow=0, x;
+ size_t x;
+ int borrow=0;
doubledigit_t t;
for (x=0; x<subtrahend.mLength; ++x) {
t=(digits[x]+digit_overflowbit)-subtrahend.digits[x]-borrow;
@@ -248,12 +249,12 @@
skipLeadingZeros();
}
-void data_t::shift_left(int byBits) {
+void data_t::shift_left(size_t byBits) {
assert(mCopies==1);
assert(byBits>0);
- int bytes=byBits / bits_per_digit, bits=byBits % bits_per_digit;
- int oldLength=mLength;
+ size_t bytes=byBits / bits_per_digit, bits=byBits % bits_per_digit;
+ size_t oldLength=mLength;
realloc(mLength+bytes+1);
@@ -276,11 +277,11 @@
skipLeadingZeros();
}
-void data_t::shift_right(int byBits) {
+void data_t::shift_right(size_t byBits) {
assert(mCopies==1);
assert(byBits>0);
- int bytes=byBits / bits_per_digit, bits=byBits % bits_per_digit,
+ size_t bytes=byBits / bits_per_digit, bits=byBits % bits_per_digit,
bits2 = bits_per_digit - bits;
if (bytes >= mLength) {
Modified: sandbox/xint/boost/xint/src/gcd.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/gcd.cpp (original)
+++ sandbox/xint/boost/xint/src/gcd.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -55,6 +55,11 @@
num1._throw_if_nan();
num2._throw_if_nan();
+ int sign1=num1.sign(), sign2=num2.sign();
+ if (sign1==0 && sign2==0) return integer::zero();
+ else if (sign1==0) return num2;
+ else if (sign2==0) return num1;
+
integer n(abs(num1)), m(abs(num2));
size_t k=0;
@@ -79,7 +84,10 @@
else return integer(not_a_number());
}
- if (n.sign() < 0) {
+ int sign=n.sign();
+ if (sign==0) {
+ return integer(not_a_number());
+ } else if (n.sign() < 0) {
integer _n(n);
_n._set_negative(false);
Modified: sandbox/xint/boost/xint/src/integer.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/integer.cpp (original)
+++ sandbox/xint/boost/xint/src/integer.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -14,6 +14,10 @@
#include "../xint.hpp"
#include "../xint_data_t.hpp"
+#ifdef XINT_THREADSAFE
+ #define XINT_DISABLE_COPY_ON_WRITE
+#endif
+
namespace xint {
const integer *integer::cZero=0, *integer::cOne=0;
@@ -44,14 +48,14 @@
try {
data=new detail::data_t(init);
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
_attach();
}
void integer::_init(const integer &c) {
- #ifdef XINT_THREADSAFE
- data=(c.data ? new data_t(c.data) : 0);
+ #ifdef XINT_DISABLE_COPY_ON_WRITE
+ data=(c.data ? new detail::data_t(c.data) : 0);
#else
data=c.data;
#endif
@@ -65,7 +69,7 @@
try {
data=new detail::data_t;
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
_attach();
@@ -94,7 +98,7 @@
_attach();
}
} catch (std::bad_alloc&) {
- throw std::overflow_error("Out of memory allocating xint::integer");
+ throw xint::overflow_error("Out of memory allocating xint::integer");
}
}
@@ -157,8 +161,8 @@
integer& integer::operator=(const integer &c) {
_detach();
- #ifdef XINT_THREADSAFE
- data=(c.data ? new data_t(c.data) : 0);
+ #ifdef XINT_DISABLE_COPY_ON_WRITE
+ data=(c.data ? new detail::data_t(c.data) : 0);
#else
data=c.data;
#endif
Modified: sandbox/xint/boost/xint/src/modular.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/modular.cpp (original)
+++ sandbox/xint/boost/xint/src/modular.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -51,15 +51,15 @@
} else {
integer p(abs(n));
- int length=exponent._get_length(), lastBitCount=0;
+ size_t length=exponent._get_length(), lastBitCount=0;
detail::digit_t ee(exponent._get_digit(length-1));
while (ee != 0) { ee >>= 1; ++lastBitCount; }
- for (int eIndex=0; eIndex < length; ++eIndex) {
+ for (size_t eIndex=0; eIndex < length; ++eIndex) {
detail::digit_t e(exponent._get_digit(eIndex));
- int bitCount(eIndex == length-1 ? lastBitCount :
- detail::bits_per_digit);
+ int bitCount(int(eIndex == length-1 ? lastBitCount :
+ detail::bits_per_digit));
while (bitCount-- > 0) {
if (e & 0x01) answer=mulmod(answer, p, modulus);
p=sqrmod(p, modulus);
Modified: sandbox/xint/boost/xint/src/monty.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/monty.cpp (original)
+++ sandbox/xint/boost/xint/src/monty.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -84,10 +84,10 @@
// nPrime0 is nPrime mod B, or digit zero of nPrime
const integer B(digit_overflowbit);
- const int L(n._get_length()), L1(L-1);
+ const size_t L(n._get_length()), L1(L-1);
integer t=a*b;
- int i=0;
+ size_t i=0;
do {
digit_t mi=digit_t(doubledigit_t(t._get_digit(i))*nPrime0);
@@ -166,7 +166,7 @@
integer aa=a*r%n, aSquared=a*a%n;
vxint_t rval;
- rval.reserve(ddPowerOfTwo(k));
+ rval.reserve(size_t(ddPowerOfTwo(k)));
rval.push_back(integer::one()); // Anything to the zeroth power is one
rval.push_back(aa); // Anything to the first power is itself
@@ -253,7 +253,7 @@
} else {
std::pair<int, int> tu=tuTable[i];
- int s=k-tu.first;
+ size_t s=k-tu.first;
while (s-- > 0) pp=montgomeryMultiplyMod(pp, pp, n, nPrime0);
pp=montgomeryMultiplyMod(pp, oddPowersOfAa[tu.second], n, nPrime0);
Modified: sandbox/xint/boost/xint/src/operators.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/operators.cpp (original)
+++ sandbox/xint/boost/xint/src/operators.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -13,13 +13,17 @@
#include "../xint.hpp"
-const xint::integer& operator+(const xint::integer& a) { return a; }
-xint::integer operator-(const xint::integer& a) { return xint::negate(a); }
-xint::integer operator+(const xint::integer& num1, const xint::integer& num2) { return xint::add(num1, num2); }
-xint::integer operator-(const xint::integer& num1, const xint::integer& num2) { return xint::subtract(num1, num2); }
-xint::integer operator*(const xint::integer& num1, const xint::integer& num2) { return xint::multiply(num1, num2); }
-xint::integer operator/(const xint::integer& num1, const xint::integer& num2) { return xint::divide(num1, num2); }
-xint::integer operator%(const xint::integer& num1, const xint::integer& num2) { return xint::mod(num1, num2); }
-xint::integer operator&(const xint::integer& n1, const xint::integer& n2) { return xint::bitwise_and(n1, n2); }
-xint::integer operator|(const xint::integer& n1, const xint::integer& n2) { return xint::bitwise_or(n1, n2); }
-xint::integer operator^(const xint::integer& n1, const xint::integer& n2) { return xint::bitwise_xor(n1, n2); }
+namespace xint {
+
+const integer& operator+(const integer& a) { return a; }
+integer operator-(const integer& a) { return negate(a); }
+integer operator+(const integer& num1, const integer& num2) { return add(num1, num2); }
+integer operator-(const integer& num1, const integer& num2) { return subtract(num1, num2); }
+integer operator*(const integer& num1, const integer& num2) { return multiply(num1, num2); }
+integer operator/(const integer& num1, const integer& num2) { return divide(num1, num2); }
+integer operator%(const integer& num1, const integer& num2) { return mod(num1, num2); }
+integer operator&(const integer& n1, const integer& n2) { return bitwise_and(n1, n2); }
+integer operator|(const integer& n1, const integer& n2) { return bitwise_or(n1, n2); }
+integer operator^(const integer& n1, const integer& n2) { return bitwise_xor(n1, n2); }
+
+} // namespace xint
Modified: sandbox/xint/boost/xint/src/powers.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/powers.cpp (original)
+++ sandbox/xint/boost/xint/src/powers.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -46,7 +46,7 @@
std::vector<doubledigit_t> a(ndata->mLength*2+1, 0);
doubledigit_t *adigit=&a[0];
- int i, j;
+ size_t i, j;
integer addend;
data_t *addenddata=addend._get_data();
addenddata->alloc(ndata->mLength*2+1);
@@ -86,15 +86,15 @@
integer pow(const integer& n, const integer& exponent) {
bool neg=(n.sign() < 0 && exponent.odd());
- int length=exponent._get_length(), lastBitCount=0;
+ size_t length=exponent._get_length(), lastBitCount=0;
digit_t ee(exponent._get_digit(length-1));
while (ee != 0) { ee >>= 1; ++lastBitCount; }
integer p(abs(n)), answer=integer::one();
- for (int eIndex=0; eIndex < length; ++eIndex) {
+ for (size_t eIndex=0; eIndex < length; ++eIndex) {
digit_t e(exponent._get_digit(eIndex));
- int bitCount(eIndex == length-1 ? lastBitCount : bits_per_digit);
+ int bitCount(int(eIndex == length-1 ? lastBitCount : bits_per_digit));
while (bitCount-- > 0) {
if (e & 0x01) answer*=p;
p=sqr(p);
Modified: sandbox/xint/boost/xint/src/primes.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/primes.cpp (original)
+++ sandbox/xint/boost/xint/src/primes.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -87,7 +87,7 @@
// Run the number through the Miller-Rabin Probabilistic Test of Primality
// a few times to see if it's actually (probably) prime.
for (int count=0; count<5; ++count) {
- int k=random<int>();
+ unsigned int k=detail::get_random();
int isP=isProbablePrimeBaseB(n, abs(k), callback);
if (isP <= 0) return isP;
}
Modified: sandbox/xint/boost/xint/src/primitives.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/primitives.cpp (original)
+++ sandbox/xint/boost/xint/src/primitives.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -33,58 +33,45 @@
}
integer add(const integer& n1, const integer& n2) {
- if (n1.sign()==0) return n2;
- if (n2.sign()==0) return n1;
-
- bool swapped=false;
- const data_t *n1data=n1._get_data(), *n2data=n2._get_data();
- if (n1data->mLength < n2data->mLength) { swapped=true; std::swap(n1data, n2data); }
-
- integer r;
- data_t *rdata=r._get_data();
- rdata->copy(n1data, 1);
-
- if (n1.sign() != n2.sign()) {
- int level=n2data->mLength;
-
- integer _n2(swapped ? n1 : n2);
- _n2._make_unique();
- _n2._get_data()->invert();
-
- rdata->add(_n2._get_data());
-
- if (rdata->mLength > level) {
- --rdata->digits[level];
- rdata->skipLeadingZeros();
- } else rdata->invert();
+ int sign1=n1.sign(), sign2=n2.sign();
+ if (sign1 != sign2) {
+ if (sign1==0) return n2;
+ else if (sign2==0) return n1;
+ else return subtract(n1, -n2);
} else {
+ const data_t *n1data=n1._get_data(), *n2data=n2._get_data();
+ if (n1data->mLength < n2data->mLength) std::swap(n1data, n2data);
+
+ integer r;
+ data_t *rdata=r._get_data();
+ rdata->copy(n1data, 1);
rdata->add(*n2data);
+ return r;
}
- return r;
}
integer subtract(const integer& n1, const integer& n2) {
- if ((n1.sign() < 0) != (n2.sign() < 0)) {
- return add(n1, -n2);
- } else if (n1.sign() < 0) {
- return -subtract(-n1, -n2);
- }
-
- // Signs are both guaranteed positive now.
-
- if (n1 < n2) {
- return -subtract(n2, n1);
+ int sign1=n1.sign(), sign2=n2.sign();
+ if (sign1 != sign2) {
+ if (sign1 == 0) return -n2;
+ else if (sign2 == 0) return n1;
+ else return add(n1, -n2);
} else {
+ bool invert=(sign1 == (n1 < n2 ? 1 : -1));
+ const data_t *n1data=n1._get_data(), *n2data=n2._get_data();
+ if (invert) std::swap(n1data, n2data);
+
integer r;
data_t *rdata=r._get_data();
- rdata->copy(n1._get_data());
- rdata->subtract(*n2._get_data());
- return r;
+ rdata->copy(n1data);
+ rdata->subtract(*n2data);
+ return (invert ? -r : r);
}
}
integer multiply(const integer& n, const integer& by) {
- if (n.sign()==0 || by.sign()==0) return integer::zero();
+ int nsign=n.sign(), bysign=by.sign();
+ if (nsign==0 || bysign==0) return integer::zero();
const data_t *ndata=n._get_data(), *bydata=by._get_data();
if (ndata == bydata) return sqr(n);
@@ -123,7 +110,7 @@
}
}
- answer._set_negative(n.sign() != by.sign());
+ answer._set_negative(nsign != bysign);
answer._get_data()->skipLeadingZeros();
return answer;
}
@@ -142,7 +129,7 @@
const doubledigit_t lomask(digit_mask);
const doubledigit_t himask(doubledigit_t(digit_mask) << bits_per_digit);
- int m = d1data->mLength - 1;
+ int m = int(d1data->mLength) - 1;
const digit_t *d1p=d1data->digits+m;
digit_t *qp=qdata->digits+m;
for (int i = m; i >= 0; --i, --d1p, --qp) {
@@ -161,7 +148,7 @@
std::pair<integer, integer> subDivide(integer d1, integer d2) {
const data_t *ndata=d1._get_data(), *bydata=d2._get_data();
const digit_t *nDigits = ndata->digits, *byDigits = bydata->digits;
- int nMSD = ndata->mLength-1, byMSD = bydata->mLength-1;
+ size_t nMSD = ndata->mLength-1, byMSD = bydata->mLength-1;
// The normalization step
digit_t d = static_cast<digit_t>(digit_overflowbit /
@@ -186,7 +173,7 @@
// has the same number of digits as the divisor; if what remains is greater
// than the divisor, then we start there, otherwise that one's zero and we
// start on the next lower one.
- int highestQuotientDigit=(nMSD - byMSD);
+ size_t highestQuotientDigit=(nMSD - byMSD);
integer nTest(d1);
nTest -= integer::one();
nTest >>= (bits_per_digit * highestQuotientDigit);
@@ -196,7 +183,7 @@
data_t *qdata=quotient._get_data();
qdata->alloc(highestQuotientDigit + 1);
- for (int j = highestQuotientDigit; j >= 0; --j) {
+ for (int j = int(highestQuotientDigit); j >= 0; --j) {
doubledigit_t q = (nDigits[nMSD] > byDigits[byMSD] ?
doubledigit_t(nDigits[nMSD]) / byDigits[byMSD] :
((doubledigit_t(nDigits[nMSD]) << bits_per_digit) +
Modified: sandbox/xint/boost/xint/src/random.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/random.cpp (original)
+++ sandbox/xint/boost/xint/src/random.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -17,8 +17,7 @@
#include <vector>
#include <sstream>
#include <fstream>
-
-#include <boost/crc.hpp>
+#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#ifdef XINT_THREADSAFE
@@ -40,10 +39,9 @@
namespace {
class generator_t {
- typedef boost::mt19937 internal_generator_t;
-
public:
- typedef internal_generator_t::result_type result_type;
+ typedef base_random_generator::result_type result_type;
+ typedef boost::mt19937 default_random_t;
#ifdef XINT_THREADSAFE
generator_t() { mLock.lock(); init(); }
@@ -52,166 +50,152 @@
generator_t() { init(); }
#endif
- void seed_manual(const std::string& bytes);
- bool seed_secure();
- void seed_fallback();
- result_type operator()();
+ result_type operator()() { return mGeneratorFn(); }
+
+ static void set_generator(random_t g, base_random_generator *p) {
+ mGeneratorObj.reset(p);
+ mGeneratorFn=g;
+ }
private:
- class SeedGenerator {
- public:
- SeedGenerator(const std::string& seedstring): mString(seedstring.substr(0,
- cSeedMaximumBytes)), mNumber(0) { }
- internal_generator_t::result_type operator()() {
- std::ostringstream s1;
- s1 << mNumber++ << mString;
- std::string s2=s1.str();
-
- boost::crc_32_type crc;
- crc.process_bytes(s2.c_str(), s2.length());
- return crc.checksum();
+ void init() {
+ if (!mGeneratorFn) {
+ typedef default_random_t T;
+ mDefaultGenerator.reset(new T(boost::uint32_t(time(0)+clock())));
+ random_generator<T> *obj=new random_generator<T>(*mDefaultGenerator);
+ set_generator(*obj, obj);
}
+ }
- #ifdef XINT_SECURE
- static char zero(char) { return 0; }
-
- ~SeedGenerator() {
- mNumber=0;
- std::transform(mString.begin(), mString.end(), mString.begin(),
- zero);
- }
- #endif
-
- private:
- static const size_t cSeedMaximumBytes=4096;
-
- std::string mString;
- int mNumber;
- };
-
- void init();
-
- static internal_generator_t *mGen;
- static bool mSeeded;
+ static random_t mGeneratorFn;
+ static std::auto_ptr<base_random_generator> mGeneratorObj;
+ static std::auto_ptr<default_random_t> mDefaultGenerator;
#ifdef XINT_THREADSAFE
static boost::mutex mLock;
#endif
};
-generator_t::internal_generator_t *generator_t::mGen=0;
-bool generator_t::mSeeded=false;
+std::auto_ptr<base_random_generator> generator_t::mGeneratorObj;
+std::auto_ptr<generator_t::default_random_t> generator_t::mDefaultGenerator;
+random_t generator_t::mGeneratorFn;
#ifdef XINT_THREADSAFE
boost::mutex generator_t::mLock;
#endif
-void generator_t::seed_manual(const std::string& bytes) {
- SeedGenerator gen(bytes);
- mGen->seed(gen);
- mSeeded=true;
+} // namespace
+
+namespace detail {
+
+void set_random_generator(random_t fn, base_random_generator *obj) {
+ generator_t::set_generator(fn, obj);
+}
+
+unsigned int get_random() {
+ generator_t gen;
+ return gen();
}
-bool generator_t::seed_secure() {
- const int cBitsRequested=256,
- cBytesRequested=cBitsRequested / std::numeric_limits<char>::digits;
- bool success=false;
-
- #ifdef _WIN32
- // This should work under WinXP, Vista, and Win7. No guarantees about
- // future compatibility, but I doubt that Microsoft will get rid of it
- // (it's too useful), and I doubt that they'll change it now that it's
- // well-known (it would break too many programs). We could also use the
- // rand_s function in more recent versions of Visual C++, but that
- // causes compatibility problems with older versions of Windows.
+} // namespace detail
+
+////////////////////////////////////////////////////////////////////////////////
+// The secure random generator
+
+#ifdef _WIN32
+ struct strong_random_generator::impl_t {
typedef BOOLEAN (WINAPI *RtlGenRandomFn)(PVOID, ULONG);
- HMODULE dll=LoadLibrary(_T("Advapi32.dll"));
- if (dll != 0) {
- RtlGenRandomFn RtlGenRandom=RtlGenRandomFn(GetProcAddress(dll,
- "SystemFunction036"));
- if (RtlGenRandom != 0) {
- std::vector<char> buffer(cBytesRequested, '\0');
- if (RtlGenRandom(&buffer[0], cBytesRequested)) {
- char *c=&buffer[0];
- seed_manual(std::string(c, c+cBytesRequested));
- success=true;
- }
+ typedef DWORD result_type;
+
+ impl_t(): dll(0), fn(0) {
+ // This should work under WinXP, Vista, and Win7. No guarantees about
+ // future compatibility, but I doubt that Microsoft will get rid of it
+ // (it's too useful), and I doubt that they'll change it now that it's
+ // well-known (it would break too many programs). We could also use the
+ // rand_s function in more recent versions of Visual C++, but that
+ // causes compatibility problems with older versions of Windows.
+ dll=LoadLibrary(_T("Advapi32.dll"));
+ if (dll != 0) fn=RtlGenRandomFn(GetProcAddress(dll, "SystemFunction036"));
+ if (fn == 0) {
+ destroy();
+ throw no_strong_random();
}
- FreeLibrary(dll);
- }
- #else
- // This should be supported under most non-Windows systems. Note that
- // we're using /dev/urandom, not /dev/random -- /dev/random is more
- // secure, but it can be VERY slow.
- std::ifstream rng("/dev/urandom");
- if (rng) {
- std::string rstr;
- for (int i=0; i < cBytesRequested; ++i)
- rstr.push_back(rng.get());
- seed_manual(rstr);
- success=true;
}
- #endif
- return success;
-}
+ ~impl_t() { destroy(); }
-void generator_t::seed_fallback() {
- // No cryptographically-secure device available. Fall back onto the
- // system clock. It's not much, but it's portable, fast, and will
- // provide at least a *little* entropy.
- std::ostringstream out;
- out << time(0) << clock();
- seed_manual(out.str());
-}
+ result_type operator()() {
+ result_type r=0;
+ if (!fn(&r, sizeof(result_type)))
+ throw no_strong_random("RtlGenRandom failed");
+ return r;
+ }
-generator_t::result_type generator_t::operator()() {
- if (!mSeeded)
- if (!seed_secure())
- seed_fallback();
- return (*mGen)();
-}
+ void destroy() { if (dll) FreeLibrary(dll); }
-void generator_t::init() {
- if (!mGen) mGen=new internal_generator_t();
-}
+ HMODULE dll;
+ RtlGenRandomFn fn;
+ };
-} // namespace
+ double strong_random_generator::entropy() const { return 32; }
+#else
+ struct strong_random_generator::impl_t {
+ typedef unsigned char result_type;
+
+ impl_t(): rng("/dev/urandom", std::ios::binary) {
+ // This should be supported under most non-Windows systems. Note
+ // that we're using /dev/urandom, not /dev/random -- /dev/random is
+ // more secure, but it can be VERY slow.
+ if (!rng) throw no_strong_random();
+ }
-bool seed_secure() {
- generator_t gen;
- return gen.seed_secure();
-}
+ result_type operator()() {
+ int r=rng.get();
+ if (r==EOF) throw no_strong_random("/dev/urandom returned EOF");
+ return static_cast<result_type>(r);
+ }
-void seed_fallback() {
- generator_t gen;
- gen.seed_fallback();
-}
+ std::ifstream rng;
+ };
-void seed_manual(const std::string& value) {
- generator_t gen;
- gen.seed_manual(value);
-}
+ double strong_random_generator::entropy() const { return 8; }
+#endif
+
+const bool strong_random_generator::has_fixed_range = true;
+const strong_random_generator::result_type strong_random_generator::min_value =
+ (std::numeric_limits<impl_t::result_type>::min)();
+const strong_random_generator::result_type strong_random_generator::max_value =
+ (std::numeric_limits<impl_t::result_type>::max)();
+strong_random_generator::strong_random_generator(): impl(new impl_t) { }
+strong_random_generator::~strong_random_generator() { delete impl; }
+strong_random_generator::result_type strong_random_generator::operator()() {
+ return (*impl)(); }
+strong_random_generator::result_type strong_random_generator::min
+ BOOST_PREVENT_MACRO_SUBSTITUTION () const { return min_value; }
+strong_random_generator::result_type strong_random_generator::max
+ BOOST_PREVENT_MACRO_SUBSTITUTION () const { return max_value; }
+////////////////////////////////////////////////////////////////////////////////
// Returns a positive (unless told otherwise) integer between zero and
// (1<<bits)-1, inclusive
-integer random_by_size(size_t bits, bool highBitOn, bool lowBitOn, bool canBeNegative) {
+integer random_by_size(size_t bits, bool highBitOn, bool lowBitOn, bool
+ canBeNegative)
+{
if (bits<=0) return integer::zero();
generator_t randomGenerator;
-
const size_t cBitsPerIteration=std::numeric_limits<generator_t::result_type>::digits;
// Grab a set of random bits, of at least the specified size
- int iterations = (bits+cBitsPerIteration-1) / cBitsPerIteration;
+ size_t iterations = (bits+cBitsPerIteration-1) / cBitsPerIteration;
std::vector<generator_t::result_type> v;
- for (int i=0; i<iterations; ++i) v.push_back(randomGenerator());
+ for (size_t i=0; i<iterations; ++i) v.push_back(randomGenerator());
const char *vptr=(const char *)&v[0], *vptr_end=vptr+(v.size() * sizeof(generator_t::result_type));
integer p=from_binary(std::string(vptr, vptr_end));
// Trim it to the proper length
- int index=(bits/bits_per_digit);
+ size_t index=(bits/bits_per_digit);
digit_t mask=(digit_t(1) << (bits % bits_per_digit))-1;
if (mask==0) { mask=digit_mask; --index; }
p._get_data()->digits[index] &= mask;
@@ -226,10 +210,4 @@
return p;
}
-template <>
-integer random<integer>(const integer& lowest, const integer& highest) {
- integer range(abs(highest-lowest+1));
- return lowest+(random_by_size(log2(range)) % range);
-}
-
} // namespace xint
Modified: sandbox/xint/boost/xint/src/roots.cpp
==============================================================================
--- sandbox/xint/boost/xint/src/roots.cpp (original)
+++ sandbox/xint/boost/xint/src/roots.cpp 2010-03-31 09:25:56 EDT (Wed, 31 Mar 2010)
@@ -17,7 +17,12 @@
namespace xint {
integer sqrt(const integer& n) {
- if (n.sign() <= 0) return integer::zero();
+ if (n.sign() < 0) {
+ if (exceptions_allowed()) throw cannot_represent("library cannot "
+ "represent imaginary values (tried to take sqrt of negative "
+ "number)");
+ else return integer(not_a_number());
+ } else if (n.sign() == 0) return integer::zero();
// Initial guess is half the length of n, in bits
integer guess;
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