diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ff091..d68844a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.4) project(eosio-keygen VERSION 0.1.0) +option(USE_THREADS "Compile with support for threads (if available)." ON) + set( CMAKE_CXX_STANDARD 11 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) set( CMAKE_CXX_EXTENSIONS OFF ) @@ -10,6 +12,14 @@ set( INSTALL_SHARE_DIR share/${CMAKE_PROJECT_NAME} ) find_package(OpenSSL 1.1 REQUIRED) +if (USE_THREADS) + find_package(Threads) + if (Threads_FOUND) + # Add preprocessor flag + add_definitions( "-DHAVE_THREADS=1" ) + endif (Threads_FOUND) +endif (USE_THREADS) + include_directories( ${OPENSSL_INCLUDE_DIR} ) add_executable( ${CMAKE_PROJECT_NAME} @@ -18,10 +28,11 @@ add_executable( ${CMAKE_PROJECT_NAME} src/base58.cpp src/checksum.cpp src/WIF.cpp + src/key_search.cpp src/main.cpp ) -target_link_libraries( ${CMAKE_PROJECT_NAME} PUBLIC ${OPENSSL_LIBRARIES} ) +target_link_libraries( ${CMAKE_PROJECT_NAME} PUBLIC ${OPENSSL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) if (WIN32) if (CMAKE_SIZEOF_VOID_P EQUAL 8) diff --git a/src/key_search.cpp b/src/key_search.cpp new file mode 100644 index 0000000..24ddeb9 --- /dev/null +++ b/src/key_search.cpp @@ -0,0 +1,28 @@ + +#include +#include +#include "ec.h" +#include "WIF.h" +#include "key_search.h" + +void key_search(strlist_t word_list, size_t n) { + + size_t count = 0; + struct ec_keypair pair; + + while (count < n) { + std::string pubstr; + ec_generate_key(&pair); + pubstr = wif_pub_encode(pair.pub); + strtolower(pubstr); + + for(auto const& word: word_list) { + if (pubstr.find(word) != std::string::npos) { + std::cout << "----" << std::endl; + std::cout << "Found: " << word << std::endl; + wif_print_key(&pair); + count++; + } + } + } +} diff --git a/src/key_search.h b/src/key_search.h new file mode 100644 index 0000000..742195c --- /dev/null +++ b/src/key_search.h @@ -0,0 +1,31 @@ +/** + * 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. + */ +#ifndef KEY_SEARCH_H +#define KEY_SEARCH_H + +#include "string.h" + +void key_search(strlist_t word_list, size_t n); + +#endif /* KEY_SEARCH_H */ diff --git a/src/main.cpp b/src/main.cpp index 648c2b7..c035c48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,43 +28,76 @@ #include "base58.h" #include "WIF.h" #include "ec.h" +#include "key_search.h" -static void search(std::string words, size_t n) { +#ifdef HAVE_THREADS +#include +#include - size_t count = 0; - struct ec_keypair pair; - std::vector word_list; +// Minium number of threads. +#define MIN_THREADS 2 - std::cout << "Searching for " << n << " keys containing: " << words << std::endl; +// Number of threads to use. +static int n_threads; - word_list = strsplitwords(strtolower(words)); +#define search_func thread_search +static void thread_search(const strlist_t& words, int n) { - while (count < n) { - std::string pubstr; - ec_generate_key(&pair); - pubstr = wif_pub_encode(pair.pub); - strtolower(pubstr); + // create n_threads - 1 as we use main process also. + std::vector t(n_threads - 1); + // divide the number of results for all threads. + int d = n / n_threads; + // Also calculate the reminder (will be assigned to the main thread) + int m = n % n_threads; - for(auto const& word: word_list) { - if (pubstr.find(word) != std::string::npos) { - std::cout << "----" << std::endl; - std::cout << "Found: " << word << std::endl; - wif_print_key(&pair); - count++; - } - } + // Launch threads. + for(int i = 0; i < t.size(); i++) { + t[i] = std::thread(key_search, words, d); + } + + // Use main thread for 1 search + key_search(words, d + m); + + // Wait for all threads to compelete. + for(int i = 0; i < t.size(); i++) { + t[i].join(); } } +#else +#define search_func key_search +#endif int main(int argc, char **argv) { // search [ ] if (argc > 2 && !strcmp(argv[1], "search")) { int n = 100; + std::string search(argv[2]); + strlist_t words = strsplitwords(strtolower(search)); + if (argc > 3) { n = atoi(argv[3]); } - search(argv[2], n); + +#ifdef HAVE_THREADS + if (argc > 4) { + n_threads = atoi(argv[4]); + // Make sure we never go under min threads. + if (n_threads < MIN_THREADS) { + n_threads = MIN_THREADS; + } + } +# endif /* HAVE_THREADS */ + +std::cout << "Searching for " << n + << " keys containing: " << search +#ifdef HAVE_THREADS + << ", Using: " << n_threads << " threads" +#endif /* HAVE_THREADS */ + << std::endl; + + search_func(words, n); + } else { struct ec_keypair pair; ec_generate_key(&pair);