#include "smg_rsa.h" #include "mpi.h" #include #include #include #include extern void adainit(void); extern void adafinal(void); void err(char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } void time_entropy_source(int nruns, int noctets) { unsigned char buffer[noctets]; int read, i; struct timespec tstart, tend; long int diff; clock_gettime(CLOCK_MONOTONIC, &tstart); for (i=0; i buffer_length) to_read = buffer_length; nread = get_random_octets_from(to_read, buffer, source); if (nread > 0) { total_read = total_read + nread; fwrite(buffer, 1, nread, out); fflush(out); printf("."); fflush(stdout); } } printf("done.\n"); fclose(out); close(source); } void test_is_composite(int nruns, char *hex_number, int expected) { int i; int output; int count_ok = 0; int source = open_entropy_source(ENTROPY_SOURCE); MPI p = mpi_alloc(0); mpi_fromstr(p, hex_number); printf("TEST is_composite on MPI(hex) "); mpi_print(stdout, p, 1); for (i=0; i < nruns; i++) { printf("."); fflush(stdout); output = is_composite(p, M_R_ITERATIONS, source); if (output == expected) count_ok = count_ok + 1; } printf("done, with %d out of %d correct runs for expected=%d: %s\n", count_ok, nruns, expected, count_ok==nruns? "PASS":"FAIL"); mpi_free(p); close(source); } void time_mr(int nruns) { struct timespec tstart, tend; long int diff; int i; MPI prime; unsigned int noctets = KEY_LENGTH_OCTETS / 2; unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets); int entropy_source = open_entropy_source(ENTROPY_SOURCE); if (entropy_source <= 0) err("can't open entropy source!"); /* first generate a prime of half key length, to make sure M-R will run max number of iterations */ printf("Generating a prime number of %d octets length for M-R timing test\n", noctets); prime = mpi_alloc(nlimbs); gen_random_prime(noctets, prime); printf("Running timing test for Miller-Rabin with %d repetitions and %d witnesses on prime number ", nruns, M_R_ITERATIONS); mpi_print(stdout, prime, 1); printf("\n"); /* now do the actual runs and time it all */ clock_gettime(CLOCK_MONOTONIC, &tstart); for (i=0; in); pk.e = mpi_copy(sk->e); unsigned char *p; p = xmalloc(noctets); fprintf(file, "TEST encrypt/decrypt on %d octets of random data\n", noctets); fflush(file); if (get_random_octets( noctets, p) == noctets) { mpi_set_buffer( test, p, noctets, 0 ); fprintf(file, "TEST data:\n"); mpi_print(file, test, 1); fprintf(file, "\n"); fflush(file); public_rsa( out1, test, &pk ); secret_rsa( out2, out1, sk ); fprintf(file, "ENCRYPTED with PUBLIC key data:\n"); mpi_print(file, out1, 1); fprintf(file, "\n"); fflush(file); fprintf(file, "DECRYPTED with SECRET key:\n"); mpi_print(file, out2, 1); fprintf(file, "\n"); fflush(file); if( mpi_cmp( test, out2 ) ) fprintf(file, "FAILED: RSA operation: public(secret) failed\n"); else fprintf(file, "PASSED: RSA operation: public(secret) passed\n"); fflush(file); secret_rsa( out1, test, sk ); public_rsa( out2, out1, &pk ); if( mpi_cmp( test, out2 ) ) fprintf(file, "FAILED: RSA operation: secret(public) failed\n"); else fprintf(file, "PASSED: RSA operation: secret(public) passed\n"); } else fprintf(file, "FAILED: not enough bits returned from entropy source\n"); fflush(file); xfree(p); mpi_free( pk.n); mpi_free( pk.e); mpi_free( test ); mpi_free( out1 ); mpi_free( out2 ); } void test_rsa( int nruns, FILE *fkeys, FILE *fout) { RSA_secret_key sk; int noctets = KEY_LENGTH_OCTETS; int noctets_pq = noctets / 2; int nlimbs = mpi_nlimb_hint_from_nbytes(noctets); int nlimbs_pq = mpi_nlimb_hint_from_nbytes(noctets_pq); int i; sk.n = mpi_alloc(nlimbs); sk.e = mpi_alloc(nlimbs); sk.d = mpi_alloc(nlimbs); sk.p = mpi_alloc(nlimbs_pq); sk.q = mpi_alloc(nlimbs_pq); sk.u = mpi_alloc(nlimbs_pq); printf("TEST RSA key generation and use with %d runs\n", nruns); fflush(stdout); for (i = 0;i < nruns; i++) { gen_keypair(&sk); printf("."); fflush(stdout); mpi_print(fkeys, sk.n, 1); fwrite("\n", sizeof(char), 1, fkeys); mpi_print(fkeys, sk.e, 1); fwrite("\n", sizeof(char), 1, fkeys); mpi_print(fkeys, sk.d, 1); fwrite("\n", sizeof(char), 1, fkeys); mpi_print(fkeys, sk.p, 1); fwrite("\n", sizeof(char), 1, fkeys); mpi_print(fkeys, sk.q, 1); fwrite("\n", sizeof(char), 1, fkeys); mpi_print(fkeys, sk.u, 1); fwrite("\n", sizeof(char), 1, fkeys); test_rsa_keys(&sk, noctets_pq, fout); printf("*"); fflush(stdout); } mpi_free(sk.n); mpi_free(sk.e); mpi_free(sk.d); mpi_free(sk.p); mpi_free(sk.q); mpi_free(sk.u); } void test_rsa_8e(int nruns) { RSA_secret_key sk; int noctets = KEY_LENGTH_OCTETS; int noctets_pq = noctets / 2; int nlimbs_pq = mpi_nlimb_hint_from_nbytes(noctets_pq); sk.n = mpi_alloc(0); sk.e = mpi_alloc(0); sk.d = mpi_alloc(0); sk.p = mpi_alloc(0); sk.q = mpi_alloc(0); sk.u = mpi_alloc(0); mpi_fromstr(sk.n, "0x\ B51BE851F39159EAC714F3E0376713A84DAD36A82D446D0A257A391870F45FAE13C4CC\ F400DDA9F604991134C0934161554EEFEAA3147BF0EADC77B99E2B9B6E4EE942EA9D07\ 5F015EE2465B491F4130E04E1BBB6CCDC98F6E8789D4F7FCA3E3FF83C6100CAF2B764E\ A5AF7CBA9B27C13EE72EA7A8602F34B32E17C2BA56CFBA4223F7D9A03C23336095D34F\ BF66E88BF5CE661D66C251DFAD4CB2BA8D1E1669AC927894EA20DABABD2495BC2A4BA3\ A25C79ABEC2D57F45F0F889D962C777A663D0AB25D3650DFDC6D77C528803C0C6E12BD\ 05281B33C603BEA66A0C2ACBEBD1CA53D32C2269294C9B93E742CA563AF39E939C32CE\ 51D5ED827F9C217EF58CC518B635D0E03BA778BCEBAF9A2CDB493282D751A5977CB907\ C8708D1EF1CAE644C1F2525DDE98E29761B1ADF0965F08AA856DF540AEFD67F96B92AE\ 83636C31A507C59635C6D435C5E7EE333DC2257C07BC0FCE27CF400F6EB7A6B90FFF00\ C3C1179615BF5DA6137476926C09D8CCD03257DFCAEF12BE9DC1D3F621D6C97D7F3E6D\ 534337579B4B65AE212ACC26FC3861E24033E6F12A601D473A65EFC5F25ABD5D6049EA\ DD6D76BA60AA218C5EBE13439AAFFF0088C49ACC0E9F7DE56DB03F585E1AC2862EB990\ 59724FD407C4ACD3DD14A53A6A35F6AFAE03EA53A4E742CC370087692E206A2422FF9D"); sk.e = mpi_alloc(nlimbs_pq); int i; char echar[109]; int ne = 109; for (i=0;i0) printf("FAIL: got %d different values!\n", nerrors); else printf("PASSED: mpi_get/set_buffer\n"); } mpi_free(m); xfree(setbuffer); xfree(getbuffer); } void test_dirty_float_rng( int nruns ) { int i, status; float dirty; printf("Running test for smg rng dirty float with %d runs\n", nruns); for (i=0; i0 ? "OK" : "FAIL"); } } void test_ieee_float_rng( int nruns ) { int i, status; float ieee; printf("Running test for smg rng ieee 745/1985 float with %d runs\n", nruns); for (i=0; i0 ? "OK" : "FAIL"); } } void test_uint32_rng( int nruns ) { int i, status; uint32_t n; printf("Running test for smg rng unsigned int32 with %d runs\n", nruns); for (i=0; i0 ? "OK" : "FAIL"); } } void test_uint64_rng( int nruns ) { int i, status; uint64_t n; printf("Running test for smg rng unsigned int64 with %d runs\n", nruns); for (i=0; i0 ? "OK" : "FAIL"); } } int main(int ac, char **av) { int nruns; int id; FILE *fk; FILE *fout; if (ac<2) { printf("Usage: %s number_of_runs/octets [testID]\n", av[0]); return -1; } nruns = atoi(av[1]); if (ac < 3) id = -1; else id = atoi(av[2]); switch ( id ) { case 0: printf("Timing entropy source...\n"); time_entropy_source(nruns, 4096); break; case 1: test_entropy_output(nruns, "entropy_source_output.txt"); break; case 2: /* tests on miller-rabin */ /* a few primes (decimal): 65537, 116447, 411949103, 20943302231 */ test_is_composite(nruns, "0x10001", 0); test_is_composite(nruns, "0x1C6DF", 0); test_is_composite(nruns, "0x188DD82F", 0); test_is_composite(nruns, "0x4E0516E57", 0); /* a few mersenne primes (decimal): 2^13 - 1 = 8191, 2^17 - 1 = 131071, 2^31 - 1 = 2147483647 */ test_is_composite(nruns, "0x1FFF", 0); test_is_composite(nruns, "0x1FFFF", 0); test_is_composite(nruns, "0x7FFFFFFF", 0); /* a few carmichael numbers, in decimal: 561, 60977817398996785 */ test_is_composite(nruns, "0x231", 1); test_is_composite(nruns, "0xD8A300793EEF31", 1); /* an even number */ test_is_composite(nruns, "0x15A9E672864B1E", 1); /* a phuctor-found non-prime public exponent: 170141183460469231731687303715884105731 */ test_is_composite(nruns, "0x80000000000000000000000000000003", 1); break; case 3: time_mr(nruns); break; case 4: test_rpng(nruns); break; case 5: time_rpng(nruns); break; case 6: fk = fopen("keys.asc", "a"); if ( fk == NULL ) err("Failed to open file keys.asc!"); fout = fopen("check_keys.asc", "a"); if ( fout == NULL ) { fclose(fk); err("Failed to open file keys_check.asc!"); } test_rsa(nruns, fk, fout); fclose(fk); fclose(fout); break; case 7: test_rsa_exp(); break; case 8: time_rsa_gen(nruns); break; case 9: test_mpi_buffer(); break; case 10: test_dirty_float_rng(nruns); break; case 11: test_ieee_float_rng(nruns); break; case 12: test_uint32_rng(nruns); break; case 13: test_uint64_rng(nruns); break; case 14: test_rsa_8e(nruns); break; default: printf("Current test ids:\n"); printf("0 for timing entropy source\n"); printf("1 for entropy output test\n"); printf("2 for is_composite (Miller-Rabin) test\n"); printf("3 for timing Miller-Rabin\n"); printf("4 for random prime number generator test\n"); printf("5 for timing random prime number generator\n"); printf("6 for testing rsa key pair generation and use; \ writes to keys.asc and check_keys.asc\n"); printf("7 for testing rsa exponentiation (fixed data)\n"); printf("8 for timing rsa key pair generator\n"); printf("9 for testing mpi_set/get_buffer\n"); printf("10 for testing smg_rng dirty float\n"); printf("11 for testing smg_rng ieee 745/1985 float\n"); printf("12 for testing smg_rng uint32 \n"); printf("13 for testing smg_rng uint64 \n"); printf("14 for testing rsa with 8-octets e \n"); } return 0; }