aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormonero-project <sempre.amaro@gmail.com>2014-06-12 19:14:25 -0400
committermonero-project <sempre.amaro@gmail.com>2014-06-12 19:14:25 -0400
commitc3203c86c671d41ed4a07231c8a5054124d2e7d2 (patch)
tree06a7aceb34d1e53ca4bfd28d3fbc13b5ef0d8a30
parentnew error code for rpc (diff)
parentallow two-random-numbers wallet generation (but not as default) (diff)
downloadmonero-c3203c86c671d41ed4a07231c8a5054124d2e7d2.tar.xz
Merge pull request #34 from tewinget/master
Add electrum-seed wallet backup/recovery
-rw-r--r--.gitignore4
-rw-r--r--src/common/command_line.cpp12
-rw-r--r--src/common/command_line.h3
-rw-r--r--src/common/pod-class.h6
-rw-r--r--src/crypto/crypto.cpp25
-rw-r--r--src/crypto/crypto.h8
-rw-r--r--src/crypto/electrum-words.cpp110
-rw-r--r--src/crypto/electrum-words.h3280
-rw-r--r--src/cryptonote_core/account.cpp16
-rw-r--r--src/cryptonote_core/account.h2
-rw-r--r--src/simplewallet/simplewallet.cpp106
-rw-r--r--src/simplewallet/simplewallet.h9
-rw-r--r--src/wallet/wallet2.cpp7
-rw-r--r--src/wallet/wallet2.h3
-rw-r--r--src/wallet/wallet_errors.h11
15 files changed, 3567 insertions, 35 deletions
diff --git a/.gitignore b/.gitignore
index 20a3894a6..527864624 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
.DS_Store
/build
/tags
+
+# vim swap files
+*.swp
+*.swo
diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp
index 0b90345d9..d507f36a7 100644
--- a/src/common/command_line.cpp
+++ b/src/common/command_line.cpp
@@ -3,9 +3,21 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "command_line.h"
+#include "string_tools.h"
namespace command_line
{
+ std::string input_line(const std::string& prompt)
+ {
+ std::cout << prompt;
+
+ std::string buf;
+ std::getline(std::cin, buf);
+
+ return epee::string_tools::trim(buf);
+
+ }
+
const arg_descriptor<bool> arg_help = {"help", "Produce help message"};
const arg_descriptor<bool> arg_version = {"version", "Output version information"};
const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"};
diff --git a/src/common/command_line.h b/src/common/command_line.h
index 860653772..a6f78569c 100644
--- a/src/common/command_line.h
+++ b/src/common/command_line.h
@@ -14,6 +14,9 @@
namespace command_line
{
+
+ std::string input_line(const std::string& prompt);
+
template<typename T, bool required = false>
struct arg_descriptor;
diff --git a/src/common/pod-class.h b/src/common/pod-class.h
index c07edb208..10d680484 100644
--- a/src/common/pod-class.h
+++ b/src/common/pod-class.h
@@ -4,8 +4,14 @@
#pragma once
+// FIXME: Why is this ifdef needed? Hopefully making it struct won't break things.
+
+/*
#if defined(_MSC_VER)
#define POD_CLASS struct
#else
#define POD_CLASS class
#endif
+*/
+
+#define POD_CLASS struct
diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp
index f5f525700..98a17a3e4 100644
--- a/src/crypto/crypto.cpp
+++ b/src/crypto/crypto.cpp
@@ -50,6 +50,7 @@ namespace crypto {
return &reinterpret_cast<const unsigned char &>(scalar);
}
+ /* generate a random 32-byte (256-bit) integer and copy it to res */
static inline void random_scalar(ec_scalar &res) {
unsigned char tmp[64];
generate_random_bytes(64, tmp);
@@ -62,12 +63,32 @@ namespace crypto {
sc_reduce32(&res);
}
- void crypto_ops::generate_keys(public_key &pub, secret_key &sec) {
+ /*
+ * generate public and secret keys from a random 256-bit integer
+ * TODO: allow specifiying random value (for wallet recovery)
+ *
+ */
+ secret_key crypto_ops::generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover) {
lock_guard<mutex> lock(random_lock);
ge_p3 point;
- random_scalar(sec);
+
+ secret_key rng;
+
+ if (recover)
+ {
+ rng = recovery_key;
+ }
+ else
+ {
+ random_scalar(rng);
+ }
+ sec = rng;
+ sc_reduce32(&sec); // reduce in case second round of keys (sendkeys)
+
ge_scalarmult_base(&point, &sec);
ge_p3_tobytes(&pub, &point);
+
+ return rng;
}
bool crypto_ops::check_key(const public_key &key) {
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 61641fbcf..024713df1 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -62,8 +62,8 @@ namespace crypto {
void operator=(const crypto_ops &);
~crypto_ops();
- static void generate_keys(public_key &, secret_key &);
- friend void generate_keys(public_key &, secret_key &);
+ static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false);
+ friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover);
static bool check_key(const public_key &);
friend bool check_key(const public_key &);
static bool secret_key_to_public_key(const secret_key &, public_key &);
@@ -102,8 +102,8 @@ namespace crypto {
/* Generate a new key pair
*/
- inline void generate_keys(public_key &pub, secret_key &sec) {
- crypto_ops::generate_keys(pub, sec);
+ inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
+ return crypto_ops::generate_keys(pub, sec, recovery_key, recover);
}
/* Check a public key. Returns true if it is valid, false otherwise.
diff --git a/src/crypto/electrum-words.cpp b/src/crypto/electrum-words.cpp
new file mode 100644
index 000000000..96a392d04
--- /dev/null
+++ b/src/crypto/electrum-words.cpp
@@ -0,0 +1,110 @@
+/*
+ * This file and its header file are for translating Electrum-style word lists
+ * into their equivalent byte representations for cross-compatibility with
+ * that method of "backing up" one's wallet keys.
+ */
+
+#include <string>
+#include <cassert>
+#include <map>
+#include <cstdint>
+#include <vector>
+#include <boost/algorithm/string.hpp>
+#include "crypto/crypto.h" // for declaration of crypto::secret_key
+
+#include "crypto/electrum-words.h"
+
+namespace crypto
+{
+ namespace ElectrumWords
+ {
+
+ /* convert words to bytes, 3 words -> 4 bytes
+ * returns:
+ * false if not a multiple of 3 words, or if a words is not in the
+ * words list
+ *
+ * true otherwise
+ */
+ bool words_to_bytes(const std::string& words, crypto::secret_key& dst)
+ {
+ int n = NUMWORDS; // hardcoded because this is what electrum uses
+
+ std::vector<std::string> wlist;
+
+ boost::split(wlist, words, boost::is_any_of(" "));
+
+ // error on non-compliant word list
+ if (wlist.size() != 12 && wlist.size() != 24) return false;
+
+ for (unsigned int i=0; i < wlist.size() / 3; i++)
+ {
+ uint32_t val;
+ uint32_t w1, w2, w3;
+
+ // verify all three words exist in the word list
+ if (wordsMap.count(wlist[i*3]) == 0 ||
+ wordsMap.count(wlist[i*3 + 1]) == 0 ||
+ wordsMap.count(wlist[i*3 + 2]) == 0)
+ {
+ return false;
+ }
+
+ w1 = wordsMap.at(wlist[i*3]);
+ w2 = wordsMap.at(wlist[i*3 + 1]);
+ w3 = wordsMap.at(wlist[i*3 + 2]);
+
+ val = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n);
+
+ if (!(val % n == w1)) return false;
+
+ memcpy(dst.data + i * 4, &val, 4); // copy 4 bytes to position
+ }
+
+ std::string wlist_copy = words;
+ if (wlist.size() == 12)
+ {
+ memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate
+ wlist_copy += ' ';
+ wlist_copy += words;
+ }
+
+ return true;
+ }
+
+ /* convert bytes to words, 4 bytes-> 3 words
+ * returns:
+ * false if wrong number of bytes (shouldn't be possible)
+ * true otherwise
+ */
+ bool bytes_to_words(const crypto::secret_key& src, std::string& words)
+ {
+ int n = NUMWORDS; // hardcoded because this is what electrum uses
+
+ if (sizeof(src.data) % 4 != 0) return false;
+
+ // 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626
+ for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ')
+ {
+ uint32_t w1, w2, w3;
+
+ uint32_t val;
+
+ memcpy(&val, (src.data) + (i * 4), 4);
+
+ w1 = val % n;
+ w2 = ((val / n) + w1) % n;
+ w3 = (((val / n) / n) + w2) % n;
+
+ words += wordsArray[w1];
+ words += ' ';
+ words += wordsArray[w2];
+ words += ' ';
+ words += wordsArray[w3];
+ }
+ return false;
+ }
+
+ } // namespace ElectrumWords
+
+} // namespace crypto
diff --git a/src/crypto/electrum-words.h b/src/crypto/electrum-words.h
new file mode 100644
index 000000000..a533299bd
--- /dev/null
+++ b/src/crypto/electrum-words.h
@@ -0,0 +1,3280 @@
+/*
+ * This file and its cpp file are for translating Electrum-style word lists
+ * into their equivalent byte representations for cross-compatibility with
+ * that method of "backing up" one's wallet keys.
+ */
+
+#include <string>
+#include <cstdint>
+#include <map>
+#include "crypto/crypto.h" // for declaration of crypto::secret_key
+
+namespace crypto
+{
+ namespace ElectrumWords
+ {
+
+ const int NUMWORDS = 1626;
+
+ bool words_to_bytes(const std::string& words, crypto::secret_key& dst);
+ bool bytes_to_words(const crypto::secret_key& src, std::string& words);
+
+ const std::map<std::string,uint32_t> wordsMap = {
+ {"like", 0},
+ {"just", 1},
+ {"love", 2},
+ {"know", 3},
+ {"never", 4},
+ {"want", 5},
+ {"time", 6},
+ {"out", 7},
+ {"there", 8},
+ {"make", 9},
+ {"look", 10},
+ {"eye", 11},
+ {"down", 12},
+ {"only", 13},
+ {"think", 14},
+ {"heart", 15},
+ {"back", 16},
+ {"then", 17},
+ {"into", 18},
+ {"about", 19},
+ {"more", 20},
+ {"away", 21},
+ {"still", 22},
+ {"them", 23},
+ {"take", 24},
+ {"thing", 25},
+ {"even", 26},
+ {"through", 27},
+ {"long", 28},
+ {"always", 29},
+ {"world", 30},
+ {"too", 31},
+ {"friend", 32},
+ {"tell", 33},
+ {"try", 34},
+ {"hand", 35},
+ {"thought", 36},
+ {"over", 37},
+ {"here", 38},
+ {"other", 39},
+ {"need", 40},
+ {"smile", 41},
+ {"again", 42},
+ {"much", 43},
+ {"cry", 44},
+ {"been", 45},
+ {"night", 46},
+ {"ever", 47},
+ {"little", 48},
+ {"said", 49},
+ {"end", 50},
+ {"some", 51},
+ {"those", 52},
+ {"around", 53},
+ {"mind", 54},
+ {"people", 55},
+ {"girl", 56},
+ {"leave", 57},
+ {"dream", 58},
+ {"left", 59},
+ {"turn", 60},
+ {"myself", 61},
+ {"give", 62},
+ {"nothing", 63},
+ {"really", 64},
+ {"off", 65},
+ {"before", 66},
+ {"something", 67},
+ {"find", 68},
+ {"walk", 69},
+ {"wish", 70},
+ {"good", 71},
+ {"once", 72},
+ {"place", 73},
+ {"ask", 74},
+ {"stop", 75},
+ {"keep", 76},
+ {"watch", 77},
+ {"seem", 78},
+ {"everything", 79},
+ {"wait", 80},
+ {"got", 81},
+ {"yet", 82},
+ {"made", 83},
+ {"remember", 84},
+ {"start", 85},
+ {"alone", 86},
+ {"run", 87},
+ {"hope", 88},
+ {"maybe", 89},
+ {"believe", 90},
+ {"body", 91},
+ {"hate", 92},
+ {"after", 93},
+ {"close", 94},
+ {"talk", 95},
+ {"stand", 96},
+ {"own", 97},
+ {"each", 98},
+ {"hurt", 99},
+ {"help", 100},
+ {"home", 101},
+ {"god", 102},
+ {"soul", 103},
+ {"new", 104},
+ {"many", 105},
+ {"two", 106},
+ {"inside", 107},
+ {"should", 108},
+ {"true", 109},
+ {"first", 110},
+ {"fear", 111},
+ {"mean", 112},
+ {"better", 113},
+ {"play", 114},
+ {"another", 115},
+ {"gone", 116},
+ {"change", 117},
+ {"use", 118},
+ {"wonder", 119},
+ {"someone", 120},
+ {"hair", 121},
+ {"cold", 122},
+ {"open", 123},
+ {"best", 124},
+ {"any", 125},
+ {"behind", 126},
+ {"happen", 127},
+ {"water", 128},
+ {"dark", 129},
+ {"laugh", 130},
+ {"stay", 131},
+ {"forever", 132},
+ {"name", 133},
+ {"work", 134},
+ {"show", 135},
+ {"sky", 136},
+ {"break", 137},
+ {"came", 138},
+ {"deep", 139},
+ {"door", 140},
+ {"put", 141},
+ {"black", 142},
+ {"together", 143},
+ {"upon", 144},
+ {"happy", 145},
+ {"such", 146},
+ {"great", 147},
+ {"white", 148},
+ {"matter", 149},
+ {"fill", 150},
+ {"past", 151},
+ {"please", 152},
+ {"burn", 153},
+ {"cause", 154},
+ {"enough", 155},
+ {"touch", 156},
+ {"moment", 157},
+ {"soon", 158},
+ {"voice", 159},
+ {"scream", 160},
+ {"anything", 161},
+ {"stare", 162},
+ {"sound", 163},
+ {"red", 164},
+ {"everyone", 165},
+ {"hide", 166},
+ {"kiss", 167},
+ {"truth", 168},
+ {"death", 169},
+ {"beautiful", 170},
+ {"mine", 171},
+ {"blood", 172},
+ {"broken", 173},
+ {"very", 174},
+ {"pass", 175},
+ {"next", 176},
+ {"forget", 177},
+ {"tree", 178},
+ {"wrong", 179},
+ {"air", 180},
+ {"mother", 181},
+ {"understand", 182},
+ {"lip", 183},
+ {"hit", 184},
+ {"wall", 185},
+ {"memory", 186},
+ {"sleep", 187},
+ {"free", 188},
+ {"high", 189},
+ {"realize", 190},
+ {"school", 191},
+ {"might", 192},
+ {"skin", 193},
+ {"sweet", 194},
+ {"perfect", 195},
+ {"blue", 196},
+ {"kill", 197},
+ {"breath", 198},
+ {"dance", 199},
+ {"against", 200},
+ {"fly", 201},
+ {"between", 202},
+ {"grow", 203},
+ {"strong", 204},
+ {"under", 205},
+ {"listen", 206},
+ {"bring", 207},
+ {"sometimes", 208},
+ {"speak", 209},
+ {"pull", 210},
+ {"person", 211},
+ {"become", 212},
+ {"family", 213},
+ {"begin", 214},
+ {"ground", 215},
+ {"real", 216},
+ {"small", 217},
+ {"father", 218},
+ {"sure", 219},
+ {"feet", 220},
+ {"rest", 221},
+ {"young", 222},
+ {"finally", 223},
+ {"land", 224},
+ {"across", 225},
+ {"today", 226},
+ {"different", 227},
+ {"guy", 228},
+ {"line", 229},
+ {"fire", 230},
+ {"reason", 231},
+ {"reach", 232},
+ {"second", 233},
+ {"slowly", 234},
+ {"write", 235},
+ {"eat", 236},
+ {"smell", 237},
+ {"mouth", 238},
+ {"step", 239},
+ {"learn", 240},
+ {"three", 241},
+ {"floor", 242},
+ {"promise", 243},
+ {"breathe", 244},
+ {"darkness", 245},
+ {"push", 246},
+ {"earth", 247},
+ {"guess", 248},
+ {"save", 249},
+ {"song", 250},
+ {"above", 251},
+ {"along", 252},
+ {"both", 253},
+ {"color", 254},
+ {"house", 255},
+ {"almost", 256},
+ {"sorry", 257},
+ {"anymore", 258},
+ {"brother", 259},
+ {"okay", 260},
+ {"dear", 261},
+ {"game", 262},
+ {"fade", 263},
+ {"already", 264},
+ {"apart", 265},
+ {"warm", 266},
+ {"beauty", 267},
+ {"heard", 268},
+ {"notice", 269},
+ {"question", 270},
+ {"shine", 271},
+ {"began", 272},
+ {"piece", 273},
+ {"whole", 274},
+ {"shadow", 275},
+ {"secret", 276},
+ {"street", 277},
+ {"within", 278},
+ {"finger", 279},
+ {"point", 280},
+ {"morning", 281},
+ {"whisper", 282},
+ {"child", 283},
+ {"moon", 284},
+ {"green", 285},
+ {"story", 286},
+ {"glass", 287},
+ {"kid", 288},
+ {"silence", 289},
+ {"since", 290},
+ {"soft", 291},
+ {"yourself", 292},
+ {"empty", 293},
+ {"shall", 294},
+ {"angel", 295},
+ {"answer", 296},
+ {"baby", 297},
+ {"bright", 298},
+ {"dad", 299},
+ {"path", 300},
+ {"worry", 301},
+ {"hour", 302},
+ {"drop", 303},
+ {"follow", 304},
+ {"power", 305},
+ {"war", 306},
+ {"half", 307},
+ {"flow", 308},
+ {"heaven", 309},
+ {"act", 310},
+ {"chance", 311},
+ {"fact", 312},
+ {"least", 313},
+ {"tired", 314},
+ {"children", 315},
+ {"near", 316},
+ {"quite", 317},
+ {"afraid", 318},
+ {"rise", 319},
+ {"sea", 320},
+ {"taste", 321},
+ {"window", 322},
+ {"cover", 323},
+ {"nice", 324},
+ {"trust", 325},
+ {"lot", 326},
+ {"sad", 327},
+ {"cool", 328},
+ {"force", 329},
+ {"peace", 330},
+ {"return", 331},
+ {"blind", 332},
+ {"easy", 333},
+ {"ready", 334},
+ {"roll", 335},
+ {"rose", 336},
+ {"drive", 337},
+ {"held", 338},
+ {"music", 339},
+ {"beneath", 340},
+ {"hang", 341},
+ {"mom", 342},
+ {"paint", 343},
+ {"emotion", 344},
+ {"quiet", 345},
+ {"clear", 346},
+ {"cloud", 347},
+ {"few", 348},
+ {"pretty", 349},
+ {"bird", 350},
+ {"outside", 351},
+ {"paper", 352},
+ {"picture", 353},
+ {"front", 354},
+ {"rock", 355},
+ {"simple", 356},
+ {"anyone", 357},
+ {"meant", 358},
+ {"reality", 359},
+ {"road", 360},
+ {"sense", 361},
+ {"waste", 362},
+ {"bit", 363},
+ {"leaf", 364},
+ {"thank", 365},
+ {"happiness", 366},
+ {"meet", 367},
+ {"men", 368},
+ {"smoke", 369},
+ {"truly", 370},
+ {"decide", 371},
+ {"self", 372},
+ {"age", 373},
+ {"book", 374},
+ {"form", 375},
+ {"alive", 376},
+ {"carry", 377},
+ {"escape", 378},
+ {"damn", 379},
+ {"instead", 380},
+ {"able", 381},
+ {"ice", 382},
+ {"minute", 383},
+ {"throw", 384},
+ {"catch", 385},
+ {"leg", 386},
+ {"ring", 387},
+ {"course", 388},
+ {"goodbye", 389},
+ {"lead", 390},
+ {"poem", 391},
+ {"sick", 392},
+ {"corner", 393},
+ {"desire", 394},
+ {"known", 395},
+ {"problem", 396},
+ {"remind", 397},
+ {"shoulder", 398},
+ {"suppose", 399},
+ {"toward", 400},
+ {"wave", 401},
+ {"drink", 402},
+ {"jump", 403},
+ {"woman", 404},
+ {"pretend", 405},
+ {"sister", 406},
+ {"week", 407},
+ {"human", 408},
+ {"joy", 409},
+ {"crack", 410},
+ {"grey", 411},
+ {"pray", 412},
+ {"surprise", 413},
+ {"dry", 414},
+ {"knee", 415},
+ {"less", 416},
+ {"search", 417},
+ {"bleed", 418},
+ {"caught", 419},
+ {"clean", 420},
+ {"embrace", 421},
+ {"future", 422},
+ {"king", 423},
+ {"son", 424},
+ {"sorrow", 425},
+ {"chest", 426},
+ {"hug", 427},
+ {"remain", 428},
+ {"sat", 429},
+ {"worth", 430},
+ {"blow", 431},
+ {"daddy", 432},
+ {"final", 433},
+ {"parent", 434},
+ {"tight", 435},
+ {"also", 436},
+ {"create", 437},
+ {"lonely", 438},
+ {"safe", 439},
+ {"cross", 440},
+ {"dress", 441},
+ {"evil", 442},
+ {"silent", 443},
+ {"bone", 444},
+ {"fate", 445},
+ {"perhaps", 446},
+ {"anger", 447},
+ {"class", 448},
+ {"scar", 449},
+ {"snow", 450},
+ {"tiny", 451},
+ {"tonight", 452},
+ {"continue", 453},
+ {"control", 454},
+ {"dog", 455},
+ {"edge", 456},
+ {"mirror", 457},
+ {"month", 458},
+ {"suddenly", 459},
+ {"comfort", 460},
+ {"given", 461},
+ {"loud", 462},
+ {"quickly", 463},
+ {"gaze", 464},
+ {"plan", 465},
+ {"rush", 466},
+ {"stone", 467},
+ {"town", 468},
+ {"battle", 469},
+ {"ignore", 470},
+ {"spirit", 471},
+ {"stood", 472},
+ {"stupid", 473},
+ {"yours", 474},
+ {"brown", 475},
+ {"build", 476},
+ {"dust", 477},
+ {"hey", 478},
+ {"kept", 479},
+ {"pay", 480},
+ {"phone", 481},
+ {"twist", 482},
+ {"although", 483},
+ {"ball", 484},
+ {"beyond", 485},
+ {"hidden", 486},
+ {"nose", 487},
+ {"taken", 488},
+ {"fail", 489},
+ {"float", 490},
+ {"pure", 491},
+ {"somehow", 492},
+ {"wash", 493},
+ {"wrap", 494},
+ {"angry", 495},
+ {"cheek", 496},
+ {"creature", 497},
+ {"forgotten", 498},
+ {"heat", 499},
+ {"rip", 500},
+ {"single", 501},
+ {"space", 502},
+ {"special", 503},
+ {"weak", 504},
+ {"whatever", 505},
+ {"yell", 506},
+ {"anyway", 507},
+ {"blame", 508},
+ {"job", 509},
+ {"choose", 510},
+ {"country", 511},
+ {"curse", 512},
+ {"drift", 513},
+ {"echo", 514},
+ {"figure", 515},
+ {"grew", 516},
+ {"laughter", 517},
+ {"neck", 518},
+ {"suffer", 519},
+ {"worse", 520},
+ {"yeah", 521},
+ {"disappear", 522},
+ {"foot", 523},
+ {"forward", 524},
+ {"knife", 525},
+ {"mess", 526},
+ {"somewhere", 527},
+ {"stomach", 528},
+ {"storm", 529},
+ {"beg", 530},
+ {"idea", 531},
+ {"lift", 532},
+ {"offer", 533},
+ {"breeze", 534},
+ {"field", 535},
+ {"five", 536},
+ {"often", 537},
+ {"simply", 538},
+ {"stuck", 539},
+ {"win", 540},
+ {"allow", 541},
+ {"confuse", 542},
+ {"enjoy", 543},
+ {"except", 544},
+ {"flower", 545},
+ {"seek", 546},
+ {"strength", 547},
+ {"calm", 548},
+ {"grin", 549},
+ {"gun", 550},
+ {"heavy", 551},
+ {"hill", 552},
+ {"large", 553},
+ {"ocean", 554},
+ {"shoe", 555},
+ {"sigh", 556},
+ {"straight", 557},
+ {"summer", 558},
+ {"tongue", 559},
+ {"accept", 560},
+ {"crazy", 561},
+ {"everyday", 562},
+ {"exist", 563},
+ {"grass", 564},
+ {"mistake", 565},
+ {"sent", 566},
+ {"shut", 567},
+ {"surround", 568},
+ {"table", 569},
+ {"ache", 570},
+ {"brain", 571},
+ {"destroy", 572},
+ {"heal", 573},
+ {"nature", 574},
+ {"shout", 575},
+ {"sign", 576},
+ {"stain", 577},
+ {"choice", 578},
+ {"doubt", 579},
+ {"glance", 580},
+ {"glow", 581},
+ {"mountain", 582},
+ {"queen", 583},
+ {"stranger", 584},
+ {"throat", 585},
+ {"tomorrow", 586},
+ {"city", 587},
+ {"either", 588},
+ {"fish", 589},
+ {"flame", 590},
+ {"rather", 591},
+ {"shape", 592},
+ {"spin", 593},
+ {"spread", 594},
+ {"ash", 595},
+ {"distance", 596},
+ {"finish", 597},
+ {"image", 598},
+ {"imagine", 599},
+ {"important", 600},
+ {"nobody", 601},
+ {"shatter", 602},
+ {"warmth", 603},
+ {"became", 604},
+ {"feed", 605},
+ {"flesh", 606},
+ {"funny", 607},
+ {"lust", 608},
+ {"shirt", 609},
+ {"trouble", 610},
+ {"yellow", 611},
+ {"attention", 612},
+ {"bare", 613},
+ {"bite", 614},
+ {"money", 615},
+ {"protect", 616},
+ {"amaze", 617},
+ {"appear", 618},
+ {"born", 619},
+ {"choke", 620},
+ {"completely", 621},
+ {"daughter", 622},
+ {"fresh", 623},
+ {"friendship", 624},
+ {"gentle", 625},
+ {"probably", 626},
+ {"six", 627},
+ {"deserve", 628},
+ {"expect", 629},
+ {"grab", 630},
+ {"middle", 631},
+ {"nightmare", 632},
+ {"river", 633},
+ {"thousand", 634},
+ {"weight", 635},
+ {"worst", 636},
+ {"wound", 637},
+ {"barely", 638},
+ {"bottle", 639},
+ {"cream", 640},
+ {"regret", 641},
+ {"relationship", 642},
+ {"stick", 643},
+ {"test", 644},
+ {"crush", 645},
+ {"endless", 646},
+ {"fault", 647},
+ {"itself", 648},
+ {"rule", 649},
+ {"spill", 650},
+ {"art", 651},
+ {"circle", 652},
+ {"join", 653},
+ {"kick", 654},
+ {"mask", 655},
+ {"master", 656},
+ {"passion", 657},
+ {"quick", 658},
+ {"raise", 659},
+ {"smooth", 660},
+ {"unless", 661},
+ {"wander", 662},
+ {"actually", 663},
+ {"broke", 664},
+ {"chair", 665},
+ {"deal", 666},
+ {"favorite", 667},
+ {"gift", 668},
+ {"note", 669},
+ {"number", 670},
+ {"sweat", 671},
+ {"box", 672},
+ {"chill", 673},
+ {"clothes", 674},
+ {"lady", 675},
+ {"mark", 676},
+ {"park", 677},
+ {"poor", 678},
+ {"sadness", 679},
+ {"tie", 680},
+ {"animal", 681},
+ {"belong", 682},
+ {"brush", 683},
+ {"consume", 684},
+ {"dawn", 685},
+ {"forest", 686},
+ {"innocent", 687},
+ {"pen", 688},
+ {"pride", 689},
+ {"stream", 690},
+ {"thick", 691},
+ {"clay", 692},
+ {"complete", 693},
+ {"count", 694},
+ {"draw", 695},
+ {"faith", 696},
+ {"press", 697},
+ {"silver", 698},
+ {"struggle", 699},
+ {"surface", 700},
+ {"taught", 701},
+ {"teach", 702},
+ {"wet", 703},
+ {"bless", 704},
+ {"chase", 705},
+ {"climb", 706},
+ {"enter", 707},
+ {"letter", 708},
+ {"melt", 709},
+ {"metal", 710},
+ {"movie", 711},
+ {"stretch", 712},
+ {"swing", 713},
+ {"vision", 714},
+ {"wife", 715},
+ {"beside", 716},
+ {"crash", 717},
+ {"forgot", 718},
+ {"guide", 719},
+ {"haunt", 720},
+ {"joke", 721},
+ {"knock", 722},
+ {"plant", 723},
+ {"pour", 724},
+ {"prove", 725},
+ {"reveal", 726},
+ {"steal", 727},
+ {"stuff", 728},
+ {"trip", 729},
+ {"wood", 730},
+ {"wrist", 731},
+ {"bother", 732},
+ {"bottom", 733},
+ {"crawl", 734},
+ {"crowd", 735},
+ {"fix", 736},
+ {"forgive", 737},
+ {"frown", 738},
+ {"grace", 739},
+ {"loose", 740},
+ {"lucky", 741},
+ {"party", 742},
+ {"release", 743},
+ {"surely", 744},
+ {"survive", 745},
+ {"teacher", 746},
+ {"gently", 747},
+ {"grip", 748},
+ {"speed", 749},
+ {"suicide", 750},
+ {"travel", 751},
+ {"treat", 752},
+ {"vein", 753},
+ {"written", 754},
+ {"cage", 755},
+ {"chain", 756},
+ {"conversation", 757},
+ {"date", 758},
+ {"enemy", 759},
+ {"however", 760},
+ {"interest", 761},
+ {"million", 762},
+ {"page", 763},
+ {"pink", 764},
+ {"proud", 765},
+ {"sway", 766},
+ {"themselves", 767},
+ {"winter", 768},
+ {"church", 769},
+ {"cruel", 770},
+ {"cup", 771},
+ {"demon", 772},
+ {"experience", 773},
+ {"freedom", 774},
+ {"pair", 775},
+ {"pop", 776},
+ {"purpose", 777},
+ {"respect", 778},
+ {"shoot", 779},
+ {"softly", 780},
+ {"state", 781},
+ {"strange", 782},
+ {"bar", 783},
+ {"birth", 784},
+ {"curl", 785},
+ {"dirt", 786},
+ {"excuse", 787},
+ {"lord", 788},
+ {"lovely", 789},
+ {"monster", 790},
+ {"order", 791},
+ {"pack", 792},
+ {"pants", 793},
+ {"pool", 794},
+ {"scene", 795},
+ {"seven", 796},
+ {"shame", 797},
+ {"slide", 798},
+ {"ugly", 799},
+ {"among", 800},
+ {"blade", 801},
+ {"blonde", 802},
+ {"closet", 803},
+ {"creek", 804},
+ {"deny", 805},
+ {"drug", 806},
+ {"eternity", 807},
+ {"gain", 808},
+ {"grade", 809},
+ {"handle", 810},
+ {"key", 811},
+ {"linger", 812},
+ {"pale", 813},
+ {"prepare", 814},
+ {"swallow", 815},
+ {"swim", 816},
+ {"tremble", 817},
+ {"wheel", 818},
+ {"won", 819},
+ {"cast", 820},
+ {"cigarette", 821},
+ {"claim", 822},
+ {"college", 823},
+ {"direction", 824},
+ {"dirty", 825},
+ {"gather", 826},
+ {"ghost", 827},
+ {"hundred", 828},
+ {"loss", 829},
+ {"lung", 830},
+ {"orange", 831},
+ {"present", 832},
+ {"swear", 833},
+ {"swirl", 834},
+ {"twice", 835},
+ {"wild", 836},
+ {"bitter", 837},
+ {"blanket", 838},
+ {"doctor", 839},
+ {"everywhere", 840},
+ {"flash", 841},
+ {"grown", 842},
+ {"knowledge", 843},
+ {"numb", 844},
+ {"pressure", 845},
+ {"radio", 846},
+ {"repeat", 847},
+ {"ruin", 848},
+ {"spend", 849},
+ {"unknown", 850},
+ {"buy", 851},
+ {"clock", 852},
+ {"devil", 853},
+ {"early", 854},
+ {"false", 855},
+ {"fantasy", 856},
+ {"pound", 857},
+ {"precious", 858},
+ {"refuse", 859},
+ {"sheet", 860},
+ {"teeth", 861},
+ {"welcome", 862},
+ {"add", 863},
+ {"ahead", 864},
+ {"block", 865},
+ {"bury", 866},
+ {"caress", 867},
+ {"content", 868},
+ {"depth", 869},
+ {"despite", 870},
+ {"distant", 871},
+ {"marry", 872},
+ {"purple", 873},
+ {"threw", 874},
+ {"whenever", 875},
+ {"bomb", 876},
+ {"dull", 877},
+ {"easily", 878},
+ {"grasp", 879},
+ {"hospital", 880},
+ {"innocence", 881},
+ {"normal", 882},
+ {"receive", 883},
+ {"reply", 884},
+ {"rhyme", 885},
+ {"shade", 886},
+ {"someday", 887},
+ {"sword", 888},
+ {"toe", 889},
+ {"visit", 890},
+ {"asleep", 891},
+ {"bought", 892},
+ {"center", 893},
+ {"consider", 894},
+ {"flat", 895},
+ {"hero", 896},
+ {"history", 897},
+ {"ink", 898},
+ {"insane", 899},
+ {"muscle", 900},
+ {"mystery", 901},
+ {"pocket", 902},
+ {"reflection", 903},
+ {"shove", 904},
+ {"silently", 905},
+ {"smart", 906},
+ {"soldier", 907},
+ {"spot", 908},
+ {"stress", 909},
+ {"train", 910},
+ {"type", 911},
+ {"view", 912},
+ {"whether", 913},
+ {"bus", 914},
+ {"energy", 915},
+ {"explain", 916},
+ {"holy", 917},
+ {"hunger", 918},
+ {"inch", 919},
+ {"magic", 920},
+ {"mix", 921},
+ {"noise", 922},
+ {"nowhere", 923},
+ {"prayer", 924},
+ {"presence", 925},
+ {"shock", 926},
+ {"snap", 927},
+ {"spider", 928},
+ {"study", 929},
+ {"thunder", 930},
+ {"trail", 931},
+ {"admit", 932},
+ {"agree", 933},
+ {"bag", 934},
+ {"bang", 935},
+ {"bound", 936},
+ {"butterfly", 937},
+ {"cute", 938},
+ {"exactly", 939},
+ {"explode", 940},
+ {"familiar", 941},
+ {"fold", 942},
+ {"further", 943},
+ {"pierce", 944},
+ {"reflect", 945},
+ {"scent", 946},
+ {"selfish", 947},
+ {"sharp", 948},
+ {"sink", 949},
+ {"spring", 950},
+ {"stumble", 951},
+ {"universe", 952},
+ {"weep", 953},
+ {"women", 954},
+ {"wonderful", 955},
+ {"action", 956},
+ {"ancient", 957},
+ {"attempt", 958},
+ {"avoid", 959},
+ {"birthday", 960},
+ {"branch", 961},
+ {"chocolate", 962},
+ {"core", 963},
+ {"depress", 964},
+ {"drunk", 965},
+ {"especially", 966},
+ {"focus", 967},
+ {"fruit", 968},
+ {"honest", 969},
+ {"match", 970},
+ {"palm", 971},
+ {"perfectly", 972},
+ {"pillow", 973},
+ {"pity", 974},
+ {"poison", 975},
+ {"roar", 976},
+ {"shift", 977},
+ {"slightly", 978},
+ {"thump", 979},
+ {"truck", 980},
+ {"tune", 981},
+ {"twenty", 982},
+ {"unable", 983},
+ {"wipe", 984},
+ {"wrote", 985},
+ {"coat", 986},
+ {"constant", 987},
+ {"dinner", 988},
+ {"drove", 989},
+ {"egg", 990},
+ {"eternal", 991},
+ {"flight", 992},
+ {"flood", 993},
+ {"frame", 994},
+ {"freak", 995},
+ {"gasp", 996},
+ {"glad", 997},
+ {"hollow", 998},
+ {"motion", 999},
+ {"peer", 1000},
+ {"plastic", 1001},
+ {"root", 1002},
+ {"screen", 1003},
+ {"season", 1004},
+ {"sting", 1005},
+ {"strike", 1006},
+ {"team", 1007},
+ {"unlike", 1008},
+ {"victim", 1009},
+ {"volume", 1010},
+ {"warn", 1011},
+ {"weird", 1012},
+ {"attack", 1013},
+ {"await", 1014},
+ {"awake", 1015},
+ {"built", 1016},
+ {"charm", 1017},
+ {"crave", 1018},
+ {"despair", 1019},
+ {"fought", 1020},
+ {"grant", 1021},
+ {"grief", 1022},
+ {"horse", 1023},
+ {"limit", 1024},
+ {"message", 1025},
+ {"ripple", 1026},
+ {"sanity", 1027},
+ {"scatter", 1028},
+ {"serve", 1029},
+ {"split", 1030},
+ {"string", 1031},
+ {"trick", 1032},
+ {"annoy", 1033},
+ {"blur", 1034},
+ {"boat", 1035},
+ {"brave", 1036},
+ {"clearly", 1037},
+ {"cling", 1038},
+ {"connect", 1039},
+ {"fist", 1040},
+ {"forth", 1041},
+ {"imagination", 1042},
+ {"iron", 1043},
+ {"jock", 1044},
+ {"judge", 1045},
+ {"lesson", 1046},
+ {"milk", 1047},
+ {"misery", 1048},
+ {"nail", 1049},
+ {"naked", 1050},
+ {"ourselves", 1051},
+ {"poet", 1052},
+ {"possible", 1053},
+ {"princess", 1054},
+ {"sail", 1055},
+ {"size", 1056},
+ {"snake", 1057},
+ {"society", 1058},
+ {"stroke", 1059},
+ {"torture", 1060},
+ {"toss", 1061},
+ {"trace", 1062},
+ {"wise", 1063},
+ {"bloom", 1064},
+ {"bullet", 1065},
+ {"cell", 1066},
+ {"check", 1067},
+ {"cost", 1068},
+ {"darling", 1069},
+ {"during", 1070},
+ {"footstep", 1071},
+ {"fragile", 1072},
+ {"hallway", 1073},
+ {"hardly", 1074},
+ {"horizon", 1075},
+ {"invisible", 1076},
+ {"journey", 1077},
+ {"midnight", 1078},
+ {"mud", 1079},
+ {"nod", 1080},
+ {"pause", 1081},
+ {"relax", 1082},
+ {"shiver", 1083},
+ {"sudden", 1084},
+ {"value", 1085},
+ {"youth", 1086},
+ {"abuse", 1087},
+ {"admire", 1088},
+ {"blink", 1089},
+ {"breast", 1090},
+ {"bruise", 1091},
+ {"constantly", 1092},
+ {"couple", 1093},
+ {"creep", 1094},
+ {"curve", 1095},
+ {"difference", 1096},
+ {"dumb", 1097},
+ {"emptiness", 1098},
+ {"gotta", 1099},
+ {"honor", 1100},
+ {"plain", 1101},
+ {"planet", 1102},
+ {"recall", 1103},
+ {"rub", 1104},
+ {"ship", 1105},
+ {"slam", 1106},
+ {"soar", 1107},
+ {"somebody", 1108},
+ {"tightly", 1109},
+ {"weather", 1110},
+ {"adore", 1111},
+ {"approach", 1112},
+ {"bond", 1113},
+ {"bread", 1114},
+ {"burst", 1115},
+ {"candle", 1116},
+ {"coffee", 1117},
+ {"cousin", 1118},
+ {"crime", 1119},
+ {"desert", 1120},
+ {"flutter", 1121},
+ {"frozen", 1122},
+ {"grand", 1123},
+ {"heel", 1124},
+ {"hello", 1125},
+ {"language", 1126},
+ {"level", 1127},
+ {"movement", 1128},
+ {"pleasure", 1129},
+ {"powerful", 1130},
+ {"random", 1131},
+ {"rhythm", 1132},
+ {"settle", 1133},
+ {"silly", 1134},
+ {"slap", 1135},
+ {"sort", 1136},
+ {"spoken", 1137},
+ {"steel", 1138},
+ {"threaten", 1139},
+ {"tumble", 1140},
+ {"upset", 1141},
+ {"aside", 1142},
+ {"awkward", 1143},
+ {"bee", 1144},
+ {"blank", 1145},
+ {"board", 1146},
+ {"button", 1147},
+ {"card", 1148},
+ {"carefully", 1149},
+ {"complain", 1150},
+ {"crap", 1151},
+ {"deeply", 1152},
+ {"discover", 1153},
+ {"drag", 1154},
+ {"dread", 1155},
+ {"effort", 1156},
+ {"entire", 1157},
+ {"fairy", 1158},
+ {"giant", 1159},
+ {"gotten", 1160},
+ {"greet", 1161},
+ {"illusion", 1162},
+ {"jeans", 1163},
+ {"leap", 1164},
+ {"liquid", 1165},
+ {"march", 1166},
+ {"mend", 1167},
+ {"nervous", 1168},
+ {"nine", 1169},
+ {"replace", 1170},
+ {"rope", 1171},
+ {"spine", 1172},
+ {"stole", 1173},
+ {"terror", 1174},
+ {"accident", 1175},
+ {"apple", 1176},
+ {"balance", 1177},
+ {"boom", 1178},
+ {"childhood", 1179},
+ {"collect", 1180},
+ {"demand", 1181},
+ {"depression", 1182},
+ {"eventually", 1183},
+ {"faint", 1184},
+ {"glare", 1185},
+ {"goal", 1186},
+ {"group", 1187},
+ {"honey", 1188},
+ {"kitchen", 1189},
+ {"laid", 1190},
+ {"limb", 1191},
+ {"machine", 1192},
+ {"mere", 1193},
+ {"mold", 1194},
+ {"murder", 1195},
+ {"nerve", 1196},
+ {"painful", 1197},
+ {"poetry", 1198},
+ {"prince", 1199},
+ {"rabbit", 1200},
+ {"shelter", 1201},
+ {"shore", 1202},
+ {"shower", 1203},
+ {"soothe", 1204},
+ {"stair", 1205},
+ {"steady", 1206},
+ {"sunlight", 1207},
+ {"tangle", 1208},
+ {"tease", 1209},
+ {"treasure", 1210},
+ {"uncle", 1211},
+ {"begun", 1212},
+ {"bliss", 1213},
+ {"canvas", 1214},
+ {"cheer", 1215},
+ {"claw", 1216},
+ {"clutch", 1217},
+ {"commit", 1218},
+ {"crimson", 1219},
+ {"crystal", 1220},
+ {"delight", 1221},
+ {"doll", 1222},
+ {"existence", 1223},
+ {"express", 1224},
+ {"fog", 1225},
+ {"football", 1226},
+ {"gay", 1227},
+ {"goose", 1228},
+ {"guard", 1229},
+ {"hatred", 1230},
+ {"illuminate", 1231},
+ {"mass", 1232},
+ {"math", 1233},
+ {"mourn", 1234},
+ {"rich", 1235},
+ {"rough", 1236},
+ {"skip", 1237},
+ {"stir", 1238},
+ {"student", 1239},
+ {"style", 1240},
+ {"support", 1241},
+ {"thorn", 1242},
+ {"tough", 1243},
+ {"yard", 1244},
+ {"yearn", 1245},
+ {"yesterday", 1246},
+ {"advice", 1247},
+ {"appreciate", 1248},
+ {"autumn", 1249},
+ {"bank", 1250},
+ {"beam", 1251},
+ {"bowl", 1252},
+ {"capture", 1253},
+ {"carve", 1254},
+ {"collapse", 1255},
+ {"confusion", 1256},
+ {"creation", 1257},
+ {"dove", 1258},
+ {"feather", 1259},
+ {"girlfriend", 1260},
+ {"glory", 1261},
+ {"government", 1262},
+ {"harsh", 1263},
+ {"hop", 1264},
+ {"inner", 1265},
+ {"loser", 1266},
+ {"moonlight", 1267},
+ {"neighbor", 1268},
+ {"neither", 1269},
+ {"peach", 1270},
+ {"pig", 1271},
+ {"praise", 1272},
+ {"screw", 1273},
+ {"shield", 1274},
+ {"shimmer", 1275},
+ {"sneak", 1276},
+ {"stab", 1277},
+ {"subject", 1278},
+ {"throughout", 1279},
+ {"thrown", 1280},
+ {"tower", 1281},
+ {"twirl", 1282},
+ {"wow", 1283},
+ {"army", 1284},
+ {"arrive", 1285},
+ {"bathroom", 1286},
+ {"bump", 1287},
+ {"cease", 1288},
+ {"cookie", 1289},
+ {"couch", 1290},
+ {"courage", 1291},
+ {"dim", 1292},
+ {"guilt", 1293},
+ {"howl", 1294},
+ {"hum", 1295},
+ {"husband", 1296},
+ {"insult", 1297},
+ {"led", 1298},
+ {"lunch", 1299},
+ {"mock", 1300},
+ {"mostly", 1301},
+ {"natural", 1302},
+ {"nearly", 1303},
+ {"needle", 1304},
+ {"nerd", 1305},
+ {"peaceful", 1306},
+ {"perfection", 1307},
+ {"pile", 1308},
+ {"price", 1309},
+ {"remove", 1310},
+ {"roam", 1311},
+ {"sanctuary", 1312},
+ {"serious", 1313},
+ {"shiny", 1314},
+ {"shook", 1315},
+ {"sob", 1316},
+ {"stolen", 1317},
+ {"tap", 1318},
+ {"vain", 1319},
+ {"void", 1320},
+ {"warrior", 1321},
+ {"wrinkle", 1322},
+ {"affection", 1323},
+ {"apologize", 1324},
+ {"blossom", 1325},
+ {"bounce", 1326},
+ {"bridge", 1327},
+ {"cheap", 1328},
+ {"crumble", 1329},
+ {"decision", 1330},
+ {"descend", 1331},
+ {"desperately", 1332},
+ {"dig", 1333},
+ {"dot", 1334},
+ {"flip", 1335},
+ {"frighten", 1336},
+ {"heartbeat", 1337},
+ {"huge", 1338},
+ {"lazy", 1339},
+ {"lick", 1340},
+ {"odd", 1341},
+ {"opinion", 1342},
+ {"process", 1343},
+ {"puzzle", 1344},
+ {"quietly", 1345},
+ {"retreat", 1346},
+ {"score", 1347},
+ {"sentence", 1348},
+ {"separate", 1349},
+ {"situation", 1350},
+ {"skill", 1351},
+ {"soak", 1352},
+ {"square", 1353},
+ {"stray", 1354},
+ {"taint", 1355},
+ {"task", 1356},
+ {"tide", 1357},
+ {"underneath", 1358},
+ {"veil", 1359},
+ {"whistle", 1360},
+ {"anywhere", 1361},
+ {"bedroom", 1362},
+ {"bid", 1363},
+ {"bloody", 1364},
+ {"burden", 1365},
+ {"careful", 1366},
+ {"compare", 1367},
+ {"concern", 1368},
+ {"curtain", 1369},
+ {"decay", 1370},
+ {"defeat", 1371},
+ {"describe", 1372},
+ {"double", 1373},
+ {"dreamer", 1374},
+ {"driver", 1375},
+ {"dwell", 1376},
+ {"evening", 1377},
+ {"flare", 1378},
+ {"flicker", 1379},
+ {"grandma", 1380},
+ {"guitar", 1381},
+ {"harm", 1382},
+ {"horrible", 1383},
+ {"hungry", 1384},
+ {"indeed", 1385},
+ {"lace", 1386},
+ {"melody", 1387},
+ {"monkey", 1388},
+ {"nation", 1389},
+ {"object", 1390},
+ {"obviously", 1391},
+ {"rainbow", 1392},
+ {"salt", 1393},
+ {"scratch", 1394},
+ {"shown", 1395},
+ {"shy", 1396},
+ {"stage", 1397},
+ {"stun", 1398},
+ {"third", 1399},
+ {"tickle", 1400},
+ {"useless", 1401},
+ {"weakness", 1402},
+ {"worship", 1403},
+ {"worthless", 1404},
+ {"afternoon", 1405},
+ {"beard", 1406},
+ {"boyfriend", 1407},
+ {"bubble", 1408},
+ {"busy", 1409},
+ {"certain", 1410},
+ {"chin", 1411},
+ {"concrete", 1412},
+ {"desk", 1413},
+ {"diamond", 1414},
+ {"doom", 1415},
+ {"drawn", 1416},
+ {"due", 1417},
+ {"felicity", 1418},
+ {"freeze", 1419},
+ {"frost", 1420},
+ {"garden", 1421},
+ {"glide", 1422},
+ {"harmony", 1423},
+ {"hopefully", 1424},
+ {"hunt", 1425},
+ {"jealous", 1426},
+ {"lightning", 1427},
+ {"mama", 1428},
+ {"mercy", 1429},
+ {"peel", 1430},
+ {"physical", 1431},
+ {"position", 1432},
+ {"pulse", 1433},
+ {"punch", 1434},
+ {"quit", 1435},
+ {"rant", 1436},
+ {"respond", 1437},
+ {"salty", 1438},
+ {"sane", 1439},
+ {"satisfy", 1440},
+ {"savior", 1441},
+ {"sheep", 1442},
+ {"slept", 1443},
+ {"social", 1444},
+ {"sport", 1445},
+ {"tuck", 1446},
+ {"utter", 1447},
+ {"valley", 1448},
+ {"wolf", 1449},
+ {"aim", 1450},
+ {"alas", 1451},
+ {"alter", 1452},
+ {"arrow", 1453},
+ {"awaken", 1454},
+ {"beaten", 1455},
+ {"belief", 1456},
+ {"brand", 1457},
+ {"ceiling", 1458},
+ {"cheese", 1459},
+ {"clue", 1460},
+ {"confidence", 1461},
+ {"connection", 1462},
+ {"daily", 1463},
+ {"disguise", 1464},
+ {"eager", 1465},
+ {"erase", 1466},
+ {"essence", 1467},
+ {"everytime", 1468},
+ {"expression", 1469},
+ {"fan", 1470},
+ {"flag", 1471},
+ {"flirt", 1472},
+ {"foul", 1473},
+ {"fur", 1474},
+ {"giggle", 1475},
+ {"glorious", 1476},
+ {"ignorance", 1477},
+ {"law", 1478},
+ {"lifeless", 1479},
+ {"measure", 1480},
+ {"mighty", 1481},
+ {"muse", 1482},
+ {"north", 1483},
+ {"opposite", 1484},
+ {"paradise", 1485},
+ {"patience", 1486},
+ {"patient", 1487},
+ {"pencil", 1488},
+ {"petal", 1489},
+ {"plate", 1490},
+ {"ponder", 1491},
+ {"possibly", 1492},
+ {"practice", 1493},
+ {"slice", 1494},
+ {"spell", 1495},
+ {"stock", 1496},
+ {"strife", 1497},
+ {"strip", 1498},
+ {"suffocate", 1499},
+ {"suit", 1500},
+ {"tender", 1501},
+ {"tool", 1502},
+ {"trade", 1503},
+ {"velvet", 1504},
+ {"verse", 1505},
+ {"waist", 1506},
+ {"witch", 1507},
+ {"aunt", 1508},
+ {"bench", 1509},
+ {"bold", 1510},
+ {"cap", 1511},
+ {"certainly", 1512},
+ {"click", 1513},
+ {"companion", 1514},
+ {"creator", 1515},
+ {"dart", 1516},
+ {"delicate", 1517},
+ {"determine", 1518},
+ {"dish", 1519},
+ {"dragon", 1520},
+ {"drama", 1521},
+ {"drum", 1522},
+ {"dude", 1523},
+ {"everybody", 1524},
+ {"feast", 1525},
+ {"forehead", 1526},
+ {"former", 1527},
+ {"fright", 1528},
+ {"fully", 1529},
+ {"gas", 1530},
+ {"hook", 1531},
+ {"hurl", 1532},
+ {"invite", 1533},
+ {"juice", 1534},
+ {"manage", 1535},
+ {"moral", 1536},
+ {"possess", 1537},
+ {"raw", 1538},
+ {"rebel", 1539},
+ {"royal", 1540},
+ {"scale", 1541},
+ {"scary", 1542},
+ {"several", 1543},
+ {"slight", 1544},
+ {"stubborn", 1545},
+ {"swell", 1546},
+ {"talent", 1547},
+ {"tea", 1548},
+ {"terrible", 1549},
+ {"thread", 1550},
+ {"torment", 1551},
+ {"trickle", 1552},
+ {"usually", 1553},
+ {"vast", 1554},
+ {"violence", 1555},
+ {"weave", 1556},
+ {"acid", 1557},
+ {"agony", 1558},
+ {"ashamed", 1559},
+ {"awe", 1560},
+ {"belly", 1561},
+ {"blend", 1562},
+ {"blush", 1563},
+ {"character", 1564},
+ {"cheat", 1565},
+ {"common", 1566},
+ {"company", 1567},
+ {"coward", 1568},
+ {"creak", 1569},
+ {"danger", 1570},
+ {"deadly", 1571},
+ {"defense", 1572},
+ {"define", 1573},
+ {"depend", 1574},
+ {"desperate", 1575},
+ {"destination", 1576},
+ {"dew", 1577},
+ {"duck", 1578},
+ {"dusty", 1579},
+ {"embarrass", 1580},
+ {"engine", 1581},
+ {"example", 1582},
+ {"explore", 1583},
+ {"foe", 1584},
+ {"freely", 1585},
+ {"frustrate", 1586},
+ {"generation", 1587},
+ {"glove", 1588},
+ {"guilty", 1589},
+ {"health", 1590},
+ {"hurry", 1591},
+ {"idiot", 1592},
+ {"impossible", 1593},
+ {"inhale", 1594},
+ {"jaw", 1595},
+ {"kingdom", 1596},
+ {"mention", 1597},
+ {"mist", 1598},
+ {"moan", 1599},
+ {"mumble", 1600},
+ {"mutter", 1601},
+ {"observe", 1602},
+ {"ode", 1603},
+ {"pathetic", 1604},
+ {"pattern", 1605},
+ {"pie", 1606},
+ {"prefer", 1607},
+ {"puff", 1608},
+ {"rape", 1609},
+ {"rare", 1610},
+ {"revenge", 1611},
+ {"rude", 1612},
+ {"scrape", 1613},
+ {"spiral", 1614},
+ {"squeeze", 1615},
+ {"strain", 1616},
+ {"sunset", 1617},
+ {"suspend", 1618},
+ {"sympathy", 1619},
+ {"thigh", 1620},
+ {"throne", 1621},
+ {"total", 1622},
+ {"unseen", 1623},
+ {"weapon", 1624},
+ {"weary", 1625}
+ };
+
+ const std::string wordsArray[] = {
+ "like",
+ "just",
+ "love",
+ "know",
+ "never",
+ "want",
+ "time",
+ "out",
+ "there",
+ "make",
+ "look",
+ "eye",
+ "down",
+ "only",
+ "think",
+ "heart",
+ "back",
+ "then",
+ "into",
+ "about",
+ "more",
+ "away",
+ "still",
+ "them",
+ "take",
+ "thing",
+ "even",
+ "through",
+ "long",
+ "always",
+ "world",
+ "too",
+ "friend",
+ "tell",
+ "try",
+ "hand",
+ "thought",
+ "over",
+ "here",
+ "other",
+ "need",
+ "smile",
+ "again",
+ "much",
+ "cry",
+ "been",
+ "night",
+ "ever",
+ "little",
+ "said",
+ "end",
+ "some",
+ "those",
+ "around",
+ "mind",
+ "people",
+ "girl",
+ "leave",
+ "dream",
+ "left",
+ "turn",
+ "myself",
+ "give",
+ "nothing",
+ "really",
+ "off",
+ "before",
+ "something",
+ "find",
+ "walk",
+ "wish",
+ "good",
+ "once",
+ "place",
+ "ask",
+ "stop",
+ "keep",
+ "watch",
+ "seem",
+ "everything",
+ "wait",
+ "got",
+ "yet",
+ "made",
+ "remember",
+ "start",
+ "alone",
+ "run",
+ "hope",
+ "maybe",
+ "believe",
+ "body",
+ "hate",
+ "after",
+ "close",
+ "talk",
+ "stand",
+ "own",
+ "each",
+ "hurt",
+ "help",
+ "home",
+ "god",
+ "soul",
+ "new",
+ "many",
+ "two",
+ "inside",
+ "should",
+ "true",
+ "first",
+ "fear",
+ "mean",
+ "better",
+ "play",
+ "another",
+ "gone",
+ "change",
+ "use",
+ "wonder",
+ "someone",
+ "hair",
+ "cold",
+ "open",
+ "best",
+ "any",
+ "behind",
+ "happen",
+ "water",
+ "dark",
+ "laugh",
+ "stay",
+ "forever",
+ "name",
+ "work",
+ "show",
+ "sky",
+ "break",
+ "came",
+ "deep",
+ "door",
+ "put",
+ "black",
+ "together",
+ "upon",
+ "happy",
+ "such",
+ "great",
+ "white",
+ "matter",
+ "fill",
+ "past",
+ "please",
+ "burn",
+ "cause",
+ "enough",
+ "touch",
+ "moment",
+ "soon",
+ "voice",
+ "scream",
+ "anything",
+ "stare",
+ "sound",
+ "red",
+ "everyone",
+ "hide",
+ "kiss",
+ "truth",
+ "death",
+ "beautiful",
+ "mine",
+ "blood",
+ "broken",
+ "very",
+ "pass",
+ "next",
+ "forget",
+ "tree",
+ "wrong",
+ "air",
+ "mother",
+ "understand",
+ "lip",
+ "hit",
+ "wall",
+ "memory",
+ "sleep",
+ "free",
+ "high",
+ "realize",
+ "school",
+ "might",
+ "skin",
+ "sweet",
+ "perfect",
+ "blue",
+ "kill",
+ "breath",
+ "dance",
+ "against",
+ "fly",
+ "between",
+ "grow",
+ "strong",
+ "under",
+ "listen",
+ "bring",
+ "sometimes",
+ "speak",
+ "pull",
+ "person",
+ "become",
+ "family",
+ "begin",
+ "ground",
+ "real",
+ "small",
+ "father",
+ "sure",
+ "feet",
+ "rest",
+ "young",
+ "finally",
+ "land",
+ "across",
+ "today",
+ "different",
+ "guy",
+ "line",
+ "fire",
+ "reason",
+ "reach",
+ "second",
+ "slowly",
+ "write",
+ "eat",
+ "smell",
+ "mouth",
+ "step",
+ "learn",
+ "three",
+ "floor",
+ "promise",
+ "breathe",
+ "darkness",
+ "push",
+ "earth",
+ "guess",
+ "save",
+ "song",
+ "above",
+ "along",
+ "both",
+ "color",
+ "house",
+ "almost",
+ "sorry",
+ "anymore",
+ "brother",
+ "okay",
+ "dear",
+ "game",
+ "fade",
+ "already",
+ "apart",
+ "warm",
+ "beauty",
+ "heard",
+ "notice",
+ "question",
+ "shine",
+ "began",
+ "piece",
+ "whole",
+ "shadow",
+ "secret",
+ "street",
+ "within",
+ "finger",
+ "point",
+ "morning",
+ "whisper",
+ "child",
+ "moon",
+ "green",
+ "story",
+ "glass",
+ "kid",
+ "silence",
+ "since",
+ "soft",
+ "yourself",
+ "empty",
+ "shall",
+ "angel",
+ "answer",
+ "baby",
+ "bright",
+ "dad",
+ "path",
+ "worry",
+ "hour",
+ "drop",
+ "follow",
+ "power",
+ "war",
+ "half",
+ "flow",
+ "heaven",
+ "act",
+ "chance",
+ "fact",
+ "least",
+ "tired",
+ "children",
+ "near",
+ "quite",
+ "afraid",
+ "rise",
+ "sea",
+ "taste",
+ "window",
+ "cover",
+ "nice",
+ "trust",
+ "lot",
+ "sad",
+ "cool",
+ "force",
+ "peace",
+ "return",
+ "blind",
+ "easy",
+ "ready",
+ "roll",
+ "rose",
+ "drive",
+ "held",
+ "music",
+ "beneath",
+ "hang",
+ "mom",
+ "paint",
+ "emotion",
+ "quiet",
+ "clear",
+ "cloud",
+ "few",
+ "pretty",
+ "bird",
+ "outside",
+ "paper",
+ "picture",
+ "front",
+ "rock",
+ "simple",
+ "anyone",
+ "meant",
+ "reality",
+ "road",
+ "sense",
+ "waste",
+ "bit",
+ "leaf",
+ "thank",
+ "happiness",
+ "meet",
+ "men",
+ "smoke",
+ "truly",
+ "decide",
+ "self",
+ "age",
+ "book",
+ "form",
+ "alive",
+ "carry",
+ "escape",
+ "damn",
+ "instead",
+ "able",
+ "ice",
+ "minute",
+ "throw",
+ "catch",
+ "leg",
+ "ring",
+ "course",
+ "goodbye",
+ "lead",
+ "poem",
+ "sick",
+ "corner",
+ "desire",
+ "known",
+ "problem",
+ "remind",
+ "shoulder",
+ "suppose",
+ "toward",
+ "wave",
+ "drink",
+ "jump",
+ "woman",
+ "pretend",
+ "sister",
+ "week",
+ "human",
+ "joy",
+ "crack",
+ "grey",
+ "pray",
+ "surprise",
+ "dry",
+ "knee",
+ "less",
+ "search",
+ "bleed",
+ "caught",
+ "clean",
+ "embrace",
+ "future",
+ "king",
+ "son",
+ "sorrow",
+ "chest",
+ "hug",
+ "remain",
+ "sat",
+ "worth",
+ "blow",
+ "daddy",
+ "final",
+ "parent",
+ "tight",
+ "also",
+ "create",
+ "lonely",
+ "safe",
+ "cross",
+ "dress",
+ "evil",
+ "silent",
+ "bone",
+ "fate",
+ "perhaps",
+ "anger",
+ "class",
+ "scar",
+ "snow",
+ "tiny",
+ "tonight",
+ "continue",
+ "control",
+ "dog",
+ "edge",
+ "mirror",
+ "month",
+ "suddenly",
+ "comfort",
+ "given",
+ "loud",
+ "quickly",
+ "gaze",
+ "plan",
+ "rush",
+ "stone",
+ "town",
+ "battle",
+ "ignore",
+ "spirit",
+ "stood",
+ "stupid",
+ "yours",
+ "brown",
+ "build",
+ "dust",
+ "hey",
+ "kept",
+ "pay",
+ "phone",
+ "twist",
+ "although",
+ "ball",
+ "beyond",
+ "hidden",
+ "nose",
+ "taken",
+ "fail",
+ "float",
+ "pure",
+ "somehow",
+ "wash",
+ "wrap",
+ "angry",
+ "cheek",
+ "creature",
+ "forgotten",
+ "heat",
+ "rip",
+ "single",
+ "space",
+ "special",
+ "weak",
+ "whatever",
+ "yell",
+ "anyway",
+ "blame",
+ "job",
+ "choose",
+ "country",
+ "curse",
+ "drift",
+ "echo",
+ "figure",
+ "grew",
+ "laughter",
+ "neck",
+ "suffer",
+ "worse",
+ "yeah",
+ "disappear",
+ "foot",
+ "forward",
+ "knife",
+ "mess",
+ "somewhere",
+ "stomach",
+ "storm",
+ "beg",
+ "idea",
+ "lift",
+ "offer",
+ "breeze",
+ "field",
+ "five",
+ "often",
+ "simply",
+ "stuck",
+ "win",
+ "allow",
+ "confuse",
+ "enjoy",
+ "except",
+ "flower",
+ "seek",
+ "strength",
+ "calm",
+ "grin",
+ "gun",
+ "heavy",
+ "hill",
+ "large",
+ "ocean",
+ "shoe",
+ "sigh",
+ "straight",
+ "summer",
+ "tongue",
+ "accept",
+ "crazy",
+ "everyday",
+ "exist",
+ "grass",
+ "mistake",
+ "sent",
+ "shut",
+ "surround",
+ "table",
+ "ache",
+ "brain",
+ "destroy",
+ "heal",
+ "nature",
+ "shout",
+ "sign",
+ "stain",
+ "choice",
+ "doubt",
+ "glance",
+ "glow",
+ "mountain",
+ "queen",
+ "stranger",
+ "throat",
+ "tomorrow",
+ "city",
+ "either",
+ "fish",
+ "flame",
+ "rather",
+ "shape",
+ "spin",
+ "spread",
+ "ash",
+ "distance",
+ "finish",
+ "image",
+ "imagine",
+ "important",
+ "nobody",
+ "shatter",
+ "warmth",
+ "became",
+ "feed",
+ "flesh",
+ "funny",
+ "lust",
+ "shirt",
+ "trouble",
+ "yellow",
+ "attention",
+ "bare",
+ "bite",
+ "money",
+ "protect",
+ "amaze",
+ "appear",
+ "born",
+ "choke",
+ "completely",
+ "daughter",
+ "fresh",
+ "friendship",
+ "gentle",
+ "probably",
+ "six",
+ "deserve",
+ "expect",
+ "grab",
+ "middle",
+ "nightmare",
+ "river",
+ "thousand",
+ "weight",
+ "worst",
+ "wound",
+ "barely",
+ "bottle",
+ "cream",
+ "regret",
+ "relationship",
+ "stick",
+ "test",
+ "crush",
+ "endless",
+ "fault",
+ "itself",
+ "rule",
+ "spill",
+ "art",
+ "circle",
+ "join",
+ "kick",
+ "mask",
+ "master",
+ "passion",
+ "quick",
+ "raise",
+ "smooth",
+ "unless",
+ "wander",
+ "actually",
+ "broke",
+ "chair",
+ "deal",
+ "favorite",
+ "gift",
+ "note",
+ "number",
+ "sweat",
+ "box",
+ "chill",
+ "clothes",
+ "lady",
+ "mark",
+ "park",
+ "poor",
+ "sadness",
+ "tie",
+ "animal",
+ "belong",
+ "brush",
+ "consume",
+ "dawn",
+ "forest",
+ "innocent",
+ "pen",
+ "pride",
+ "stream",
+ "thick",
+ "clay",
+ "complete",
+ "count",
+ "draw",
+ "faith",
+ "press",
+ "silver",
+ "struggle",
+ "surface",
+ "taught",
+ "teach",
+ "wet",
+ "bless",
+ "chase",
+ "climb",
+ "enter",
+ "letter",
+ "melt",
+ "metal",
+ "movie",
+ "stretch",
+ "swing",
+ "vision",
+ "wife",
+ "beside",
+ "crash",
+ "forgot",
+ "guide",
+ "haunt",
+ "joke",
+ "knock",
+ "plant",
+ "pour",
+ "prove",
+ "reveal",
+ "steal",
+ "stuff",
+ "trip",
+ "wood",
+ "wrist",
+ "bother",
+ "bottom",
+ "crawl",
+ "crowd",
+ "fix",
+ "forgive",
+ "frown",
+ "grace",
+ "loose",
+ "lucky",
+ "party",
+ "release",
+ "surely",
+ "survive",
+ "teacher",
+ "gently",
+ "grip",
+ "speed",
+ "suicide",
+ "travel",
+ "treat",
+ "vein",
+ "written",
+ "cage",
+ "chain",
+ "conversation",
+ "date",
+ "enemy",
+ "however",
+ "interest",
+ "million",
+ "page",
+ "pink",
+ "proud",
+ "sway",
+ "themselves",
+ "winter",
+ "church",
+ "cruel",
+ "cup",
+ "demon",
+ "experience",
+ "freedom",
+ "pair",
+ "pop",
+ "purpose",
+ "respect",
+ "shoot",
+ "softly",
+ "state",
+ "strange",
+ "bar",
+ "birth",
+ "curl",
+ "dirt",
+ "excuse",
+ "lord",
+ "lovely",
+ "monster",
+ "order",
+ "pack",
+ "pants",
+ "pool",
+ "scene",
+ "seven",
+ "shame",
+ "slide",
+ "ugly",
+ "among",
+ "blade",
+ "blonde",
+ "closet",
+ "creek",
+ "deny",
+ "drug",
+ "eternity",
+ "gain",
+ "grade",
+ "handle",
+ "key",
+ "linger",
+ "pale",
+ "prepare",
+ "swallow",
+ "swim",
+ "tremble",
+ "wheel",
+ "won",
+ "cast",
+ "cigarette",
+ "claim",
+ "college",
+ "direction",
+ "dirty",
+ "gather",
+ "ghost",
+ "hundred",
+ "loss",
+ "lung",
+ "orange",
+ "present",
+ "swear",
+ "swirl",
+ "twice",
+ "wild",
+ "bitter",
+ "blanket",
+ "doctor",
+ "everywhere",
+ "flash",
+ "grown",
+ "knowledge",
+ "numb",
+ "pressure",
+ "radio",
+ "repeat",
+ "ruin",
+ "spend",
+ "unknown",
+ "buy",
+ "clock",
+ "devil",
+ "early",
+ "false",
+ "fantasy",
+ "pound",
+ "precious",
+ "refuse",
+ "sheet",
+ "teeth",
+ "welcome",
+ "add",
+ "ahead",
+ "block",
+ "bury",
+ "caress",
+ "content",
+ "depth",
+ "despite",
+ "distant",
+ "marry",
+ "purple",
+ "threw",
+ "whenever",
+ "bomb",
+ "dull",
+ "easily",
+ "grasp",
+ "hospital",
+ "innocence",
+ "normal",
+ "receive",
+ "reply",
+ "rhyme",
+ "shade",
+ "someday",
+ "sword",
+ "toe",
+ "visit",
+ "asleep",
+ "bought",
+ "center",
+ "consider",
+ "flat",
+ "hero",
+ "history",
+ "ink",
+ "insane",
+ "muscle",
+ "mystery",
+ "pocket",
+ "reflection",
+ "shove",
+ "silently",
+ "smart",
+ "soldier",
+ "spot",
+ "stress",
+ "train",
+ "type",
+ "view",
+ "whether",
+ "bus",
+ "energy",
+ "explain",
+ "holy",
+ "hunger",
+ "inch",
+ "magic",
+ "mix",
+ "noise",
+ "nowhere",
+ "prayer",
+ "presence",
+ "shock",
+ "snap",
+ "spider",
+ "study",
+ "thunder",
+ "trail",
+ "admit",
+ "agree",
+ "bag",
+ "bang",
+ "bound",
+ "butterfly",
+ "cute",
+ "exactly",
+ "explode",
+ "familiar",
+ "fold",
+ "further",
+ "pierce",
+ "reflect",
+ "scent",
+ "selfish",
+ "sharp",
+ "sink",
+ "spring",
+ "stumble",
+ "universe",
+ "weep",
+ "women",
+ "wonderful",
+ "action",
+ "ancient",
+ "attempt",
+ "avoid",
+ "birthday",
+ "branch",
+ "chocolate",
+ "core",
+ "depress",
+ "drunk",
+ "especially",
+ "focus",
+ "fruit",
+ "honest",
+ "match",
+ "palm",
+ "perfectly",
+ "pillow",
+ "pity",
+ "poison",
+ "roar",
+ "shift",
+ "slightly",
+ "thump",
+ "truck",
+ "tune",
+ "twenty",
+ "unable",
+ "wipe",
+ "wrote",
+ "coat",
+ "constant",
+ "dinner",
+ "drove",
+ "egg",
+ "eternal",
+ "flight",
+ "flood",
+ "frame",
+ "freak",
+ "gasp",
+ "glad",
+ "hollow",
+ "motion",
+ "peer",
+ "plastic",
+ "root",
+ "screen",
+ "season",
+ "sting",
+ "strike",
+ "team",
+ "unlike",
+ "victim",
+ "volume",
+ "warn",
+ "weird",
+ "attack",
+ "await",
+ "awake",
+ "built",
+ "charm",
+ "crave",
+ "despair",
+ "fought",
+ "grant",
+ "grief",
+ "horse",
+ "limit",
+ "message",
+ "ripple",
+ "sanity",
+ "scatter",
+ "serve",
+ "split",
+ "string",
+ "trick",
+ "annoy",
+ "blur",
+ "boat",
+ "brave",
+ "clearly",
+ "cling",
+ "connect",
+ "fist",
+ "forth",
+ "imagination",
+ "iron",
+ "jock",
+ "judge",
+ "lesson",
+ "milk",
+ "misery",
+ "nail",
+ "naked",
+ "ourselves",
+ "poet",
+ "possible",
+ "princess",
+ "sail",
+ "size",
+ "snake",
+ "society",
+ "stroke",
+ "torture",
+ "toss",
+ "trace",
+ "wise",
+ "bloom",
+ "bullet",
+ "cell",
+ "check",
+ "cost",
+ "darling",
+ "during",
+ "footstep",
+ "fragile",
+ "hallway",
+ "hardly",
+ "horizon",
+ "invisible",
+ "journey",
+ "midnight",
+ "mud",
+ "nod",
+ "pause",
+ "relax",
+ "shiver",
+ "sudden",
+ "value",
+ "youth",
+ "abuse",
+ "admire",
+ "blink",
+ "breast",
+ "bruise",
+ "constantly",
+ "couple",
+ "creep",
+ "curve",
+ "difference",
+ "dumb",
+ "emptiness",
+ "gotta",
+ "honor",
+ "plain",
+ "planet",
+ "recall",
+ "rub",
+ "ship",
+ "slam",
+ "soar",
+ "somebody",
+ "tightly",
+ "weather",
+ "adore",
+ "approach",
+ "bond",
+ "bread",
+ "burst",
+ "candle",
+ "coffee",
+ "cousin",
+ "crime",
+ "desert",
+ "flutter",
+ "frozen",
+ "grand",
+ "heel",
+ "hello",
+ "language",
+ "level",
+ "movement",
+ "pleasure",
+ "powerful",
+ "random",
+ "rhythm",
+ "settle",
+ "silly",
+ "slap",
+ "sort",
+ "spoken",
+ "steel",
+ "threaten",
+ "tumble",
+ "upset",
+ "aside",
+ "awkward",
+ "bee",
+ "blank",
+ "board",
+ "button",
+ "card",
+ "carefully",
+ "complain",
+ "crap",
+ "deeply",
+ "discover",
+ "drag",
+ "dread",
+ "effort",
+ "entire",
+ "fairy",
+ "giant",
+ "gotten",
+ "greet",
+ "illusion",
+ "jeans",
+ "leap",
+ "liquid",
+ "march",
+ "mend",
+ "nervous",
+ "nine",
+ "replace",
+ "rope",
+ "spine",
+ "stole",
+ "terror",
+ "accident",
+ "apple",
+ "balance",
+ "boom",
+ "childhood",
+ "collect",
+ "demand",
+ "depression",
+ "eventually",
+ "faint",
+ "glare",
+ "goal",
+ "group",
+ "honey",
+ "kitchen",
+ "laid",
+ "limb",
+ "machine",
+ "mere",
+ "mold",
+ "murder",
+ "nerve",
+ "painful",
+ "poetry",
+ "prince",
+ "rabbit",
+ "shelter",
+ "shore",
+ "shower",
+ "soothe",
+ "stair",
+ "steady",
+ "sunlight",
+ "tangle",
+ "tease",
+ "treasure",
+ "uncle",
+ "begun",
+ "bliss",
+ "canvas",
+ "cheer",
+ "claw",
+ "clutch",
+ "commit",
+ "crimson",
+ "crystal",
+ "delight",
+ "doll",
+ "existence",
+ "express",
+ "fog",
+ "football",
+ "gay",
+ "goose",
+ "guard",
+ "hatred",
+ "illuminate",
+ "mass",
+ "math",
+ "mourn",
+ "rich",
+ "rough",
+ "skip",
+ "stir",
+ "student",
+ "style",
+ "support",
+ "thorn",
+ "tough",
+ "yard",
+ "yearn",
+ "yesterday",
+ "advice",
+ "appreciate",
+ "autumn",
+ "bank",
+ "beam",
+ "bowl",
+ "capture",
+ "carve",
+ "collapse",
+ "confusion",
+ "creation",
+ "dove",
+ "feather",
+ "girlfriend",
+ "glory",
+ "government",
+ "harsh",
+ "hop",
+ "inner",
+ "loser",
+ "moonlight",
+ "neighbor",
+ "neither",
+ "peach",
+ "pig",
+ "praise",
+ "screw",
+ "shield",
+ "shimmer",
+ "sneak",
+ "stab",
+ "subject",
+ "throughout",
+ "thrown",
+ "tower",
+ "twirl",
+ "wow",
+ "army",
+ "arrive",
+ "bathroom",
+ "bump",
+ "cease",
+ "cookie",
+ "couch",
+ "courage",
+ "dim",
+ "guilt",
+ "howl",
+ "hum",
+ "husband",
+ "insult",
+ "led",
+ "lunch",
+ "mock",
+ "mostly",
+ "natural",
+ "nearly",
+ "needle",
+ "nerd",
+ "peaceful",
+ "perfection",
+ "pile",
+ "price",
+ "remove",
+ "roam",
+ "sanctuary",
+ "serious",
+ "shiny",
+ "shook",
+ "sob",
+ "stolen",
+ "tap",
+ "vain",
+ "void",
+ "warrior",
+ "wrinkle",
+ "affection",
+ "apologize",
+ "blossom",
+ "bounce",
+ "bridge",
+ "cheap",
+ "crumble",
+ "decision",
+ "descend",
+ "desperately",
+ "dig",
+ "dot",
+ "flip",
+ "frighten",
+ "heartbeat",
+ "huge",
+ "lazy",
+ "lick",
+ "odd",
+ "opinion",
+ "process",
+ "puzzle",
+ "quietly",
+ "retreat",
+ "score",
+ "sentence",
+ "separate",
+ "situation",
+ "skill",
+ "soak",
+ "square",
+ "stray",
+ "taint",
+ "task",
+ "tide",
+ "underneath",
+ "veil",
+ "whistle",
+ "anywhere",
+ "bedroom",
+ "bid",
+ "bloody",
+ "burden",
+ "careful",
+ "compare",
+ "concern",
+ "curtain",
+ "decay",
+ "defeat",
+ "describe",
+ "double",
+ "dreamer",
+ "driver",
+ "dwell",
+ "evening",
+ "flare",
+ "flicker",
+ "grandma",
+ "guitar",
+ "harm",
+ "horrible",
+ "hungry",
+ "indeed",
+ "lace",
+ "melody",
+ "monkey",
+ "nation",
+ "object",
+ "obviously",
+ "rainbow",
+ "salt",
+ "scratch",
+ "shown",
+ "shy",
+ "stage",
+ "stun",
+ "third",
+ "tickle",
+ "useless",
+ "weakness",
+ "worship",
+ "worthless",
+ "afternoon",
+ "beard",
+ "boyfriend",
+ "bubble",
+ "busy",
+ "certain",
+ "chin",
+ "concrete",
+ "desk",
+ "diamond",
+ "doom",
+ "drawn",
+ "due",
+ "felicity",
+ "freeze",
+ "frost",
+ "garden",
+ "glide",
+ "harmony",
+ "hopefully",
+ "hunt",
+ "jealous",
+ "lightning",
+ "mama",
+ "mercy",
+ "peel",
+ "physical",
+ "position",
+ "pulse",
+ "punch",
+ "quit",
+ "rant",
+ "respond",
+ "salty",
+ "sane",
+ "satisfy",
+ "savior",
+ "sheep",
+ "slept",
+ "social",
+ "sport",
+ "tuck",
+ "utter",
+ "valley",
+ "wolf",
+ "aim",
+ "alas",
+ "alter",
+ "arrow",
+ "awaken",
+ "beaten",
+ "belief",
+ "brand",
+ "ceiling",
+ "cheese",
+ "clue",
+ "confidence",
+ "connection",
+ "daily",
+ "disguise",
+ "eager",
+ "erase",
+ "essence",
+ "everytime",
+ "expression",
+ "fan",
+ "flag",
+ "flirt",
+ "foul",
+ "fur",
+ "giggle",
+ "glorious",
+ "ignorance",
+ "law",
+ "lifeless",
+ "measure",
+ "mighty",
+ "muse",
+ "north",
+ "opposite",
+ "paradise",
+ "patience",
+ "patient",
+ "pencil",
+ "petal",
+ "plate",
+ "ponder",
+ "possibly",
+ "practice",
+ "slice",
+ "spell",
+ "stock",
+ "strife",
+ "strip",
+ "suffocate",
+ "suit",
+ "tender",
+ "tool",
+ "trade",
+ "velvet",
+ "verse",
+ "waist",
+ "witch",
+ "aunt",
+ "bench",
+ "bold",
+ "cap",
+ "certainly",
+ "click",
+ "companion",
+ "creator",
+ "dart",
+ "delicate",
+ "determine",
+ "dish",
+ "dragon",
+ "drama",
+ "drum",
+ "dude",
+ "everybody",
+ "feast",
+ "forehead",
+ "former",
+ "fright",
+ "fully",
+ "gas",
+ "hook",
+ "hurl",
+ "invite",
+ "juice",
+ "manage",
+ "moral",
+ "possess",
+ "raw",
+ "rebel",
+ "royal",
+ "scale",
+ "scary",
+ "several",
+ "slight",
+ "stubborn",
+ "swell",
+ "talent",
+ "tea",
+ "terrible",
+ "thread",
+ "torment",
+ "trickle",
+ "usually",
+ "vast",
+ "violence",
+ "weave",
+ "acid",
+ "agony",
+ "ashamed",
+ "awe",
+ "belly",
+ "blend",
+ "blush",
+ "character",
+ "cheat",
+ "common",
+ "company",
+ "coward",
+ "creak",
+ "danger",
+ "deadly",
+ "defense",
+ "define",
+ "depend",
+ "desperate",
+ "destination",
+ "dew",
+ "duck",
+ "dusty",
+ "embarrass",
+ "engine",
+ "example",
+ "explore",
+ "foe",
+ "freely",
+ "frustrate",
+ "generation",
+ "glove",
+ "guilty",
+ "health",
+ "hurry",
+ "idiot",
+ "impossible",
+ "inhale",
+ "jaw",
+ "kingdom",
+ "mention",
+ "mist",
+ "moan",
+ "mumble",
+ "mutter",
+ "observe",
+ "ode",
+ "pathetic",
+ "pattern",
+ "pie",
+ "prefer",
+ "puff",
+ "rape",
+ "rare",
+ "revenge",
+ "rude",
+ "scrape",
+ "spiral",
+ "squeeze",
+ "strain",
+ "sunset",
+ "suspend",
+ "sympathy",
+ "thigh",
+ "throne",
+ "total",
+ "unseen",
+ "weapon",
+ "weary"
+ };
+ }
+}
diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp
index ba39b9b77..7da1c6745 100644
--- a/src/cryptonote_core/account.cpp
+++ b/src/cryptonote_core/account.cpp
@@ -10,6 +10,10 @@
#include "account.h"
#include "warnings.h"
#include "crypto/crypto.h"
+extern "C"
+{
+#include "crypto/blake256.h"
+}
#include "cryptonote_core/cryptonote_basic_impl.h"
#include "cryptonote_core/cryptonote_format_utils.h"
using namespace std;
@@ -29,11 +33,17 @@ DISABLE_VS_WARNINGS(4244 4345)
m_keys = account_keys();
}
//-----------------------------------------------------------------
- void account_base::generate()
+ crypto::secret_key account_base::generate(const crypto::secret_key& recovery_key, bool recover, bool two_random)
{
- generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key);
- generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key);
+ crypto::secret_key first = generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, recovery_key, recover);
+
+ // rng for generating second set of keys is hash of first rng. means only one set of electrum-style words needed for recovery
+ crypto::secret_key second;
+ blake256_hash((uint8_t *)&second, (uint8_t *)&first, sizeof(crypto::secret_key));
+
+ generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, two_random ? false : true);
m_creation_timestamp = time(NULL);
+ return first;
}
//-----------------------------------------------------------------
const account_keys& account_base::get_keys() const
diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h
index 8b525da97..cb77d7c4e 100644
--- a/src/cryptonote_core/account.h
+++ b/src/cryptonote_core/account.h
@@ -31,7 +31,7 @@ namespace cryptonote
{
public:
account_base();
- void generate();
+ crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
const account_keys& get_keys() const;
std::string get_public_address_str();
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 4cab12c22..95d163f2e 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -17,6 +17,8 @@
#include "rpc/core_rpc_server_commands_defs.h"
#include "wallet/wallet_rpc_server.h"
#include "version.h"
+#include "crypto/crypto.h" // for crypto::secret_key definition
+#include "crypto/electrum-words.h"
#if defined(WIN32)
#include <crtdbg.h>
@@ -38,6 +40,9 @@ namespace
const command_line::arg_descriptor<std::string> arg_daemon_address = {"daemon-address", "Use daemon instance at <host>:<port>", ""};
const command_line::arg_descriptor<std::string> arg_daemon_host = {"daemon-host", "Use daemon instance at host <arg> instead of localhost", ""};
const command_line::arg_descriptor<std::string> arg_password = {"password", "Wallet password", "", true};
+ const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", "Specify electrum seed for wallet recovery/creation", ""};
+ const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", "Recover wallet using electrum-style mnemonic", false};
+ const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", "requires --generate-new-wallet, uses old generation method", false};
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of 8081", 0};
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true};
@@ -208,17 +213,25 @@ bool simple_wallet::ask_wallet_create_if_needed()
{
std::string wallet_path;
- std::cout << "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n";
- std::cout << "Wallet file name: ";
-
- std::getline(std::cin, wallet_path);
-
- wallet_path = string_tools::trim(wallet_path);
+ wallet_path = command_line::input_line(
+ "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n"
+ "Wallet file name: "
+ );
bool keys_file_exists;
bool wallet_file_exists;
tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists);
+ // add logic to error out if new wallet requested but named wallet file exists
+ if (keys_file_exists || wallet_file_exists)
+ {
+ if (!m_generate_new.empty() || m_restore_deterministic_wallet)
+ {
+ fail_msg_writer() << "Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.";
+ return false;
+ }
+ }
+
bool r;
if(keys_file_exists)
{
@@ -251,13 +264,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false;
}
- size_t c = 0;
- if(!m_generate_new.empty()) ++c;
- if(!m_wallet_file.empty()) ++c;
- if (1 != c)
+ if(!m_generate_new.empty() && !m_wallet_file.empty())
{
- if(!ask_wallet_create_if_needed())
- return false;
+ fail_msg_writer() << "Specifying both --generate-new-wallet=\"wallet_name\" and --wallet-file=\"wallet_name\" doesn't make sense!";
+ return false;
+ }
+ else if (m_generate_new.empty() && m_wallet_file.empty())
+ {
+ if(!ask_wallet_create_if_needed()) return false;
}
if (m_daemon_host.empty())
@@ -282,9 +296,36 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
}
}
- if (!m_generate_new.empty())
+ if (!m_generate_new.empty() || m_restore_deterministic_wallet)
{
- bool r = new_wallet(m_generate_new, pwd_container.password());
+ if (m_wallet_file.empty()) m_wallet_file = m_generate_new; // alias for simplicity later
+
+ // check for recover flag. if present, require electrum word list (only recovery option for now).
+ if (m_restore_deterministic_wallet)
+ {
+ if (m_non_deterministic)
+ {
+ fail_msg_writer() << "Cannot specify both --restore-deterministic-wallet and --non-deterministic";
+ return false;
+ }
+
+ if (m_electrum_seed.empty())
+ {
+ m_electrum_seed = command_line::input_line("Specify electrum seed: ");
+ if (m_electrum_seed.empty())
+ {
+ fail_msg_writer() << "specify a recovery parameter with the --electrum-seed=\"words list here\"";
+ return false;
+ }
+ }
+
+ if (!crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key))
+ {
+ fail_msg_writer() << "electrum-style word list failed verification";
+ return false;
+ }
+ }
+ bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic);
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
}
else
@@ -306,11 +347,14 @@ bool simple_wallet::deinit()
//----------------------------------------------------------------------------------------------------
void simple_wallet::handle_command_line(const boost::program_options::variables_map& vm)
{
- m_wallet_file = command_line::get_arg(vm, arg_wallet_file);
- m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
- m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
- m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
- m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
+ m_wallet_file = command_line::get_arg(vm, arg_wallet_file);
+ m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
+ m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
+ m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
+ m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
+ m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed);
+ m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
+ m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::try_connect_to_daemon()
@@ -324,16 +368,19 @@ bool simple_wallet::try_connect_to_daemon()
}
return true;
}
+
//----------------------------------------------------------------------------------------------------
-bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password)
+bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random)
{
m_wallet_file = wallet_file;
m_wallet.reset(new tools::wallet2());
m_wallet->callback(this);
+
+ crypto::secret_key recovery_val;
try
{
- m_wallet->generate(wallet_file, password);
+ recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random);
message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " << m_wallet->get_account().get_public_address_str() << std::endl << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
}
catch (const std::exception& e)
@@ -344,6 +391,19 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
m_wallet->init(m_daemon_address);
+ // convert rng value to electrum-style word list
+ std::string electrum_words;
+ crypto::ElectrumWords::bytes_to_words(recovery_val, electrum_words);
+
+ std::string print_electrum = "";
+
+ if (!two_random)
+ {
+ print_electrum = "\nYour wallet can be recovered using the following electrum-style word list:\n";
+ print_electrum += electrum_words;
+ print_electrum += "\n";
+ }
+
success_msg_writer() <<
"**********************************************************************\n" <<
"Your wallet has been generated.\n" <<
@@ -352,6 +412,7 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
"Always use \"exit\" command when closing simplewallet to save\n" <<
"current session's state. Otherwise, you will possibly need to synchronize \n" <<
"your wallet again. Your wallet key is NOT under risk anyway.\n" <<
+ print_electrum <<
"**********************************************************************";
return true;
}
@@ -916,6 +977,9 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_daemon_port);
command_line::add_arg(desc_params, arg_command);
command_line::add_arg(desc_params, arg_log_level);
+ command_line::add_arg(desc_params, arg_restore_deterministic_wallet );
+ command_line::add_arg(desc_params, arg_non_deterministic );
+ command_line::add_arg(desc_params, arg_electrum_seed );
tools::wallet_rpc_server::init_options(desc_params);
po::positional_options_description positional_options;
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 3dcaaeaa0..006cdd08e 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -13,6 +13,7 @@
#include "wallet/wallet2.h"
#include "console_handler.h"
#include "password_container.h"
+#include "crypto/crypto.h" // for definition of crypto::secret_key
namespace cryptonote
@@ -39,7 +40,7 @@ namespace cryptonote
bool run_console_handler();
- bool new_wallet(const std::string &wallet_file, const std::string& password);
+ bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
bool open_wallet(const std::string &wallet_file, const std::string& password);
bool close_wallet();
@@ -125,6 +126,12 @@ namespace cryptonote
std::string m_generate_new;
std::string m_import_path;
+ std::string m_electrum_seed; // electrum-style seed parameter
+
+ crypto::secret_key m_recovery_key; // recovery key (used as random for wallet gen)
+ bool m_restore_deterministic_wallet; // recover flag
+ bool m_non_deterministic; // old 2-random generation
+
std::string m_daemon_address;
std::string m_daemon_host;
int m_daemon_port;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index fb1e5575b..a63eb4be7 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -38,6 +38,7 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file,
keys_file += ".keys";
}
}
+
} //namespace
namespace tools
@@ -435,7 +436,7 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa
THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password);
}
//----------------------------------------------------------------------------------------------------
-void wallet2::generate(const std::string& wallet_, const std::string& password)
+crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover, bool two_random)
{
clear();
prepare_file_names(wallet_);
@@ -444,7 +445,8 @@ void wallet2::generate(const std::string& wallet_, const std::string& password)
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file);
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
- m_account.generate();
+ crypto::secret_key retval = m_account.generate(recovery_param, recover, two_random);
+
m_account_public_address = m_account.get_keys().m_account_address;
bool r = store_keys(m_keys_file, password);
@@ -454,6 +456,7 @@ void wallet2::generate(const std::string& wallet_, const std::string& password)
if(!r) LOG_PRINT_RED_L0("String with address text not saved");
store();
+ return retval;
}
//----------------------------------------------------------------------------------------------------
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists)
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 9ca586425..534a0517b 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -97,7 +97,7 @@ namespace tools
END_SERIALIZE()
};
- void generate(const std::string& wallet, const std::string& password);
+ crypto::secret_key generate(const std::string& wallet, const std::string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false, bool two_random = false);
void load(const std::string& wallet, const std::string& password);
void store();
cryptonote::account_base& get_account(){return m_account;}
@@ -227,6 +227,7 @@ namespace boost
namespace tools
{
+
namespace detail
{
//----------------------------------------------------------------------------------------------------
diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h
index 0d42dbaf4..71c946545 100644
--- a/src/wallet/wallet_errors.h
+++ b/src/wallet/wallet_errors.h
@@ -188,6 +188,17 @@ namespace tools
std::string to_string() const { return wallet_logic_error::to_string(); }
};
+
+ //----------------------------------------------------------------------------------------------------
+ struct invalid_pregenerated_random : public wallet_logic_error
+ {
+ explicit invalid_pregenerated_random (std::string&& loc)
+ : wallet_logic_error(std::move(loc), "invalid pregenerated random for wallet creation/recovery")
+ {
+ }
+
+ std::string to_string() const { return wallet_logic_error::to_string(); }
+ };
//----------------------------------------------------------------------------------------------------
struct refresh_error : public wallet_logic_error
{