00001 00002 /* 00003 The Extended Integer (XInt) Library 00004 A fast, portable C++ library for multi-precision integer math 00005 Copyright 2010 by Chad Nelson 00006 00007 Distributed under the Boost Software License, Version 1.0. 00008 See accompanying file LICENSE_1_0.txt or copy at 00009 http://www.boost.org/LICENSE_1_0.txt 00010 00011 See http://www.boost.org/libs/xint for library home page. 00012 */ 00013 00020 #ifndef BOOST_INCLUDED_XINT_RANDOMGEN_HPP 00021 #define BOOST_INCLUDED_XINT_RANDOMGEN_HPP 00022 00024 // The secure random generator 00025 00027 namespace boost { 00028 namespace xint { 00029 namespace detail { 00030 00031 #define BOOST_XINT_INLINE inline 00032 00033 #ifdef _WIN32 00034 template <typename T> 00035 struct strong_random_generator_t<T>::impl_t { 00036 typedef BOOLEAN (WINAPI *RtlGenRandomFn)(PVOID, ULONG); 00037 typedef DWORD result_type; 00038 00039 impl_t(): dll(0), fn(0) { 00040 // This should work under WinXP, Vista, and Win7. No guarantees 00041 // about future compatibility, but I doubt that Microsoft will get 00042 // rid of it (it's too useful), and I doubt that they'll change it 00043 // now that it's well-known (it would break too many programs). We 00044 // could also use the rand_s function in more recent versions of 00045 // Visual C++, but that causes compatibility problems with older 00046 // versions of Windows. 00047 dll=LoadLibraryA("Advapi32.dll"); 00048 if (dll != 0) fn=RtlGenRandomFn(GetProcAddress(dll, 00049 "SystemFunction036")); 00050 if (fn == 0) { 00051 destroy(); 00052 exception_handler<>::call(__FILE__, __LINE__, 00053 exceptions::no_strong_random()); 00054 } 00055 } 00056 00057 ~impl_t() { destroy(); } 00058 00059 result_type operator()() { 00060 result_type r=0; 00061 if (!fn(&r, sizeof(result_type))) 00062 exception_handler<>::call(__FILE__, __LINE__, 00063 exceptions::no_strong_random("RtlGenRandom failed")); 00064 return r; 00065 } 00066 00067 void destroy() { if (dll) FreeLibrary(dll); } 00068 00069 HMODULE dll; 00070 RtlGenRandomFn fn; 00071 }; 00072 00073 template <typename T> 00074 BOOST_XINT_INLINE double strong_random_generator_t<T>::entropy() const 00075 { return 32; } 00076 #else 00077 template <typename T> 00078 struct strong_random_generator_t<T>::impl_t { 00079 typedef unsigned char result_type; 00080 00081 impl_t(): rng("/dev/urandom", std::ios::binary) { 00082 // This should be supported under most non-Windows systems. Note 00083 // that we're using /dev/urandom, not /dev/random -- /dev/random is 00084 // more secure, but it can be VERY slow. 00085 if (!rng) exception_handler<>::call(__FILE__, __LINE__, 00086 exceptions::no_strong_random()); 00087 } 00088 00089 result_type operator()() { 00090 int r=rng.get(); 00091 if (r==EOF) exception_handler<>::call(__FILE__, __LINE__, 00092 exceptions::no_strong_random("/dev/urandom returned EOF")); 00093 return static_cast<result_type>(r); 00094 } 00095 00096 std::ifstream rng; 00097 }; 00098 00099 template <typename T> 00100 BOOST_XINT_INLINE double strong_random_generator_t<T>::entropy() const 00101 { return 8; } 00102 #endif 00103 00104 template <typename T> 00105 const bool strong_random_generator_t<T>::has_fixed_range = true; 00106 00107 template <typename T> 00108 const typename strong_random_generator_t<T>::result_type 00109 strong_random_generator_t<T>::min_value = 00110 (std::numeric_limits<typename 00111 strong_random_generator_t<T>::impl_t::result_type>::min)(); 00112 00113 template <typename T> 00114 const typename strong_random_generator_t<T>::result_type 00115 strong_random_generator_t<T>::max_value = 00116 (std::numeric_limits<typename 00117 strong_random_generator_t<T>::impl_t::result_type>::max)(); 00118 00119 template <typename T> 00120 BOOST_XINT_INLINE strong_random_generator_t<T>::strong_random_generator_t(): 00121 impl(new impl_t) { } 00122 00123 template <typename T> 00124 BOOST_XINT_INLINE strong_random_generator_t<T>::~strong_random_generator_t() { 00125 delete impl; } 00126 00127 template <typename T> 00128 BOOST_XINT_INLINE typename strong_random_generator_t<T>::result_type 00129 strong_random_generator_t<T>::operator()() { return (*impl)(); } 00130 00131 template <typename T> 00132 BOOST_XINT_INLINE typename strong_random_generator_t<T>::result_type 00133 strong_random_generator_t<T>::min BOOST_PREVENT_MACRO_SUBSTITUTION () const 00134 { return min_value; } 00135 00136 template <typename T> 00137 BOOST_XINT_INLINE typename strong_random_generator_t<T>::result_type 00138 strong_random_generator_t<T>::max BOOST_PREVENT_MACRO_SUBSTITUTION () const 00139 { return max_value; } 00140 00141 } // namespace detail 00142 } // namespace xint 00143 } // namespace boost 00145 00146 #endif // BOOST_INCLUDED_XINT_RANDOMGEN_HPP
© Copyright Chad Nelson, 2010-2011. 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)