Created
January 24, 2024 23:15
Revisions
-
rfl890 created this gist
Jan 24, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,97 @@ From c796842c4aaaca1b640a1fd0e03c9d8e85f571c8 Mon Sep 17 00:00:00 2001 From: rfl890 <87506407+rfl890@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:14:16 -0500 Subject: [PATCH] Update PRNG --- src/lib_math.c | 2 +- src/lj_prng.c | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/lib_math.c b/src/lib_math.c index 4539f804..5ca674f6 100644 --- a/src/lib_math.c +++ b/src/lib_math.c @@ -194,7 +194,7 @@ LJLIB_CF(math_randomseed) LUALIB_API int luaopen_math(lua_State *L) { PRNGState *rs = (PRNGState *)lua_newuserdata(L, sizeof(PRNGState)); - lj_prng_seed_fixed(rs); + lj_prng_seed_secure(rs); LJ_LIB_REG(L, LUA_MATHLIBNAME, math); return 1; } diff --git a/src/lj_prng.c b/src/lj_prng.c index 326b41e6..1697a304 100644 --- a/src/lj_prng.c +++ b/src/lj_prng.c @@ -17,10 +17,7 @@ /* -- PRNG step function -------------------------------------------------- */ -/* This implements a Tausworthe PRNG with period 2^223. Based on: -** Tables of maximally-equidistributed combined LFSR generators, -** Pierre L'Ecuyer, 1991, table 3, 1st entry. -** Full-period ME-CF generator with L=64, J=4, k=223, N1=49. +/* This implements an Xoshiro256** PRNG with period 2^256. ** ** Important note: This PRNG is NOT suitable for cryptographic use! ** @@ -31,33 +28,37 @@ ** the difficulty for various attacks on the VM. */ -/* Update generator i and compute a running xor of all states. */ -#define TW223_GEN(rs, z, r, i, k, q, s) \ - z = rs->u[i]; \ - z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \ - r ^= z; rs->u[i] = z; +static LJ_AINLINE uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +static uint64_t xs256(uint64_t *s) { + const uint64_t result = rotl(s[1] * 5, 7) * 9; + + const uint64_t t = s[1] << 17; + + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; -#define TW223_STEP(rs, z, r) \ - TW223_GEN(rs, z, r, 0, 63, 31, 18) \ - TW223_GEN(rs, z, r, 1, 58, 19, 28) \ - TW223_GEN(rs, z, r, 2, 55, 24, 7) \ - TW223_GEN(rs, z, r, 3, 47, 21, 8) + s[2] ^= t; + + s[3] = rotl(s[3], 45); + + return result; +} /* PRNG step function with uint64_t result. */ LJ_NOINLINE uint64_t LJ_FASTCALL lj_prng_u64(PRNGState *rs) { - uint64_t z, r = 0; - TW223_STEP(rs, z, r) - return r; + return xs256(rs->u); } /* PRNG step function with double in uint64_t result. */ LJ_NOINLINE uint64_t LJ_FASTCALL lj_prng_u64d(PRNGState *rs) { - uint64_t z, r = 0; - TW223_STEP(rs, z, r) - /* Returns a double bit pattern in the range 1.0 <= d < 2.0. */ - return (r & U64x(000fffff,ffffffff)) | U64x(3ff00000,00000000); + return (xs256(rs->u) & U64x(000fffff,ffffffff)) | U64x(3ff00000,00000000); } /* Condition seed: ensure k[i] MSB of u[i] are non-zero. */ -- 2.43.0.windows.1