diff options
Diffstat (limited to 'moduli.c')
-rw-r--r-- | moduli.c | 69 |
1 files changed, 66 insertions, 3 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */ | 1 | /* $OpenBSD: moduli.c,v 1.23 2011/10/16 11:02:46 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 1994 Phil Karn <karn@qualcomm.com> | 3 | * Copyright 1994 Phil Karn <karn@qualcomm.com> |
4 | * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> | 4 | * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> |
@@ -49,6 +49,7 @@ | |||
49 | #include <string.h> | 49 | #include <string.h> |
50 | #include <stdarg.h> | 50 | #include <stdarg.h> |
51 | #include <time.h> | 51 | #include <time.h> |
52 | #include <unistd.h> | ||
52 | 53 | ||
53 | #include "xmalloc.h" | 54 | #include "xmalloc.h" |
54 | #include "dh.h" | 55 | #include "dh.h" |
@@ -137,7 +138,7 @@ static u_int32_t largebits, largememory; /* megabytes */ | |||
137 | static BIGNUM *largebase; | 138 | static BIGNUM *largebase; |
138 | 139 | ||
139 | int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); | 140 | int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); |
140 | int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); | 141 | int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *); |
141 | 142 | ||
142 | /* | 143 | /* |
143 | * print moduli out in consistent form, | 144 | * print moduli out in consistent form, |
@@ -438,6 +439,52 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) | |||
438 | return (ret); | 439 | return (ret); |
439 | } | 440 | } |
440 | 441 | ||
442 | static void | ||
443 | write_checkpoint(char *cpfile, u_int32_t lineno) | ||
444 | { | ||
445 | FILE *fp; | ||
446 | char tmpfile[MAXPATHLEN]; | ||
447 | int r; | ||
448 | |||
449 | r = snprintf(tmpfile, sizeof(tmpfile), "%s.XXXXXXXXXX", cpfile); | ||
450 | if (r == -1 || r >= MAXPATHLEN) { | ||
451 | logit("write_checkpoint: temp pathname too long"); | ||
452 | return; | ||
453 | } | ||
454 | if ((r = mkstemp(tmpfile)) == -1) { | ||
455 | logit("mkstemp(%s): %s", tmpfile, strerror(errno)); | ||
456 | return; | ||
457 | } | ||
458 | if ((fp = fdopen(r, "w")) == NULL) { | ||
459 | logit("write_checkpoint: fdopen: %s", strerror(errno)); | ||
460 | close(r); | ||
461 | return; | ||
462 | } | ||
463 | if (fprintf(fp, "%lu\n", (unsigned long)lineno) > 0 && fclose(fp) == 0 | ||
464 | && rename(tmpfile, cpfile) == 0) | ||
465 | debug3("wrote checkpoint line %lu to '%s'", | ||
466 | (unsigned long)lineno, cpfile); | ||
467 | else | ||
468 | logit("failed to write to checkpoint file '%s': %s", cpfile, | ||
469 | strerror(errno)); | ||
470 | } | ||
471 | |||
472 | static unsigned long | ||
473 | read_checkpoint(char *cpfile) | ||
474 | { | ||
475 | FILE *fp; | ||
476 | unsigned long lineno = 0; | ||
477 | |||
478 | if ((fp = fopen(cpfile, "r")) == NULL) | ||
479 | return 0; | ||
480 | if (fscanf(fp, "%lu\n", &lineno) < 1) | ||
481 | logit("Failed to load checkpoint from '%s'", cpfile); | ||
482 | else | ||
483 | logit("Loaded checkpoint from '%s' line %lu", cpfile, lineno); | ||
484 | fclose(fp); | ||
485 | return lineno; | ||
486 | } | ||
487 | |||
441 | /* | 488 | /* |
442 | * perform a Miller-Rabin primality test | 489 | * perform a Miller-Rabin primality test |
443 | * on the list of candidates | 490 | * on the list of candidates |
@@ -445,13 +492,15 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) | |||
445 | * The result is a list of so-call "safe" primes | 492 | * The result is a list of so-call "safe" primes |
446 | */ | 493 | */ |
447 | int | 494 | int |
448 | prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) | 495 | prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, |
496 | char *checkpoint_file) | ||
449 | { | 497 | { |
450 | BIGNUM *q, *p, *a; | 498 | BIGNUM *q, *p, *a; |
451 | BN_CTX *ctx; | 499 | BN_CTX *ctx; |
452 | char *cp, *lp; | 500 | char *cp, *lp; |
453 | u_int32_t count_in = 0, count_out = 0, count_possible = 0; | 501 | u_int32_t count_in = 0, count_out = 0, count_possible = 0; |
454 | u_int32_t generator_known, in_tests, in_tries, in_type, in_size; | 502 | u_int32_t generator_known, in_tests, in_tries, in_type, in_size; |
503 | unsigned long last_processed = 0; | ||
455 | time_t time_start, time_stop; | 504 | time_t time_start, time_stop; |
456 | int res; | 505 | int res; |
457 | 506 | ||
@@ -472,10 +521,21 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) | |||
472 | debug2("%.24s Final %u Miller-Rabin trials (%x generator)", | 521 | debug2("%.24s Final %u Miller-Rabin trials (%x generator)", |
473 | ctime(&time_start), trials, generator_wanted); | 522 | ctime(&time_start), trials, generator_wanted); |
474 | 523 | ||
524 | if (checkpoint_file != NULL) | ||
525 | last_processed = read_checkpoint(checkpoint_file); | ||
526 | |||
475 | res = 0; | 527 | res = 0; |
476 | lp = xmalloc(QLINESIZE + 1); | 528 | lp = xmalloc(QLINESIZE + 1); |
477 | while (fgets(lp, QLINESIZE + 1, in) != NULL) { | 529 | while (fgets(lp, QLINESIZE + 1, in) != NULL) { |
478 | count_in++; | 530 | count_in++; |
531 | if (checkpoint_file != NULL) { | ||
532 | if (count_in <= last_processed) { | ||
533 | debug3("skipping line %u, before checkpoint", | ||
534 | count_in); | ||
535 | continue; | ||
536 | } | ||
537 | write_checkpoint(checkpoint_file, count_in); | ||
538 | } | ||
479 | if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { | 539 | if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { |
480 | debug2("%10u: comment or short line", count_in); | 540 | debug2("%10u: comment or short line", count_in); |
481 | continue; | 541 | continue; |
@@ -644,6 +704,9 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) | |||
644 | BN_free(q); | 704 | BN_free(q); |
645 | BN_CTX_free(ctx); | 705 | BN_CTX_free(ctx); |
646 | 706 | ||
707 | if (checkpoint_file != NULL) | ||
708 | unlink(checkpoint_file); | ||
709 | |||
647 | logit("%.24s Found %u safe primes of %u candidates in %ld seconds", | 710 | logit("%.24s Found %u safe primes of %u candidates in %ld seconds", |
648 | ctime(&time_stop), count_out, count_possible, | 711 | ctime(&time_stop), count_out, count_possible, |
649 | (long) (time_stop - time_start)); | 712 | (long) (time_stop - time_start)); |