diff options
Diffstat (limited to '')
-rw-r--r-- | src/prng.c | 91 |
1 files changed, 91 insertions, 0 deletions
@@ -25,12 +25,21 @@ #include "mt19937ar-cok/mt19937ar-cok.h" #include "isaac_rand/isaac_rand.h" #include "isaac_rand/isaac64.h" +#include "alfg/add_lagg_fibonacci_prng.h" //Lagged Fibonacci generator prototype +#include "xor/xoroshiro256_prng.h" //XORoshiro-256 prototype nwipe_prng_t nwipe_twister = { "Mersenne Twister (mt19937ar-cok)", nwipe_twister_init, nwipe_twister_read }; nwipe_prng_t nwipe_isaac = { "ISAAC (rand.c 20010626)", nwipe_isaac_init, nwipe_isaac_read }; nwipe_prng_t nwipe_isaac64 = { "ISAAC-64 (isaac64.c)", nwipe_isaac64_init, nwipe_isaac64_read }; +/* ALFG PRNG Structure */ +nwipe_prng_t nwipe_add_lagg_fibonacci_prng = { "Lagged Fibonacci generator", + nwipe_add_lagg_fibonacci_prng_init, + nwipe_add_lagg_fibonacci_prng_read }; +/* XOROSHIRO-256 PRNG Structure */ +nwipe_prng_t nwipe_xoroshiro256_prng = { "XORoshiro-256", nwipe_xoroshiro256_prng_init, nwipe_xoroshiro256_prng_read }; + /* Print given number of bytes from unsigned integer number to a byte stream buffer starting with low-endian. */ static inline void u32_to_buffer( u8* restrict buffer, u32 val, const int len ) { @@ -250,3 +259,85 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE ) return 0; } + +/* EXPERIMENTAL implementation of Lagged Fibonacci generator a lot of random numbers */ +int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE ) +{ + if( *state == NULL ) + { + nwipe_log( NWIPE_LOG_NOTICE, "Initialising Lagged Fibonacci generator PRNG" ); + *state = malloc( sizeof( add_lagg_fibonacci_state_t ) ); + } + add_lagg_fibonacci_init( + (add_lagg_fibonacci_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) ); + + return 0; +} + +/* EXPERIMENTAL implementation of XORoroshiro256 algorithm to provide high-quality, but a lot of random numbers */ +int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE ) +{ + nwipe_log( NWIPE_LOG_NOTICE, "Initialising XORoroshiro-256 PRNG" ); + + if( *state == NULL ) + { + /* This is the first time that we have been called. */ + *state = malloc( sizeof( xoroshiro256_state_t ) ); + } + xoroshiro256_init( + (xoroshiro256_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) ); + + return 0; +} + +int nwipe_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE ) +{ + u8* restrict bufpos = buffer; + size_t words = count / SIZE_OF_ADD_LAGG_FIBONACCI_PRNG; + + /* Loop to fill the buffer with blocks directly from the Fibonacci algorithm */ + for( size_t ii = 0; ii < words; ++ii ) + { + add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, bufpos ); + bufpos += SIZE_OF_ADD_LAGG_FIBONACCI_PRNG; // Move to the next block + } + + /* Handle remaining bytes if count is not a multiple of SIZE_OF_ADD_LAGG_FIBONACCI_PRNG */ + const size_t remain = count % SIZE_OF_ADD_LAGG_FIBONACCI_PRNG; + if( remain > 0 ) + { + unsigned char temp_output[16]; // Temporary buffer for the last block + add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, temp_output ); + + // Copy the remaining bytes + memcpy( bufpos, temp_output, remain ); + } + + return 0; // Success +} + +int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE ) +{ + u8* restrict bufpos = buffer; + size_t words = count / SIZE_OF_XOROSHIRO256_PRNG; + + /* Loop to fill the buffer with blocks directly from the XORoroshiro256 algorithm */ + for( size_t ii = 0; ii < words; ++ii ) + { + xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, bufpos ); + bufpos += SIZE_OF_XOROSHIRO256_PRNG; // Move to the next block + } + + /* Handle remaining bytes if count is not a multiple of SIZE_OF_XOROSHIRO256_PRNG */ + const size_t remain = count % SIZE_OF_XOROSHIRO256_PRNG; + if( remain > 0 ) + { + unsigned char temp_output[16]; // Temporary buffer for the last block + xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, temp_output ); + + // Copy the remaining bytes + memcpy( bufpos, temp_output, remain ); + } + + return 0; // Success +} |