diff --git a/Knot.files b/Knot.files
index e60b931fd367211156b9ccdbe811956ea0f60bf5..f364dccaad656272b557db1cdb163ad30c457fdd 100644
--- a/Knot.files
+++ b/Knot.files
@@ -105,8 +105,12 @@ src/common/ref.h
 src/common/modified_tree.h
 src/common/general-tree.h
 src/common/general-tree.c
-src/common/WELL1024a.c
-src/common/WELL1024a.h
+src/common/dSFMT.c
+src/common/dSFMT.h
+src/common/dSFMT-params.h
+src/common/dSFMT-params521.h
+src/common/prng.c
+src/common/prng.h
 src/common/fdset.h
 src/common/fdset.c
 src/common/fdset_poll.h
diff --git a/configure.ac b/configure.ac
index b824a43362b2e64b01ec5fca8a701585d0d9f962..ca9fc04cf20ce33382aac1dfe73de604e1092e30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,9 @@ AC_TYPE_UINT32_T
 AC_TYPE_UINT64_T
 AC_TYPE_UINT8_T
 
+# Set PRNG parameters
+AC_DEFINE([DSFMT_MEXP], [521], [DSFMT parameters.])
+
 # Checks for library functions.
 AC_FUNC_FORK
 AC_FUNC_MMAP
diff --git a/src/Makefile.am b/src/Makefile.am
index f8d81e5d213272ddc3ff788e6671f773b488e2c7..e73b2bfb4d020fc6dfed9b58f3b2e70ed7496dc8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -252,8 +252,12 @@ libknots_la_SOURCES =				\
 	common/ref.c				\
 	common/errors.h				\
 	common/errors.c				\
-        common/WELL1024a.h			\
-        common/WELL1024a.c			\
+        common/dSFMT.h				\
+        common/dSFMT-params.h			\
+        common/dSFMT-params521.h		\
+        common/dSFMT.c				\
+        common/prng.h				\
+        common/prng.c				\
         common/fdset.h				\
         common/fdset.c				\
         common/fdset_poll.h			\
