correctly handle filter file loading error, small tweak
[mkp224o.git] / worker_batch.inc.h
blobe544d00cf41417c75d84908e091e92784e1e06d3
2 void *worker_batch(void *task)
4 union pubonionunion pubonion;
5 u8 * const pk = &pubonion.raw[PKPREFIX_SIZE];
6 u8 secret[SKPREFIX_SIZE + SECRET_LEN];
7 u8 * const sk = &secret[SKPREFIX_SIZE];
8 u8 seed[SEED_LEN];
9 u8 hashsrc[checksumstrlen + PUBLIC_LEN + 1];
10 u8 wpk[PUBLIC_LEN + 1];
11 ge_p3 ge_public;
12 char *sname;
14 // state to keep batch data
15 ge_p3 ge_batch[BATCHNUM];
16 fe *(batchgez)[BATCHNUM];
17 fe tmp_batch[BATCHNUM];
18 bytes32 pk_batch[BATCHNUM];
20 size_t counter;
21 size_t i;
23 #ifdef STATISTICS
24 struct statstruct *st = (struct statstruct *)task;
25 #endif
27 // set up right pointers
28 for (size_t b = 0;b < BATCHNUM;++b)
29 batchgez[b] = &GEZ(ge_batch[b]);
31 PREFILTER
33 memcpy(secret,skprefix,SKPREFIX_SIZE);
34 wpk[PUBLIC_LEN] = 0;
35 memset(&pubonion,0,sizeof(pubonion));
36 memcpy(pubonion.raw,pkprefix,PKPREFIX_SIZE);
37 // write version later as it will be overwritten by hash
38 memcpy(hashsrc,checksumstr,checksumstrlen);
39 hashsrc[checksumstrlen + PUBLIC_LEN] = 0x03; // version
41 sname = makesname();
43 initseed:
44 #ifdef STATISTICS
45 ++st->numrestart.v;
46 #endif
48 randombytes(seed,sizeof(seed));
50 ed25519_seckey_expand(sk,seed);
52 ge_scalarmult_base(&ge_public,sk);
54 for (counter = 0;counter < SIZE_MAX-(8*BATCHNUM);counter += 8*BATCHNUM) {
55 ge_p1p1 sum;
57 if (unlikely(endwork))
58 goto end;
61 for (size_t b = 0;b < BATCHNUM;++b) {
62 ge_batch[b] = ge_public;
63 ge_add(&sum,&ge_public,&ge_eightpoint);
64 ge_p1p1_to_p3(&ge_public,&sum);
66 // NOTE: leaves unfinished one bit at the very end
67 ge_p3_batchtobytes_destructive_1(pk_batch,ge_batch,batchgez,tmp_batch,BATCHNUM);
69 #ifdef STATISTICS
70 st->numcalc.v += BATCHNUM;
71 #endif
73 for (size_t b = 0;b < BATCHNUM;++b) {
74 DOFILTER(i,pk_batch[b],{
75 if (numwords > 1) {
76 shiftpk(wpk,pk_batch[b],filter_len(i));
77 size_t j;
78 for (int w = 1;;) {
79 DOFILTER(j,wpk,goto secondfind);
80 goto next;
81 secondfind:
82 if (++w >= numwords)
83 break;
84 shiftpk(wpk,wpk,filter_len(j));
87 // found!
88 // finish it up
89 ge_p3_batchtobytes_destructive_finish(pk_batch[b],&ge_batch[b]);
90 // copy public key
91 memcpy(pk,pk_batch[b],PUBLIC_LEN);
92 // update secret key with counter
93 addsztoscalar32(sk,counter + (b * 8));
94 // sanity check
95 if ((sk[0] & 248) != sk[0] || ((sk[31] & 63) | 64) != sk[31])
96 goto initseed;
98 ADDNUMSUCCESS;
100 // calc checksum
101 memcpy(&hashsrc[checksumstrlen],pk,PUBLIC_LEN);
102 FIPS202_SHA3_256(hashsrc,sizeof(hashsrc),&pk[PUBLIC_LEN]);
103 // version byte
104 pk[PUBLIC_LEN + 2] = 0x03;
105 // full name
106 strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion");
107 onionready(sname,secret,pubonion.raw);
108 pk[PUBLIC_LEN] = 0; // what is this for?
109 // don't reuse same seed
110 goto initseed;
112 next:
116 goto initseed;
118 end:
119 free(sname);
120 POSTFILTER
121 sodium_memzero(secret,sizeof(secret));
122 sodium_memzero(seed,sizeof(seed));
123 return 0;