Line data Source code
1 : #include "passgen/random.h" 2 : #include "passgen/util/endian.h" 3 : #include <stdlib.h> 4 : #include <string.h> 5 : 6 72449 : static uint64_t xorshift64(uint64_t *state) { 7 72449 : uint64_t x = *state; 8 72449 : x ^= x << 13; 9 72449 : x ^= x >> 7; 10 72449 : x ^= x << 17; 11 72449 : return *state = x; 12 : } 13 : 14 : static size_t 15 566 : passgen_random_xorshift_read(void *context, void *dest, size_t size) { 16 566 : size_t written = 0; 17 : uint64_t result; 18 : 19 : // fill all whole uint64 blocks 20 73014 : while((size - written) >= sizeof(result)) { 21 72448 : result = xorshift64(context); 22 72448 : memcpy(dest + written, &result, sizeof(result)); 23 72448 : written += sizeof(result); 24 : } 25 : 26 : // maybe fill the last incomplete block 27 566 : if(size != written) { 28 1 : result = xorshift64(context); 29 1 : memcpy(dest + written, &result, size - written); 30 1 : written += size - written; 31 : } 32 : 33 566 : return written; 34 : } 35 : 36 18 : static void passgen_random_xorshift_close(void *context) { 37 18 : free(context); 38 18 : } 39 : 40 : passgen_random * 41 18 : passgen_random_xorshift_open(passgen_random *random, uint64_t seed) { 42 18 : if(!random) { 43 2 : random = malloc(sizeof(passgen_random)); 44 2 : if(!random) return NULL; 45 : } 46 : 47 : // create state 48 18 : uint64_t *state = malloc(sizeof(uint64_t)); 49 18 : if(!state) return NULL; 50 : 51 : // initialise state 52 18 : *state = seed; 53 : 54 18 : random->context = state; 55 18 : random->read = passgen_random_xorshift_read; 56 18 : random->close = passgen_random_xorshift_close; 57 18 : passgen_random_reload(random); 58 : 59 18 : return random; 60 : }