1 #define _POSIX_C_SOURCE 200112L
9 #include <sodium/randombytes.h>
11 #include <sodium/crypto_hash_sha256.h>
13 #include <sodium/utils.h>
20 #include "ed25519/ed25519.h"
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;
49 size_t numneedgenerate
= 0;
53 size_t workdirlen
= 0;
55 void worker_init(void)
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
];
71 char *sname
= (char *) malloc(workdirlen
+ ONION_LEN
+ 63 + 1);
75 memcpy(sname
,workdir
,workdirlen
);
79 static void onionready(char *sname
,const u8
*secret
,const u8
*pubonion
)
84 if (numneedgenerate
) {
85 pthread_mutex_lock(&keysgenerated_mutex
);
86 if (keysgenerated
>= numneedgenerate
) {
87 pthread_mutex_unlock(&keysgenerated_mutex
);
91 if (keysgenerated
== numneedgenerate
)
93 pthread_mutex_unlock(&keysgenerated_mutex
);
96 // Sanity check that the public key matches the private one.
98 u8 testpk
[PUBLIC_LEN
];
99 ge_scalarmult_base(&point
, secret
);
100 ge_p3_tobytes(testpk
, &point
);
101 if (!memcmp(testpk
, pubonion
, PUBLIC_LEN
))
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
);
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';
122 fwrite(&sname
[direndpos
],ONION_LEN
+ 1,1,hfile
);
126 pthread_mutex_lock(&fout_mutex
);
127 fwrite(&sname
[printstartpos
],printlen
,1,fout
);
129 pthread_mutex_unlock(&fout_mutex
);
133 yamlout_writekeys(&sname
[direndpos
],pubonion
,secret
,yamlraw
);
136 #include "filters_worker.inc.h"
139 #define ADDNUMSUCCESS ++st->numsuccess.v
141 #define ADDNUMSUCCESS do ; while (0)
145 union pubonionunion
{
146 u8 raw
[PKPREFIX_SIZE
+ PUBLIC_LEN
+ 32];
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;
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;
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
)
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
)
187 for (i
= 0;i
< 32;++i
) {
188 c
+= *dst
+ (v
& 0xFF); *dst
= c
& 0xFF; c
>>= 8;
194 #include "worker_fast.inc.h"
198 static void reseedright(u8 sk
[SECRET_LEN
])
200 crypto_hash_sha256_state state
;
201 crypto_hash_sha256_init(&state
);
203 crypto_hash_sha256_update(&state
,&sk
[32],32);
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]);
212 #include "worker_fast_pass.inc.h"
215 #if !defined(BATCHNUM)
216 #define BATCHNUM 2048
219 #include "worker_batch.inc.h"
221 #include "worker_batch_pass.inc.h"