1
0
Fork 0
mirror of https://github.com/eosswedenorg/antelope-keygen synced 2026-06-18 04:00:03 +02:00

Use remove library files and use libeoskeygen

This commit is contained in:
Henrik Hautakoski 2020-03-23 13:43:39 +01:00
parent 6c26ce8ac6
commit 086d9e1241
22 changed files with 40 additions and 1407 deletions

View file

@ -1,103 +0,0 @@
#include <vector>
#include <iostream>
#include <cstdio>
#include <iterator>
#include <algorithm>
#include <eoskeygen/core/string.h>
#include <eoskeygen/core/dictionary.h>
#include <eoskeygen/core/file.h>
namespace eoskeygen {
struct StringContains {
StringContains(const std::string& str, std::vector<size_t>& pos) : m_str(str), m_pos(pos) {}
bool operator()(const std::string& w) {
for(size_t p = m_str.find(w); p != std::string::npos; p = m_str.find(w, p+1)) {
m_pos.push_back(p);
}
return !m_pos.empty();
}
std::string m_str;
std::vector<size_t>& m_pos;
};
bool Dictionary::loadFromFile(const std::string& filename)
{
strlist_t lines;
// Clear before adding.
clear();
if (readLines(filename, lines)) {
// Read each line and add to the dictionary.
for(auto it = lines.begin(); it != lines.end(); it++) {
add(*it);
}
return true;
}
return false;
}
void Dictionary::add(const std::string& word)
{
// Do not insert a empty string.
if (word.length()) {
m_words.insert(word);
}
}
void Dictionary::add(const Dictionary& dictionary)
{
std::set_union(
m_words.begin(), m_words.end(),
dictionary.m_words.begin(), dictionary.m_words.end(),
std::inserter(m_words, m_words.begin())
);
}
void Dictionary::clear()
{
m_words.clear();
}
bool Dictionary::contains(const std::string& word) const
{
return m_words.find(word) != m_words.cend();
}
Dictionary::search_result_t Dictionary::search(const std::string& subject) const
{
search_result_t res;
std::vector<size_t> pos;
StringContains pred(subject, pos);
// Find all words.
for(auto it = std::find_if(m_words.begin(), m_words.end(), pred);
it != m_words.end();
it = std::find_if(++it, m_words.end(), pred)) {
// Go through all found positions.
for (auto it2 = pos.begin(); it2 != pos.end(); it2++) {
// Insert
auto rit = res.find(*it2);
if (rit == res.end()) {
res.emplace(*it2, it->length());
}
// Update length if it's longer then the previous we found.
else if (rit->second < it->length()) {
rit->second = it->length();
}
}
// Clear positions
pos.clear();
}
return res;
}
} // namespace eoskeygen

View file

@ -1,26 +0,0 @@
#include <cstdio>
#include <eoskeygen/core/file.h>
namespace eoskeygen {
bool readLines(const std::string& filename, strlist_t& lines) {
FILE *fd;
char buf[1024];
fd = fopen(filename.c_str(), "r");
if (!fd) {
return false;
}
while(fgets(buf, sizeof(buf), fd) != NULL) {
std::string line(buf);
lines.push_back(trim(line));
}
fclose(fd);
return true;
}
} // namespace eoskeygen

View file

@ -1,151 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <cstddef>
#include <cctype>
#include <algorithm>
#include <eoskeygen/crypto/base58.h>
#include <eoskeygen/core/string.h>
namespace eoskeygen {
strlist_t strsplitwords(const std::string& str, const std::string& delim) {
strlist_t words = strsplit(str, delim);
std::for_each(words.begin(), words.end(), trim);
return words;
}
strlist_t strsplit(const std::string& str, const std::string& delim) {
strlist_t r;
size_t s = 0, e = 0, dlen = delim.length();
while((e = str.find(delim, s)) != std::string::npos) {
r.push_back(str.substr(s, e - s));
s = e + dlen;
}
r.push_back(str.substr(s));
return r;
}
std::string strjoin(const strlist_t& list, const std::string& delim) {
std::string out;
for(const std::string& item : list) {
if (item.length() < 1) {
continue;
}
out += item + delim;
}
if (out.length() > 0) {
out.erase(out.end() - delim.length());
}
return out;
}
std::string& strtolower(std::string& str) {
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::tolower(c); });
return str;
}
std::string& ltrim(std::string& str) {
auto it = std::find_if(str.begin(), str.end(), [](char ch){ return !std::isspace(ch); });
str.erase(str.begin(), it);
return str;
}
std::string& rtrim(std::string& str) {
auto it = std::find_if(str.rbegin(), str.rend(), [](char ch){ return !std::isspace(ch); });
str.erase(it.base(), str.end());
return str;
}
std::string& trim(std::string& str) {
return ltrim(rtrim(str));
}
strlist_t& base58_strip(strlist_t& list) {
std::transform(list.begin(), list.end(), list.begin(), [](std::string& str){ return base58_strip(str); });
return list;
}
static bool is_l33t(char ch, char& r) {
// '1', '2', '3', '4', '5', '6', '7', '8', '9'
static char alphabet[9] = { 'l', 'z', 'e', 'a', 's', 'G', 't', 'B', 'g' };
for(std::size_t i = 0; i < sizeof(alphabet) / sizeof(char); i++) {
if (ch == alphabet[i]) {
r = static_cast<char>('1' + i);
return true;
}
}
return false;
}
static void _l33t(strlist_t& list, const std::string& a, std::size_t pos) {
// Find the next character to be replaced.
for(std::size_t i = pos; i < a.length(); i++) {
char ch;
if (is_l33t(a[i], ch)) {
// create a new string and replace the character.
std::string b = a;
b[i] = ch;
// Store the new string as the result.
list.push_back(b);
// Perform the same algorithm for both strings
// at the next position.
_l33t(list, a, i + 1);
_l33t(list, b, i + 1);
break;
}
}
}
strlist_t l33twords(std::string str) {
strlist_t list;
// "l" is abit special and are not included in base58 so we set it to 1.
// All other characters in "l33t" are valid.
std::transform(str.begin(), str.end(), str.begin(), [](char c){ return c == 'l' ? '1' : c; });
// Store the original string as the first in list.
list.push_back(str);
_l33t(list, str, 0);
return list;
}
} // namespace eoskeygen

View file

@ -1,66 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <iostream>
#include <string.h>
#include <eoskeygen/crypto/base58.h>
#include <eoskeygen/crypto/checksum.h>
#include <eoskeygen/crypto/WIF.h>
namespace eoskeygen {
#define PRIV_KEY_PREFIX 0x80 /* 0x80 for "Bitcoin mainnet". Always used by EOS. */
std::string wif_priv_encode(ec_privkey_t priv) {
checksum_t check;
// 1 byte extra for prefix.
unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { PRIV_KEY_PREFIX };
memcpy(buf + 1, priv.data(), priv.size());
// Checksum
check = checksum_sha256d(buf, 1 + EC_PRIVKEY_SIZE);
memcpy(buf + 1 + EC_PRIVKEY_SIZE, check.data(), check.size());
return base58_encode(buf, buf + sizeof(buf));
}
std::string wif_pub_encode(ec_pubkey_t pub) {
checksum_t check = checksum_ripemd160(pub.data(), pub.size());
unsigned char buf[EC_PUBKEY_SIZE + CHECKSUM_SIZE];
memcpy(buf, pub.data(), pub.size());
memcpy(buf + EC_PUBKEY_SIZE, check.data(), check.size());
return "EOS" + base58_encode(buf, buf + sizeof(buf));
}
void wif_print_key(const struct ec_keypair *key) {
std::cout << "Public: " << wif_pub_encode(key->pub) << std::endl;
std::cout << "Private: " << wif_priv_encode(key->secret) << std::endl;
}
} // namespace eoskeygen

