/* * Copyright (C) 2009 Martin Willi * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See . * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include #include #include #include #include #include static void usage() { printf("usage: dh_speed plugins rounds group1 [group2 [...]]\n"); exit(1); } struct { char *name; diffie_hellman_group_t group; } groups[] = { {"modp768", MODP_768_BIT}, {"modp1024", MODP_1024_BIT}, {"modp1024s160", MODP_1024_160}, {"modp1536", MODP_1536_BIT}, {"modp2048", MODP_2048_BIT}, {"modp2048s224", MODP_2048_224}, {"modp2048s256", MODP_2048_256}, {"modp3072", MODP_3072_BIT}, {"modp4096", MODP_4096_BIT}, {"modp6144", MODP_6144_BIT}, {"modp8192", MODP_8192_BIT}, {"ecp256", ECP_256_BIT}, {"ecp384", ECP_384_BIT}, {"ecp521", ECP_521_BIT}, {"ecp192", ECP_192_BIT}, {"ecp224", ECP_224_BIT}, {"curve25519", CURVE_25519}, }; static void start_timing(struct timespec *start) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, start); } static double end_timing(struct timespec *start) { struct timespec end; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); return (end.tv_nsec - start->tv_nsec) / 1000000000.0 + (end.tv_sec - start->tv_sec) * 1.0; } static void run_test(diffie_hellman_group_t group, int rounds) { diffie_hellman_t *l[rounds], *r; chunk_t chunk, chunks[rounds], lsecrets[rounds], rsecrets[rounds]; struct timespec timing; int round; r = lib->crypto->create_dh(lib->crypto, group); if (!r) { printf("skipping %N, not supported\n", diffie_hellman_group_names, group); return; } printf("%N:\t", diffie_hellman_group_names, group); start_timing(&timing); for (round = 0; round < rounds; round++) { l[round] = lib->crypto->create_dh(lib->crypto, group); assert(l[round]->get_my_public_value(l[round], &chunks[round])); } printf("A = g^a/s: %8.1f", rounds / end_timing(&timing)); for (round = 0; round < rounds; round++) { assert(r->set_other_public_value(r, chunks[round])); assert(r->get_shared_secret(r, &rsecrets[round])); chunk_free(&chunks[round]); } assert(r->get_my_public_value(r, &chunk)); start_timing(&timing); for (round = 0; round < rounds; round++) { assert(l[round]->set_other_public_value(l[round], chunk)); assert(l[round]->get_shared_secret(l[round], &lsecrets[round])); } printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing)); chunk_free(&chunk); for (round = 0; round < rounds; round++) { assert(chunk_equals(rsecrets[round], lsecrets[round])); free(lsecrets[round].ptr); free(rsecrets[round].ptr); l[round]->destroy(l[round]); } r->destroy(r); } int main(int argc, char *argv[]) { int rounds, i, j; if (argc < 4) { usage(); } library_init(NULL, "dh_speed"); lib->plugins->load(lib->plugins, argv[1]); atexit(library_deinit); rounds = atoi(argv[2]); for (i = 3; i < argc; i++) { bool found = FALSE; for (j = 0; j < countof(groups); j++) { if (streq(groups[j].name, argv[i])) { run_test(groups[j].group, rounds); found = TRUE; } } if (!found) { printf("group %s not found\n", argv[i]); } } return 0; }