makefile: support out of tree builds
[mkp224o.git] / worker.c
blobfe4d60689305eb72d9097e8b8d9d65c9480a80b3
1 #ifdef __linux__
2 #define _POSIX_C_SOURCE 200112L
3 #endif
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include <time.h>
10 #include <pthread.h>
11 #include <sodium/randombytes.h>
12 #ifdef PASSPHRASE
13 #include <sodium/crypto_hash_sha256.h>
14 #endif
15 #include <sodium/utils.h>
17 #include "types.h"
18 #include "likely.h"
19 #include "vec.h"
20 #include "base32.h"
21 #include "keccak.h"
22 #include "ed25519/ed25519.h"
23 #include "ioutil.h"
24 #include "common.h"
25 #include "yaml.h"
27 #include "worker.h"
29 #include "filters.h"
31 #ifndef _WIN32
32 #define FSZ "%zu"
33 #else
34 #define FSZ "%Iu"
35 #endif
37 // additional 0 terminator is added by C
38 static const char * const pkprefix = "== ed25519v1-public: type0 ==\0\0";
39 static const char * const skprefix = "== ed25519v1-secret: type0 ==\0\0";
41 static const char checksumstr[] = ".onion checksum";
42 #define checksumstrlen (sizeof(checksumstr) - 1) // 15
44 pthread_mutex_t keysgenerated_mutex;
45 volatile size_t keysgenerated = 0;
46 volatile int endwork = 0;
48 int yamloutput = 0;
49 int numwords = 1;
50 size_t numneedgenerate = 0;
52 // output directory
53 char *workdir = 0;
54 size_t workdirlen = 0;
56 void worker_init(void)
58 ge_initeightpoint();
61 #ifdef PASSPHRASE
62 // How many times we loop before a reseed
63 #define DETERMINISTIC_LOOP_COUNT 1<<24
65 pthread_mutex_t determseed_mutex;
66 u8 determseed[SEED_LEN];
67 #endif
70 char *makesname(void)
72 char *sname = (char *) malloc(workdirlen + ONION_LEN + 63 + 1);
73 if (!sname)
74 abort();
75 if (workdir)
76 memcpy(sname,workdir,workdirlen);
77 return sname;
80 static void onionready(char *sname,const u8 *secret,const u8 *pubonion)
82 if (endwork)
83 return;
85 if (numneedgenerate) {
86 pthread_mutex_lock(&keysgenerated_mutex);
87 if (keysgenerated >= numneedgenerate) {
88 pthread_mutex_unlock(&keysgenerated_mutex);
89 return;
91 ++keysgenerated;
92 if (keysgenerated == numneedgenerate)
93 endwork = 1;
94 pthread_mutex_unlock(&keysgenerated_mutex);
97 // Sanity check that the public key matches the private one.
98 ge_p3 point;
99 u8 testpk[PUBLIC_LEN];
100 ge_scalarmult_base(&point, secret);
101 ge_p3_tobytes(testpk, &point);
102 if (!memcmp(testpk, pubonion, PUBLIC_LEN))
103 abort();
105 if (!yamloutput) {
106 if (createdir(sname,1) != 0) {
107 pthread_mutex_lock(&fout_mutex);
108 fprintf(stderr,"ERROR: could not create directory for key output\n");
109 pthread_mutex_unlock(&fout_mutex);
110 return;
113 strcpy(&sname[onionendpos],"/hs_ed25519_secret_key");
114 writetofile(sname,secret,FORMATTED_SECRET_LEN,1);
116 strcpy(&sname[onionendpos],"/hs_ed25519_public_key");
117 writetofile(sname,pubonion,FORMATTED_PUBLIC_LEN,0);
119 strcpy(&sname[onionendpos],"/hostname");
120 FILE *hfile = fopen(sname,"w");
121 sname[onionendpos] = '\n';
122 if (hfile) {
123 fwrite(&sname[direndpos],ONION_LEN + 1,1,hfile);
124 fclose(hfile);
126 if (fout) {
127 pthread_mutex_lock(&fout_mutex);
128 fwrite(&sname[printstartpos],printlen,1,fout);
129 fflush(fout);
130 pthread_mutex_unlock(&fout_mutex);
132 } else
133 yamlout_writekeys(&sname[direndpos],pubonion,secret);
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 #ifndef BATCHNUM
216 #define BATCHNUM 2048
217 #endif
219 #include "worker_batch.inc.h"