diff --git a/include/opendht/rng.h b/include/opendht/rng.h
index ebc1aead33c04da5aa52c745e30f213851284379..356c56b968c4ad786e2182827b684ad96fcb3e50 100644
--- a/include/opendht/rng.h
+++ b/include/opendht/rng.h
@@ -110,21 +110,47 @@ using random_device = std::random_device;
 using random_device = std::random_device;
 #endif
 
-template<class T = std::mt19937, std::size_t N = T::state_size>
-auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
-    typename T::result_type random_data[N];
-    for (unsigned i=0; i<256; i++) {
+/** 
+ * Generate a seeded random engine.
+ */
+template<class T = std::mt19937, std::size_t N = T::state_size+1>
+auto getSeededRandomEngine() -> typename std::enable_if<!!N, T>::type {
+    std::array<typename T::result_type, N> random_data;
+    constexpr auto gen = [](random_device& source) -> typename T::result_type {
+        for (unsigned j=0; j<64; j++) {
+            try {
+                return source();
+            } catch (...) {
+                std::this_thread::sleep_for(std::chrono::microseconds(500));
+            }
+        }
+        throw std::runtime_error("Can't generate random number");
+    };
+    for (unsigned i=0; i<8; i++) {
         try {
             random_device source;
-            std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
-            std::seed_seq seeds(std::begin(random_data), std::end(random_data));
-            T seededEngine (seeds);
-            return seededEngine;
+            for (auto& r : random_data)
+                r = gen(source);
+            std::seed_seq seed(
+                (std::seed_seq::result_type*)random_data.data(),
+                (std::seed_seq::result_type*)(random_data.data() + random_data.size()));
+            return T(seed);
         } catch (...) {
-            std::this_thread::sleep_for(std::chrono::milliseconds(1));
+            std::this_thread::sleep_for(std::chrono::microseconds(500));
         }
     }
-    throw std::runtime_error("Can't seed random engine");
+    throw std::runtime_error("Can't seed random seed");
+}
+
+/**
+ * Generate a random engine from another source.
+ */
+template<class T = std::mt19937, std::size_t N = T::state_size+1>
+auto getDerivedRandomEngine(T& source) -> typename std::enable_if<!!N, T>::type {
+    std::array<typename T::result_type, N> random_data;
+    std::generate(random_data.begin(), random_data.end(), std::ref(source));
+    std::seed_seq seed(random_data.begin(), random_data.end());
+    return T(seed);
 }
 
 }} // dht::crypto