mirror of
https://github.com/eosswedenorg/antelope-keygen
synced 2026-06-18 04:00:03 +02:00
Merge branch 'dictionary' into develop
# Conflicts: # CMakeLists.txt # src/main.cpp
This commit is contained in:
commit
f84f474290
19 changed files with 97183 additions and 19 deletions
31
src/config.h.in
Normal file
31
src/config.h.in
Normal file
|
|
@ -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 CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
// Paths
|
||||
#define CONFIG_SHARE_PATH "@CMAKE_INSTALL_DATADIR@/@CMAKE_PROJECT_NAME@"
|
||||
#define CONFIG_SHARE_FULL_PATH "@CMAKE_INSTALL_FULL_DATADIR@/@CMAKE_PROJECT_NAME@"
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
106
src/core/dictionary.cpp
Normal file
106
src/core/dictionary.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include "../string.h"
|
||||
#include "dictionary.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)
|
||||
{
|
||||
FILE *fd;
|
||||
char buf[1024];
|
||||
|
||||
fd = fopen(filename.c_str(), "r");
|
||||
if (!fd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear before adding.
|
||||
clear();
|
||||
|
||||
// Read each line and add to the dictionary.
|
||||
while(fgets(buf, sizeof(buf), fd) != NULL) {
|
||||
std::string word(buf);
|
||||
add(trim(word));
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
72
src/core/dictionary.h
Normal file
72
src/core/dictionary.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* 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 EOSIOKEYGEN_DICTIONARY_H
|
||||
#define EOSIOKEYGEN_DICTIONARY_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace eoskeygen {
|
||||
|
||||
class Dictionary
|
||||
{
|
||||
public :
|
||||
//typedef std::map< std::string, std::vector<size_t> > search_result_t;
|
||||
|
||||
// index = position in the search string.
|
||||
// value = length of the word from this position.
|
||||
typedef std::map< size_t, size_t > search_result_t;
|
||||
|
||||
public :
|
||||
|
||||
// Load words from file.
|
||||
bool loadFromFile(const std::string& filename);
|
||||
|
||||
// Add a word
|
||||
void add(const std::string& word);
|
||||
|
||||
// Add words from another dictionary.
|
||||
void add(const Dictionary& dictionary);
|
||||
|
||||
void clear();
|
||||
|
||||
// Returns true if word exists in the dictionary.
|
||||
bool contains(const std::string& word) const;
|
||||
|
||||
// Searches the subject for words defined in the dictionary.
|
||||
// Returns a map with the word as key and a vector<int>
|
||||
// of each position the word was found.
|
||||
search_result_t search(const std::string& subject) const;
|
||||
|
||||
protected :
|
||||
|
||||
// Words in the dictionary.
|
||||
std::set<std::string> m_words;
|
||||
};
|
||||
|
||||
} // namespace eoskeygen
|
||||
|
||||
#endif /* EOSIOKEYGEN_DICTIONARY_H */
|
||||
|
|
@ -43,6 +43,11 @@ void KeySearch::addList(const strlist_t& list)
|
|||
}
|
||||
}
|
||||
|
||||
void KeySearch::addDictionary(const Dictionary& dictionary)
|
||||
{
|
||||
m_dict = dictionary;
|
||||
}
|
||||
|
||||
const strlist_t& KeySearch::getList()
|
||||
{
|
||||
return m_words;
|
||||
|
|
@ -62,7 +67,7 @@ void KeySearch::_search_linear(size_t n) {
|
|||
struct key_result res;
|
||||
ec_generate_key(&pair);
|
||||
if (key_contains_word(&pair, m_words, &res)) {
|
||||
key_search_result(&pair, &res);
|
||||
key_search_result(&pair, &res, m_dict);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#ifndef EOSIOKEYGEN_KEY_SEARCH_H
|
||||
#define EOSIOKEYGEN_KEY_SEARCH_H
|
||||
|
||||
#include "core/dictionary.h"
|
||||
#include "string.h"
|
||||
|
||||
namespace eoskeygen {
|
||||
|
|
@ -37,6 +38,8 @@ public :
|
|||
// Add a list of words to search for.
|
||||
void addList(const strlist_t& list);
|
||||
|
||||
void addDictionary(const Dictionary& dictionary);
|
||||
|
||||
// get the list of words to search for.
|
||||
const strlist_t& getList();
|
||||
|
||||
|
|
@ -54,6 +57,8 @@ public :
|
|||
protected :
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
void _thr_proc();
|
||||
|
||||
void _search_mt(size_t n);
|
||||
#endif /* HAVE_THREADS */
|
||||
|
||||
|
|
@ -63,6 +68,9 @@ protected :
|
|||
// List of words to search for.
|
||||
strlist_t m_words;
|
||||
|
||||
// Dictionary to use when we find a search result.
|
||||
Dictionary m_dict;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
// Number of threads to use.
|
||||
size_t m_threads;
|
||||
|
|
|
|||
|
|
@ -22,27 +22,48 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "core/dictionary.h"
|
||||
#include "WIF.h"
|
||||
#include "console.h"
|
||||
#include "key_search_helpers.h"
|
||||
|
||||
namespace eoskeygen {
|
||||
|
||||
void key_search_result(const struct ec_keypair* key, const struct key_result* result) {
|
||||
static size_t highlight(console::Color color, const std::string& str, size_t pos, size_t len) {
|
||||
|
||||
std::cout << console::fg(color, console::bold)
|
||||
<< str.substr(pos, len)
|
||||
<< console::reset;
|
||||
return len;
|
||||
}
|
||||
|
||||
void key_search_result(const struct ec_keypair* key, const struct key_result* result, const Dictionary& dict) {
|
||||
|
||||
std::string pub = wif_pub_encode(key->pub);
|
||||
std::string word = pub.substr(result->pos, result->len);
|
||||
Dictionary::search_result_t dict_res = dict.search(pub);
|
||||
|
||||
std::cout << "----" << std::endl;
|
||||
std::cout << "Found: " << word << std::endl;
|
||||
std::cout << "Found: " << pub.substr(result->pos, result->len) << std::endl;
|
||||
|
||||
std::cout << "Public: "
|
||||
<< pub.substr(0, result->pos)
|
||||
<< console::fg(console::red, console::bold) << word << console::reset
|
||||
<< pub.substr(result->pos + result->len)
|
||||
<< std::endl;
|
||||
std::cout << "Public: EOS";
|
||||
for(size_t i = 3; i < pub.length(); ) {
|
||||
|
||||
std::cout << "Private: " << wif_priv_encode(key->secret) << std::endl;
|
||||
if (i == result->pos) {
|
||||
i += highlight(console::red, pub, result->pos, result->len);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto p = dict_res.find(i);
|
||||
if (p != dict_res.end()) {
|
||||
i += highlight(console::blue, pub, p->first, p->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << pub[i++];
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Private: " << wif_priv_encode(key->secret) << std::endl;
|
||||
}
|
||||
|
||||
bool key_contains_word(const struct ec_keypair* key, const strlist_t& word_list, struct key_result *result) {
|
||||
|
|
|
|||
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
namespace eoskeygen {
|
||||
|
||||
class Dictionary;
|
||||
|
||||
struct key_result {
|
||||
size_t pos; // position where the word was found.
|
||||
size_t len; // the length of the word.
|
||||
};
|
||||
|
||||
void key_search_result(const struct ec_keypair* key, const struct key_result* result);
|
||||
void key_search_result(const struct ec_keypair* key, const struct key_result* result, const Dictionary& dict);
|
||||
|
||||
// Check if any word in <word_list> appears in <key>'s public key.
|
||||
// returns true if a word was found (stored in <result>), false otherwise.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ std::size_t g_count;
|
|||
std::mutex g_count_mtx;
|
||||
|
||||
// Thread process.
|
||||
static void _thr_proc(const strlist_t& word_list) {
|
||||
void KeySearch::_thr_proc() {
|
||||
|
||||
struct ec_keypair pair;
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ static void _thr_proc(const strlist_t& word_list) {
|
|||
struct key_result res;
|
||||
|
||||
ec_generate_key(&pair);
|
||||
if (key_contains_word(&pair, word_list, &res)) {
|
||||
if (key_contains_word(&pair, m_words, &res)) {
|
||||
|
||||
// Guard output with mutex, so we don't get
|
||||
// interrupted mid write and can write to g_count safely.
|
||||
|
|
@ -64,7 +64,7 @@ static void _thr_proc(const strlist_t& word_list) {
|
|||
|
||||
// Update count and print result.
|
||||
g_count++;
|
||||
key_search_result(&pair, &res);
|
||||
key_search_result(&pair, &res, m_dict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,11 +86,11 @@ void KeySearch::_search_mt(size_t n)
|
|||
|
||||
// Launch them.
|
||||
for(std::size_t i = 0; i < t.size(); i++) {
|
||||
t[i] = std::thread(_thr_proc, m_words);
|
||||
t[i] = std::thread(&KeySearch::_thr_proc, this);
|
||||
}
|
||||
|
||||
// Use main thread for 1 search
|
||||
_thr_proc(m_words);
|
||||
_thr_proc();
|
||||
|
||||
// Wait for all threads to compelete.
|
||||
for(std::size_t i = 0; i < t.size(); i++) {
|
||||
|
|
|
|||
46
src/main.cpp
46
src/main.cpp
|
|
@ -27,6 +27,8 @@
|
|||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "console.h"
|
||||
#include "config.h"
|
||||
#include "core/dictionary.h"
|
||||
#include "string.h"
|
||||
#include "WIF.h"
|
||||
#include "crypto/ec.h"
|
||||
|
|
@ -40,10 +42,12 @@ bool option_l33t = false;
|
|||
int option_num_threads = std::thread::hardware_concurrency();
|
||||
#endif /* HAVE_THREADS */
|
||||
|
||||
void cmd_search(const eoskeygen::strlist_t& words, int count) {
|
||||
void cmd_search(const eoskeygen::strlist_t& words, const eoskeygen::Dictionary& dict, int count) {
|
||||
|
||||
eoskeygen::KeySearch ks;
|
||||
|
||||
ks.addDictionary(dict);
|
||||
|
||||
if (option_l33t) {
|
||||
for(std::size_t i = 0; i < words.size(); i++) {
|
||||
ks.addList(eoskeygen::l33twords(words[i]));
|
||||
|
|
@ -73,7 +77,8 @@ void usage(const char *name) {
|
|||
#ifdef HAVE_THREADS
|
||||
<< " | --threads=<num>"
|
||||
#endif /* HAVE_THREADS */
|
||||
<< " ] <word_list> [ <count:10> ]"
|
||||
<< " | --dict=<file> ... "
|
||||
<< " | --lang=<value> ... ] <word_list> [ <count:10> ]"
|
||||
<< " | benchmark [ <num:1000> ]"
|
||||
<< " ]"
|
||||
<< std::endl << std::endl;
|
||||
|
|
@ -100,6 +105,17 @@ void usage(const char *name) {
|
|||
<< " --threads=<num>: Use <num> of parallel threads for searching." << std::endl
|
||||
<< " Default is what the operating system recomend."
|
||||
#endif /* HAVE_THREADS */
|
||||
<< std::endl << std::endl
|
||||
<< " --dict=<file>: Use words found in <file> (separated by newline) to" << std::endl
|
||||
<< " highlight words in the keys found (note that the words in this" << std::endl
|
||||
<< " file are not used for search. only for highlight output)." << std::endl
|
||||
<< " There can be more then one --dict flag. In that case contents" << std::endl
|
||||
<< " of all files are merged into one dictionary." << std::endl
|
||||
<< std::endl << std::endl
|
||||
<< " --lang=<value>: Same as --dict but will use <value>" << std::endl
|
||||
<< " to find a file in " << CONFIG_SHARE_FULL_PATH << "/dict." << std::endl
|
||||
<< " There can be more then one --lang flag. In that case contents" << std::endl
|
||||
<< " of all files are merged into one dictionary." << std::endl
|
||||
<< std::endl;
|
||||
|
||||
std::cout << " Benchmark: " << std::endl
|
||||
|
|
@ -143,6 +159,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
int count = 10;
|
||||
eoskeygen::strlist_t words;
|
||||
eoskeygen::Dictionary dict;
|
||||
|
||||
while(p++ < argc - 1) {
|
||||
if (!strcmp(argv[p], "-m")) {
|
||||
|
|
@ -164,6 +181,29 @@ int main(int argc, char **argv) {
|
|||
<< " thread support. this option is ignored." << std::endl;
|
||||
#endif /* HAVE_THREADS */
|
||||
}
|
||||
// Dictionary.
|
||||
else if (!memcmp(argv[p], "--dict=", 7)) {
|
||||
eoskeygen::Dictionary d;
|
||||
std::string filename(argv[p] + 7);
|
||||
|
||||
if (d.loadFromFile(filename)) {
|
||||
dict.add(d);
|
||||
} else {
|
||||
std::cerr << "Could not load dictionary from file: " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
// Language (dictionary, but we find the file in <CONFIG_SHARE_FULL_PATH>/dict/<lang>)
|
||||
else if (!memcmp(argv[p], "--lang=", 7)) {
|
||||
eoskeygen::Dictionary d;
|
||||
std::string lang(argv[p] + 7);
|
||||
std::string filename(std::string(CONFIG_SHARE_FULL_PATH) + "/dict" + lang);
|
||||
|
||||
if (d.loadFromFile(filename)) {
|
||||
dict.add(d);
|
||||
} else {
|
||||
std::cerr << "Could not load language " << lang << " (" << filename << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
// Error out on any flag we don't support.
|
||||
else if (argv[p][0] == '-') {
|
||||
std::cerr << "Unrecognized flag: " << argv[p] << std::endl;
|
||||
|
|
@ -189,7 +229,7 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
cmd_search(words, count);
|
||||
cmd_search(words, dict, count);
|
||||
}
|
||||
// Benchmark
|
||||
else if (!strcmp(argv[p], "benchmark")) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue