aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core/prng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/core/prng.c')
-rw-r--r--src/kernel/core/prng.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/kernel/core/prng.c b/src/kernel/core/prng.c
new file mode 100644
index 0000000..d4307b6
--- /dev/null
+++ b/src/kernel/core/prng.c
@@ -0,0 +1,38 @@
+#include <prng.h>
+
+#define EPOOLSIZE 2048
+
+static uint32_t x = 211;
+static int n = 0;
+static char entropy[EPOOLSIZE];
+static int entropy_count = 0;
+static const uint32_t a = 16807;
+static const uint32_t m = 0x7FFFFFFF;
+
+uint16_t prng_word() {
+ if (++n == 100) {
+ n = 0;
+ if (entropy_count) {
+ entropy_count--;
+ x += entropy[entropy_count];
+ }
+ }
+ x = (x * a) % m;
+ return x & 0xFFFF;
+}
+
+void prng_bytes(uint8_t* out, size_t nbytes) {
+ uint16_t *d = (uint16_t*)out;
+ for (size_t i = 0; i < nbytes / 2; i++) {
+ d[i] = prng_word();
+ }
+ if (nbytes & 1) out[nbytes-1] = prng_word() & 0xFF;
+}
+
+void prng_add_entropy(const uint8_t* ptr, size_t nbytes) {
+ while (nbytes-- && entropy_count < EPOOLSIZE - 1) {
+ entropy[entropy_count++] = *(ptr++);
+ }
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/