tree checksum vpatch file split hunks
all signers: diana_coman
antecedents: eucrypt_ch3_miller_rabin ch1_mpi
press order:
eucrypt_genesis | diana_coman |
ch1_mpi | diana_coman |
eucrypt_mpi_fix_copy_incr | diana_coman |
ch2_truerandom | diana_coman |
eucrypt_ch3_miller_rabin | diana_coman |
eucrypt_ch4_rpng | diana_coman |
patch:
(1 . 5)(1 . 6)- 4F010F44B2944A2995791C5A74D41BC1FFBE017C6BCBCEFA0655DD33C72CFC6AA547B7BCEDA6705C629AB707BBD2F260023EFAE997DD1EC53FD016D22FE1D5F5
5 /* mpi.h - Multi Precision Integers
6 * Modified by No Such Labs. (C) 2015. See README.
7 * Modified by S.MG, 2018. Added mpi_get_alloced, function for retrieving currently allocated number of limbs.
8 *
9 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
10 * SHA256(gnupg-1.4.10.tar.gz):
(75 . 6)(76 . 7)
12 void mpi_m_check( MPI a );
13 void mpi_swap( MPI a, MPI b);
14 int mpi_get_nlimbs (MPI a);
15 int mpi_get_alloced (MPI a); /* returns the allocated memory space for this MPI, in number of limbs */
16 int mpi_is_neg (MPI a);
17 unsigned int mpi_nlimb_hint_from_nbytes (unsigned int nbytes);
18 unsigned int mpi_nlimb_hint_from_nbits (unsigned int nbits);
(1 . 5)(1 . 6)- 69ED0DE509C413D6E911966E2E60DE118D6D8DB4516AC444FEC119C08576153246DA0F6AA27DDFCFE3398290A93E000C4A4B6F296B452ED3DDFE406660247708
23 /* mpiutil.ac - Utility functions for MPI
24 * Modified by No Such Labs. (C) 2015. See README.
25 * Modified by S.MG, 2018. Added mpi_get_alloced(MPI a)
26 *
27 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
28 * SHA256(gnupg-1.4.10.tar.gz):
(477 . 6)(478 . 14)
30 return a->nlimbs;
31 }
32
33 /*
34 * Returns the allocated space for the given MPI, as number of limbs.
35 */
36 int
37 mpi_get_alloced (MPI a)
38 {
39 return a->alloced;
40 }
41
42 int
43 mpi_is_neg (MPI a)
(8 . 6)(8 . 13)- D5A314BAA0F6D77B60210629541A02F8DD8923A03D0003A2005E46DCAC8022780577CF2D584BB869FD241A367153854838FBE88B46380914EDB6F35946B457DD
48 #include "mpi.h"
49 #include "knobs.h"
50
51 /*
52 * These are constants as per TMSR RSA specification, NOT knobs!
53 * TMSR key length is 4096 bits (512 octets); this means 2 primes of 2048 bits (256 octets) each.
54 * NB: if you choose here an odd key length in octets you might end up with a smaller actual key, read the code.
55 */
56 static const int KEY_LENGTH_OCTETS = 512;
57
58 /*********truerandom.c*********/
59
60 /*
(63 . 6)(70 . 22)
62 */
63 int is_composite( MPI n, int nwitnesses, int entropy_source);
64
65 /**
66 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
67 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 110....01 is applied to the random bits)
68 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
69 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
70 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
71 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
72 * Preconditions:
73 * noctets > 0 (at least one octet!)
74 * output has known allocated memory for at least nlimbs(noctets)
75 * successful access to the entropy source
76 * @param noctets the length of the desired prime number, in octets
77 * @param output an MPI with sufficient memory allocated for a number that is noctets long
78 */
79 void gen_random_prime( unsigned int noctets, MPI output);
80
81
82 #endif /*SMG_RSA*/
83
(103 . 3)(103 . 47)
88
89 return evidence;
90 }
91
92 /**
93 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
94 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 11.....1 is applied)
95 * a prime of 8*noctets long will have only 8*noctets-3 bits that are randomly chosen
96 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
97 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
98 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
99 * Preconditions:
100 * noctets > 0 (at least one octet!)
101 * memory allocated for noctets in output MPI
102 * successful access to the entropy source
103 */
104 void gen_random_prime( unsigned int noctets, MPI output )
105 {
106 /* precondition: at least one octet long */
107 assert(noctets > 0);
108
109 /* precondition: enough memory allocated for the limbs corresponding to noctets */
110 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
111 assert(mpi_get_alloced(output) >= nlimbs);
112
113 /* precondition: access to the entropy source */
114 int entropy_source = open_entropy_source(ENTROPY_SOURCE); /* source of random bits */
115 assert(entropy_source >= 0);
116
117 unsigned int nbits = 8*noctets; /* length of MPI in bits */
118
119 /*
120 * loop until a prime is found: get noctets of random bits, trim and apply 110...01 mask, check if prime
121 */
122 unsigned char *p = xmalloc( noctets );
123 do {
124 get_random_octets_from( noctets, p, entropy_source );
125 mpi_set_buffer( output, p, noctets, 0); /* convert to MPI representation */
126 mpi_set_highbit( output, nbits - 1 ); /* trim at required size and set top bit */
127 mpi_set_bit( output, nbits - 2); /* set second top bit */
128 mpi_set_bit( output, 0 ); /* set bottom bit to unsure odd number */
129 } while (is_composite(output, M_R_ITERATIONS, entropy_source));
130
131 /* tidy up, a prime was found */
132 xfree(p);
133 close(entropy_source);
134 }
- 0EB9FD7240D16B287C06A319D1D170AEA9AA046B4F443FF1339F509D8E7B42317425FD369CEDB6E7E3D898700BA917B0B56A83305D730A5CD7D5BD09F4809986(4 . 6)(4 . 7)- 72A4C1F55A1EF9D853F44A93F1F5396E63739DC4C1C70017DD3F3D2EA6C7E1B843CE0CA60E5D06DDCC742ECDE6F17CDABDDBE833F83AD7BEA2CEBC40B80E332A
139 #include <stdlib.h>
140 #include <unistd.h>
141 #include <time.h>
142 #include <stdio.h>
143
144 void err(char *msg)
145 {
(30 . 6)(31 . 43)
147 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);
148 }
149
150 void test_entropy_output(unsigned int noctets, char * filename) {
151 FILE * out;
152 int source;
153 unsigned int nread, total_read, to_read;
154 const int buffer_length = 1000;
155 unsigned char buffer[buffer_length];
156
157 source = open_entropy_source(ENTROPY_SOURCE);
158 if (source <= 0)
159 err("unable to access entropy source!");
160
161 out = fopen(filename, "wb");
162 if ( !out )
163 err("unable to open output file for test_entropy_output!");
164
165 printf("TEST_ENTROPY_SOURCE: reading %u octets from %s ", noctets, ENTROPY_SOURCE);
166 total_read = 0;
167 while (total_read < noctets) {
168 to_read = noctets - total_read;
169 if (to_read > buffer_length)
170 to_read = buffer_length;
171
172 nread = get_random_octets_from(to_read, buffer, source);
173 if (nread > 0) {
174 total_read = total_read + nread;
175 fwrite(buffer, 1, nread, out);
176 fflush(out);
177 printf(".");
178 fflush(stdout);
179 }
180 }
181 printf("done.\n");
182
183 fclose(out);
184 close(source);
185 }
186
187 void test_is_composite(int nruns, char *hex_number, int expected) {
188 int i;
189 int output;
(52 . 49)(90 . 161)
191 close(source);
192 }
193
194 void time_mr(int nruns) {
195 struct timespec tstart, tend;
196 long int diff;
197 int i;
198 MPI prime;
199 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
200 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
201
202 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
203 if (entropy_source <= 0)
204 err("can't open entropy source!");
205
206 /* first generate a prime of half key length, to make sure M-R will run max number of iterations */
207 printf("Generating a prime number of %d octets length for M-R timing test\n", noctets);
208 prime = mpi_alloc(nlimbs);
209 gen_random_prime(noctets, prime);
210
211 printf("Running timing test for Miller-Rabin with %d repetitions and %d witnesses on prime number ", nruns, M_R_ITERATIONS);
212 mpi_print(stdout, prime, 1);
213 printf("\n");
214 /* now do the actual runs and time it all */
215 clock_gettime(CLOCK_MONOTONIC, &tstart);
216 for (i=0; i<nruns; i++) {
217 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
218 printf("FAIL");
219 else printf(".");
220 fflush(stdout);
221 }
222 clock_gettime(CLOCK_MONOTONIC, &tend);
223
224 diff = tend.tv_sec-tstart.tv_sec;
225 printf("\nTimings on prime number %d octets long, %d runs of MR with %d iterations (witnesses checked) each\n", \
226 noctets, nruns, M_R_ITERATIONS);
227 printf("Total time: %ld seconds\nTime per MR run: %f seconds\nTime per MR iteration: %f seconds\n",\
228 diff, diff / (1.0*nruns), diff / (1.0*nruns * M_R_ITERATIONS));
229
230 mpi_free(prime);
231 close(entropy_source);
232 }
233
234 void test_rpng(int nruns) {
235 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
236 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
237 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
238 if (entropy_source <= 0)
239 err("can't open entropy source!");
240
241 MPI prime = mpi_alloc(nlimbs);
242 int i;
243
244 printf("TEST: random prime number generator with %d runs\n", nruns);
245 for (i = 0;i < nruns; i++) {
246 gen_random_prime(noctets, prime);
247 printf("Run %d: ", i+1);
248 mpi_print(stdout, prime, 1);
249 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
250 printf(" **FAIL**\n");
251 else
252 printf(" **PASS**\n");
253 }
254
255 mpi_free(prime);
256 close(entropy_source);
257 }
258
259 void time_rpng(int nruns) {
260 struct timespec tstart, tend;
261 long int diff;
262
263 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
264 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
265
266 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
267 if (entropy_source <= 0)
268 err("can't open entropy source!");
269
270 MPI prime = mpi_alloc(nlimbs);
271 int i;
272
273 printf("TIMING: random prime number generator with %d runs\n", nruns);
274 clock_gettime(CLOCK_MONOTONIC, &tstart);
275 for (i = 0;i < nruns; i++) {
276 gen_random_prime(noctets, prime);
277 }
278 clock_gettime(CLOCK_MONOTONIC, &tend);
279
280 diff = tend.tv_sec-tstart.tv_sec;
281
282 printf("TOTAL: %ld seconds\n", diff);
283 printf("Average: %f seconds to generate one random prime of %d octets length\n", diff / (1.0*nruns), noctets);
284 mpi_free(prime);
285 close(entropy_source);
286 }
287
288 int main(int ac, char **av)
289 {
290 int nruns;
291 int id;
292
293 if (ac<2) {
294 printf("Usage: %s number_of_runs [testID]\n", av[0]);
295 printf("Usage: %s number_of_runs/octets [testID]\n", av[0]);
296 return -1;
297 }
298 nruns = atoi(av[1]);
299
300 if (ac < 3)
301 id = 0;
302 id = -1;
303 else
304 id = atoi(av[2]);
305
306 if (id == 0 || id == 1) {
307 printf("Timing entropy source...\n");
308 time_entropy_source(nruns,4096);
309 }
310
311 if (id == 0 || id == 2) {
312
313 /* a few primes (decimal): 65537, 116447, 411949103, 20943302231 */
314 test_is_composite(nruns, "0x10001", 0);
315 test_is_composite(nruns, "0x1C6DF", 0);
316 test_is_composite(nruns, "0x188DD82F", 0);
317 test_is_composite(nruns, "0x4E0516E57", 0);
318 /* a few mersenne primes (decimal): 2^13 - 1 = 8191, 2^17 - 1 = 131071, 2^31 - 1 = 2147483647 */
319 test_is_composite(nruns, "0x1FFF", 0);
320 test_is_composite(nruns, "0x1FFFF", 0);
321 test_is_composite(nruns, "0x7FFFFFFF", 0);
322 /* a few carmichael numbers, in decimal: 561, 60977817398996785 */
323 test_is_composite(nruns, "0x231", 1);
324 test_is_composite(nruns, "0xD8A300793EEF31", 1);
325 /* an even number */
326 test_is_composite(nruns, "0x15A9E672864B1E", 1);
327 /* a phuctor-found non-prime public exponent: 170141183460469231731687303715884105731 */
328 test_is_composite(nruns, "0x80000000000000000000000000000003", 1);
329 switch ( id ) {
330 case 0:
331 printf("Timing entropy source...\n");
332 time_entropy_source(nruns, 4096);
333 break;
334 case 1:
335 test_entropy_output(nruns, "entropy_source_output.txt");
336 break;
337 case 2:
338 /* tests on miller-rabin */
339 /* a few primes (decimal): 65537, 116447, 411949103, 20943302231 */
340 test_is_composite(nruns, "0x10001", 0);
341 test_is_composite(nruns, "0x1C6DF", 0);
342 test_is_composite(nruns, "0x188DD82F", 0);
343 test_is_composite(nruns, "0x4E0516E57", 0);
344 /* a few mersenne primes (decimal): 2^13 - 1 = 8191, 2^17 - 1 = 131071, 2^31 - 1 = 2147483647 */
345 test_is_composite(nruns, "0x1FFF", 0);
346 test_is_composite(nruns, "0x1FFFF", 0);
347 test_is_composite(nruns, "0x7FFFFFFF", 0);
348 /* a few carmichael numbers, in decimal: 561, 60977817398996785 */
349 test_is_composite(nruns, "0x231", 1);
350 test_is_composite(nruns, "0xD8A300793EEF31", 1);
351 /* an even number */
352 test_is_composite(nruns, "0x15A9E672864B1E", 1);
353 /* a phuctor-found non-prime public exponent: 170141183460469231731687303715884105731 */
354 test_is_composite(nruns, "0x80000000000000000000000000000003", 1);
355 break;
356 case 3:
357 time_mr(nruns);
358 break;
359 case 4:
360 test_rpng(nruns);
361 break;
362 case 5:
363 time_rpng(nruns);
364 break;
365 default:
366 printf("Current test ids:\n");
367 printf("0 for timing entropy source\n");
368 printf("1 for entropy output test\n");
369 printf("2 for is_composite (Miller-Rabin) test\n");
370 printf("3 for timing Miller-Rabin\n");
371 printf("4 for random prime number generator test\n");
372 printf("5 for timing random prime number generator\n");
373 }
374
375 if (id > 2)
376 printf("Current test ids: 0 for all, 1 for entropy source test only, 2 for is_composite test only.");
377
378 return 0;
379 }
(16 . 27)(16 . 19)
384 return -1;
385 }
386
387 //input and output speeds
388 /* input and output speeds */
389 cfsetospeed(&tty, (speed_t)speed);
390 cfsetispeed(&tty, (speed_t)speed);
391
392 tty.c_cflag |= (CLOCAL | CREAD); //ignore modem controls
393 tty.c_cflag &= ~CSIZE;
394 tty.c_cflag |= CS8; //8 bit characters
395 tty.c_cflag &= ~PARENB; //no parity bit
396 tty.c_cflag &= ~CSTOPB; //only need 1 stop bit
397 tty.c_cflag &= ~CRTSCTS; //no hardware flow control
398 /* raw */
399 tty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
400 tty.c_oflag &= ~OPOST;
401
402 //non-canonical mode
403 tty.c_cflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
404 tty.c_cflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
405 tty.c_cflag &= ~OPOST;
406
407 //read at least one octet at a time; timeout 1 tenth of second between octets read
408 /* read at least one octet at a time; BLOCK until at least VMIN octets read */
409 tty.c_cc[VMIN] = 1;
410 tty.c_cc[VTIME] = 1;
411 tty.c_cc[VTIME] = 0;
412
413 if (tcsetattr(fd, TCSANOW, &tty) != 0)
414 if (tcsetattr(fd, TCSAFLUSH, &tty) != 0)
415 return -1;
416
417 return 0;