builds, but doesn't link. other than that, electrum-style recovery implemented (but not tested\!)
This commit is contained in:
parent
8661f9a970
commit
d22e458c6c
|
@ -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
|
||||
|
|
|
@ -68,12 +68,27 @@ namespace crypto {
|
|||
* TODO: allow specifiying random value (for wallet recovery)
|
||||
*
|
||||
*/
|
||||
void crypto_ops::generate_keys(public_key &pub, secret_key &sec) {
|
||||
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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace crypto
|
|||
// error on non-compliant word list
|
||||
if (wlist.size() != 12 && wlist.size() != 24) return false;
|
||||
|
||||
for (int i=0; i < wlist.size() / 3; i++)
|
||||
for (unsigned int i=0; i < wlist.size() / 3; i++)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t w1, w2, w3;
|
||||
|
@ -55,12 +55,12 @@ namespace crypto
|
|||
|
||||
val = w1 + n * ((w2 - w1) % n) + n * n * ((w3 - w2) % n);
|
||||
|
||||
memcpy(dst.data + i * 4, val, 4); // copy 4 bytes to position
|
||||
memcpy(&dst.data + i * 4, &val, 4); // copy 4 bytes to position
|
||||
}
|
||||
|
||||
if (wlist.size() == 12)
|
||||
{
|
||||
memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate
|
||||
memcpy(&dst.data, &dst.data + 16, 16); // if electrum 12-word seed, duplicate
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -78,13 +78,13 @@ namespace crypto
|
|||
if (sizeof(src.data) % 4 != 0) return false;
|
||||
|
||||
// 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626
|
||||
for (int i=0; i < sizeof(src.data)/4; i++, words += ' ')
|
||||
for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ')
|
||||
{
|
||||
uint32_t w1, w2, w3;
|
||||
|
||||
uint32_t val;
|
||||
|
||||
memcpy(val, src, 4);
|
||||
memcpy(&val, &src.data, 4);
|
||||
|
||||
w1 = val % n;
|
||||
w2 = ((val / n) + w1) % n;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "account.h"
|
||||
#include "warnings.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/blake256.h"
|
||||
#include "cryptonote_core/cryptonote_basic_impl.h"
|
||||
#include "cryptonote_core/cryptonote_format_utils.h"
|
||||
using namespace std;
|
||||
|
@ -29,11 +30,17 @@ DISABLE_VS_WARNINGS(4244 4345)
|
|||
m_keys = account_keys();
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
void account_base::generate(const crypto::secret_key& recovery_key, bool recover)
|
||||
crypto::secret_key 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_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, true);
|
||||
m_creation_timestamp = time(NULL);
|
||||
return first;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
const account_keys& account_base::get_keys() const
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace cryptonote
|
|||
{
|
||||
public:
|
||||
account_base();
|
||||
void generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false);
|
||||
crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false);
|
||||
const account_keys& get_keys() const;
|
||||
std::string get_public_address_str();
|
||||
|
||||
|
|
|
@ -360,9 +360,11 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this);
|
||||
|
||||
crypto::secret_key recovery_val;
|
||||
try
|
||||
{
|
||||
m_wallet->generate(wallet_file, password, recovery_key, recover);
|
||||
recovery_val = 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);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
@ -373,6 +375,10 @@ 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);
|
||||
|
||||
success_msg_writer() <<
|
||||
"**********************************************************************\n" <<
|
||||
"Your wallet has been generated.\n" <<
|
||||
|
@ -381,6 +387,8 @@ 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" <<
|
||||
"\nYour wallet can be recovered using the following electrum-style word list:\n" <<
|
||||
electrum_words << "\n" <<
|
||||
"**********************************************************************";
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -436,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, const crypto::secret_key& recovery_param, bool recover)
|
||||
crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover)
|
||||
{
|
||||
clear();
|
||||
prepare_file_names(wallet_);
|
||||
|
@ -445,7 +445,7 @@ 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(recovery_param, recover);
|
||||
crypto::secret_key retval = m_account.generate(recovery_param, recover);
|
||||
|
||||
m_account_public_address = m_account.get_keys().m_account_address;
|
||||
|
||||
|
@ -456,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)
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace tools
|
|||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
void generate(const std::string& wallet, const std::string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false);
|
||||
crypto::secret_key generate(const std::string& wallet, const std::string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false);
|
||||
void load(const std::string& wallet, const std::string& password);
|
||||
void store();
|
||||
cryptonote::account_base& get_account(){return m_account;}
|
||||
|
|
Loading…
Reference in New Issue