diff --git a/src/common/prng.c b/src/common/prng.c
new file mode 100644
index 0000000000000000000000000000000000000000..ca87b0de4b745e9b84ecd4632627c5b6cada4eaf
--- /dev/null
+++ b/src/common/prng.c
@@ -0,0 +1,93 @@
+/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include "prng.h"
+#include "dSFMT.h"
+
+/*! \brief TLS unique key for each thread seed. */
+static pthread_key_t tls_prng_key;
+static pthread_once_t tls_prng_once = PTHREAD_ONCE_INIT;
+
+static void tls_prng_deinit(void *ptr)
+{
+	free(ptr);
+}
+
+static void tls_prng_deinit_main()
+{
+	tls_prng_deinit(pthread_getspecific(tls_prng_key));
+}
+
+static void tls_prng_init()
+{
+	(void) pthread_key_create(&tls_prng_key, tls_prng_deinit);
+	atexit(tls_prng_deinit_main); // Main thread cleanup
+}
+
+double tls_rand()
+{
+	/* Setup PRNG state for current thread. */
+	(void)pthread_once(&tls_prng_once, tls_prng_init);
+
+	/* Create PRNG state if not exists. */
+	dsfmt_t* s = pthread_getspecific(tls_prng_key);
+	if (!s) {
+		/* Initialize seed from system PRNG generator. */
+		uint32_t seed = 0;
+		FILE *fp = fopen("/dev/urandom", "r");
+		if (fp == NULL) {
+			fp = fopen("/dev/random", "r");
+		}
+		if (fp != NULL) {
+			if (fread(&seed, sizeof(uint32_t), 1, fp) != 1) {
+				fclose(fp);
+				fp = NULL;
+			}
+		}
+		if (fp == NULL) {
+			fprintf(stderr, "error: PRNG: cannot seed from "
+				"/dev/urandom, seeding from local time\n");
+			struct timeval tv;
+			if (gettimeofday(&tv, NULL) == 0) {
+				seed = (uint32_t)(tv.tv_sec ^ tv.tv_usec);
+			} else {
+				/* Last resort. */
+				seed = (uint32_t)time(NULL);
+			}
+		} else {
+			fclose(fp);
+		}
+
+		/* Initialize PRNG state. */
+		s = malloc(sizeof(dsfmt_t));
+		if (s == NULL) {
+			fprintf(stderr, "error: PRNG: not enough memory\n");
+			return .0;
+		} else {
+			dsfmt_init_gen_rand(s, seed);
+			(void)pthread_setspecific(tls_prng_key, s);
+		}
+	}
+
+	return dsfmt_genrand_close_open(s);
+}
diff --git a/src/common/prng.h b/src/common/prng.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f17a780d93a403efb64178afa80b8b3fc00a45d
--- /dev/null
+++ b/src/common/prng.h
@@ -0,0 +1,41 @@
+/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/*!
+ * \file prng.h
+ *
+ * \author Marek Vavrusa <marek.vavrusa@nic.cz>
+ *
+ * \brief Pseudo-random number generator interface.
+ *
+ * Interface for accessing underlying PRNG.
+ *
+ * \addtogroup common_lib
+ * @{
+ */
+
+#ifndef _KNOTD_PRNG_H_
+#define _KNOTD_PRNG_H_
+
+/*!
+ * \brief Get pseudorandom number from PRNG initialized in thread-local storage.
+ *
+ * No need for initialization, TLS will take care of it.
+ *
+ * \retval Pseudorandom number.
+ */
+double tls_rand();
+
+#endif //_KNOTD_ACL_H_
diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c
index 2fdc354bd7c2c2257f32d210b4c68b849087627f..71452e9cc238d3e3791671caef5bbd8c6c91587d 100644
--- a/src/knot/server/tcp-handler.c
+++ b/src/knot/server/tcp-handler.c
@@ -28,7 +28,7 @@
 #include "common/sockaddr.h"
 #include "common/skip-list.h"
 #include "common/fdset.h"
-#include "common/WELL1024a.h"
+#include "common/prng.h"
 #include "knot/common.h"
 #include "knot/server/tcp-handler.h"
 #include "knot/server/xfr-handler.h"
diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c
index cec3f53c568638748f521381eae052e6375d8300..bc55434e4e43ec18ff351fa293f53efa69dc5196 100644
--- a/src/knot/server/xfr-handler.c
+++ b/src/knot/server/xfr-handler.c
@@ -39,7 +39,7 @@
 #include "libknot/util/error.h"
 #include "libknot/tsig-op.h"
 #include "common/evsched.h"
-#include "common/WELL1024a.h"
+#include "common/prng.h"
 
 /* Constants */
 #define XFR_BUFFER_SIZE 65535 /*! Do not change this - maximum value for UDP packet length. */
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index bd23c7d64d1bab33ce172cb93a0a808a4429beb8..8616ebd53e4a617c2bbc7b0ffaaabb7fa18c8840 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -17,7 +17,7 @@
 #include <sys/stat.h>
 
 #include "common/lists.h"
-#include "common/WELL1024a.h"
+#include "common/prng.h"
 #include "libknot/dname.h"
 #include "libknot/util/wire.h"
 #include "knot/zone/zone-dump-text.h"
diff --git a/src/libknot/util/utils.c b/src/libknot/util/utils.c
index 17b33a73ea14eb44c28d14bcb205a1f6f02876d8..04e12c52225ebe7bb08c7e40f60bd6ae4bf3d4af 100644
--- a/src/libknot/util/utils.c
+++ b/src/libknot/util/utils.c
@@ -22,7 +22,7 @@
 
 #include "common.h"
 #include "util/utils.h"
-#include "common/WELL1024a.h"
+#include "common/prng.h"
 
 /*----------------------------------------------------------------------------*/