View file

@ -1,113 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2009-2019 The Bitcoin Core developers
* Copyright (c) 2009-2019 Bitcoin Developers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Based on code from https://github.com/bitcoin/bitcoin/blob/f1e2f2a85962c1664e4e55471061af0eaa798d40/src/base58.cpp
*/
#include <algorithm>
#include <cstddef>
#include <cassert>
#include <eoskeygen/crypto/base58.h>
namespace eoskeygen {
static const char charmap[59] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
std::string base58_encode(const unsigned char* pbegin, const unsigned char* pend) {
// Skip & count leading zeroes.
int zeroes = 0;
int length = 0;
while (pbegin != pend && *pbegin == 0) {
pbegin++;
zeroes++;
}
// Allocate enough space in big-endian base58 representation.
std::size_t size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up.
std::vector<unsigned char> b58(size);
// Process the bytes.
while (pbegin != pend) {
int carry = *pbegin;
int i = 0;
// Apply "b58 = b58 * 256 + ch".
for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) {
carry += 256 * (*it);
*it = static_cast<unsigned char>(carry % 58);
carry /= 58;
}
assert(carry == 0);
length = i;
pbegin++;
}
// Skip leading zeroes in base58 result.
std::vector<unsigned char>::iterator it = b58.begin() + (size - length);
while (it != b58.end() && *it == 0)
it++;
// Translate the result into a string.
std::string str;
str.reserve(zeroes + (b58.end() - it));
str.assign(zeroes, '1');
while (it != b58.end())
str += charmap[*(it++)];
return str;
}
std::string base58_encode(const std::string& str) {
const unsigned char *ptr = (const unsigned char *) str.c_str();
return base58_encode(ptr, ptr + str.length());
}
std::string base58_encode(const std::vector<unsigned char>& vch) {
return base58_encode(vch.data(), vch.data() + vch.size());
}
bool is_base58(char ch) {
for(unsigned int i=0; i < sizeof(charmap); i++) {
if (ch == charmap[i]) {
return true;
}
}
return false;
}
size_t is_base58(const std::string& str) {
auto p = std::find_if_not(str.begin(), str.end(), static_cast<bool (*)(char)>(is_base58));
if (p == str.end()) {
return std::string::npos;
}
return p - str.begin();
}
std::string& base58_strip(std::string &str) {
str.erase(std::remove_if(str.begin(), str.end(), [] (std::string::value_type ch)
{ return is_base58(ch) == false; }
), str.end());
return str;
}
} // namespace eoskeygen

View file

@ -1,70 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/hmac.h>
#include <eoskeygen/crypto/ec.h>
namespace eoskeygen {
int ec_generate_key(struct ec_keypair *pair) {
int ret = -1;
EC_KEY *k;
BN_CTX *ctx;
// Create BIGNUM context.
ctx = BN_CTX_new();
if (ctx == NULL) {
return -1;
}
// Construct curve.
k = EC_KEY_new_by_curve_name(NID_secp256k1);
if (k == NULL) {
goto fail1;
}
// Generate new key pair.
if (EC_KEY_generate_key(k) != 1) {
goto fail2;
}
// Copy private key to binary format.
EC_KEY_priv2oct(k, pair->secret.data(), EC_PRIVKEY_SIZE);
// Copy public key
EC_POINT_point2oct(EC_KEY_get0_group(k),
EC_KEY_get0_public_key(k), POINT_CONVERSION_COMPRESSED,
pair->pub.data(), EC_PUBKEY_SIZE, ctx);
ret = 0;
fail2:
EC_KEY_free(k);
fail1:
BN_CTX_free(ctx);
return ret;
}
} // namespace eoskeygen

View file

