aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/arrays.c71
-rw-r--r--src/stdlib/arrays.h10
-rw-r--r--src/stdlib/chacha.h201
-rw-r--r--src/stdlib/datatypes.h2
-rw-r--r--src/stdlib/rng.c274
-rw-r--r--src/stdlib/rng.h36
-rw-r--r--src/stdlib/stdlib.c6
-rw-r--r--src/stdlib/tomo.h1
8 files changed, 59 insertions, 542 deletions
diff --git a/src/stdlib/arrays.c b/src/stdlib/arrays.c
index 6579536b..b018012f 100644
--- a/src/stdlib/arrays.c
+++ b/src/stdlib/arrays.c
@@ -10,7 +10,6 @@
#include "math.h"
#include "metamethods.h"
#include "optionals.h"
-#include "rng.h"
#include "tables.h"
#include "text.h"
#include "util.h"
@@ -271,33 +270,63 @@ public Array_t Array$sorted(Array_t arr, Closure_t comparison, int64_t padded_it
return arr;
}
-public void Array$shuffle(Array_t *arr, RNG_t rng, int64_t padded_item_size)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+static ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
+ (void)flags;
+ arc4random_buf(buf, buflen);
+ return buflen;
+}
+#elif defined(__linux__)
+// Use getrandom()
+# include <sys/random.h>
+#else
+ #error "Unsupported platform for secure random number generation"
+#endif
+
+static int64_t _default_random_int64(int64_t min, int64_t max, void *userdata)
+{
+ (void)userdata;
+ if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
+ if (min == max) return min;
+ uint64_t range = (uint64_t)max - (uint64_t)min + 1;
+ uint64_t min_r = -range % range;
+ uint64_t r;
+ for (;;) {
+ getrandom(&r, sizeof(r), 0);
+ if (r >= min_r) break;
+ }
+ return (int64_t)((uint64_t)min + (r % range));
+}
+
+public void Array$shuffle(Array_t *arr, OptionalClosure_t random_int64, int64_t padded_item_size)
{
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
Array$compact(arr, padded_item_size);
+ int64_t (*rng_fn)(int64_t, int64_t, void*) = random_int64.fn ? random_int64.fn : _default_random_int64;
char tmp[padded_item_size];
for (int64_t i = arr->length-1; i > 1; i--) {
- int64_t j = RNG$int64(rng, 0, i);
+ int64_t j = rng_fn(0, i, random_int64.userdata);
memcpy(tmp, arr->data + i*padded_item_size, (size_t)padded_item_size);
memcpy((void*)arr->data + i*padded_item_size, arr->data + j*padded_item_size, (size_t)padded_item_size);
memcpy((void*)arr->data + j*padded_item_size, tmp, (size_t)padded_item_size);
}
}
-public Array_t Array$shuffled(Array_t arr, RNG_t rng, int64_t padded_item_size)
+public Array_t Array$shuffled(Array_t arr, Closure_t random_int64, int64_t padded_item_size)
{
Array$compact(&arr, padded_item_size);
- Array$shuffle(&arr, rng, padded_item_size);
+ Array$shuffle(&arr, random_int64, padded_item_size);
return arr;
}
-public void *Array$random(Array_t arr, RNG_t rng)
+public void *Array$random(Array_t arr, OptionalClosure_t random_int64)
{
if (arr.length == 0)
return NULL; // fail("Cannot get a random item from an empty array!");
- int64_t index = RNG$int64(rng, 0, arr.length-1);
+ int64_t (*rng_fn)(int64_t, int64_t, void*) = random_int64.fn;
+ int64_t index = rng_fn(0, arr.length-1, random_int64.userdata);
return arr.data + arr.stride*index;
}
@@ -314,7 +343,22 @@ public Table_t Array$counts(Array_t arr, const TypeInfo_t *type)
return counts;
}
-public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng, int64_t padded_item_size)
+static double _default_random_num(void *userdata)
+{
+ (void)userdata;
+ union {
+ Num_t num;
+ uint64_t bits;
+ } r = {.bits=0}, one = {.num=1.0};
+ getrandom((uint8_t*)&r, sizeof(r), 0);
+
+ // Set r.num to 1.<random-bits>
+ r.bits &= ~(0xFFFULL << 52);
+ r.bits |= (one.bits & (0xFFFULL << 52));
+ return r.num - 1.0;
+}
+
+public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, OptionalClosure_t random_num, int64_t padded_item_size)
{
int64_t n = Int64$from_int(int_n, false);
if (n < 0)
@@ -331,14 +375,6 @@ public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng
.length=n,
.stride=padded_item_size, .atomic=arr.atomic};
- if (weights.length < 0) {
- for (int64_t i = 0; i < n; i++) {
- int64_t index = RNG$int64(rng, 0, arr.length-1);
- memcpy(selected.data + i*padded_item_size, arr.data + arr.stride*index, (size_t)padded_item_size);
- }
- return selected;
- }
-
if (weights.length != arr.length)
fail("Array has ", (int64_t)arr.length, " elements, but there are ", (int64_t)weights.length, " weights given");
@@ -396,8 +432,9 @@ public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, RNG_t rng
if (aliases[i].alias == -1)
aliases[i].alias = i;
+ double (*rng_fn)(void*) = random_num.fn ? random_num.fn : _default_random_num;
for (int64_t i = 0; i < n; i++) {
- double r = RNG$num(rng, 0, arr.length);
+ double r = (double)arr.length * rng_fn(random_num.userdata);
int64_t index = (int64_t)r;
if ((r - (double)index) > aliases[index].odds)
index = aliases[index].alias;
diff --git a/src/stdlib/arrays.h b/src/stdlib/arrays.h
index e286dfdb..9f5f3d00 100644
--- a/src/stdlib/arrays.h
+++ b/src/stdlib/arrays.h
@@ -82,11 +82,11 @@ OptionalInt_t Array$find(Array_t arr, void *item, const TypeInfo_t *type);
OptionalInt_t Array$first(Array_t arr, Closure_t predicate);
void Array$sort(Array_t *arr, Closure_t comparison, int64_t padded_item_size);
Array_t Array$sorted(Array_t arr, Closure_t comparison, int64_t padded_item_size);
-void Array$shuffle(Array_t *arr, RNG_t rng, int64_t padded_item_size);
-Array_t Array$shuffled(Array_t arr, RNG_t rng, int64_t padded_item_size);
-void *Array$random(Array_t arr, RNG_t rng);
-#define Array$random_value(arr, rng, t) ({ Array_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty array!"); *(t*)Array$random(_arr, rng); })
-Array_t Array$sample(Array_t arr, Int_t n, Array_t weights, RNG_t rng, int64_t padded_item_size);
+void Array$shuffle(Array_t *arr, OptionalClosure_t random_int64, int64_t padded_item_size);
+Array_t Array$shuffled(Array_t arr, OptionalClosure_t random_int64, int64_t padded_item_size);
+void *Array$random(Array_t arr, OptionalClosure_t random_int64);
+#define Array$random_value(arr, random_int64, t) ({ Array_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty array!"); *(t*)Array$random(_arr, random_int64); })
+Array_t Array$sample(Array_t arr, Int_t n, Array_t weights, Closure_t random_num, int64_t padded_item_size);
Table_t Array$counts(Array_t arr, const TypeInfo_t *type);
void Array$clear(Array_t *array);
void Array$compact(Array_t *arr, int64_t padded_item_size);
diff --git a/src/stdlib/chacha.h b/src/stdlib/chacha.h
deleted file mode 100644
index 69d79ea3..00000000
--- a/src/stdlib/chacha.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-chacha-merged.c version 20080118
-D. J. Bernstein
-Public domain.
-*/
-
-/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
-/* Tomo: chacha.h,v 1.0 2024/11/03 Bruce Hill */
-
-typedef unsigned char u8;
-typedef unsigned int u32;
-
-typedef struct
-{
- u32 input[16]; /* could be compressed */
-} chacha_ctx;
-
-#define U8C(v) (v##U)
-#define U32C(v) (v##U)
-
-#define U8V(v) ((u8)(v) & U8C(0xFF))
-#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
-
-#define ROTL32(v, n) \
- (U32V((v) << (n)) | ((v) >> (32 - (n))))
-
-#define U8TO32_LITTLE(p) \
- (((u32)((p)[0]) ) | \
- ((u32)((p)[1]) << 8) | \
- ((u32)((p)[2]) << 16) | \
- ((u32)((p)[3]) << 24))
-
-#define U32TO8_LITTLE(p, v) \
- do { \
- (p)[0] = U8V((v) ); \
- (p)[1] = U8V((v) >> 8); \
- (p)[2] = U8V((v) >> 16); \
- (p)[3] = U8V((v) >> 24); \
- } while (0)
-
-#define ROTATE(v, c) (ROTL32(v, c))
-#define XOR(v, w) ((v) ^ (w))
-#define PLUS(v, w) (U32V((v) + (w)))
-#define PLUSONE(v) (PLUS((v), 1))
-
-#define QUARTERROUND(a, b, c, d) \
- a = PLUS(a, b); d = ROTATE(XOR(d, a), 16); \
- c = PLUS(c, d); b = ROTATE(XOR(b, c), 12); \
- a = PLUS(a, b); d = ROTATE(XOR(d, a), 8); \
- c = PLUS(c, d); b = ROTATE(XOR(b, c), 7);
-
-static const char sigma[16] = "expand 32-byte k";
-static const char tau[16] = "expand 16-byte k";
-
-static void
-chacha_keysetup(chacha_ctx *chacha, const u8 *k, u32 kbits)
-{
- const char *constants;
-
- chacha->input[4] = U8TO32_LITTLE(k + 0);
- chacha->input[5] = U8TO32_LITTLE(k + 4);
- chacha->input[6] = U8TO32_LITTLE(k + 8);
- chacha->input[7] = U8TO32_LITTLE(k + 12);
- if (kbits == 256) { /* recommended */
- k += 16;
- constants = sigma;
- } else { /* kbits == 128 */
- constants = tau;
- }
- chacha->input[8] = U8TO32_LITTLE(k + 0);
- chacha->input[9] = U8TO32_LITTLE(k + 4);
- chacha->input[10] = U8TO32_LITTLE(k + 8);
- chacha->input[11] = U8TO32_LITTLE(k + 12);
- chacha->input[0] = U8TO32_LITTLE(constants + 0);
- chacha->input[1] = U8TO32_LITTLE(constants + 4);
- chacha->input[2] = U8TO32_LITTLE(constants + 8);
- chacha->input[3] = U8TO32_LITTLE(constants + 12);
-}
-
-static void
-chacha_ivsetup(chacha_ctx *chacha, const u8 *iv)
-{
- chacha->input[12] = 0;
- chacha->input[13] = 0;
- chacha->input[14] = U8TO32_LITTLE(iv + 0);
- chacha->input[15] = U8TO32_LITTLE(iv + 4);
-}
-
-static void
-chacha_encrypt_bytes(chacha_ctx *chacha, const u8 *m, u8 *c, u32 bytes)
-{
- u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
- u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
- u8 *ctarget = NULL;
- u8 tmp[64];
- u_int i;
-
- if (!bytes) return;
-
- j0 = chacha->input[0];
- j1 = chacha->input[1];
- j2 = chacha->input[2];
- j3 = chacha->input[3];
- j4 = chacha->input[4];
- j5 = chacha->input[5];
- j6 = chacha->input[6];
- j7 = chacha->input[7];
- j8 = chacha->input[8];
- j9 = chacha->input[9];
- j10 = chacha->input[10];
- j11 = chacha->input[11];
- j12 = chacha->input[12];
- j13 = chacha->input[13];
- j14 = chacha->input[14];
- j15 = chacha->input[15];
-
- for (;;) {
- if (bytes < 64) {
- for (i = 0;i < bytes;++i) tmp[i] = m[i];
- m = tmp;
- ctarget = c;
- c = tmp;
- }
- x0 = j0;
- x1 = j1;
- x2 = j2;
- x3 = j3;
- x4 = j4;
- x5 = j5;
- x6 = j6;
- x7 = j7;
- x8 = j8;
- x9 = j9;
- x10 = j10;
- x11 = j11;
- x12 = j12;
- x13 = j13;
- x14 = j14;
- x15 = j15;
- for (i = 20;i > 0;i -= 2) {
- QUARTERROUND( x0, x4, x8, x12)
- QUARTERROUND( x1, x5, x9, x13)
- QUARTERROUND( x2, x6, x10, x14)
- QUARTERROUND( x3, x7, x11, x15)
- QUARTERROUND( x0, x5, x10, x15)
- QUARTERROUND( x1, x6, x11, x12)
- QUARTERROUND( x2, x7, x8, x13)
- QUARTERROUND( x3, x4, x9, x14)
- }
- x0 = PLUS(x0, j0);
- x1 = PLUS(x1, j1);
- x2 = PLUS(x2, j2);
- x3 = PLUS(x3, j3);
- x4 = PLUS(x4, j4);
- x5 = PLUS(x5, j5);
- x6 = PLUS(x6, j6);
- x7 = PLUS(x7, j7);
- x8 = PLUS(x8, j8);
- x9 = PLUS(x9, j9);
- x10 = PLUS(x10, j10);
- x11 = PLUS(x11, j11);
- x12 = PLUS(x12, j12);
- x13 = PLUS(x13, j13);
- x14 = PLUS(x14, j14);
- x15 = PLUS(x15, j15);
-
- j12 = PLUSONE(j12);
- if (!j12) {
- j13 = PLUSONE(j13);
- /* stopping at 2^70 bytes per nonce is user's responsibility */
- }
-
- U32TO8_LITTLE(c + 0, x0);
- U32TO8_LITTLE(c + 4, x1);
- U32TO8_LITTLE(c + 8, x2);
- U32TO8_LITTLE(c + 12, x3);
- U32TO8_LITTLE(c + 16, x4);
- U32TO8_LITTLE(c + 20, x5);
- U32TO8_LITTLE(c + 24, x6);
- U32TO8_LITTLE(c + 28, x7);
- U32TO8_LITTLE(c + 32, x8);
- U32TO8_LITTLE(c + 36, x9);
- U32TO8_LITTLE(c + 40, x10);
- U32TO8_LITTLE(c + 44, x11);
- U32TO8_LITTLE(c + 48, x12);
- U32TO8_LITTLE(c + 52, x13);
- U32TO8_LITTLE(c + 56, x14);
- U32TO8_LITTLE(c + 60, x15);
-
- if (bytes <= 64) {
- if (bytes < 64) {
- for (i = 0;i < bytes;++i) ctarget[i] = c[i];
- }
- chacha->input[12] = j12;
- chacha->input[13] = j13;
- return;
- }
- bytes -= 64;
- c += 64;
- }
-}
diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h
index 26bd9c3c..6f3b7676 100644
--- a/src/stdlib/datatypes.h
+++ b/src/stdlib/datatypes.h
@@ -105,8 +105,6 @@ typedef struct {
} Path_t;
#define OptionalPath_t Path_t
-typedef struct RNGState_t* RNG_t;
-
#define OptionalBool_t uint8_t
#define OptionalArray_t Array_t
#define OptionalTable_t Table_t
diff --git a/src/stdlib/rng.c b/src/stdlib/rng.c
deleted file mode 100644
index ffc28084..00000000
--- a/src/stdlib/rng.c
+++ /dev/null
@@ -1,274 +0,0 @@
-// Random Number Generator (RNG) implementation based on ChaCha
-
-#include <ctype.h>
-#include <err.h>
-#include <gc.h>
-#include <gmp.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-
-#include "arrays.h"
-#include "datatypes.h"
-#include "rng.h"
-#include "text.h"
-#include "util.h"
-
-#include "chacha.h"
-
-struct RNGState_t {
- chacha_ctx chacha;
- size_t unused_bytes;
- uint8_t random_bytes[1024];
-};
-
-#ifdef __TINYC__
-// TinyCC doesn't implement _Thread_local
-public RNG_t default_rng = (struct RNGState_t[1]){};
-#else
-public _Thread_local RNG_t default_rng = (struct RNGState_t[1]){};
-#endif
-
-PUREFUNC static Text_t RNG$as_text(const void *rng, bool colorize, const TypeInfo_t*)
-{
- if (!rng) return Text("RNG");
- return Text$format(colorize ? "\x1b[34;1mRNG(%p)\x1b[m" : "RNG(%p)", *(RNG_t**)rng);
-}
-
-#define KEYSZ 32
-#define IVSZ 8
-
-public void RNG$set_seed(RNG_t rng, Array_t seed)
-{
- uint8_t seed_bytes[KEYSZ + IVSZ] = {};
- for (int64_t i = 0; i < (int64_t)sizeof(seed_bytes); i++)
- seed_bytes[i] = i < seed.length ? *(uint8_t*)(seed.data + i*seed.stride) : 0;
-
- rng->unused_bytes = 0;
- chacha_keysetup(&rng->chacha, seed_bytes, KEYSZ/8);
- chacha_ivsetup(&rng->chacha, seed_bytes + KEYSZ);
-}
-
-public RNG_t RNG$copy(RNG_t rng)
-{
- RNG_t copy = GC_MALLOC_ATOMIC(sizeof(struct RNGState_t));
- *copy = *rng;
- return copy;
-}
-
-public RNG_t RNG$new(Array_t seed)
-{
- RNG_t rng = GC_MALLOC_ATOMIC(sizeof(struct RNGState_t));
- RNG$set_seed(rng, seed);
- return rng;
-}
-
-static void rekey(RNG_t rng)
-{
- // Fill the buffer with the keystream
- chacha_encrypt_bytes(&rng->chacha, rng->random_bytes, rng->random_bytes, sizeof(rng->random_bytes));
- // Immediately reinitialize for backtracking resistance
- chacha_keysetup(&rng->chacha, rng->random_bytes, KEYSZ/8);
- chacha_ivsetup(&rng->chacha, rng->random_bytes + KEYSZ);
-#ifdef __APPLE__
- bzero(rng->random_bytes, KEYSZ + IVSZ);
-#else
- explicit_bzero(rng->random_bytes, KEYSZ + IVSZ);
-#endif
- rng->unused_bytes = sizeof(rng->random_bytes) - KEYSZ - IVSZ;
- assert(rng->unused_bytes <= sizeof(rng->random_bytes));
-}
-
-static void random_bytes(RNG_t rng, uint8_t *dest, size_t needed)
-{
- while (needed > 0) {
- assert(rng->unused_bytes <= sizeof(rng->random_bytes));
- if (rng->unused_bytes == 0)
- rekey(rng);
-
- size_t batch_size = MIN(needed, rng->unused_bytes);
- uint8_t *batch_src = rng->random_bytes + sizeof(rng->random_bytes) - rng->unused_bytes;
- memcpy(dest, batch_src, batch_size);
- memset(batch_src, 0, batch_size);
- rng->unused_bytes -= batch_size;
- dest += batch_size;
- needed -= batch_size;
- assert(rng->unused_bytes <= sizeof(rng->random_bytes));
- }
-}
-
-public Bool_t RNG$bool(RNG_t rng, Num_t p)
-{
- if (p == 0.5) {
- uint8_t b;
- random_bytes(rng, &b, sizeof(b));
- return b & 1;
- } else {
- return RNG$num(rng, 0.0, 1.0) < p;
- }
-}
-
-public Int_t RNG$int(RNG_t rng, Int_t min, Int_t max)
-{
- if (likely(((min.small & max.small) & 1) != 0)) {
- int32_t r = RNG$int32(rng, (int32_t)(min.small >> 2), (int32_t)(max.small >> 2));
- return I_small(r);
- }
-
- int32_t cmp = Int$compare_value(min, max);
- if (cmp > 0)
- fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (cmp == 0) return min;
-
- mpz_t range_size;
- mpz_init_set_int(range_size, max);
- if (min.small & 1) {
- mpz_t min_mpz;
- mpz_init_set_si(min_mpz, min.small >> 2);
- mpz_sub(range_size, range_size, min_mpz);
- } else {
- mpz_sub(range_size, range_size, *min.big);
- }
-
- gmp_randstate_t gmp_rng;
- gmp_randinit_default(gmp_rng);
- gmp_randseed_ui(gmp_rng, (unsigned long)RNG$int64(rng, INT64_MIN, INT64_MAX));
-
- mpz_t r;
- mpz_init(r);
- mpz_urandomm(r, gmp_rng, range_size);
-
- gmp_randclear(gmp_rng);
- return Int$plus(min, Int$from_mpz(r));
-}
-
-public Int64_t RNG$int64(RNG_t rng, Int64_t min, Int64_t max)
-{
- if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (min == max) return min;
- if (min == INT64_MIN && max == INT64_MAX) {
- int64_t r;
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- return r;
- }
- uint64_t range = (uint64_t)max - (uint64_t)min + 1;
- uint64_t min_r = -range % range;
- uint64_t r;
- for (;;) {
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- if (r >= min_r) break;
- }
- return (int64_t)((uint64_t)min + (r % range));
-}
-
-public Int32_t RNG$int32(RNG_t rng, Int32_t min, Int32_t max)
-{
- if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (min == max) return min;
- if (min == INT32_MIN && max == INT32_MAX) {
- int32_t r;
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- return r;
- }
- uint32_t range = (uint32_t)max - (uint32_t)min + 1;
- uint32_t min_r = -range % range;
- uint32_t r;
- for (;;) {
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- if (r >= min_r) break;
- }
- return (int32_t)((uint32_t)min + (r % range));
-}
-
-public Int16_t RNG$int16(RNG_t rng, Int16_t min, Int16_t max)
-{
- if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (min == max) return min;
- if (min == INT16_MIN && max == INT16_MAX) {
- int16_t r;
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- return r;
- }
- uint16_t range = (uint16_t)max - (uint16_t)min + 1;
- uint16_t min_r = -range % range;
- uint16_t r;
- for (;;) {
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- if (r >= min_r) break;
- }
- return (int16_t)((uint16_t)min + (r % range));
-}
-
-public Int8_t RNG$int8(RNG_t rng, Int8_t min, Int8_t max)
-{
- if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (min == max) return min;
- if (min == INT8_MIN && max == INT8_MAX) {
- int8_t r;
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- return r;
- }
- uint8_t range = (uint8_t)max - (uint8_t)min + 1;
- uint8_t min_r = -range % range;
- uint8_t r;
- for (;;) {
- random_bytes(rng, (uint8_t*)&r, sizeof(r));
- if (r >= min_r) break;
- }
- return (int8_t)((uint8_t)min + (r % range));
-}
-
-public Num_t RNG$num(RNG_t rng, Num_t min, Num_t max)
-{
- if (min > max) fail("Random minimum value (", min, ") is larger than the maximum value (", max, ")");
- if (min == max) return min;
-
- union {
- Num_t num;
- uint64_t bits;
- } r = {.bits=0}, one = {.num=1.0};
- random_bytes(rng, (void*)&r, sizeof(r));
-
- // Set r.num to 1.<random-bits>
- r.bits &= ~(0xFFFULL << 52);
- r.bits |= (one.bits & (0xFFFULL << 52));
-
- r.num -= 1.0;
-
- if (min == 0.0 && max == 1.0)
- return r.num;
-
- return (1.0-r.num)*min + r.num*max;
-}
-
-public Num32_t RNG$num32(RNG_t rng, Num32_t min, Num32_t max)
-{
- return (Num32_t)RNG$num(rng, (Num_t)min, (Num_t)max);
-}
-
-public Byte_t RNG$byte(RNG_t rng)
-{
- Byte_t b;
- random_bytes(rng, &b, sizeof(b));
- return b;
-}
-
-public Array_t RNG$bytes(RNG_t rng, Int_t count)
-{
- int64_t n = Int64$from_int(count, false);
- Byte_t *r = GC_MALLOC_ATOMIC(sizeof(Byte_t[n]));
- random_bytes(rng, r, sizeof(Byte_t[n]));
- return (Array_t){.data=r, .length=n, .stride=1, .atomic=1};
-}
-
-public const TypeInfo_t RNG$info = {
- .size=sizeof(void*),
- .align=__alignof__(void*),
- .metamethods={
- .as_text=RNG$as_text,
- },
-};
-
-// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/stdlib/rng.h b/src/stdlib/rng.h
deleted file mode 100644
index 34f1ca03..00000000
--- a/src/stdlib/rng.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-// Random Number Generator (RNG) functions/type info
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "datatypes.h"
-#include "types.h"
-#include "bools.h"
-#include "bytes.h"
-#include "util.h"
-
-RNG_t RNG$new(Array_t seed);
-void RNG$set_seed(RNG_t rng, Array_t seed);
-RNG_t RNG$copy(RNG_t rng);
-Bool_t RNG$bool(RNG_t rng, Num_t p);
-Int_t RNG$int(RNG_t rng, Int_t min, Int_t max);
-Int64_t RNG$int64(RNG_t rng, Int64_t min, Int64_t max);
-Int32_t RNG$int32(RNG_t rng, Int32_t min, Int32_t max);
-Int16_t RNG$int16(RNG_t rng, Int16_t min, Int16_t max);
-Int8_t RNG$int8(RNG_t rng, Int8_t min, Int8_t max);
-Byte_t RNG$byte(RNG_t rng);
-Array_t RNG$bytes(RNG_t rng, Int_t count);
-Num_t RNG$num(RNG_t rng, Num_t min, Num_t max);
-Num32_t RNG$num32(RNG_t rng, Num32_t min, Num32_t max);
-
-extern const TypeInfo_t RNG$info;
-// TinyCC doesn't implement _Thread_local
-#ifdef __TINYC__
-extern RNG_t default_rng;
-#else
-extern _Thread_local RNG_t default_rng;
-#endif
-
-// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c
index 2177397d..80c53b68 100644
--- a/src/stdlib/stdlib.c
+++ b/src/stdlib/stdlib.c
@@ -21,7 +21,6 @@
#include "metamethods.h"
#include "nums.h"
#include "paths.h"
-#include "rng.h"
#include "siphash.h"
#include "stdlib.h"
#include "tables.h"
@@ -65,11 +64,6 @@ public void tomo_init(void)
setlocale(LC_ALL, "");
getrandom(TOMO_HASH_KEY, sizeof(TOMO_HASH_KEY), 0);
- uint8_t *random_bytes[40] = {};
- getrandom(random_bytes, sizeof(random_bytes), 0);
- Array_t rng_seed = {.length=sizeof(random_bytes), .data=random_bytes, .stride=1, .atomic=1};
- RNG$set_seed(default_rng, rng_seed);
-
struct sigaction sigact;
sigact.sa_sigaction = signal_handler;
sigemptyset(&sigact.sa_mask);
diff --git a/src/stdlib/tomo.h b/src/stdlib/tomo.h
index e42b562e..b5642ec5 100644
--- a/src/stdlib/tomo.h
+++ b/src/stdlib/tomo.h
@@ -22,7 +22,6 @@
#include "paths.h"
#include "pointers.h"
#include "print.h"
-#include "rng.h"
#include "siphash.h"
#include "structs.h"
#include "tables.h"