1
0
Fork 0
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:
Henrik Hautakoski 2020-02-18 15:08:48 +01:00
commit f84f474290
19 changed files with 97183 additions and 19 deletions

31
src/config.h.in Normal file
View 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
View 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
View 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 */

View file

@ -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++;
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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.

View file

@ -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++) {

View file

@ -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")) {