1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
/*
* Copyright (C) 2022 The University of Notre Dame
* This software is distributed under the GNU General Public License.
* See the file COPYING for details.
*/
#include "random.h"
#include "debug.h"
#include "full_io.h"
#include "timestamp.h"
#include "twister.h"
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
void random_init(void)
{
static int random_initialized = 0;
if (random_initialized)
return;
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
fd = open("/dev/random", O_RDONLY);
}
if (fd >= 0) {
uint64_t seed[8];
if (full_read(fd, seed, sizeof(seed)) < (int64_t)sizeof(seed))
goto nasty_fallback;
srand(seed[0]);
twister_init_by_array64(seed, sizeof(seed) / sizeof(seed[0]));
} else {
uint64_t seed;
nasty_fallback:
debug(D_NOTICE, "warning: falling back to low-quality entropy");
seed = (uint64_t)getpid() ^ (uint64_t)timestamp_get();
seed |= (((uint64_t)(uintptr_t)&seed) << 32); /* using ASLR */
srand(seed);
twister_init_genrand64(seed);
}
close(fd);
random_initialized = 1;
return;
}
int64_t random_int64(void)
{
return twister_genrand64_int64();
}
double random_double(void)
{
return twister_genrand64_real3();
}
void random_array(void *dest, size_t len)
{
size_t i;
uint8_t *out = dest;
for (i = 0; i < len; i += sizeof(int64_t)) {
int64_t r = twister_genrand64_int64();
size_t count = len > sizeof(int64_t) ? sizeof(int64_t) : len;
memcpy(out + i, &r, count);
}
}
void random_hex(char *str, size_t len)
{
int64_t r;
size_t i = 0;
do {
r = twister_genrand64_int64();
snprintf(str + i, len - i, "%016" PRIx64, r);
i += sizeof(r) * 2;
} while (i < len);
}
/* vim: set noexpandtab tabstop=8: */
|