most functions prototyped/modified for wallet recovery
This commit is contained in:
parent
105825b4ce
commit
4f382b3830
10 changed files with 3371 additions and 9 deletions
|
@ -50,6 +50,7 @@ namespace crypto {
|
||||||
return &reinterpret_cast<const unsigned char &>(scalar);
|
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) {
|
static inline void random_scalar(ec_scalar &res) {
|
||||||
unsigned char tmp[64];
|
unsigned char tmp[64];
|
||||||
generate_random_bytes(64, tmp);
|
generate_random_bytes(64, tmp);
|
||||||
|
@ -62,6 +63,11 @@ namespace crypto {
|
||||||
sc_reduce32(&res);
|
sc_reduce32(&res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate public and secret keys from a random 256-bit integer
|
||||||
|
* TODO: allow specifiying random value (for wallet recovery)
|
||||||
|
*
|
||||||
|
*/
|
||||||
void crypto_ops::generate_keys(public_key &pub, secret_key &sec) {
|
void crypto_ops::generate_keys(public_key &pub, secret_key &sec) {
|
||||||
lock_guard<mutex> lock(random_lock);
|
lock_guard<mutex> lock(random_lock);
|
||||||
ge_p3 point;
|
ge_p3 point;
|
||||||
|
|
29
src/crypto/electrum-words.cpp
Normal file
29
src/crypto/electrum-words.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 <map>
|
||||||
|
#include "crypto/crypto.h" // for declaration of crypto::secret_key
|
||||||
|
|
||||||
|
#include "crypto/electrum-words.h"
|
||||||
|
|
||||||
|
namespace crypto
|
||||||
|
{
|
||||||
|
namespace ElectrumWords
|
||||||
|
{
|
||||||
|
|
||||||
|
bool words_to_bytes(const std::string& words, crypto::secret_key& dst)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool bytes_to_words(const crypto::secret_key& src, std::string& words)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ElectrumWords
|
||||||
|
|
||||||
|
} // namespace crypto
|
3276
src/crypto/electrum-words.h
Normal file
3276
src/crypto/electrum-words.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,7 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||||
m_keys = account_keys();
|
m_keys = account_keys();
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
void account_base::generate()
|
void account_base::generate(const crypto::secret_key& recovery_key, bool recover)
|
||||||
{
|
{
|
||||||
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_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);
|
generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key);
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace cryptonote
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
account_base();
|
account_base();
|
||||||
void generate();
|
void generate(const crypto::secret_key& recovery_key, bool recover);
|
||||||
const account_keys& get_keys() const;
|
const account_keys& get_keys() const;
|
||||||
std::string get_public_address_str();
|
std::string get_public_address_str();
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "rpc/core_rpc_server_commands_defs.h"
|
#include "rpc/core_rpc_server_commands_defs.h"
|
||||||
#include "wallet/wallet_rpc_server.h"
|
#include "wallet/wallet_rpc_server.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "crypto/crypto.h" // for crypto::secret_key definition
|
||||||
|
#include "crypto/electrum-words.h"
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
|
@ -38,6 +40,8 @@ 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_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_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_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_recover = {"recover", "Recover wallet using mnemonic generator (e.g. electrum word list)", 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<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};
|
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true};
|
||||||
|
|
||||||
|
@ -284,7 +288,24 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||||
|
|
||||||
if (!m_generate_new.empty())
|
if (!m_generate_new.empty())
|
||||||
{
|
{
|
||||||
bool r = new_wallet(m_generate_new, pwd_container.password());
|
// check for recover flag. if present, require electrum word list (only recovery option for now).
|
||||||
|
if (m_recover)
|
||||||
|
{
|
||||||
|
if (m_electrum_seed.empty())
|
||||||
|
{
|
||||||
|
fail_msg_writer() << "specify a recovery parameter (e.g. electrum word list) with the recover option";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // verify recovery param (electrum word list) and convert to byte representation
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_MES(
|
||||||
|
crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key),
|
||||||
|
false,
|
||||||
|
"electrum-style word list failed verification"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool r = new_wallet(m_generate_new, pwd_container.password(), m_recovery_key, m_recover);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
|
CHECK_AND_ASSERT_MES(r, false, "account creation failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -311,6 +332,8 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_
|
||||||
m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
m_daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||||
m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
|
m_daemon_host = command_line::get_arg(vm, arg_daemon_host);
|
||||||
m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
|
m_daemon_port = command_line::get_arg(vm, arg_daemon_port);
|
||||||
|
m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed);
|
||||||
|
m_recover = command_line::get_arg(vm, arg_recover);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::try_connect_to_daemon()
|
bool simple_wallet::try_connect_to_daemon()
|
||||||
|
@ -324,8 +347,14 @@ bool simple_wallet::try_connect_to_daemon()
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool simple_wallet::parse_electrum()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
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)
|
||||||
{
|
{
|
||||||
m_wallet_file = wallet_file;
|
m_wallet_file = wallet_file;
|
||||||
|
|
||||||
|
@ -333,7 +362,7 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
||||||
m_wallet->callback(this);
|
m_wallet->callback(this);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_wallet->generate(wallet_file, password);
|
m_wallet->generate(wallet_file, password, recovery_key, recover);
|
||||||
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);
|
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)
|
catch (const std::exception& e)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "wallet/wallet2.h"
|
#include "wallet/wallet2.h"
|
||||||
#include "console_handler.h"
|
#include "console_handler.h"
|
||||||
#include "password_container.h"
|
#include "password_container.h"
|
||||||
|
#include "crypto/crypto.h" // for definition of crypto::secret_key
|
||||||
|
|
||||||
|
|
||||||
namespace cryptonote
|
namespace cryptonote
|
||||||
|
@ -39,7 +40,9 @@ namespace cryptonote
|
||||||
|
|
||||||
bool run_console_handler();
|
bool run_console_handler();
|
||||||
|
|
||||||
bool new_wallet(const std::string &wallet_file, const std::string& password);
|
bool parse_electrum();
|
||||||
|
|
||||||
|
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 open_wallet(const std::string &wallet_file, const std::string& password);
|
bool open_wallet(const std::string &wallet_file, const std::string& password);
|
||||||
bool close_wallet();
|
bool close_wallet();
|
||||||
|
|
||||||
|
@ -125,6 +128,11 @@ namespace cryptonote
|
||||||
std::string m_generate_new;
|
std::string m_generate_new;
|
||||||
std::string m_import_path;
|
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_recover; // recover flag
|
||||||
|
|
||||||
std::string m_daemon_address;
|
std::string m_daemon_address;
|
||||||
std::string m_daemon_host;
|
std::string m_daemon_host;
|
||||||
int m_daemon_port;
|
int m_daemon_port;
|
||||||
|
|
|
@ -38,6 +38,7 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file,
|
||||||
keys_file += ".keys";
|
keys_file += ".keys";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
namespace tools
|
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);
|
THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::generate(const std::string& wallet_, const std::string& password)
|
void wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
prepare_file_names(wallet_);
|
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_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);
|
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
|
||||||
|
|
||||||
m_account.generate();
|
m_account.generate(recovery_param, recover);
|
||||||
|
|
||||||
m_account_public_address = m_account.get_keys().m_account_address;
|
m_account_public_address = m_account.get_keys().m_account_address;
|
||||||
|
|
||||||
bool r = store_keys(m_keys_file, password);
|
bool r = store_keys(m_keys_file, password);
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace tools
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
void generate(const std::string& wallet, const std::string& password);
|
void generate(const std::string& wallet, const std::string& password, const crypto::secret_key& recovery_param, bool recover = false);
|
||||||
void load(const std::string& wallet, const std::string& password);
|
void load(const std::string& wallet, const std::string& password);
|
||||||
void store();
|
void store();
|
||||||
cryptonote::account_base& get_account(){return m_account;}
|
cryptonote::account_base& get_account(){return m_account;}
|
||||||
|
@ -227,6 +227,7 @@ namespace boost
|
||||||
|
|
||||||
namespace tools
|
namespace tools
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -188,6 +188,17 @@ namespace tools
|
||||||
|
|
||||||
std::string to_string() const { return wallet_logic_error::to_string(); }
|
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
|
struct refresh_error : public wallet_logic_error
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue