implemented custom seed option(experimental)

This commit is contained in:
cryptozoidberg 2024-09-14 21:46:09 +04:00
parent 9d10050325
commit 17aebd29b5
No known key found for this signature in database
GPG key ID: 2E10CC61CAC8F36D
3 changed files with 78 additions and 5 deletions

View file

@ -60,7 +60,7 @@ namespace currency
return m_keys;
}
//-----------------------------------------------------------------
void crypt_with_pass(const void* scr_data, std::size_t src_length, void* dst_data, const std::string& password)
void account_base::crypt_with_pass(const void* scr_data, std::size_t src_length, void* dst_data, const std::string& password)
{
crypto::chacha8_key key = AUTO_VAL_INIT(key);
crypto::generate_chacha8_key(password, key);
@ -71,16 +71,23 @@ namespace currency
crypto::chacha8(scr_data, src_length, key, iv, (char*)dst_data);
}
//-----------------------------------------------------------------
std::string account_base::get_seed_phrase(const std::string& password) const
std::string account_base::get_seed_phrase(const std::string& password) const
{
if (m_keys_seed_binary.empty())
return "";
return get_seed_phrase(password, m_keys_seed_binary);
}
//-----------------------------------------------------------------
std::string account_base::get_seed_phrase(const std::string& password, const std::vector<unsigned char>& keys_seed_binary) const
{
if (keys_seed_binary.empty())
return "";
std::vector<unsigned char> processed_seed_binary = m_keys_seed_binary;
std::vector<unsigned char> processed_seed_binary = keys_seed_binary;
if (!password.empty())
{
//encrypt seed phrase binary data
crypt_with_pass(&m_keys_seed_binary[0], m_keys_seed_binary.size(), &processed_seed_binary[0], password);
crypt_with_pass(&keys_seed_binary[0], keys_seed_binary.size(), &processed_seed_binary[0], password);
}
std::string keys_seed_text = tools::mnemonic_encoding::binary2text(processed_seed_binary);
@ -92,7 +99,7 @@ namespace currency
CHECK_AND_ASSERT_THROW_MES(self_check_is_password_used == !password.empty(), "Account seed phrase internal error: password flag encoded wrong");
constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum
std::string binary_for_check_sum((const char*)&m_keys_seed_binary[0], m_keys_seed_binary.size());
std::string binary_for_check_sum((const char*)&keys_seed_binary[0], keys_seed_binary.size());
binary_for_check_sum.append(password);
crypto::hash h = crypto::cn_fast_hash(binary_for_check_sum.data(), binary_for_check_sum.size());
*reinterpret_cast<uint64_t*>(&h) = creation_timestamp_rounded;

View file

@ -56,6 +56,7 @@ namespace currency
std::string get_public_address_str() const;
std::string get_seed_phrase(const std::string& seed_password) const;
std::string get_seed_phrase(const std::string& password, const std::vector<unsigned char>& keys_seed_binary) const;
std::string get_tracking_seed() const;
bool restore_from_seed_phrase(const std::string& seed_phrase, const std::string& seed_password);
bool restore_from_tracking_seed(const std::string& tracking_seed);
@ -82,6 +83,8 @@ namespace currency
static std::vector<unsigned char> string_to_vector_of_chars(const std::string& v) { return std::vector<unsigned char>(v.begin(), v.end()); }
static bool is_seed_password_protected(const std::string& seed_phrase, bool& is_password_protected);
static bool is_seed_tracking(const std::string& seed_phrase);
static void crypt_with_pass(const void* scr_data, std::size_t src_length, void* dst_data, const std::string& password);
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_keys)

View file

@ -125,6 +125,7 @@ namespace
{
const command_line::arg_descriptor<std::string> arg_wallet_file ("wallet-file", "Use wallet <arg>", "");
const command_line::arg_descriptor<std::string> arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to <arg> or <address>.wallet by default", "");
const command_line::arg_descriptor<bool> arg_derive_custom_seed("derive_custom_seed", "Derive seed phrase from custom 24-words secret(advanced option, do it on your own risk)", "");
const command_line::arg_descriptor<std::string> arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to <arg>", "");
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", "");
@ -2872,7 +2873,63 @@ bool search_for_wallet_file(const std::wstring &search_here/*, const std::string
return false;
}
int custom_seed_builder()
{
success_msg_writer() <<
"**********************************************************************\n" <<
"This is an experimental tool that helps you create a custom seed phrase \n"
"based on your own 24 words. It can be extremely unsafe, so only use it \n"
"if you're confident in what you're doing.\n"
"**********************************************************************";
success_msg_writer() << "Please enter 24 words that you want to use as base for the seed:";
std::string seed_24;
std::getline(std::cin, seed_24);
std::list<std::string> words;
std::string trimed_seed_24 = epee::string_tools::trim(seed_24);
boost::split(words, trimed_seed_24, boost::is_space(), boost::token_compress_on);
seed_24 = boost::algorithm::join(words, " ");
std::string passphrase;
success_msg_writer() << "Please enter seed passphrase(it's highly recommended to use passphrase for custom seed):";
std::getline(std::cin, passphrase);
if (passphrase.empty())
{
success_msg_writer() << "Using unsecured seed(no passphrase)";
}
else
{
std::string passphrase_confirmation;
success_msg_writer() << "Please confirm passphrase:";
std::getline(std::cin, passphrase_confirmation);
if (passphrase_confirmation != passphrase)
{
success_msg_writer() << "Passphrase mismatched, try again";
return EXIT_FAILURE;
}
}
account_base acc;
acc.generate();
std::string pass_protected_or_not = "";
std::vector<unsigned char> binary_from_seed = tools::mnemonic_encoding::text2binary(seed_24);
std::vector<unsigned char> processed_binary_from_seed = binary_from_seed;
if (!passphrase.empty())
{
//encrypt seed phrase binary data
account_base::crypt_with_pass(&binary_from_seed[0], binary_from_seed.size(), &processed_binary_from_seed[0], passphrase);
pass_protected_or_not = "(secured with passphrase)";
}
{
pass_protected_or_not = "(!without passphrase!)";
}
const std::string new_seed = acc.get_seed_phrase(passphrase, processed_binary_from_seed);
success_msg_writer() << "Here is your seed" << pass_protected_or_not << "\n " << new_seed;
return EXIT_SUCCESS;
}
int seed_doctor()
{
@ -3142,6 +3199,8 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_no_password_confirmations);
command_line::add_arg(desc_params, command_line::arg_generate_rpc_autodoc);
command_line::add_arg(desc_params, arg_seed_doctor);
command_line::add_arg(desc_params, arg_derive_custom_seed);
tools::wallet_rpc_server::init_options(desc_params);
@ -3225,6 +3284,10 @@ int main(int argc, char* argv[])
return seed_doctor();
}
if (command_line::has_arg(vm, arg_derive_custom_seed))
{
return custom_seed_builder();
}
if (command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port))
{