From 6f833be9d59863b086ec6af259b18769c8b06d0b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 20 Aug 2016 11:36:02 -0600 Subject: [PATCH] Separate XorShift128 PRNG from /dev/urandom and make it generally available. --- drivers/dev_urandom.c | 77 +++++++------------ include/nuttx/lib/xorshift128.h | 98 ++++++++++++++++++++++++ libc/misc/Make.defs | 2 +- libc/misc/lib_xorshift128.c | 123 +++++++++++++++++++++++++++++++ sched/sched/sched_processtimer.c | 16 +--- 5 files changed, 254 insertions(+), 62 deletions(-) create mode 100644 include/nuttx/lib/xorshift128.h create mode 100644 libc/misc/lib_xorshift128.c diff --git a/drivers/dev_urandom.c b/drivers/dev_urandom.c index 4923544eae..28bad840b4 100644 --- a/drivers/dev_urandom.c +++ b/drivers/dev_urandom.c @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -75,17 +76,13 @@ * Private Types ****************************************************************************/ -typedef union +struct xorshift128_state_s { - struct - { - uint32_t x; - uint32_t y; - uint32_t z; - uint32_t w; - }; - uint8_t u[16]; -} xorshift128_state_t; + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; +}; /**************************************************************************** * Private Function Prototypes @@ -106,7 +103,7 @@ static int devurand_poll(FAR struct file *filep, FAR struct pollfd *fds, * Private Data ****************************************************************************/ -static const struct file_operations devurand_fops = +static const struct file_operations g_urand_fops = { NULL, /* open */ NULL, /* close */ @@ -122,37 +119,10 @@ static const struct file_operations devurand_fops = #endif }; -#ifdef CONFIG_DEV_URANDOM_XORSHIFT128 -static xorshift128_state_t prng; -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: xorshift128 - ****************************************************************************/ - -#ifdef CONFIG_DEV_URANDOM_XORSHIFT128 -static uint32_t xorshift128(void) -{ - uint32_t t = prng.x; - - t ^= t << 11; - t ^= t >> 8; - - prng.x = prng.y; - prng.y = prng.z; - prng.z = prng.w; - - prng.w ^= prng.w >> 19; - prng.w ^= t; - - return prng.w; -} -#endif - /**************************************************************************** * Name: congruential ****************************************************************************/ @@ -241,14 +211,26 @@ static ssize_t devurand_write(FAR struct file *filep, FAR const char *buffer, #ifdef CONFIG_DEV_URANDOM_CONGRUENTIAL unsigned int seed = 0; - len = min(len, sizeof(unsigned int)); - memcpy(&seed, buffer, len); + if (len < sizeof(unsigned int)) + { + return -ERANGE; + } + + memcpy(&seed, buffer, sizeof(unsigned int)); srand(seed); - return len; + return sizeof(unsigned int); + #else - len = min(len, sizeof(prng.u)); - memcpy(&prng.u, buffer, len); - return len; + struct xorshift128_state_s seed; + + if (len < sizeof(struct xorshift128_state_s)) + { + return -ERANGE; + } + + memcpy(&seed, buffer, sizeof(struct xorshift128_state_s)); + xorshift128_seed(seed.w, seed.x, seed.y, seed.z); + return sizeof(struct xorshift128_state_s); #endif } @@ -292,13 +274,10 @@ void devurandom_register(void) #else /* Seed the PRNG */ - prng.w = 97; - prng.x = 101; - prng.y = prng.w << 17; - prng.z = prng.x << 25; + xorshift128_seed(97, 101, 97 << 17, 101 << 25); #endif - (void)register_driver("/dev/urandom", &devurand_fops, 0666, NULL); + (void)register_driver("/dev/urandom", &g_urand_fops, 0666, NULL); } #endif /* CONFIG_DEV_URANDOM && CONFIG_DEV_URANDOM_ARCH */ diff --git a/include/nuttx/lib/xorshift128.h b/include/nuttx/lib/xorshift128.h new file mode 100644 index 0000000000..f2952d44d7 --- /dev/null +++ b/include/nuttx/lib/xorshift128.h @@ -0,0 +1,98 @@ +/**************************************************************************** + * include/nuttx/lib/xorshift128.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: David S. Alessio + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This random number generator is simple, fast and portable. + * Ref: https://en.wikipedia.org/wiki/Xorshift + */ + +#ifndef __INCLUDE_NUTTX_LIB_XORSHIFT128_H +#define __INCLUDE_NUTTX_LIB_XORSHIFT128_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: xorshift128_seed + * + * Description: + * Seed the XorShift128 PRNG + * + * Input Parameters: + * w, x, y, z: Values for XorShift128 generation state. + * + * Returned Value: + * No + * + ****************************************************************************/ + +void xorshift128_seed(uint32_t w, uint32_t x, uint32_t y, uint32_t z); + +/**************************************************************************** + * Name: xorshift128 + * + * Description: + * Generate one 32-bit pseudo-random number + * + * Input Parameters: + * None + * + * Returned Value: + * The generated pseudo-random number + * + ****************************************************************************/ + +uint32_t xorshift128(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_LIB_XORSHIFT128_H */ diff --git a/libc/misc/Make.defs b/libc/misc/Make.defs index dbdb349547..ec3c76b94d 100644 --- a/libc/misc/Make.defs +++ b/libc/misc/Make.defs @@ -36,7 +36,7 @@ # Add the internal C files to the build CSRCS += lib_stream.c lib_filesem.c lib_utsname.c -CSRCS += lib_tea_encrypt.c lib_tea_decrypt.c +CSRCS += lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c # Support for platforms that do not have long long types diff --git a/libc/misc/lib_xorshift128.c b/libc/misc/lib_xorshift128.c new file mode 100644 index 0000000000..3c92309587 --- /dev/null +++ b/libc/misc/lib_xorshift128.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * libc/misc/lib_xorshift.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: David S. Alessio + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* This random number generator is simple, fast and portable. + * Ref: https://en.wikipedia.org/wiki/Xorshift + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct xorshift128_state_s +{ + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct xorshift128_state_s g_prng; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xorshift128_seed + * + * Description: + * Seed the XorShift128 PRNG + * + * Input Parameters: + * w, x, y, z: Values for XorShift128 generation state. + * + * Returned Value: + * No + * + ****************************************************************************/ + +void xorshift128_seed(uint32_t w, uint32_t x, uint32_t y, uint32_t z) +{ + /* Seed the PRNG */ + + g_prng.w = w; + g_prng.x = x; + g_prng.y = y; + g_prng.z = z; +} + +/**************************************************************************** + * Name: xorshift128 + * + * Description: + * Generate one 32-bit pseudo-random number + * + * Input Parameters: + * None + * + * Returned Value: + * The generated pseudo-random number + * + ****************************************************************************/ + +uint32_t xorshift128(void) +{ + uint32_t t; + + t = g_prng.x; + t ^= t << 11; + t ^= t >> 8; + + g_prng.x = g_prng.y; + g_prng.y = g_prng.z; + g_prng.z = g_prng.w; + + g_prng.w ^= g_prng.w >> 19; + g_prng.w ^= t; + + return g_prng.w; +} diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 9b64abed1b..62dce45b02 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -50,14 +50,6 @@ #include "wdog/wdog.h" #include "clock/clock.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifndef CONFIG_SCHED_CPULOAD_TIMECONSTANT -# define CONFIG_SCHED_CPULOAD_TIMECONSTANT 2 -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -69,10 +61,10 @@ * Check for operations specific to scheduling policy of the currently * active task. * - * Inputs: + * Input Parameters: * None * - * Return Value: + * Returned Value: * None * ****************************************************************************/ @@ -134,10 +126,10 @@ static inline void sched_process_scheduler(void) * function periodically -- the calling interval must be * USEC_PER_TICK * - * Inputs: + * Input Parameters: * None * - * Return Value: + * Returned Value: * None * ****************************************************************************/