int main(int argc, char **argv) { int ret; hash160_t hash; char *line = NULL; size_t line_sz = 0; unsigned char buf[128]; unsigned char *bloom, *bloomfile, *hashfile; FILE *ifile = stdin, *ofile = stdout, *hfile = NULL; mmapf_ctx bloom_mmapf; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s BLOOM_FILTER_FILE HASH_FILE\n", argv[0]); return 1; } bloomfile = argv[1]; if ((ret = mmapf(&bloom_mmapf, bloomfile, BLOOM_SIZE, MMAPF_RNDRD)) != MMAPF_OKAY) { fprintf(stderr, "failed to open bloom filter '%s': %s\n", bloomfile, mmapf_strerror(ret)); return 1; } else if (bloom_mmapf.mem == NULL) { fprintf(stderr, "got NULL pointer trying to set up bloom filter\n"); return 1; } bloom = bloom_mmapf.mem; if (argc == 3) { hashfile = argv[2]; hfile = fopen(hashfile, "r"); } while (getline(&line, &line_sz, ifile) > 0) { unhex(line, strlen(line), hash.uc, sizeof(hash.uc)); if (bloom_chk_hash160(bloom, hash.ul)) { if (hfile && !hsearchf(hfile, &hash)) { //fprintf(ofile, "%s (false positive)\n", hex(hash.uc, sizeof(hash.uc), buf, sizeof(buf))); continue; } //fprintf(ofile, "%s\n", hex(hash.uc, sizeof(hash.uc), buf, sizeof(buf))); fprintf(ofile, "%s", line); } } return 0; }
int main(int argc, char **argv) { FILE *ifile = stdin; FILE *ofile = stdout; FILE *ffile = NULL; int ret; float alpha, ilines_rate, ilines_rate_avg; int64_t raw_lines = -1; uint64_t report_mask = 0; uint64_t time_last, time_curr, time_delta; uint64_t time_start, time_elapsed; uint64_t ilines_last, ilines_curr, ilines_delta; uint64_t olines; int skipping = 0, tty = 0; char *line = NULL; size_t line_sz = 0; int line_read; int c, spok = 0, aopt = 0, vopt = 0, wopt = 16, Lopt = 0; int nopt_mod = 0, nopt_rem = 0; uint64_t kopt = 0; unsigned char *bopt = NULL, *iopt = NULL, *oopt = NULL; unsigned char *topt = NULL, *sopt = NULL, *popt = NULL; unsigned char *mopt = NULL, *fopt = NULL, *ropt = NULL; while ((c = getopt(argc, argv, "avb:hi:k:f:m:n:o:p:s:r:t:w:L")) != -1) { switch (c) { case 'a': aopt = 1; // open output file in append mode break; case 'k': kopt = strtoull(optarg, NULL, 10); // skip first k lines of input skipping = 1; break; case 'n': // only try the rem'th of every mod lines (one indexed) nopt_rem = atoi(optarg) - 1; optarg = strchr(optarg, '/'); if (optarg != NULL) { nopt_mod = atoi(optarg+1); } skipping = 1; break; case 'w': if (wopt > 1) wopt = atoi(optarg); break; case 'm': mopt = optarg; // table file wopt = 1; // auto break; case 'v': vopt = 1; // verbose break; case 'b': bopt = optarg; // bloom filter file break; case 'f': fopt = optarg; // full filter file break; case 'i': iopt = optarg; // input file break; case 'o': oopt = optarg; // output file break; case 's': sopt = optarg; // salt break; case 'p': popt = optarg; // passphrase break; case 'r': ropt = optarg; // rushwallet break; case 't': topt = optarg; // type of input break; case 'L': Lopt = 1; // lookup output break; case 'h': // show help usage(argv[0]); return 0; case '?': // show error return 1; default: // should never be reached... printf("got option '%c' (%d)\n", c, c); return 1; } } if (optind < argc) { if (optind == 1 && argc == 2) { // older versions of brainflayer had the bloom filter file as a // single optional argument, this keeps compatibility with that bopt = argv[1]; } else { fprintf(stderr, "Invalid arguments:\n"); while (optind < argc) { fprintf(stderr, " '%s'\n", argv[optind++]); } exit(1); } } if (nopt_rem != 0 || nopt_mod != 0) { // note that nopt_rem has had one subtracted at option parsing if (nopt_rem >= nopt_mod) { bail(1, "Invalid '-n' argument, remainder '%d' must be <= modulus '%d'\n", nopt_rem+1, nopt_mod); } else if (nopt_rem < 0) { bail(1, "Invalid '-n' argument, remainder '%d' must be > 0\n", nopt_rem+1); } else if (nopt_mod < 1) { bail(1, "Invalid '-n' argument, modulus '%d' must be > 0\n", nopt_mod); } } if (wopt < 1 || wopt > 28) { bail(1, "Invalid window size '%d' - must be >= 1 and <= 28\n", wopt); } else { // very rough sanity check of window size struct sysinfo info; sysinfo(&info); uint64_t sysram = info.mem_unit * info.totalram; if (3584LLU*(1<<wopt) > sysram) { bail(1, "Not enough ram for requested window size '%d'\n", wopt); } } if (topt != NULL) { if (strcmp(topt, "str") == 0) { input2hash160 = &pass2hash160; } else if (strcmp(topt, "hex") == 0) { input2hash160 = &hexpass2hash160; } else if (strcmp(topt, "priv") == 0) { input2hash160 = &hexpriv2hash160; } else if (strcmp(topt, "warp") == 0) { spok = 1; input2hash160 = popt ? &warpsalt2hash160 : &warppass2hash160; } else if (strcmp(topt, "bwio") == 0) { spok = 1; input2hash160 = popt ? &bwiosalt2hash160 : &bwiopass2hash160; } else if (strcmp(topt, "bv2") == 0) { spok = 1; input2hash160 = popt ? &brainv2salt2hash160 : &brainv2pass2hash160; } else if (strcmp(topt, "rush") == 0) { input2hash160 = &rush2hash160; } else { bail(1, "Unknown input type '%s'.\n", topt); } } else { topt = "str"; input2hash160 = &pass2hash160; } if (spok) { if (sopt && popt) { bail(1, "Cannot specify both a salt and a passphrase\n"); } if (popt) { kdfpass = popt; kdfpass_sz = strlen(popt); } else { if (sopt) { kdfsalt = sopt; kdfsalt_sz = strlen(kdfsalt); } else { kdfsalt = chkmalloc(0); kdfsalt_sz = 0; } } } else { if (popt) { bail(1, "Specifying a passphrase not supported with input type '%s'\n", topt); } else if (sopt) { bail(1, "Specifying a salt not supported with this input type '%s'\n", topt); } } if (ropt) { if (input2hash160 != &rush2hash160) { bail(1, "Specifying a url fragment only supported with input type 'rush'\n"); } kdfsalt = ropt; kdfsalt_sz = strlen(kdfsalt) - sizeof(rushchk)*2; if (kdfsalt[kdfsalt_sz-1] != '!') { bail(1, "Invalid rushwallet url fragment '%s'\n", kdfsalt); } unhex(kdfsalt+kdfsalt_sz, sizeof(rushchk)*2, rushchk, sizeof(rushchk)); kdfsalt[kdfsalt_sz] = '\0'; } else if (input2hash160 == &rush2hash160) { bail(1, "The '-r' option is required for rushwallet.\n"); } if (bopt) { if (Lopt) { bail(1, "The '-L' option cannot be used with a bloom filter\n"); } if ((ret = mmapf(&bloom_mmapf, bopt, BLOOM_SIZE, MMAPF_RNDRD)) != MMAPF_OKAY) { bail(1, "failed to open bloom filter '%s': %s\n", bopt, mmapf_strerror(ret)); } else if (bloom_mmapf.mem == NULL) { bail(1, "got NULL pointer trying to set up bloom filter\n"); } bloom = bloom_mmapf.mem; } if (fopt) { if (!bopt) { bail(1, "The '-f' option must be used with a bloom filter\n"); } if ((ffile = fopen(fopt, "r")) == NULL) { bail(1, "failed to open '%s' for reading: %s\n", fopt, strerror(errno)); } } if (iopt) { if ((ifile = fopen(iopt, "r")) == NULL) { bail(1, "failed to open '%s' for reading: %s\n", iopt, strerror(errno)); } // increases readahead window, don't really care if it fails posix_fadvise(fileno(ifile), 0, 0, POSIX_FADV_SEQUENTIAL); } if (oopt && (ofile = fopen(oopt, (aopt ? "a" : "w"))) == NULL) { bail(1, "failed to open '%s' for writing: %s\n", oopt, strerror(errno)); } /* line buffer output */ setvbuf(ofile, NULL, _IOLBF, 0); /* line buffer stderr */ setvbuf(stderr, NULL, _IOLBF, 0); if (vopt && ofile == stdout && isatty(fileno(stdout))) { tty = 1; } brainflayer_init_globals(); if (secp256k1_ec_pubkey_precomp_table(wopt, mopt) != 0) { bail(1, "failed to initialize precomputed table\n"); } if (vopt) { /* initialize timing data */ time_start = time_last = getns(); olines = ilines_last = ilines_curr = 0; ilines_rate_avg = -1; alpha = 0.500; } else { time_start = time_last = 0; // prevent compiler warning about uninitialized use } for (;;) { if ((line_read = getline(&line, &line_sz, ifile)-1) > -1) { if (skipping) { ++raw_lines; if (kopt && raw_lines < kopt) { continue; } if (nopt_mod && raw_lines % nopt_mod != nopt_rem) { continue; } } line[line_read] = 0; if (input2hash160(line, line_read) == 0) { if (bloom) { if (bloom_chk_hash160(bloom, hash160_uncmp.ul)) { if (!fopt || hsearchf(ffile, &hash160_uncmp)) { if (tty) { fprintf(ofile, "\033[0K"); } fprintresult(ofile, &hash160_uncmp, 'u', topt, line); ++olines; } } if (bloom_chk_hash160(bloom, hash160_compr.ul)) { if (!fopt || hsearchf(ffile, &hash160_compr)) { if (tty) { fprintf(ofile, "\033[0K"); } fprintresult(ofile, &hash160_compr, 'c', topt, line); ++olines; } } } else if (Lopt) { fprintlookup(ofile, &hash160_uncmp, &hash160_compr, priv256, topt, line); } else { fprintresult(ofile, &hash160_uncmp, 'u', topt, line); fprintresult(ofile, &hash160_compr, 'c', topt, line); } } } else { if (!vopt) break; } if (vopt) { ++ilines_curr; if (line_read < 0 || (ilines_curr & report_mask) == 0) { time_curr = getns(); time_delta = time_curr - time_last; time_elapsed = time_curr - time_start; time_last = time_curr; ilines_delta = ilines_curr - ilines_last; ilines_last = ilines_curr; ilines_rate = (ilines_delta * 1.0e9) / (time_delta * 1.0); if (line_read < 0) { /* report overall average on last status update */ ilines_rate_avg = (--ilines_curr * 1.0e9) / (time_elapsed * 1.0); } else if (ilines_rate_avg < 0) { ilines_rate_avg = ilines_rate; /* target reporting frequency to about once every five seconds */ } else if (time_delta < 2500000000) { report_mask = (report_mask << 1) | 1; ilines_rate_avg = ilines_rate; /* reset EMA */ } else if (time_delta > 10000000000) { report_mask >>= 1; ilines_rate_avg = ilines_rate; /* reset EMA */ } else { /* exponetial moving average */ ilines_rate_avg = alpha * ilines_rate + (1 - alpha) * ilines_rate_avg; } fprintf(stderr, "\033[0G\033[2K" " rate: %9.2f p/s" " found: %5zu/%-10zu" " elapsed: %8.3f s" "\033[0G", ilines_rate_avg, olines, ilines_curr, time_elapsed / 1.0e9 ); if (line_read < 0) { fprintf(stderr, "\n"); break; } else { fflush(stderr); } }