#include #include #include #include #include #include #include #include "cprng.h" #include "crypto_test.h" static uint64_t rdtsc(void) { uint32_t low, high; __asm__ __volatile__ ("rdtsc" : "=a"(low), "=d"(high)); return ((uint64_t)high << 32) | low; } static struct cprng cprng; static void seed(void) { uint8_t s[32]; static int fd = -1; if (fd == -1) { fd = open("/dev/urandom", O_RDONLY); if (fd == -1) err(1, "open"); } const ssize_t nread = read(fd, s, sizeof s); if (nread == -1) err(1, "read"); if (nread != 32) errx(1, "short read: %zd != 32", nread); cprng_seed(&cprng, s); } static volatile sig_atomic_t alarmed; static void alarm_handler(int signo __unused) { alarmed = 1; } #define MISALIGN 0 unsigned char buf[0x10000 + MISALIGN]; int main(int argc, char **argv) { uint64_t start, end; unsigned int i, n, c; if (signal(SIGALRM, &alarm_handler) == SIG_ERR) err(1, "signal(SIGALRM)"); crypto_test(); printf("%6s %10s %12s %12s %14s\n", "bytes", "iters", "cycles", "cpb", "cpi"); (void)i; #if 1 printf("* cprng_buf\n"); for (i = 0; i <= 16; i++) { n = (1 << i) + MISALIGN; c = 0; seed(); alarmed = 0; alarm(3); start = rdtsc(); while (!alarmed) { cprng_buf(&cprng, buf + MISALIGN, n); c++; } end = rdtsc(); (void)printf("%6u %10u %12"PRIu64" %12f %14f\n", n, c, (end - start), ((double)(end - start) / ((double)n * c)), ((double)(end - start) / c)); } #endif printf("* cprng32\n"); n = 4; c = 0; seed(); alarmed = 0; alarm(3); start = rdtsc(); while (!alarmed) { volatile uint32_t v __unused = cprng32(&cprng); c++; } end = rdtsc(); (void)printf("%6u %10u %12"PRIu64" %12f %14f\n", n, c, (end - start), ((double)(end - start) / ((double)n * c)), ((double)(end - start) / c)); printf("* cprng64\n"); n = 8; c = 0; seed(); alarmed = 0; alarm(3); start = rdtsc(); while (!alarmed) { volatile uint64_t v __unused = cprng64(&cprng); c++; } end = rdtsc(); (void)printf("%6u %10u %12"PRIu64" %12f %14f\n", n, c, (end - start), ((double)(end - start) / ((double)n * c)), ((double)(end - start) / c)); return 0; }