diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 new file mode 100644 index 0000000..34d7f24 --- /dev/null +++ b/build/Jamfile.v2 @@ -0,0 +1,18 @@ +# Jamfile.v2 +# +# Copyright (c) 2010 +# Steven Watanabe +# +# 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) + +project /boost/random + : source-location ../src + : requirements shared:BOOST_RANDOM_DYN_LINK + : usage-requirements shared:BOOST_RANDOM_DYN_LINK +; + +lib boost_random : [ glob *.cpp ] ; + +boost-install boost_random ; diff --git a/random_demo.cpp b/example/random_demo.cpp similarity index 100% rename from random_demo.cpp rename to example/random_demo.cpp diff --git a/include/boost/nondet_random.hpp b/include/boost/nondet_random.hpp index 89bab7b..de747cf 100644 --- a/include/boost/nondet_random.hpp +++ b/include/boost/nondet_random.hpp @@ -23,6 +23,7 @@ #include #include // noncopyable #include // compile-time integral limits +#include namespace boost { @@ -61,6 +62,12 @@ namespace boost { * pseudo-device, which blocks on reads if the entropy pool has no more * random bits available. * + * Inplementation Note for Windows + * + * On the Windows operating system, token is interpreted as the name + * of a cryptographic service provider. By default \random_device uses + * MS_DEF_PROV. + * * Performance * * The test program diff --git a/include/boost/random/detail/auto_link.hpp b/include/boost/random/detail/auto_link.hpp new file mode 100644 index 0000000..2afe77c --- /dev/null +++ b/include/boost/random/detail/auto_link.hpp @@ -0,0 +1,42 @@ +/* boost random auto_link.hpp header file + * + * Copyright Steven Watanabe 2010 + * 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) + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_DETAIL_AUTO_LINK_HPP +#define BOOST_RANDOM_DETAIL_AUTO_LINK_HPP + +#include + +#ifdef BOOST_HAS_DECLSPEC + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) + #if defined(BOOST_RANDOM_SOURCE) + #define BOOST_RANDOM_DECL __declspec(dllexport) + #else + #define BOOST_RANDOM_DECL __declspec(dllimport) + #endif + #endif +#endif + +#ifndef BOOST_RANDOM_DECL + #define BOOST_RANDOM_DECL +#endif + +#if !defined(BOOST_RANDOM_NO_LIB) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_RANDOM_SOURCE) + +#define BOOST_LIB_NAME boost_random + +#if defined(BOOST_RANDOM_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) + #define BOOST_DYN_LINK +#endif + +#include + +#endif + +#endif diff --git a/generate_table.cpp b/performance/generate_table.cpp similarity index 100% rename from generate_table.cpp rename to performance/generate_table.cpp diff --git a/nondet_random_speed.cpp b/performance/nondet_random_speed.cpp similarity index 100% rename from nondet_random_speed.cpp rename to performance/nondet_random_speed.cpp diff --git a/random_speed.cpp b/performance/random_speed.cpp similarity index 100% rename from random_speed.cpp rename to performance/random_speed.cpp diff --git a/random_device.cpp b/src/random_device.cpp similarity index 61% rename from random_device.cpp rename to src/random_device.cpp index 660172f..349ec35 100644 --- a/random_device.cpp +++ b/src/random_device.cpp @@ -1,6 +1,7 @@ /* boost random_device.cpp implementation * * Copyright Jens Maurer 2000 + * Copyright Steven Watanabe 2010 * 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) @@ -9,6 +10,8 @@ * */ +#define BOOST_RANDOM_SOURCE + #include #include #include @@ -22,7 +25,79 @@ const boost::random_device::result_type boost::random_device::max_value; #endif -#if defined(__linux__) || defined (__FreeBSD__) +#if defined(BOOST_WINDOWS) + +#include +#include +#include // std::invalid_argument + +const char * const boost::random_device::default_token = ""; + +class boost::random_device::impl +{ +public: + impl(const std::string & token) : path(token) { + std::basic_string prov_name(token.begin(), token.end()); + if(prov_name.empty()) prov_name = MS_DEF_PROV; + + TCHAR buffer[80]; + DWORD type; + DWORD len; + + // Find the type of the provider + for(DWORD i = 0; ; ++i) { + len = sizeof(buffer); + if(!CryptEnumProviders(i, NULL, 0, &type, buffer, &len)) { + error("Could not find provider"); + } + if(buffer == prov_name) { + break; + } + } + + if(!CryptAcquireContext(&hProv, NULL, prov_name.c_str(), type, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + error("Failed to aqcuire CSP context"); + } + } + + ~impl() { + if(!CryptReleaseContext(hProv, 0)) error("could not release CSP"); + } + + unsigned int next() { + unsigned int result; + + if(!CryptGenRandom(hProv, sizeof(result), + static_cast(static_cast(&result)))) { + error("error while reading"); + } + + return result; + } + +private: + void error(const std::string & msg) { + DWORD error_code = GetLastError(); + TCHAR buf[80]; + DWORD num = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + 0, + buf, + sizeof(buf), + NULL); + + throw std::invalid_argument("boost::random_device: " + msg + + " random-number pseudo-device " + path + + ": " + std::string(&buf[0], &buf[0] + num)); + } + const std::string path; + HCRYPTPROV hProv; +}; + +#else // the default is the unlimited capacity device, using some secure hash // try "/dev/random" for blocking when the entropy pool has drained @@ -90,8 +165,7 @@ private: int fd; }; -#endif // __linux__ || __FreeBSD__ - +#endif // BOOST_WINDOWS boost::random_device::random_device(const std::string& token) : pimpl(new impl(token)) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f439d21..350b7a3 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -7,12 +7,10 @@ # bring in rules for testing import testing ; -project - : source-location .. - ; +project /boost/random/test ; run random_test.cpp ; -run random_demo.cpp ; +run ../example/random_demo.cpp ; run validate.cpp ; local all-urngs = diff --git a/histogram.cpp b/test/histogram.cpp similarity index 100% rename from histogram.cpp rename to test/histogram.cpp diff --git a/instantiate.cpp b/test/instantiate.cpp similarity index 100% rename from instantiate.cpp rename to test/instantiate.cpp diff --git a/integrate.hpp b/test/integrate.hpp similarity index 100% rename from integrate.hpp rename to test/integrate.hpp diff --git a/random_test.cpp b/test/random_test.cpp similarity index 100% rename from random_test.cpp rename to test/random_test.cpp diff --git a/statistic_tests.cpp b/test/statistic_tests.cpp similarity index 100% rename from statistic_tests.cpp rename to test/statistic_tests.cpp diff --git a/statistic_tests.hpp b/test/statistic_tests.hpp similarity index 100% rename from statistic_tests.hpp rename to test/statistic_tests.hpp diff --git a/validate.cpp b/test/validate.cpp similarity index 100% rename from validate.cpp rename to test/validate.cpp