From 5c7e0144d971d7d6252d7ce069bf7aaaa6618ecd Mon Sep 17 00:00:00 2001 From: cathugger Date: Wed, 20 Nov 2019 16:17:21 +0000 Subject: [PATCH] remove BATCHNUM limitations --- worker.c | 9 +----- worker_batch_pass.inc.h | 71 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/worker.c b/worker.c index 83466f3..ea8acd1 100644 --- a/worker.c +++ b/worker.c @@ -58,7 +58,7 @@ void worker_init(void) #ifdef PASSPHRASE // How many times we loop before a reseed -#define DETERMINISTIC_LOOP_COUNT 1<<24 +#define DETERMINISTIC_LOOP_COUNT (1<<24) pthread_mutex_t determseed_mutex; u8 determseed[SEED_LEN]; @@ -212,13 +212,6 @@ static void reseedright(u8 sk[SECRET_LEN]) #if !defined(BATCHNUM) #define BATCHNUM 2048 -#else - #if BATCHNUM & (BATCHNUM - 1) - #error "BATCHNUM must be power of 2" - #endif - #if (BATCHNUM * 8) > DETERMINISTIC_LOOP_COUNT - #error "BATCHNUM is too large" - #endif #endif #include "worker_batch.inc.h" diff --git a/worker_batch_pass.inc.h b/worker_batch_pass.inc.h index 3f669f2..93f4eb0 100644 --- a/worker_batch_pass.inc.h +++ b/worker_batch_pass.inc.h @@ -57,7 +57,7 @@ initseed: ge_scalarmult_base(&ge_public,sk); - for (counter = oldcounter = 0;counter < DETERMINISTIC_LOOP_COUNT;counter += 8*BATCHNUM) { + for (counter = oldcounter = 0;counter < DETERMINISTIC_LOOP_COUNT - (BATCHNUM - 1) * 8;counter += BATCHNUM * 8) { ge_p1p1 sum; if (unlikely(endwork)) @@ -121,6 +121,75 @@ initseed: ; } } + // continue if have leftovers, DETERMINISTIC_LOOP_COUNT - counter < BATCHNUM * 8 + // can't have leftovers in theory if BATCHNUM was power of 2 and smaller than DETERMINISTIC_LOOP_COUNT bound + if (((BATCHNUM & (BATCHNUM - 1)) || (BATCHNUM * 8) > DETERMINISTIC_LOOP_COUNT) && + counter < DETERMINISTIC_LOOP_COUNT) + { + ge_p1p1 sum; + + if (unlikely(endwork)) + goto end; + + const size_t remaining = (DETERMINISTIC_LOOP_COUNT - counter) / 8; + + for (size_t b = 0;b < remaining;++b) { + ge_batch[b] = ge_public; + ge_add(&sum,&ge_public,&ge_eightpoint); + ge_p1p1_to_p3(&ge_public,&sum); + } + // NOTE: leaves unfinished one bit at the very end + ge_p3_batchtobytes_destructive_1(pk_batch,ge_batch,batchgez,tmp_batch,remaining); + +#ifdef STATISTICS + st->numcalc.v += remaining; +#endif + + for (size_t b = 0;b < remaining;++b) { + DOFILTER(i,pk_batch[b],{ + if (numwords > 1) { + shiftpk(wpk,pk_batch[b],filter_len(i)); + size_t j; + for (int w = 1;;) { + DOFILTER(j,wpk,goto secondfind2); + goto next2; + secondfind2: + if (++w >= numwords) + break; + shiftpk(wpk,wpk,filter_len(j)); + } + } + // found! + // finish it up + ge_p3_batchtobytes_destructive_finish(pk_batch[b],&ge_batch[b]); + // copy public key + memcpy(pk,pk_batch[b],PUBLIC_LEN); + // update secret key with counter + addsztoscalar32(sk,counter + (b * 8) - oldcounter); + oldcounter = counter + (b * 8); + // sanity check + if ((sk[0] & 248) != sk[0] || ((sk[31] & 63) | 64) != sk[31]) + goto initseed; + + // reseed right half of key to avoid reuse, it won't change public key anyway + reseedright(sk); + + ADDNUMSUCCESS; + + // calc checksum + memcpy(&hashsrc[checksumstrlen],pk,PUBLIC_LEN); + FIPS202_SHA3_256(hashsrc,sizeof(hashsrc),&pk[PUBLIC_LEN]); + // version byte + pk[PUBLIC_LEN + 2] = 0x03; + // full name + strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion"); + onionready(sname,secret,pubonion.raw); + pk[PUBLIC_LEN] = 0; // what is this for? + }); + next2: + ; + } + } goto initseed; end: