add generic get_random_bytes function

This commit is contained in:
Daniel Micay 2019-04-15 04:52:18 -04:00
parent f115be8392
commit c7e2cb82f4
2 changed files with 24 additions and 1 deletions

View File

@ -18,7 +18,7 @@ static ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
#endif #endif
static void get_random_seed(void *buf, size_t size) { static void get_random_seed(void *buf, size_t size) {
while (size > 0) { while (size) {
ssize_t r; ssize_t r;
do { do {
@ -54,6 +54,28 @@ static void refill(struct random_state *state) {
} }
} }
void get_random_bytes(struct random_state *state, void *buf, size_t size) {
// avoid needless copying to and from the cache as an optimization
if (size > RANDOM_CACHE_SIZE / 2) {
chacha_keystream_bytes(&state->ctx, buf, size);
return;
}
while (size) {
if (state->index == RANDOM_CACHE_SIZE) {
refill(state);
}
size_t remaining = RANDOM_CACHE_SIZE - state->index;
size_t copy_size = min(size, remaining);
memcpy(buf, state->cache + state->index, copy_size);
state->index += copy_size;
buf = (char *)buf + copy_size;
size -= copy_size;
}
}
u16 get_random_u16(struct random_state *state) { u16 get_random_u16(struct random_state *state) {
u16 value; u16 value;
unsigned remaining = RANDOM_CACHE_SIZE - state->index; unsigned remaining = RANDOM_CACHE_SIZE - state->index;

View File

@ -15,6 +15,7 @@ struct random_state {
}; };
void random_state_init(struct random_state *state); void random_state_init(struct random_state *state);
void get_random_bytes(struct random_state *state, void *buf, size_t size);
u16 get_random_u16(struct random_state *state); u16 get_random_u16(struct random_state *state);
u16 get_random_u16_uniform(struct random_state *state, u16 bound); u16 get_random_u16_uniform(struct random_state *state, u16 bound);
u64 get_random_u64(struct random_state *state); u64 get_random_u64(struct random_state *state);