diff --git a/boards/arm/stm32f1/et-stm32-stamp/configs/nsh/defconfig b/boards/arm/stm32f1/et-stm32-stamp/configs/nsh/defconfig index 33ca6384081..30e6bb6b8c8 100644 --- a/boards/arm/stm32f1/et-stm32-stamp/configs/nsh/defconfig +++ b/boards/arm/stm32f1/et-stm32-stamp/configs/nsh/defconfig @@ -17,7 +17,6 @@ CONFIG_BOARD_LOOPSPERMSEC=5483 CONFIG_BUILTIN=y CONFIG_DEFAULT_SMALL=y CONFIG_INIT_ENTRYPOINT="nsh_main" -CONFIG_LIBC_RAND_ORDER=2 CONFIG_LINE_MAX=80 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=1024 diff --git a/boards/arm/stm32f1/maple/configs/nsh/defconfig b/boards/arm/stm32f1/maple/configs/nsh/defconfig index 619ff1f1dbf..8e133e7cdd2 100644 --- a/boards/arm/stm32f1/maple/configs/nsh/defconfig +++ b/boards/arm/stm32f1/maple/configs/nsh/defconfig @@ -32,7 +32,6 @@ CONFIG_BOARD_LOOPSPERMSEC=5483 CONFIG_BUILTIN=y CONFIG_DEFAULT_SMALL=y CONFIG_INIT_ENTRYPOINT="nsh_main" -CONFIG_LIBC_RAND_ORDER=2 CONFIG_LINE_MAX=80 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=1024 diff --git a/boards/arm/stm32f1/maple/configs/nx/defconfig b/boards/arm/stm32f1/maple/configs/nx/defconfig index 5d98c00a330..c53fce0cccb 100644 --- a/boards/arm/stm32f1/maple/configs/nx/defconfig +++ b/boards/arm/stm32f1/maple/configs/nx/defconfig @@ -45,7 +45,6 @@ CONFIG_I2C=y CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_LCD=y CONFIG_LCD_SHARP_MEMLCD=y -CONFIG_LIBC_RAND_ORDER=2 CONFIG_LINE_MAX=80 CONFIG_MQ_MAXMSGSIZE=64 CONFIG_NSH_BUILTIN_APPS=y diff --git a/boards/arm/stm32f1/maple/configs/usbnsh/defconfig b/boards/arm/stm32f1/maple/configs/usbnsh/defconfig index 128d504fd3f..9ad34495e29 100644 --- a/boards/arm/stm32f1/maple/configs/usbnsh/defconfig +++ b/boards/arm/stm32f1/maple/configs/usbnsh/defconfig @@ -38,7 +38,6 @@ CONFIG_CDCACM_TXBUFSIZE=256 CONFIG_DEFAULT_SMALL=y CONFIG_I2C=y CONFIG_INIT_ENTRYPOINT="nsh_main" -CONFIG_LIBC_RAND_ORDER=2 CONFIG_LINE_MAX=80 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=1024 diff --git a/boards/arm/tlsr82/tlsr8278adk80d/configs/nsh/defconfig b/boards/arm/tlsr82/tlsr8278adk80d/configs/nsh/defconfig index aaf6a79db3d..796425b9c11 100644 --- a/boards/arm/tlsr82/tlsr8278adk80d/configs/nsh/defconfig +++ b/boards/arm/tlsr82/tlsr8278adk80d/configs/nsh/defconfig @@ -58,7 +58,6 @@ CONFIG_EXAMPLES_HELLO=y CONFIG_FILE_STREAM=y CONFIG_FS_PROCFS=y CONFIG_INIT_ENTRYPOINT="nsh_main" -CONFIG_LIBC_RAND_ORDER=0 CONFIG_LIBM=y CONFIG_LINE_MAX=80 CONFIG_MTD=y diff --git a/boards/sim/sim/sim/configs/configdata/defconfig b/boards/sim/sim/sim/configs/configdata/defconfig index 9c5c36b288c..993a31cc1bf 100644 --- a/boards/sim/sim/sim/configs/configdata/defconfig +++ b/boards/sim/sim/sim/configs/configdata/defconfig @@ -21,7 +21,6 @@ CONFIG_FS_FAT=y CONFIG_FS_NXFFS=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="configdata_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_CONFIG=y diff --git a/boards/sim/sim/sim/configs/linuxspi/defconfig b/boards/sim/sim/sim/configs/linuxspi/defconfig index d2a3159e298..08ce24951c2 100644 --- a/boards/sim/sim/sim/configs/linuxspi/defconfig +++ b/boards/sim/sim/sim/configs/linuxspi/defconfig @@ -18,7 +18,6 @@ CONFIG_FS_FAT=y CONFIG_FS_NXFFS=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="nxffs_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_NXFFS_SCAN_VOLUME=y CONFIG_RAMMTD=y diff --git a/boards/sim/sim/sim/configs/mtdpart/defconfig b/boards/sim/sim/sim/configs/mtdpart/defconfig index 4c656e485bf..0b80d37dbe5 100644 --- a/boards/sim/sim/sim/configs/mtdpart/defconfig +++ b/boards/sim/sim/sim/configs/mtdpart/defconfig @@ -18,7 +18,6 @@ CONFIG_EXAMPLES_MTDPART=y CONFIG_FS_FAT=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="mtdpart_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_MTD_PARTITION=y CONFIG_RAMMTD=y diff --git a/boards/sim/sim/sim/configs/mtdrwb/defconfig b/boards/sim/sim/sim/configs/mtdrwb/defconfig index 91024b95017..5abb2285ec8 100644 --- a/boards/sim/sim/sim/configs/mtdrwb/defconfig +++ b/boards/sim/sim/sim/configs/mtdrwb/defconfig @@ -19,7 +19,6 @@ CONFIG_EXAMPLES_MTDRWB=y CONFIG_FS_FAT=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="mtdrwb_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_MTD_PARTITION=y CONFIG_MTD_READAHEAD=y diff --git a/boards/sim/sim/sim/configs/nxffs/defconfig b/boards/sim/sim/sim/configs/nxffs/defconfig index d2a3159e298..08ce24951c2 100644 --- a/boards/sim/sim/sim/configs/nxffs/defconfig +++ b/boards/sim/sim/sim/configs/nxffs/defconfig @@ -18,7 +18,6 @@ CONFIG_FS_FAT=y CONFIG_FS_NXFFS=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="nxffs_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_NXFFS_SCAN_VOLUME=y CONFIG_RAMMTD=y diff --git a/boards/sim/sim/sim/configs/spiffs/defconfig b/boards/sim/sim/sim/configs/spiffs/defconfig index d86d8f84708..490b25ca005 100644 --- a/boards/sim/sim/sim/configs/spiffs/defconfig +++ b/boards/sim/sim/sim/configs/spiffs/defconfig @@ -20,7 +20,6 @@ CONFIG_DISABLE_PTHREAD=y CONFIG_FS_SPIFFS=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="fstest_main" -CONFIG_LIBC_RAND_ORDER=3 CONFIG_MTD=y CONFIG_RAMMTD=y CONFIG_RAMMTD_FLASHSIM=y diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/mbedtls/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/mbedtls/defconfig index 7371be1a16b..2c816a4a984 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/mbedtls/defconfig +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/mbedtls/defconfig @@ -51,7 +51,6 @@ CONFIG_IOB_BUFSIZE=400 CONFIG_IOB_NBUFFERS=100 CONFIG_IOB_NCHAINS=32 CONFIG_IOB_THROTTLE=40 -CONFIG_LIBC_RAND_ORDER=2 CONFIG_LINE_MAX=255 CONFIG_MBEDTLS_APPS=y CONFIG_MBEDTLS_APP_BENCHMARK=y diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 00b4d3f9155..66b4381e640 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -43,12 +43,10 @@ config DEV_URANDOM_XORSHIFT128 config DEV_URANDOM_CONGRUENTIAL bool "Congruential" ---help--- - Use the same congruential general used with srand(). This algorithm - is computationally more intense and uses double precision floating - point. NOTE: Good randomness from the congruential generator also - requires that you also select CONFIG_LIBC_RAND_ORDER > 2 + Use the same PRNG used with srand()/rand(). Uses the system + random number generator (xorshift32). - NOTE: Not cyptographically secure + NOTE: Not cryptographically secure config DEV_URANDOM_RANDOM_POOL bool "Entropy pool" diff --git a/libs/libc/stdlib/Kconfig b/libs/libc/stdlib/Kconfig index d594b4cd8e3..272258344e3 100644 --- a/libs/libc/stdlib/Kconfig +++ b/libs/libc/stdlib/Kconfig @@ -5,15 +5,6 @@ menu "stdlib Options" -config LIBC_RAND_ORDER - int "Order of the random number generate" - default 1 - range 0 3 - ---help--- - The order of the random number generator. 0=fast but very bad random - numbers, 3=slow but very good random numbers. - 0 just use integer generation, 1-3 use floating point generation - config LIBC_HOMEDIR string "Home directory" default "/" diff --git a/libs/libc/stdlib/lib_srand.c b/libs/libc/stdlib/lib_srand.c index 3b5cc7a3273..39bc2113e84 100644 --- a/libs/libc/stdlib/lib_srand.c +++ b/libs/libc/stdlib/lib_srand.c @@ -27,231 +27,62 @@ #include #include +#include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* First, second, and thired order congruential generators are supported */ - -#ifndef CONFIG_LIBC_RAND_ORDER -# define CONFIG_LIBC_RAND_ORDER 1 -#endif - -#if CONFIG_LIBC_RAND_ORDER > 3 -# undef CONFIG_LIBC_RAND_ORDER -# define CONFIG_LIBC_RAND_ORDER 3 -#endif - -#ifndef CONFIG_HAVE_DOUBLE -typedef float float_t; -#else -typedef double float_t; -#endif - -/* Values needed by the random number generator */ - -#define RND1_CONSTK 470001 -#define RND1_CONSTP 999563 -#define RND2_CONSTK1 366528 -#define RND2_CONSTK2 508531 -#define RND2_CONSTP 998917 -#define RND3_CONSTK1 360137 -#define RND3_CONSTK2 519815 -#define RND3_CONSTK3 616087 -#define RND3_CONSTP 997783 - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/* First order congruential generators */ - -static inline unsigned long fgenerate1(FAR unsigned long *seed); -#if (CONFIG_LIBC_RAND_ORDER == 1) -static float_t frand1(FAR unsigned long *seed); -#endif - -/* Second order congruential generators */ - -#if (CONFIG_LIBC_RAND_ORDER > 1) -static inline unsigned long fgenerate2(void); -#if (CONFIG_LIBC_RAND_ORDER == 2) -static float_t frand2(void); -#endif - -/* Third order congruential generators */ - -#if (CONFIG_LIBC_RAND_ORDER > 2) -static inline unsigned long fgenerate3(void); -static float_t frand3(void); -#endif -#endif - /**************************************************************************** * Private Data ****************************************************************************/ -static unsigned long g_randint1; -#if (CONFIG_LIBC_RAND_ORDER > 1) -static unsigned long g_randint2; -#if (CONFIG_LIBC_RAND_ORDER > 2) -static unsigned long g_randint3; -#endif -#endif +static uint32_t g_randstate = 1; /**************************************************************************** * Private Functions ****************************************************************************/ -/* First order congruential generators */ +/**************************************************************************** + * Name: xorshift32 + * + * Description: + * Marsaglia's xorshift32 PRNG. Period 2^32 - 1 (about 4.29 billion). + * Much better statistical properties than a simple LCG with a small + * modulus, while remaining fast (three XOR/shift operations). + * + ****************************************************************************/ -static inline unsigned long fgenerate1(FAR unsigned long *seed) +static inline uint32_t xorshift32(FAR uint32_t *state) { - unsigned long randint; + uint32_t x = *state; - /* First order congruential generator. One may be added to the result of - * the generated value to avoid the value zero. This would be fatal for - * the first order random number generator. + /* State must never be zero, otherwise the generator is stuck. + * The seed path (srand / rand_r) already guards against this, but we + * check here as well for safety. */ - randint = (RND1_CONSTK * (*seed)) % RND1_CONSTP; - *seed = (randint == 0 ? 1 : randint); - return randint; -} - -#if (CONFIG_LIBC_RAND_ORDER == 1) -static float_t frand1(FAR unsigned long *seed) -{ - /* First order congruential generator. */ - - unsigned long randint = fgenerate1(seed); - - /* Construct an floating point value in the range from 0.0 up to 1.0 */ - - return ((float_t)randint) / ((float_t)RND1_CONSTP); -} -#endif - -/* Second order congruential generators */ - -#if (CONFIG_LIBC_RAND_ORDER > 1) -static inline unsigned long fgenerate2(void) -{ - unsigned long randint; - - /* Second order congruential generator. */ - - randint = (RND2_CONSTK1 * g_randint1 + - RND2_CONSTK2 * g_randint2) % RND2_CONSTP; - - g_randint2 = g_randint1; - g_randint1 = randint; - - /* We cannot permit both values to become zero. That would be fatal for - * the second order random number generator. - */ - - if (g_randint2 == 0 && g_randint1 == 0) + if (x == 0) { - g_randint2 = 1; + x = 1; } - return randint; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + + *state = x; + return x; } -#if (CONFIG_LIBC_RAND_ORDER == 2) -static float_t frand2(void) -{ - /* Second order congruential generator */ - - unsigned long randint = fgenerate2(); - - /* Construct an floating point value in the range from 0.0 up to 1.0 */ - - return ((float_t)randint) / ((float_t)RND2_CONSTP); -} -#endif - -/* Third order congruential generators */ - -#if (CONFIG_LIBC_RAND_ORDER > 2) -static inline unsigned long fgenerate3(void) -{ - unsigned long randint; - - /* Third order congruential generator. */ - - randint = (RND3_CONSTK1 * g_randint1 + - RND3_CONSTK2 * g_randint2 + - RND3_CONSTK2 * g_randint3) % RND3_CONSTP; - - g_randint3 = g_randint2; - g_randint2 = g_randint1; - g_randint1 = randint; - - /* We cannot permit all three values to become zero. That would be fatal - * for the third order random number generator. - */ - - if (g_randint3 == 0 && g_randint2 == 0 && g_randint1 == 0) - { - g_randint3 = 1; - } - - return randint; -} - -static float_t frand3(void) -{ - /* Third order congruential generator */ - - unsigned long randint = fgenerate3(); - - /* Construct an floating point value in the range from 0.0 up to 1.0 */ - - return ((float_t)randint) / ((float_t)RND3_CONSTP); -} -#endif -#endif - static unsigned long nrand_r(unsigned long limit, - FAR unsigned long *seed) + FAR uint32_t *state) { -#if CONFIG_LIBC_RAND_ORDER > 0 - unsigned long result; - float_t ratio; + uint32_t randval = xorshift32(state); - /* Loop to be sure a legal random number is generated */ + /* Map the 32-bit random value into the range [0, limit). + * The modulo bias is negligible for small limits relative to 2^32. + */ - do - { - /* Get a random integer in the range 0.0 - 1.0 */ - -# if (CONFIG_LIBC_RAND_ORDER == 1) - ratio = frand1(seed); -# elif (CONFIG_LIBC_RAND_ORDER == 2) - ratio = frand2(); -# elif (CONFIG_LIBC_RAND_ORDER > 2) - ratio = frand3(); -#endif - - /* Then, produce the return-able value in the requested range */ - - result = (unsigned long)(((float_t)limit) * ratio); - - /* Loop because there is an (unlikely) possibility that rounding - * could increase the result at the limit value about the limit. - */ - } - while (result >= limit); - - return result; -#else - return fgenerate1(seed) % limit; -#endif + return (unsigned long)(randval % (uint32_t)limit); } /**************************************************************************** @@ -262,21 +93,15 @@ static unsigned long nrand_r(unsigned long limit, * Name: srand * * Description: - * Seed the congruential random number generator. + * Seed the random number generator. * ****************************************************************************/ void srand(unsigned int seed) { - g_randint1 = seed; -#if (CONFIG_LIBC_RAND_ORDER > 1) - g_randint2 = seed; - fgenerate1(&g_randint1); -#if (CONFIG_LIBC_RAND_ORDER > 2) - g_randint3 = seed; - fgenerate2(); -#endif -#endif + /* Avoid a zero state which would make xorshift32 degenerate. */ + + g_randstate = (seed == 0) ? 1 : (uint32_t)seed; } /**************************************************************************** @@ -289,7 +114,7 @@ void srand(unsigned int seed) unsigned long nrand(unsigned long limit) { - return nrand_r(limit, &g_randint1); + return nrand_r(limit, &g_randstate); } /**************************************************************************** @@ -308,10 +133,15 @@ unsigned long nrand(unsigned long limit) int rand_r(FAR unsigned int *seedp) { - unsigned long seed = *seedp; + uint32_t state = (uint32_t)*seedp; unsigned long rand; - rand = nrand_r(INT_MAX, &seed); - *seedp = (unsigned int)seed; + if (state == 0) + { + state = 1; + } + + rand = nrand_r(INT_MAX, &state); + *seedp = (unsigned int)state; return (int)rand; }