raw
ch2_truerandom          1 #include "smg_rsa.h"
eucrypt_ch3_mille... 2 #include "mpi.h"
ch2_truerandom 3
ch2_truerandom 4 #include <stdlib.h>
eucrypt_ch3_mille... 5 #include <unistd.h>
ch2_truerandom 6 #include <time.h>
eucrypt_ch4_rpng 7 #include <stdio.h>
ch2_truerandom 8
ch2_truerandom 9 void err(char *msg)
ch2_truerandom 10 {
ch2_truerandom 11 fprintf(stderr, "%s\n", msg);
ch2_truerandom 12 exit(1);
ch2_truerandom 13 }
ch2_truerandom 14
ch2_truerandom 15 void time_entropy_source(int nruns, int noctets) {
ch2_truerandom 16 unsigned char buffer[noctets];
ch2_truerandom 17 int read, i;
ch2_truerandom 18 struct timespec tstart, tend;
ch2_truerandom 19 long int diff;
ch2_truerandom 20
ch2_truerandom 21 clock_gettime(CLOCK_MONOTONIC, &tstart);
ch2_truerandom 22 for (i=0; i<nruns; i++) {
ch2_truerandom 23 read = get_random_octets(noctets,buffer);
ch2_truerandom 24 if (read != noctets)
ch2_truerandom 25 err("Failed reading from entropy source!");
ch2_truerandom 26 }
ch2_truerandom 27 clock_gettime(CLOCK_MONOTONIC, &tend);
ch2_truerandom 28
ch2_truerandom 29 diff = tend.tv_sec-tstart.tv_sec;
ch2_truerandom 30 double kbps = (nruns*noctets) / (diff*1000.0);
ch2_truerandom 31 printf("ENTROPY source timing: %d kB in %ld seconds, at an average speed of %f kB/s over %d runs of %d octets each\n", nruns*noctets, diff, kbps, nruns, noctets);
ch2_truerandom 32 }
ch2_truerandom 33
eucrypt_ch4_rpng 34 void test_entropy_output(unsigned int noctets, char * filename) {
eucrypt_ch4_rpng 35 FILE * out;
eucrypt_ch4_rpng 36 int source;
eucrypt_ch4_rpng 37 unsigned int nread, total_read, to_read;
eucrypt_ch4_rpng 38 const int buffer_length = 1000;
eucrypt_ch4_rpng 39 unsigned char buffer[buffer_length];
eucrypt_ch4_rpng 40
eucrypt_ch4_rpng 41 source = open_entropy_source(ENTROPY_SOURCE);
eucrypt_ch4_rpng 42 if (source <= 0)
eucrypt_ch4_rpng 43 err("unable to access entropy source!");
eucrypt_ch4_rpng 44
eucrypt_ch4_rpng 45 out = fopen(filename, "wb");
eucrypt_ch4_rpng 46 if ( !out )
eucrypt_ch4_rpng 47 err("unable to open output file for test_entropy_output!");
eucrypt_ch4_rpng 48
eucrypt_ch4_rpng 49 printf("TEST_ENTROPY_SOURCE: reading %u octets from %s ", noctets, ENTROPY_SOURCE);
eucrypt_ch4_rpng 50 total_read = 0;
eucrypt_ch4_rpng 51 while (total_read < noctets) {
eucrypt_ch4_rpng 52 to_read = noctets - total_read;
eucrypt_ch4_rpng 53 if (to_read > buffer_length)
eucrypt_ch4_rpng 54 to_read = buffer_length;
eucrypt_ch4_rpng 55
eucrypt_ch4_rpng 56 nread = get_random_octets_from(to_read, buffer, source);
eucrypt_ch4_rpng 57 if (nread > 0) {
eucrypt_ch4_rpng 58 total_read = total_read + nread;
eucrypt_ch4_rpng 59 fwrite(buffer, 1, nread, out);
eucrypt_ch4_rpng 60 fflush(out);
eucrypt_ch4_rpng 61 printf(".");
eucrypt_ch4_rpng 62 fflush(stdout);
eucrypt_ch4_rpng 63 }
eucrypt_ch4_rpng 64 }
eucrypt_ch4_rpng 65 printf("done.\n");
eucrypt_ch4_rpng 66
eucrypt_ch4_rpng 67 fclose(out);
eucrypt_ch4_rpng 68 close(source);
eucrypt_ch4_rpng 69 }
eucrypt_ch4_rpng 70
eucrypt_ch3_mille... 71 void test_is_composite(int nruns, char *hex_number, int expected) {
eucrypt_ch3_mille... 72 int i;
eucrypt_ch3_mille... 73 int output;
eucrypt_ch3_mille... 74 int count_ok = 0;
eucrypt_ch3_mille... 75 int source = open_entropy_source(ENTROPY_SOURCE);
eucrypt_ch3_mille... 76 MPI p = mpi_alloc(0);
eucrypt_ch3_mille... 77
eucrypt_ch3_mille... 78 mpi_fromstr(p, hex_number);
eucrypt_ch3_mille... 79 printf("TEST is_composite on MPI(hex) ");
eucrypt_ch3_mille... 80 mpi_print(stdout, p, 1);
eucrypt_ch3_mille... 81 for (i=0; i < nruns; i++) {
eucrypt_ch3_mille... 82 printf(".");
eucrypt_ch3_mille... 83 fflush(stdout);
eucrypt_ch3_mille... 84 output = is_composite(p, M_R_ITERATIONS, source);
eucrypt_ch3_mille... 85 if (output == expected)
eucrypt_ch3_mille... 86 count_ok = count_ok + 1;
eucrypt_ch3_mille... 87 }
eucrypt_ch3_mille... 88 printf("done, with %d out of %d correct runs for expected=%d: %s\n", count_ok, nruns, expected, count_ok==nruns? "PASS":"FAIL");
eucrypt_ch3_mille... 89 mpi_free(p);
eucrypt_ch3_mille... 90 close(source);
eucrypt_ch3_mille... 91 }
ch2_truerandom 92
eucrypt_ch4_rpng 93 void time_mr(int nruns) {
eucrypt_ch4_rpng 94 struct timespec tstart, tend;
eucrypt_ch4_rpng 95 long int diff;
eucrypt_ch4_rpng 96 int i;
eucrypt_ch4_rpng 97 MPI prime;
eucrypt_ch4_rpng 98 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
eucrypt_ch4_rpng 99 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
eucrypt_ch4_rpng 100
eucrypt_ch4_rpng 101 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
eucrypt_ch4_rpng 102 if (entropy_source <= 0)
eucrypt_ch4_rpng 103 err("can't open entropy source!");
eucrypt_ch4_rpng 104
eucrypt_ch4_rpng 105 /* first generate a prime of half key length, to make sure M-R will run max number of iterations */
eucrypt_ch4_rpng 106 printf("Generating a prime number of %d octets length for M-R timing test\n", noctets);
eucrypt_ch4_rpng 107 prime = mpi_alloc(nlimbs);
eucrypt_ch4_rpng 108 gen_random_prime(noctets, prime);
eucrypt_ch4_rpng 109
eucrypt_ch4_rpng 110 printf("Running timing test for Miller-Rabin with %d repetitions and %d witnesses on prime number ", nruns, M_R_ITERATIONS);
eucrypt_ch4_rpng 111 mpi_print(stdout, prime, 1);
eucrypt_ch4_rpng 112 printf("\n");
eucrypt_ch4_rpng 113 /* now do the actual runs and time it all */
eucrypt_ch4_rpng 114 clock_gettime(CLOCK_MONOTONIC, &tstart);
eucrypt_ch4_rpng 115 for (i=0; i<nruns; i++) {
eucrypt_ch4_rpng 116 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
eucrypt_ch4_rpng 117 printf("FAIL");
eucrypt_ch4_rpng 118 else printf(".");
eucrypt_ch4_rpng 119 fflush(stdout);
eucrypt_ch4_rpng 120 }
eucrypt_ch4_rpng 121 clock_gettime(CLOCK_MONOTONIC, &tend);
eucrypt_ch4_rpng 122
eucrypt_ch4_rpng 123 diff = tend.tv_sec-tstart.tv_sec;
eucrypt_ch4_rpng 124 printf("\nTimings on prime number %d octets long, %d runs of MR with %d iterations (witnesses checked) each\n", \
eucrypt_ch4_rpng 125 noctets, nruns, M_R_ITERATIONS);
eucrypt_ch4_rpng 126 printf("Total time: %ld seconds\nTime per MR run: %f seconds\nTime per MR iteration: %f seconds\n",\
eucrypt_ch4_rpng 127 diff, diff / (1.0*nruns), diff / (1.0*nruns * M_R_ITERATIONS));
eucrypt_ch4_rpng 128
eucrypt_ch4_rpng 129 mpi_free(prime);
eucrypt_ch4_rpng 130 close(entropy_source);
eucrypt_ch4_rpng 131 }
eucrypt_ch4_rpng 132
eucrypt_ch4_rpng 133 void test_rpng(int nruns) {
eucrypt_ch4_rpng 134 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
eucrypt_ch4_rpng 135 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
eucrypt_ch4_rpng 136 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
eucrypt_ch4_rpng 137 if (entropy_source <= 0)
eucrypt_ch4_rpng 138 err("can't open entropy source!");
eucrypt_ch4_rpng 139
eucrypt_ch4_rpng 140 MPI prime = mpi_alloc(nlimbs);
eucrypt_ch4_rpng 141 int i;
eucrypt_ch4_rpng 142
eucrypt_ch4_rpng 143 printf("TEST: random prime number generator with %d runs\n", nruns);
eucrypt_ch4_rpng 144 for (i = 0;i < nruns; i++) {
eucrypt_ch4_rpng 145 gen_random_prime(noctets, prime);
eucrypt_ch4_rpng 146 printf("Run %d: ", i+1);
eucrypt_ch4_rpng 147 mpi_print(stdout, prime, 1);
eucrypt_ch4_rpng 148 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
eucrypt_ch4_rpng 149 printf(" **FAIL**\n");
eucrypt_ch4_rpng 150 else
eucrypt_ch4_rpng 151 printf(" **PASS**\n");
eucrypt_ch4_rpng 152 }
eucrypt_ch4_rpng 153
eucrypt_ch4_rpng 154 mpi_free(prime);
eucrypt_ch4_rpng 155 close(entropy_source);
eucrypt_ch4_rpng 156 }
eucrypt_ch4_rpng 157
eucrypt_ch4_rpng 158 void time_rpng(int nruns) {
eucrypt_ch4_rpng 159 struct timespec tstart, tend;
eucrypt_ch4_rpng 160 long int diff;
eucrypt_ch4_rpng 161
eucrypt_ch4_rpng 162 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
eucrypt_ch4_rpng 163 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
eucrypt_ch4_rpng 164
eucrypt_ch4_rpng 165 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
eucrypt_ch4_rpng 166 if (entropy_source <= 0)
eucrypt_ch4_rpng 167 err("can't open entropy source!");
eucrypt_ch4_rpng 168
eucrypt_ch4_rpng 169 MPI prime = mpi_alloc(nlimbs);
eucrypt_ch4_rpng 170 int i;
eucrypt_ch4_rpng 171
eucrypt_ch4_rpng 172 printf("TIMING: random prime number generator with %d runs\n", nruns);
eucrypt_ch4_rpng 173 clock_gettime(CLOCK_MONOTONIC, &tstart);
eucrypt_ch4_rpng 174 for (i = 0;i < nruns; i++) {
eucrypt_ch4_rpng 175 gen_random_prime(noctets, prime);
eucrypt_ch4_rpng 176 }
eucrypt_ch4_rpng 177 clock_gettime(CLOCK_MONOTONIC, &tend);
eucrypt_ch4_rpng 178
eucrypt_ch4_rpng 179 diff = tend.tv_sec-tstart.tv_sec;
eucrypt_ch4_rpng 180
eucrypt_ch4_rpng 181 printf("TOTAL: %ld seconds\n", diff);
eucrypt_ch4_rpng 182 printf("Average: %f seconds to generate one random prime of %d octets length\n", diff / (1.0*nruns), noctets);
eucrypt_ch4_rpng 183 mpi_free(prime);
eucrypt_ch4_rpng 184 close(entropy_source);
eucrypt_ch4_rpng 185 }
eucrypt_ch4_rpng 186
ch2_truerandom 187 int main(int ac, char **av)
ch2_truerandom 188 {
ch2_truerandom 189 int nruns;
eucrypt_ch3_mille... 190 int id;
ch2_truerandom 191
ch2_truerandom 192 if (ac<2) {
eucrypt_ch4_rpng 193 printf("Usage: %s number_of_runs/octets [testID]\n", av[0]);
ch2_truerandom 194 return -1;
ch2_truerandom 195 }
ch2_truerandom 196 nruns = atoi(av[1]);
ch2_truerandom 197
eucrypt_ch3_mille... 198 if (ac < 3)
eucrypt_ch4_rpng 199 id = -1;
eucrypt_ch3_mille... 200 else
eucrypt_ch3_mille... 201 id = atoi(av[2]);
eucrypt_ch3_mille... 202
eucrypt_ch4_rpng 203 switch ( id ) {
eucrypt_ch4_rpng 204 case 0:
eucrypt_ch4_rpng 205 printf("Timing entropy source...\n");
eucrypt_ch4_rpng 206 time_entropy_source(nruns, 4096);
eucrypt_ch4_rpng 207 break;
eucrypt_ch4_rpng 208 case 1:
eucrypt_ch4_rpng 209 test_entropy_output(nruns, "entropy_source_output.txt");
eucrypt_ch4_rpng 210 break;
eucrypt_ch4_rpng 211 case 2:
eucrypt_ch4_rpng 212 /* tests on miller-rabin */
eucrypt_ch4_rpng 213 /* a few primes (decimal): 65537, 116447, 411949103, 20943302231 */
eucrypt_ch4_rpng 214 test_is_composite(nruns, "0x10001", 0);
eucrypt_ch4_rpng 215 test_is_composite(nruns, "0x1C6DF", 0);
eucrypt_ch4_rpng 216 test_is_composite(nruns, "0x188DD82F", 0);
eucrypt_ch4_rpng 217 test_is_composite(nruns, "0x4E0516E57", 0);
eucrypt_ch4_rpng 218 /* a few mersenne primes (decimal): 2^13 - 1 = 8191, 2^17 - 1 = 131071, 2^31 - 1 = 2147483647 */
eucrypt_ch4_rpng 219 test_is_composite(nruns, "0x1FFF", 0);
eucrypt_ch4_rpng 220 test_is_composite(nruns, "0x1FFFF", 0);
eucrypt_ch4_rpng 221 test_is_composite(nruns, "0x7FFFFFFF", 0);
eucrypt_ch4_rpng 222 /* a few carmichael numbers, in decimal: 561, 60977817398996785 */
eucrypt_ch4_rpng 223 test_is_composite(nruns, "0x231", 1);
eucrypt_ch4_rpng 224 test_is_composite(nruns, "0xD8A300793EEF31", 1);
eucrypt_ch4_rpng 225 /* an even number */
eucrypt_ch4_rpng 226 test_is_composite(nruns, "0x15A9E672864B1E", 1);
eucrypt_ch4_rpng 227 /* a phuctor-found non-prime public exponent: 170141183460469231731687303715884105731 */
eucrypt_ch4_rpng 228 test_is_composite(nruns, "0x80000000000000000000000000000003", 1);
eucrypt_ch4_rpng 229 break;
eucrypt_ch4_rpng 230 case 3:
eucrypt_ch4_rpng 231 time_mr(nruns);
eucrypt_ch4_rpng 232 break;
eucrypt_ch4_rpng 233 case 4:
eucrypt_ch4_rpng 234 test_rpng(nruns);
eucrypt_ch4_rpng 235 break;
eucrypt_ch4_rpng 236 case 5:
eucrypt_ch4_rpng 237 time_rpng(nruns);
eucrypt_ch4_rpng 238 break;
eucrypt_ch4_rpng 239 default:
eucrypt_ch4_rpng 240 printf("Current test ids:\n");
eucrypt_ch4_rpng 241 printf("0 for timing entropy source\n");
eucrypt_ch4_rpng 242 printf("1 for entropy output test\n");
eucrypt_ch4_rpng 243 printf("2 for is_composite (Miller-Rabin) test\n");
eucrypt_ch4_rpng 244 printf("3 for timing Miller-Rabin\n");
eucrypt_ch4_rpng 245 printf("4 for random prime number generator test\n");
eucrypt_ch4_rpng 246 printf("5 for timing random prime number generator\n");
eucrypt_ch3_mille... 247 }
eucrypt_ch3_mille... 248
ch2_truerandom 249 return 0;
ch2_truerandom 250 }