Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
samr7
GitHub Repository: samr7/vanitygen
Path: blob/master/oclvanitygen.c
239 views
1
/*
2
* Vanitygen, vanity bitcoin address generator
3
* Copyright (C) 2011 <[email protected]>
4
*
5
* Vanitygen is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU Affero General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
*
10
* Vanitygen is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU Affero General Public License for more details.
14
*
15
* You should have received a copy of the GNU Affero General Public License
16
* along with Vanitygen. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <stdio.h>
20
#include <string.h>
21
#include <math.h>
22
#include <assert.h>
23
24
#include <openssl/ec.h>
25
#include <openssl/bn.h>
26
#include <openssl/rand.h>
27
28
#include "oclengine.h"
29
#include "pattern.h"
30
#include "util.h"
31
32
33
const char *version = VANITYGEN_VERSION;
34
const int debug = 0;
35
36
37
void
38
usage(const char *name)
39
{
40
fprintf(stderr,
41
"oclVanitygen %s (" OPENSSL_VERSION_TEXT ")\n"
42
"Usage: %s [-vqrik1NTS] [-d <device>] [-f <filename>|-] [<pattern>...]\n"
43
"Generates a bitcoin receiving address matching <pattern>, and outputs the\n"
44
"address and associated private key. The private key may be stored in a safe\n"
45
"location or imported into a bitcoin client to spend any balance received on\n"
46
"the address.\n"
47
"By default, <pattern> is interpreted as an exact prefix.\n"
48
"By default, if no device is specified, and the system has exactly one OpenCL\n"
49
"device, it will be selected automatically, otherwise if the system has\n"
50
"multiple OpenCL devices and no device is specified, an error will be\n"
51
"reported. To use multiple devices simultaneously, specify the -D option for\n"
52
"each device.\n"
53
"\n"
54
"Options:\n"
55
"-v Verbose output\n"
56
"-q Quiet output\n"
57
"-i Case-insensitive prefix search\n"
58
"-k Keep pattern and continue search after finding a match\n"
59
"-1 Stop after first match\n"
60
"-N Generate namecoin address\n"
61
"-T Generate bitcoin testnet address\n"
62
"-X <version> Generate address with the given version\n"
63
"-e Encrypt private keys, prompt for password\n"
64
"-E <password> Encrypt private keys with <password> (UNSAFE)\n"
65
"-p <platform> Select OpenCL platform\n"
66
"-d <device> Select OpenCL device\n"
67
"-D <devstr> Use OpenCL device, identified by device string\n"
68
" Form: <platform>:<devicenumber>[,<options>]\n"
69
" Example: 0:0,grid=1024x1024\n"
70
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
71
"-w <worksize> Set work items per thread in a work unit\n"
72
"-t <threads> Set target thread count per multiprocessor\n"
73
"-g <x>x<y> Set grid size\n"
74
"-b <invsize> Set modular inverse ops per thread\n"
75
"-V Enable kernel/OpenCL/hardware verification (SLOW)\n"
76
"-f <file> File containing list of patterns, one per line\n"
77
" (Use \"-\" as the file name for stdin)\n"
78
"-o <file> Write pattern matches to <file>\n"
79
"-s <file> Seed random number generator from <file>\n",
80
version, name);
81
}
82
83
#define MAX_DEVS 32
84
#define MAX_FILE 4
85
86
int
87
main(int argc, char **argv)
88
{
89
int addrtype = 0;
90
int privtype = 128;
91
int regex = 0;
92
int caseinsensitive = 0;
93
int opt;
94
char pwbuf[128];
95
int platformidx = -1, deviceidx = -1;
96
int prompt_password = 0;
97
char *seedfile = NULL;
98
char **patterns, *pend;
99
int verbose = 1;
100
int npatterns = 0;
101
int nthreads = 0;
102
int worksize = 0;
103
int nrows = 0, ncols = 0;
104
int invsize = 0;
105
int remove_on_match = 1;
106
int only_one = 0;
107
int verify_mode = 0;
108
int safe_mode = 0;
109
vg_context_t *vcp = NULL;
110
vg_ocl_context_t *vocp = NULL;
111
EC_POINT *pubkey_base = NULL;
112
const char *result_file = NULL;
113
const char *key_password = NULL;
114
char *devstrs[MAX_DEVS];
115
int ndevstrs = 0;
116
int opened = 0;
117
118
FILE *pattfp[MAX_FILE], *fp;
119
int pattfpi[MAX_FILE];
120
int npattfp = 0;
121
int pattstdin = 0;
122
123
int i;
124
125
while ((opt = getopt(argc, argv,
126
"vqik1NTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:D:")) != -1) {
127
switch (opt) {
128
case 'v':
129
verbose = 2;
130
break;
131
case 'q':
132
verbose = 0;
133
break;
134
case 'i':
135
caseinsensitive = 1;
136
break;
137
case 'k':
138
remove_on_match = 0;
139
break;
140
case '1':
141
only_one = 1;
142
break;
143
case 'N':
144
addrtype = 52;
145
privtype = 180;
146
break;
147
case 'T':
148
addrtype = 111;
149
privtype = 239;
150
break;
151
case 'X':
152
addrtype = atoi(optarg);
153
privtype = 128 + addrtype;
154
break;
155
case 'e':
156
prompt_password = 1;
157
break;
158
case 'E':
159
key_password = optarg;
160
break;
161
case 'p':
162
platformidx = atoi(optarg);
163
break;
164
case 'd':
165
deviceidx = atoi(optarg);
166
break;
167
case 'w':
168
worksize = atoi(optarg);
169
if (worksize == 0) {
170
fprintf(stderr,
171
"Invalid work size '%s'\n", optarg);
172
return 1;
173
}
174
break;
175
case 't':
176
nthreads = atoi(optarg);
177
if (nthreads == 0) {
178
fprintf(stderr,
179
"Invalid thread count '%s'\n", optarg);
180
return 1;
181
}
182
break;
183
case 'g':
184
nrows = 0;
185
ncols = strtol(optarg, &pend, 0);
186
if (pend && *pend == 'x') {
187
nrows = strtol(pend+1, NULL, 0);
188
}
189
if (!nrows || !ncols) {
190
fprintf(stderr,
191
"Invalid grid size '%s'\n", optarg);
192
return 1;
193
}
194
break;
195
case 'b':
196
invsize = atoi(optarg);
197
if (!invsize) {
198
fprintf(stderr,
199
"Invalid modular inverse size '%s'\n",
200
optarg);
201
return 1;
202
}
203
if (invsize & (invsize - 1)) {
204
fprintf(stderr,
205
"Modular inverse size must be "
206
"a power of 2\n");
207
return 1;
208
}
209
break;
210
case 'V':
211
verify_mode = 1;
212
break;
213
case 'S':
214
safe_mode = 1;
215
break;
216
case 'D':
217
if (ndevstrs >= MAX_DEVS) {
218
fprintf(stderr,
219
"Too many OpenCL devices (limit %d)\n",
220
MAX_DEVS);
221
return 1;
222
}
223
devstrs[ndevstrs++] = optarg;
224
break;
225
case 'P': {
226
if (pubkey_base != NULL) {
227
fprintf(stderr,
228
"Multiple base pubkeys specified\n");
229
return 1;
230
}
231
EC_KEY *pkey = vg_exec_context_new_key();
232
pubkey_base = EC_POINT_hex2point(
233
EC_KEY_get0_group(pkey),
234
optarg, NULL, NULL);
235
EC_KEY_free(pkey);
236
if (pubkey_base == NULL) {
237
fprintf(stderr,
238
"Invalid base pubkey\n");
239
return 1;
240
}
241
break;
242
}
243
case 'f':
244
if (npattfp >= MAX_FILE) {
245
fprintf(stderr,
246
"Too many input files specified\n");
247
return 1;
248
}
249
if (!strcmp(optarg, "-")) {
250
if (pattstdin) {
251
fprintf(stderr, "ERROR: stdin "
252
"specified multiple times\n");
253
return 1;
254
}
255
fp = stdin;
256
} else {
257
fp = fopen(optarg, "r");
258
if (!fp) {
259
fprintf(stderr,
260
"Could not open %s: %s\n",
261
optarg, strerror(errno));
262
return 1;
263
}
264
}
265
pattfp[npattfp] = fp;
266
pattfpi[npattfp] = caseinsensitive;
267
npattfp++;
268
break;
269
case 'o':
270
if (result_file) {
271
fprintf(stderr,
272
"Multiple output files specified\n");
273
return 1;
274
}
275
result_file = optarg;
276
break;
277
case 's':
278
if (seedfile != NULL) {
279
fprintf(stderr,
280
"Multiple RNG seeds specified\n");
281
return 1;
282
}
283
seedfile = optarg;
284
break;
285
default:
286
usage(argv[0]);
287
return 1;
288
}
289
}
290
291
#if OPENSSL_VERSION_NUMBER < 0x10000000L
292
/* Complain about older versions of OpenSSL */
293
if (verbose > 0) {
294
fprintf(stderr,
295
"WARNING: Built with " OPENSSL_VERSION_TEXT "\n"
296
"WARNING: Use OpenSSL 1.0.0d+ for best performance\n");
297
}
298
#endif
299
300
if (caseinsensitive && regex)
301
fprintf(stderr,
302
"WARNING: case insensitive mode incompatible with "
303
"regular expressions\n");
304
305
if (seedfile) {
306
opt = -1;
307
#if !defined(_WIN32)
308
{ struct stat st;
309
if (!stat(seedfile, &st) &&
310
(st.st_mode & (S_IFBLK|S_IFCHR))) {
311
opt = 32;
312
} }
313
#endif
314
opt = RAND_load_file(seedfile, opt);
315
if (!opt) {
316
fprintf(stderr, "Could not load RNG seed %s\n", optarg);
317
return 1;
318
}
319
if (verbose > 0) {
320
fprintf(stderr,
321
"Read %d bytes from RNG seed file\n", opt);
322
}
323
}
324
325
if (regex) {
326
vcp = vg_regex_context_new(addrtype, privtype);
327
328
} else {
329
vcp = vg_prefix_context_new(addrtype, privtype,
330
caseinsensitive);
331
}
332
333
vcp->vc_verbose = verbose;
334
vcp->vc_result_file = result_file;
335
vcp->vc_remove_on_match = remove_on_match;
336
vcp->vc_only_one = only_one;
337
vcp->vc_pubkeytype = addrtype;
338
vcp->vc_pubkey_base = pubkey_base;
339
340
vcp->vc_output_match = vg_output_match_console;
341
vcp->vc_output_timing = vg_output_timing_console;
342
343
if (!npattfp) {
344
if (optind >= argc) {
345
usage(argv[0]);
346
return 1;
347
}
348
patterns = &argv[optind];
349
npatterns = argc - optind;
350
351
if (!vg_context_add_patterns(vcp,
352
(const char ** const) patterns,
353
npatterns))
354
return 1;
355
}
356
357
for (i = 0; i < npattfp; i++) {
358
fp = pattfp[i];
359
if (!vg_read_file(fp, &patterns, &npatterns)) {
360
fprintf(stderr, "Failed to load pattern file\n");
361
return 1;
362
}
363
if (fp != stdin)
364
fclose(fp);
365
366
if (!regex)
367
vg_prefix_context_set_case_insensitive(vcp, pattfpi[i]);
368
369
if (!vg_context_add_patterns(vcp,
370
(const char ** const) patterns,
371
npatterns))
372
return 1;
373
}
374
375
if (!vcp->vc_npatterns) {
376
fprintf(stderr, "No patterns to search\n");
377
return 1;
378
}
379
380
if (prompt_password) {
381
if (!vg_read_password(pwbuf, sizeof(pwbuf)))
382
return 1;
383
key_password = pwbuf;
384
}
385
vcp->vc_key_protect_pass = key_password;
386
if (key_password) {
387
if (!vg_check_password_complexity(key_password, verbose))
388
fprintf(stderr,
389
"WARNING: Protecting private keys with "
390
"weak password\n");
391
}
392
393
if ((verbose > 0) && regex && (vcp->vc_npatterns > 1))
394
fprintf(stderr,
395
"Regular expressions: %ld\n", vcp->vc_npatterns);
396
397
if (ndevstrs) {
398
for (opt = 0; opt < ndevstrs; opt++) {
399
vocp = vg_ocl_context_new_from_devstr(vcp, devstrs[opt],
400
safe_mode,
401
verify_mode);
402
if (!vocp) {
403
fprintf(stderr,
404
"Could not open device '%s', ignoring\n",
405
devstrs[opt]);
406
} else {
407
opened++;
408
}
409
}
410
} else {
411
vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
412
safe_mode, verify_mode,
413
worksize, nthreads,
414
nrows, ncols, invsize);
415
if (vocp)
416
opened++;
417
}
418
419
if (!opened) {
420
vg_ocl_enumerate_devices();
421
return 1;
422
}
423
424
opt = vg_context_start_threads(vcp);
425
if (opt)
426
return 1;
427
428
vg_context_wait_for_completion(vcp);
429
vg_ocl_context_free(vocp);
430
return 0;
431
}
432
433