@ -1,43 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <eoskeygen/crypto/hash.h>
namespace eoskeygen {
sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out) {
return (sha256_t *) SHA256(data, len, out->data);
}
sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out) {
SHA256(data, len, out->data);
return (sha256_t *) SHA256(out->data, 32, out->data);
}
ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out) {
return (ripemd160_t *) RIPEMD160(data, len, out->data);
}
} // namespace eoskeygen

View file

@ -1,106 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string>
#include <eoskeygen/crypto/ec.h>
#include <eoskeygen/crypto/WIF.h>
#include <eoskeygen/key_search_result.h>
#include <eoskeygen/key_search.h>
namespace eoskeygen {
void KeySearch::addWord(const std::string& str)
{
std::string tmp = str;
strtolower(tmp);
m_words.push_back(tmp);
}
void KeySearch::addList(const strlist_t& list)
{
for(const std::string& item : list) {
addWord(item);
}
}
const strlist_t& KeySearch::getList()
{
return m_words;
}
void KeySearch::clear()
{
m_words.clear();
}
void KeySearch::setCallback(IKeySearchResult* callback)
{
m_callback = callback;
}
void KeySearch::_search_linear(size_t n) {
size_t count = 0;
struct ec_keypair pair;
while (count < n) {
struct result res;
ec_generate_key(&pair);
if (_contains_word(&pair, res)) {
m_callback->onResult(&pair, res);
count++;
}
}
}
void KeySearch::find(size_t num_results) {
#ifdef HAVE_THREADS
// Only do multithread if number of threads makes sense.
if (m_threads >= 2) {
_search_mt(num_results);
return;
}
#endif /* HAVE_THREADS */
_search_linear(num_results);
}
bool KeySearch::_contains_word(const struct ec_keypair* key, struct result& result) {
// skip first 3 chars, as those are always "EOS"
std::string pubstr = wif_pub_encode(key->pub).substr(3);
strtolower(pubstr);
for(auto const& w: m_words) {
size_t p = pubstr.find(w);
if (p != std::string::npos) {
result.pos = p + 3;
result.len = w.length();
return true;
}
}
return false;
}
} // namespace eoskeygen

View file

@ -1,101 +0,0 @@
/**
* MIT License
*
* Copyright (c) 2019-2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <cstddef>
#include <thread>
#include <mutex>
#include <vector>
#include <eoskeygen/crypto/ec.h>
#include <eoskeygen/key_search_result.h>
#include <eoskeygen/key_search.h>
namespace eoskeygen {
// Max keys to search for,
std::size_t g_max;
// How many keys we have found so far.
std::size_t g_count;
// Mutex guard for g_count.
std::mutex g_count_mtx;
// Thread process.
void KeySearch::_thr_proc() {
struct ec_keypair pair;
while (g_count < g_max) {
struct result res;
ec_generate_key(&pair);
if (_contains_word(&pair, res)) {
// Guard output with mutex, so we don't get
// interrupted mid write and can write to g_count and res safely.
const std::lock_guard<std::mutex> lock(g_count_mtx);
// It is possible g_count was updated by another thread
// after we checked it in the while loop.
// So while we have the lock, we need to check it again.
if (g_count >= g_max) {
return;
}
// Update count and call result function.
g_count++;
m_callback->onResult(&pair, res);
}
}
}
void KeySearch::setThreadCount(size_t num)
{
m_threads = num;
}
void KeySearch::_search_mt(size_t n)
{
std::vector<std::thread> t;
t.resize(m_threads - 1);
// Setup global variables for the threads.
g_max = n;
g_count = 0;
// Launch them.
for(std::size_t i = 0; i < t.size(); i++) {
t[i] = std::thread(&KeySearch::_thr_proc, this);
}
// Use main thread for 1 search
_thr_proc();
// Wait for all threads to compelete.
for(std::size_t i = 0; i < t.size(); i++) {
t[i].join();
}
}
} // namespace eoskeygen