Esempio n. 1
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);
        }
      }
int main(int argc, char **argv) {
	int rank;
	int size;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	printf("Moin. I'm process %d of %d processes.\n", rank, size);
	//FILE *ifile = stdin;
	//MPI_File ifile = stdin;
	MPI_File ifile;
	FILE *ofile = stdout;

	int c, spok = 0, aopt = 0;
	unsigned char *bopt = NULL, *iopt = NULL, *oopt = NULL;
	unsigned char *topt = NULL, *sopt = NULL, *popt = NULL;
	unsigned char *Wopt = NULL;

	while ((c = getopt(argc, argv, "ab:hi:o:p:s:t:W:")) != -1) {
		switch (c) {
		case 'a':
			aopt = 1; // open output file in append mode
			break;
		case 'b':
			bopt = optarg; // bloom 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 't':
			topt = optarg; // type of input
			break;
		case 'W':
			Wopt = optarg;
			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 (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;
			if (popt && strcmp(popt, "hello world") == 0
					&& (Wopt == NULL
							|| strcmp(Wopt, "NEVER_TELL_ME_THE_ODDS") != 0)) {
				// https://www.youtube.com/watch?v=NHWjlCaIrQo
				for (c = 0; c < 100; ++c)
					fprintf(stderr, "\n"); // try not to clobber scrollback
				fprintf(stderr, "\033[2J\033[0;0H\033[0;0f"); // clear terminal and send cursor to top left
				fflush(stderr);
				sleep(1);
				fprintf(stderr, "A STRANGE GAME.\n");
				sleep(2);
				fprintf(stderr, "THE ONLY WINNING MOVE IS NOT TO PLAY.\n");
				sleep(2);
				fprintf(stderr,
						"\n"
								"So, you're looking for that sweet, sweet 0.5BTC bounty? Brainflayer's\n"
								"cracking speed against brainwallet.io had been communicated to them before\n"
								"the challange was created. It is likely that the salt was chosen to be\n"
								"infeasible to crack in the given timeframe by a significant margin. I advise\n"
								"against trying it - it's probably a waste time and money. If you want to do it\n"
								"anyway, run with `-W NEVER_TELL_ME_THE_ODDS`.\n");
				sleep(2);
				fprintf(stderr,
						"\nAs for me, I have better things to do with my CPU cycles.\n");
				sleep(3);
				bail(83, "CONNECTION TERMINATED\n");
			}
			input2hash160 = popt ? &bwiosalt2hash160 : &bwiopass2hash160;
		} else if (strcmp(topt, "bv2") == 0) {
			spok = 1;
			input2hash160 = popt ? &brainv2salt2hash160 : &brainv2pass2hash160;
		} 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 = malloc(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 (bopt) {
		if ((bloom = bloom_open(bopt)) == NULL) {
			bail(1, "failed to open bloom filter.\n");
		}
	}

	if (iopt) {
		if (MPI_File_open(MPI_COMM_WORLD, iopt, MPI_MODE_RDONLY, MPI_INFO_NULL,
				&ifile)) {
			bail(1, "failed to open '%s' for reading: %s\n", iopt,
					strerror(errno));
		}
	}

	if (oopt) {
		if ((ofile = fopen(oopt, (aopt ? "a" : "w"))) == NULL) {
			bail(1, "failed to open '%s' for writing: %s\n", oopt,
					strerror(errno));
		}
	}

	/* use line buffered output */
	setvbuf(ofile, NULL, _IOLBF, 0);
	setvbuf(stderr, NULL, _IONBF, 0);

	secp256k1_start();
	const int overlap = 100;
	char **lines;
	int nlines;
	readlines(&ifile, rank, size, overlap, &lines, &nlines);
	fprintf(ofile, "----Welcome %d! %d Lines for you.----\n", rank, nlines);
	int index = 0;
	time_t start, end;
	double length;
	time(&start);
	for (int i = 0; i < nlines - 1; i++) {
		++index;
		input2hash160(lines[i], strlen(lines[i]));
		if (bloom) {
			if (bloom_chk_hash160(bloom, hash160_uncmp.ul)) {
				fprintresult(ofile, &hash160_uncmp, 'u', topt, lines[i]);
			}
			if (bloom_chk_hash160(bloom, hash160_compr.ul)) {
				fprintresult(ofile, &hash160_compr, 'c', topt, lines[i]);
			}
		} else {
			fprintresult(ofile, &hash160_uncmp, 'u', topt, lines[i]);
			fprintresult(ofile, &hash160_compr, 'c', topt, lines[i]);
		}
	}
	time(&end);
	length = difftime(end, start);
	double perSecond = index / length;
	fprintf(ofile, "----Process: %d, Lines: %d, speed: %.0f/sec!----\n", rank, index, perSecond);
	secp256k1_stop();
	MPI_File_close(&ifile);
	MPI_Finalize();
	return 0;
}