Last active
June 22, 2026 23:58
-
-
Save anzz1/3d4fdbf2f06729a10785eb270924a46c to your computer and use it in GitHub Desktop.
prng.c
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 characters
| // prng.c | |
| #include <stdint.h> | |
| /* ********************* */ | |
| /* * XORSHIFT798 * */ | |
| /* * 16-bit * */ | |
| /* ********************* */ | |
| static uint16_t x798_s = 0; | |
| static inline void x798_init() | |
| { | |
| while (!x798_s) { | |
| x798_s = __rdtsc(); | |
| } | |
| } | |
| uint16_t x798_next(void) | |
| { | |
| x798_s ^= x798_s << 7; | |
| x798_s ^= x798_s >> 9; | |
| x798_s ^= x798_s << 8; | |
| return x798_s; | |
| } | |
| /* ********************** */ | |
| /* * XOSHIRO128++ * */ | |
| /* * 32-bit * */ | |
| /* ********************** */ | |
| static uint32_t xs128_s[4] = { 0, 0, 0, 0 }; | |
| static inline void xs128_init() | |
| { | |
| if (!xs128_s[0] && !xs128_s[1] && !xs128_s[2] && !xs128_s[3]) { | |
| uint64_t tsc = __rdtsc(); | |
| xs128_s[0] = ((uint32_t *)&tsc)[0]; | |
| xs128_s[1] = ((uint32_t *)&tsc)[1]; | |
| xs128_s[2] = xs128_s[0] ^ (uint32_t)(uintptr_t)&tsc; | |
| xs128_s[3] = xs128_s[1] ^ (uint32_t)(uintptr_t)xs128_s; | |
| } | |
| } | |
| uint32_t xs128_next(void) | |
| { | |
| const uint32_t result = (((xs128_s[0] + xs128_s[3]) << 7) | ((xs128_s[0] + xs128_s[3]) >> (32 - 7))) + xs128_s[0]; | |
| const uint32_t t = xs128_s[1] << 9; | |
| xs128_s[2] ^= xs128_s[0]; | |
| xs128_s[3] ^= xs128_s[1]; | |
| xs128_s[1] ^= xs128_s[2]; | |
| xs128_s[0] ^= xs128_s[3]; | |
| xs128_s[2] ^= t; | |
| xs128_s[3] = ((xs128_s[3] << 11) | (xs128_s[3] >> (32 - 11))); | |
| return result; | |
| } | |
| /* ********************** */ | |
| /* * XOSHIRO256++ * */ | |
| /* * 64-bit * */ | |
| /* ********************** */ | |
| static uint64_t xs256_s[4] = { 0, 0, 0, 0 }; | |
| static inline void xs256_init() | |
| { | |
| if (!xs256_s[0] && !xs256_s[1] && !xs256_s[2] && !xs256_s[3]) { | |
| uint64_t tsc = __rdtsc(); | |
| xs256_s[0] = tsc; | |
| xs256_s[1] = xs256_s[0] ^ (uint64_t)(uintptr_t)&tsc; | |
| xs256_s[2] = xs256_s[1] ^ (uint64_t)(uintptr_t)xs256_s; | |
| xs256_s[3] = (uint64_t)(uintptr_t)&tsc ^ (uint64_t)(uintptr_t)xs256_s; | |
| } | |
| } | |
| uint64_t xs256_next(void) { | |
| const uint64_t result = (((xs256_s[0] + xs256_s[3]) << 23) | ((xs256_s[0] + xs256_s[3]) >> (64 - 23))) + xs256_s[0]; | |
| const uint64_t t = xs256_s[1] << 17; | |
| xs256_s[2] ^= xs256_s[0]; | |
| xs256_s[3] ^= xs256_s[1]; | |
| xs256_s[1] ^= xs256_s[2]; | |
| xs256_s[0] ^= xs256_s[3]; | |
| xs256_s[2] ^= t; | |
| xs256_s[3] = ((xs256_s[3] << 45) | (xs256_s[3] >> (64 - 45))); | |
| return result; | |
| } | |
| /* ********************** */ | |
| /* * PCG32 * */ | |
| /* * 32-bit * */ | |
| /* ********************** */ | |
| static uint64_t pcg32_state = 0; | |
| static uint64_t pcg32_inc = 0; | |
| static uint32_t pcg32_next(void) | |
| { | |
| uint64_t oldstate = pcg32_state; | |
| pcg32_state = oldstate * 6364136223846793005ULL + (pcg32_inc | 1); | |
| uint32_t xorshifted = (uint32_t)(((oldstate >> 18u) ^ oldstate) >> 27u); | |
| uint32_t rot = oldstate >> 59u; | |
| return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); | |
| } | |
| static void pcg32_init(void) | |
| { | |
| if (pcg32_state == 0) { | |
| uint64_t seed = __rdtsc(); | |
| seed ^= (uint64_t)(uintptr_t)&seed; | |
| pcg32_state = 0; | |
| pcg32_inc = (seed << 1u) | 1u; | |
| pcg32_next(); | |
| pcg32_state += seed; | |
| pcg32_next(); | |
| } | |
| } | |
| static void | |
| randombytes(char * const buf, const size_t size) | |
| { | |
| size_t i = 0; | |
| pcg32_init(); | |
| while (i + 4 <= size) { | |
| uint32_t r = pcg32_next(); | |
| *(uint32_t *)(buf + i) = r; | |
| i += 4; | |
| } | |
| if (i < size) { | |
| uint32_t r = pcg32_next(); | |
| for (size_t j = 0; i < size; ++i, ++j) { | |
| buf[i] = (char)(r >> (j * 8)); | |
| } | |
| } | |
| } | |
| int generate_random_int() | |
| { | |
| pcg32_init(); | |
| return (int)pcg32_next(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment