Packages

libntru wrapper for elixir. NTRU is a post quantom cryptography algorithm.

Current section

Files

Jump to
ntru_elixir libntru src bench.c
Raw

libntru/src/bench.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "ntru.h"
#define NUM_ITER_KEYGEN 50
#define NUM_ITER_ENCDEC 10000
/*
* The __MACH__ and __MINGW32__ code below is from
* https://github.com/credentials/silvia/commit/e327067cf7feaf62ac0bde84d13ee47372c0094e
*/
#ifdef __MACH__
/*
* Mac OS X does not have clock_gettime for some reason
*
* Use solution from here to fix it:
* http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
*/
#define CLOCK_REALTIME 0
#include <mach/clock.h>
#include <mach/mach.h>
void clock_gettime(uint32_t clock, struct timespec* the_time)
{
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
the_time->tv_sec = mts.tv_sec;
the_time->tv_nsec = mts.tv_nsec;
}
#endif /* __MACH__ */
#ifdef __MINGW32__
/*
* MinGW does not have clock_gettime for some reason
*
* Use solution from here to fix it:
* http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
*/
#include <stdarg.h>
#include <windef.h>
#include <winnt.h>
#include <winbase.h>
#define CLOCK_REALTIME 0
LARGE_INTEGER getFILETIMEoffset()
{
SYSTEMTIME s;
FILETIME f;
LARGE_INTEGER t;
s.wYear = 1970;
s.wMonth = 1;
s.wDay = 1;
s.wHour = 0;
s.wMinute = 0;
s.wSecond = 0;
s.wMilliseconds = 0;
SystemTimeToFileTime(&s, &f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
return (t);
}
void clock_gettime(uint32_t X, struct timespec *ts)
{
LARGE_INTEGER t;
FILETIME f;
double nanoseconds;
static LARGE_INTEGER offset;
static double frequencyToNanoseconds;
static uint32_t initialized = 0;
static BOOL usePerformanceCounter = 0;
if (!initialized) {
LARGE_INTEGER performanceFrequency;
initialized = 1;
usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
if (usePerformanceCounter) {
QueryPerformanceCounter(&offset);
frequencyToNanoseconds = (double)performanceFrequency.QuadPart / 1000000000.;
} else {
offset = getFILETIMEoffset();
frequencyToNanoseconds = 0.010;
}
}
if (usePerformanceCounter) QueryPerformanceCounter(&t);
else {
GetSystemTimeAsFileTime(&f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
}
t.QuadPart -= offset.QuadPart;
nanoseconds = (double)t.QuadPart / frequencyToNanoseconds;
t.QuadPart = nanoseconds;
ts->tv_sec = t.QuadPart / 1000000000;
ts->tv_nsec = t.QuadPart % 1000000000;
}
#endif /* __MINGW32__ */
int compare_double(const void *p1, const void *p2) {
double t1 = *(double*)p1;
double t2 = *(double*)p2;
return t1<t2 ? -1 : (t1>t2 ? 1 : 0);
}
double median(double *samples, int num_samples) {
if (num_samples == 0)
return 0;
if (num_samples == 1)
return samples[0];
qsort(samples, num_samples, sizeof(samples[0]), compare_double);
if (num_samples%2 == 0)
return (samples[num_samples/2-1]+samples[num_samples/2]) / 2;
else
return samples[num_samples/2];
}
void print_time(char *label, double *samples, int num_samples) {
double time = median(samples, num_samples);
double per_sec = 1000000.0 / time;
#ifdef WIN32
printf("%s %dus=%d/sec ", label, (uint32_t)time, (uint32_t)per_sec);
#else
printf("%s %dμs=%d/sec ", label, (uint32_t)time, (uint32_t)per_sec);
#endif
fflush(stdout);
}
int main(int argc, char **argv) {
printf("Please wait...\n");
NtruEncParams param_arr[] = ALL_PARAM_SETS;
uint8_t success = 1;
uint8_t param_idx;
for (param_idx=0; param_idx<sizeof(param_arr)/sizeof(param_arr[0]); param_idx++) {
NtruEncParams params = param_arr[param_idx];
NtruEncKeyPair kp;
uint32_t i;
struct timespec t1, t2;
printf("%-10s ", params.name);
fflush(stdout);
double samples_keygen[NUM_ITER_KEYGEN];
NtruRandGen rng = NTRU_RNG_DEFAULT;
NtruRandContext rand_ctx;
success &= ntru_rand_init(&rand_ctx, &rng) == NTRU_SUCCESS;
for (i=0; i<NUM_ITER_KEYGEN; i++) {
clock_gettime(CLOCK_REALTIME, &t1);
success &= ntru_gen_key_pair(&params, &kp, &rand_ctx) == NTRU_SUCCESS;
clock_gettime(CLOCK_REALTIME, &t2);
double duration = 1000000000.0*(t2.tv_sec-t1.tv_sec) + t2.tv_nsec-t1.tv_nsec; /* nanoseconds */
samples_keygen[i] = duration / 1000.0; /* microseconds */
}
print_time("keygen", samples_keygen, NUM_ITER_KEYGEN);
double samples_encdec[NUM_ITER_ENCDEC];
uint16_t max_len = ntru_max_msg_len(&params); /* max message length for this param set */
uint8_t plain[max_len];
success &= ntru_rand_generate(plain, max_len, &rand_ctx) == NTRU_SUCCESS;
uint16_t enc_len = ntru_enc_len(&params);
uint8_t encrypted[enc_len];
uint8_t decrypted[max_len];
for (i=0; i<NUM_ITER_ENCDEC; i++) {
clock_gettime(CLOCK_REALTIME, &t1);
success &= ntru_encrypt((uint8_t*)&plain, max_len, &kp.pub, &params, &rand_ctx, (uint8_t*)&encrypted) == NTRU_SUCCESS;
clock_gettime(CLOCK_REALTIME, &t2);
double duration = 1000000000.0*(t2.tv_sec-t1.tv_sec) + t2.tv_nsec-t1.tv_nsec; /* nanoseconds */
samples_encdec[i] = duration / 1000.0; /* microseconds */
}
print_time("enc", samples_encdec, NUM_ITER_ENCDEC);
success &= ntru_rand_release(&rand_ctx) == NTRU_SUCCESS;
uint16_t dec_len;
for (i=0; i<NUM_ITER_ENCDEC; i++) {
clock_gettime(CLOCK_REALTIME, &t1);
success &= ntru_decrypt((uint8_t*)&encrypted, &kp, &params, (uint8_t*)&decrypted, &dec_len) == NTRU_SUCCESS;
clock_gettime(CLOCK_REALTIME, &t2);
double duration = 1000000000.0*(t2.tv_sec-t1.tv_sec) + t2.tv_nsec-t1.tv_nsec; /* nanoseconds */
samples_encdec[i] = duration / 1000.0; /* microseconds */
}
print_time("dec", samples_encdec, NUM_ITER_ENCDEC);
printf("\n");
}
if (!success)
printf("Error!\n");
return success ? 0 : 1;
}