From 2a4afad91a72defee1f97f189bba0920bd63fd9e Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Fri, 15 Oct 2021 22:53:53 -0600 Subject: [PATCH] Add checkpointing support for passphrases --- main.c | 19 +++++++++++++++++++ worker.c | 2 ++ worker.h | 2 ++ worker_batch_pass.inc.h | 23 ++++++++++++++++++++++- worker_fast_pass.inc.h | 23 ++++++++++++++++++++++- 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index cec31bb..05bfcb7 100644 --- a/main.c +++ b/main.c @@ -112,6 +112,7 @@ static void printhelp(FILE *out,const char *progname) #ifdef PASSPHRASE "\t-p passphrase - use passphrase to initialize the random seed with\n" "\t-P - same as -p, but takes passphrase from PASSPHRASE environment variable\n" + "\t-c filename - load/save checkpoint of progress to specified file (requires passphrase)\n" #endif ,progname,progname); fflush(out); @@ -393,6 +394,12 @@ int main(int argc,char **argv) setpassphrase(pass); deterministic = 1; } + else if (*arg == 'c') { + if (argc--) + checkpointfile = *argv++; + else + e_additional(); + } #endif // PASSPHRASE else { fprintf(stderr,"unrecognised argument: -%c\n",*arg); @@ -465,6 +472,18 @@ int main(int argc,char **argv) goto done; } + if (checkpointfile) { + // Read current checkpoint position if file exists + FILE *checkout = fopen(checkpointfile, "r"); + if (checkout) { + if(fread(checkpoint, 1, SEED_LEN, checkout) != SEED_LEN) { + fprintf(stderr,"failed to read checkpoint file\n"); + exit(1); + } + fclose(checkout); + } + } + filters_prepare(); filters_print(); diff --git a/worker.c b/worker.c index f0aaf62..475d2a3 100644 --- a/worker.c +++ b/worker.c @@ -63,6 +63,8 @@ void worker_init(void) pthread_mutex_t determseed_mutex; u8 determseed[SEED_LEN]; +u8 checkpoint[SEED_LEN]; +const char *checkpointfile = 0; #endif diff --git a/worker.h b/worker.h index 7f50f6f..d20d037 100644 --- a/worker.h +++ b/worker.h @@ -33,6 +33,8 @@ VEC_STRUCT(statsvec,struct statstruct); #ifdef PASSPHRASE extern pthread_mutex_t determseed_mutex; extern u8 determseed[SEED_LEN]; +extern u8 checkpoint[SEED_LEN]; +extern const char *checkpointfile; #endif extern void worker_init(void); diff --git a/worker_batch_pass.inc.h b/worker_batch_pass.inc.h index 3676eec..ecdcb45 100644 --- a/worker_batch_pass.inc.h +++ b/worker_batch_pass.inc.h @@ -36,18 +36,39 @@ void *worker_batch_pass(void *task) sname = makesname(); + // load checkpoint + pthread_mutex_lock(&determseed_mutex); + for (int i = 0; i < SEED_LEN; i++) + determseed[i] += checkpoint[i]; + pthread_mutex_unlock(&determseed_mutex); + initseed: #ifdef STATISTICS ++st->numrestart.v; #endif pthread_mutex_lock(&determseed_mutex); - for (int i = 0; i < SEED_LEN; i++) + for (int i = 0; i < SEED_LEN; i++) { + ++checkpoint[i]; if (++determseed[i]) break; + } memcpy(seed, determseed, SEED_LEN); pthread_mutex_unlock(&determseed_mutex); + if (checkpointfile) { + FILE *checkout = fopen(checkpointfile, "w"); + if (!checkout) { + fprintf(stderr,"cannot open checkpoint file for writing\n"); + exit(1); + } + if(fwrite(checkpoint, 1, SEED_LEN, checkout) != SEED_LEN) { + fprintf(stderr,"cannot write to checkpoint file\n"); + exit(1); + } + fclose(checkout); + } + ed25519_seckey_expand(sk,seed); ge_scalarmult_base(&ge_public,sk); diff --git a/worker_fast_pass.inc.h b/worker_fast_pass.inc.h index 2d482b3..3f281b5 100644 --- a/worker_fast_pass.inc.h +++ b/worker_fast_pass.inc.h @@ -33,18 +33,39 @@ void *worker_fast_pass(void *task) sname = makesname(); + // load checkpoint + pthread_mutex_lock(&determseed_mutex); + for (int i = 0; i < SEED_LEN; i++) + determseed[i] += checkpoint[i]; + pthread_mutex_unlock(&determseed_mutex); + initseed: #ifdef STATISTICS ++st->numrestart.v; #endif pthread_mutex_lock(&determseed_mutex); - for (int i = 0; i < SEED_LEN; i++) + for (int i = 0; i < SEED_LEN; i++) { + ++checkpoint[i]; if (++determseed[i]) break; + } memcpy(seed, determseed, SEED_LEN); pthread_mutex_unlock(&determseed_mutex); + if (checkpointfile) { + FILE *checkout = fopen(checkpointfile, "w"); + if (!checkout) { + fprintf(stderr,"cannot open checkpoint file for writing\n"); + exit(1); + } + if(fwrite(checkpoint, 1, SEED_LEN, checkout) != SEED_LEN) { + fprintf(stderr,"cannot write to checkpoint file\n"); + exit(1); + } + fclose(checkout); + } + ed25519_seckey_expand(sk,seed); ge_scalarmult_base(&ge_public,sk);