bench.c
application/octet-stream
Filename: bench.c
Type: application/octet-stream
Part: 0
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/random.h>
#include <openssl/rand.h>
#ifndef GETENTROPY_MAX
#define GETENTROPY_MAX 256
#endif
typedef unsigned char byte;
typedef void randomize_f(byte *ptr, size_t len);
static void
rand_entropy(byte *ptr, size_t len) {
while(len > GETENTROPY_MAX) {
int r = getentropy(ptr, GETENTROPY_MAX);
assert(r == 0);
ptr += GETENTROPY_MAX;
len -= GETENTROPY_MAX;
}
if(len > 0) {
int r = getentropy(ptr, len);
assert(r == 0);
}
}
static void
rand_vgetrandom(byte *ptr, size_t len) {
int r = getrandom(ptr, len, 0);
assert(r >= 0);
}
static void
rand_getrandom(byte *ptr, size_t len) {
size_t ret;
/* simply call getrandom syscall */
ret = syscall(SYS_getrandom, ptr, len, GRND_NONBLOCK);
assert(ret >= 0);
}
static void
rand_openssl(byte *ptr, size_t len) {
int r = RAND_bytes(ptr, len);
assert(r == 1);
}
static uint64_t
nanotime(void) {
struct timespec tv;
int r = clock_gettime(CLOCK_MONOTONIC, &tv);
assert(r == 0);
return((uint64_t)tv.tv_nsec +
(uint64_t)tv.tv_sec * 1000*1000*1000);
}
static byte
consume(byte *ptr, size_t len) {
byte eat = 0;
while(len-- > 0) {
eat ^= *ptr++;
}
return(eat);
}
static byte
bench(randomize_f *randomize, size_t count, size_t len) {
byte *ptr = malloc(len);
assert(ptr != NULL);
uint64_t start = nanotime();
byte eat = 0;
for(size_t i = 0; i < count; i++) {
randomize(ptr, len);
eat ^= consume(ptr, len);
}
uint64_t finish = nanotime();
uint64_t ns = finish - start;
printf("%11"PRIu64, ns / count);
free(ptr);
return(eat);
}
int main(void) {
printf("init openssl");
byte eat = bench(rand_openssl, 1, 1);
printf("\n\n");
printf(" len"
" entropy"
" openssl"
" vgetrandom"
" getrandom\n"
);
size_t count = 10000;
for(size_t len = 16; len <= 1024; len *= 4) {
printf("%11zu", len);
eat |= bench(rand_entropy, count, len);
eat |= bench(rand_openssl, count, len);
eat |= bench(rand_vgetrandom, count, len);
eat |= bench(rand_getrandom, count, len);
printf("\n");
}
return(!eat);
}