aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core/prng.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 11:10:45 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 11:10:45 +0100
commit6c50033dfb7a4dc7094d96f9339459b08b4efac9 (patch)
treeb3c8032d95620c2eb009273adb675c699b8a5a94 /src/kernel/core/prng.c
parent88636d28b812e425c51be2d4d24d16a504dae147 (diff)
downloadkogata-6c50033dfb7a4dc7094d96f9339459b08b4efac9.tar.gz
kogata-6c50033dfb7a4dc7094d96f9339459b08b4efac9.zip
Add PRNG
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 :*/