some tweaks
[mkp224o.git] / worker.c
blob4962c8b90914b8660da0b5fb828faef5d76b420d
1 #define _POSIX_C_SOURCE 200112L
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <time.h>
8 #include <pthread.h>
9 #include <sodium/randombytes.h>
10 #ifdef PASSPHRASE
11 #include <sodium/crypto_hash_sha256.h>
12 #endif
13 #include <sodium/utils.h>
15 #include "types.h"
16 #include "likely.h"
17 #include "vec.h"
18 #include "base32.h"
19 #include "keccak.h"
20 #include "ed25519/ed25519.h"
21 #include "ioutil.h"
22 #include "common.h"
23 #include "yaml.h"
25 #include "worker.h"
27 #include "filters.h"
29 #ifndef _WIN32
30 #define FSZ "%zu"
31 #else
32 #define FSZ "%Iu"
33 #endif
35 // additional 0 terminator is added by C
36 const char * const pkprefix = "== ed25519v1-public: type0 ==\0\0";
37 const char * const skprefix = "== ed25519v1-secret: type0 ==\0\0";
39 static const char checksumstr[] = ".onion checksum";
40 #define checksumstrlen (sizeof(checksumstr) - 1) // 15
42 pthread_mutex_t keysgenerated_mutex;
43 volatile size_t keysgenerated = 0;
44 volatile int endwork = 0;
46 int yamloutput = 0;
47 int yamlraw = 0;
48 int numwords = 1;
49 size_t numneedgenerate = 0;
51 // output directory
52 char *workdir = 0;
53 size_t workdirlen = 0;
55 void worker_init(void)
57 ge_initeightpoint();
60 #ifdef PASSPHRASE
61 // How many times we loop before a reseed
62 #define DETERMINISTIC_LOOP_COUNT (1<<24)
64 pthread_mutex_t determseed_mutex;
65 u8 determseed[SEED_LEN];
66 #endif
69 char *makesname(void)
71 char *sname = (char *) malloc(workdirlen + ONION_LEN + 63 + 1);
72 if (!sname)
73 abort();
74 if (workdir)
75 memcpy(sname,workdir,workdirlen);
76 return sname;
79 static void onionready(char *sname,const u8 *secret,const u8 *pubonion)
81 if (endwork)
82 return;
84 if (numneedgenerate) {
85 pthread_mutex_lock(&keysgenerated_mutex);
86 if (keysgenerated >= numneedgenerate) {
87 pthread_mutex_unlock(&keysgenerated_mutex);
88 return;
90 ++keysgenerated;
91 if (keysgenerated == numneedgenerate)
92 endwork = 1;
93 pthread_mutex_unlock(&keysgenerated_mutex);
96 // Sanity check that the public key matches the private one.
97 ge_p3 point;
98 u8 testpk[PUBLIC_LEN];
99 ge_scalarmult_base(&point, secret);
100 ge_p3_tobytes(testpk, &point);
101 if (!memcmp(testpk, pubonion, PUBLIC_LEN))
102 abort();
104 if (!yamloutput) {
105 if (createdir(sname,1) != 0) {
106 pthread_mutex_lock(&fout_mutex);
107 fprintf(stderr,"ERROR: could not create directory for key output\n");
108 pthread_mutex_unlock(&fout_mutex);
109 return;
112 strcpy(&sname[onionendpos],"/hs_ed25519_secret_key");
113 writetofile(sname,secret,FORMATTED_SECRET_LEN,1);
115 strcpy(&sname[onionendpos],"/hs_ed25519_public_key");
116 writetofile(sname,pubonion,FORMATTED_PUBLIC_LEN,0);
118 strcpy(&sname[onionendpos],"/hostname");
119 FILE *hfile = fopen(sname,"w");
120 sname[onionendpos] = '\n';
121 if (hfile) {
122 fwrite(&sname[direndpos],ONION_LEN + 1,1,hfile);
123 fclose(hfile);
125 if (fout) {
126 pthread_mutex_lock(&fout_mutex);
127 fwrite(&sname[printstartpos],printlen,1,fout);
128 fflush(fout);
129 pthread_mutex_unlock(&fout_mutex);
132 else
133 yamlout_writekeys(&sname[direndpos],pubonion,secret,yamlraw);
136 #include "filters_worker.inc.h"
138 #ifdef STATISTICS
139 #define ADDNUMSUCCESS ++st->numsuccess.v
140 #else
141 #define ADDNUMSUCCESS do ; while (0)
142 #endif
145 union pubonionunion {
146 u8 raw[PKPREFIX_SIZE + PUBLIC_LEN + 32];
147 struct {
148 u64 prefix[4];
149 u64 key[4];
150 u64 hash[4];
151 } i;
154 // little endian inc
155 static void addsk32(u8 *sk)
157 register unsigned int c = 8;
158 for (size_t i = 0;i < 32;++i) {
159 c = (unsigned int)sk[i] + c; sk[i] = c & 0xFF; c >>= 8;
160 // unsure if needed
161 if (!c) break;
165 // 0123 4567 xxxx --3--> 3456 7xxx
166 // 0123 4567 xxxx --1--> 1234 567x
167 static inline void shiftpk(u8 *dst,const u8 *src,size_t sbits)
169 size_t i,sbytes = sbits / 8;
170 sbits %= 8;
171 for (i = 0;i + sbytes < PUBLIC_LEN;++i) {
172 dst[i] = (u8) ((src[i+sbytes] << sbits) |
173 (src[i+sbytes+1] >> (8 - sbits)));
175 for(;i < PUBLIC_LEN;++i)
176 dst[i] = 0;
179 #include "worker_slow.inc.h"
182 // in little-endian order, 32 bytes aka 256 bits
183 static void addsztoscalar32(u8 *dst,size_t v)
185 int i;
186 u32 c = 0;
187 for (i = 0;i < 32;++i) {
188 c += *dst + (v & 0xFF); *dst = c & 0xFF; c >>= 8;
189 v >>= 8;
190 ++dst;
194 #include "worker_fast.inc.h"
197 #ifdef PASSPHRASE
198 static void reseedright(u8 sk[SECRET_LEN])
200 crypto_hash_sha256_state state;
201 crypto_hash_sha256_init(&state);
202 // old right side
203 crypto_hash_sha256_update(&state,&sk[32],32);
204 // new random data
205 randombytes(&sk[32],32);
206 crypto_hash_sha256_update(&state,&sk[32],32);
207 // put result in right side
208 crypto_hash_sha256_final(&state,&sk[32]);
210 #endif // PASSPHRASE
212 #include "worker_fast_pass.inc.h"
215 #if !defined(BATCHNUM)
216 #define BATCHNUM 2048
217 #endif
219 #include "worker_batch.inc.h"
221 #include "worker_batch_pass.inc.h"