From 4c96aac02cd78f7fd2d054906d5c4ca2e2c6c5bf Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Tue, 2 Sep 2025 01:59:24 +0200 Subject: [PATCH] Badrand pseudo random number generator, emphasis on pseudo --- Makefile | 3 ++- kern/libkern/badrand.c | 35 ++++++++++++++++++++++++++++++++++ kern/libkern/badrand.h | 43 ++++++++++++++++++++++++++++++++++++++++++ kern/libkern/stdint.h | 15 +++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 kern/libkern/badrand.c create mode 100644 kern/libkern/badrand.h diff --git a/Makefile b/Makefile index c9e8c3c..928c492 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,8 @@ KERNEL_OBJ := \ kern/libkern/memory.o \ kern/libkern/spinlock.o \ kern/libkern/mini-printf.o \ - kern/libkern/stdio.o + kern/libkern/stdio.o \ + kern/libkern/badrand.o kern/kernel.elf: $(KERNEL_OBJ) @echo LD $@ diff --git a/kern/libkern/badrand.c b/kern/libkern/badrand.c new file mode 100644 index 0000000..48df698 --- /dev/null +++ b/kern/libkern/badrand.c @@ -0,0 +1,35 @@ +#include "badrand.h" +#include + +#define PRAND_BUILD_SEED \ + ((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \ + (uint64_t)(__TIME__[6]) * (uint64_t)(__TIME__[7])) + +static uint64_t seed = PRAND_BUILD_SEED * 6364136223846793005ULL + 1; + +uint64_t badrand() { + seed = seed * 6364136223846793005ULL + 1; + return seed; +} + +uint64_t badrand_range(uint64_t min, uint64_t max) { + uint64_t range = max - min + 1; + uint64_t x; + uint64_t limit = UINT64_MAX - (UINT64_MAX % range); + + do { + x = badrand(); + } while (x > limit); + + return min + (x % range); +} + +void sbadprand(uint64_t s) { + if (s) { + seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2); + } else { + seed ^= PRAND_BUILD_SEED; + } +} + +#undef PRAND_BUILD_SEED diff --git a/kern/libkern/badrand.h b/kern/libkern/badrand.h new file mode 100644 index 0000000..8a0ab9c --- /dev/null +++ b/kern/libkern/badrand.h @@ -0,0 +1,43 @@ +#ifndef BADRAND_H +#define BADRAND_H + +#include + +/* + * This is a PRNG for non-cryptographic use. + * + * See: + * https://en.wikipedia.org/wiki/Linear_congruential_generator + */ + +/** + * @brief Sets the seed for the PRNG. + * + * @param s The specific seed value or zero. If zero is passed, it will call + * rand_reseed(). + */ +void sbadrand(uint64_t s); + +/** + * @brief Generates a pseudo-random 64-bit number. + * + * Uses a simple Linear Congruential Generator (LCG) to produce + * a sequence of pseudo-random numbers. + * + * @return A pseudo-random 64-bit unsigned integer. + */ +uint64_t badrand(); + +/** + * @brief Generates a random number within a specified range. + * + * Produces a random number in the inclusive range [min, max]. + * Ensures uniform distribution by applying a modulo operation. + * + * @param min The lower bound of the range (inclusive). + * @param max The upper bound of the range (inclusive). + * @return A random number between min and max. + */ +uint64_t badrand_range(uint64_t min, uint64_t max); + +#endif // BADRAND_H diff --git a/kern/libkern/stdint.h b/kern/libkern/stdint.h index 0ce4c00..095e598 100644 --- a/kern/libkern/stdint.h +++ b/kern/libkern/stdint.h @@ -12,3 +12,18 @@ typedef unsigned long uint64_t; typedef uint64_t size_t; typedef uint64_t uintptr_t; + +#define INT8_MIN (-128) +#define INT16_MIN (-32767 - 1) +#define INT32_MIN (-2147483647 - 1) +#define INT64_MIN (-__INT64_C(9223372036854775807) - 1) + +#define INT8_MAX (127) +#define INT16_MAX (32767) +#define INT32_MAX (2147483647) +#define INT64_MAX (__INT64_C(9223372036854775807)) + +#define UINT8_MAX (255) +#define UINT16_MAX (65535) +#define UINT32_MAX (4294967295U) +#define UINT64_MAX (__UINT64_C(18446744073709551615))