From 7676fc99b78511e90b494d00575c60329394bb1e Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Mon, 18 Feb 2019 19:40:12 +0100 Subject: [PATCH] mved to 25 word seed phrase --- src/common/mnemonic-encoding.cpp | 15 +++++++++ src/common/mnemonic-encoding.h | 2 +- src/crypto/crypto.cpp | 35 ++++++++------------- src/crypto/crypto.h | 25 +++++---------- src/currency_core/account.cpp | 32 ++++++++++++------- src/currency_core/account.h | 4 +-- src/currency_core/currency_format_utils.cpp | 23 +++++++++----- src/currency_core/currency_format_utils.h | 2 ++ 8 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/common/mnemonic-encoding.cpp b/src/common/mnemonic-encoding.cpp index 3b769860..e5f46641 100644 --- a/src/common/mnemonic-encoding.cpp +++ b/src/common/mnemonic-encoding.cpp @@ -34,11 +34,13 @@ // Copyright (c) 2014-2018 Zano Project // Copyright (c) 2014-2018 The Louisdor Project + #include #include #include #include #include "mnemonic-encoding.h" +#include "include_base_utils.h" namespace tools { @@ -3371,5 +3373,18 @@ namespace tools } return res; } + std::string word_by_num(uint32_t n) + { + if (n >= NUMWORDS) + return ""; + return wordsArray[n]; + } + + uint64_t num_by_word(const std::string& w) + { + auto it = wordsMap.find(w); + CHECK_AND_ASSERT_THROW_MES(it!= wordsMap.end(), "unable to find word \"" << w << "\" in mnemonic dictionary"); + return it->second; + } } } diff --git a/src/common/mnemonic-encoding.h b/src/common/mnemonic-encoding.h index a66167ec..409a935b 100644 --- a/src/common/mnemonic-encoding.h +++ b/src/common/mnemonic-encoding.h @@ -42,7 +42,7 @@ namespace tools { std::vector text2binary(const std::string& text); std::string binary2text(const std::vector& binary); - std::string word_by_num(uint64_t n); + std::string word_by_num(uint32_t n); uint64_t num_by_word(const std::string& w); } } diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index fab703cf..df6c31ed 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -77,27 +77,16 @@ namespace crypto { memcpy(&res, tmp, 32); } - void crypto_ops::keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec) + void crypto_ops::keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size) { unsigned char tmp[64] = { 0 }; - static_assert(sizeof tmp >= BRAINWALLET_SHORT_SEED_SIZE, "size mismatch"); - memcpy(tmp, a_part, BRAINWALLET_SHORT_SEED_SIZE); - cn_fast_hash(tmp, 16, (char*)&tmp[16]); - cn_fast_hash(tmp, 32, (char*)&tmp[32]); + if (!(sizeof(tmp) >= brain_wallet_seed_size)) + { + throw std::runtime_error("size mismatch"); + } - sc_reduce(tmp); - memcpy(&sec, tmp, 32); - ge_p3 point; - ge_scalarmult_base(&point, &sec); - ge_p3_tobytes(&pub, &point); - } - - void crypto_ops::keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec) - { - unsigned char tmp[64] = { 0 }; - static_assert(sizeof tmp >= BRAINWALLET_DEFAULT_SEED_SIZE, "size mismatch"); - memcpy(tmp, a_part, BRAINWALLET_DEFAULT_SEED_SIZE); + memcpy(tmp, a_part, brain_wallet_seed_size); cn_fast_hash(tmp, 32, (char*)&tmp[32]); @@ -108,12 +97,14 @@ namespace crypto { ge_p3_tobytes(&pub, &point); } - void crypto_ops::generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed) + void crypto_ops::generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size) { - unsigned char tmp[BRAINWALLET_DEFAULT_SEED_SIZE]; - generate_random_bytes(BRAINWALLET_DEFAULT_SEED_SIZE, tmp); - seed.assign((const char*)tmp, BRAINWALLET_DEFAULT_SEED_SIZE); - keys_from_default(tmp, pub, sec); + std::vector tmp_vector; + tmp_vector.resize(brain_wallet_seed_size, 0); + unsigned char *tmp = &tmp_vector[0]; + generate_random_bytes(brain_wallet_seed_size, tmp); + seed.assign((const char*)tmp, brain_wallet_seed_size); + keys_from_default(tmp, pub, sec, brain_wallet_seed_size); } static inline void hash_to_scalar(const void *data, size_t length, ec_scalar &res) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 0019c48e..d039eee8 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -20,8 +20,6 @@ PUSH_WARNINGS DISABLE_CLANG_WARNING(unused-private-field) -#define BRAINWALLET_DEFAULT_SEED_SIZE 32 -#define BRAINWALLET_SHORT_SEED_SIZE 16 namespace crypto { @@ -75,12 +73,10 @@ namespace crypto { static void generate_keys(public_key &, secret_key &); friend void generate_keys(public_key &, secret_key &); - static void generate_brain_keys(public_key &, secret_key &, std::string& seed); - friend void generate_brain_keys(public_key &, secret_key &, std::string& seed); - static void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec); - friend void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec); - static void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec); - friend void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec); + static void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size); + friend void generate_brain_keys(public_key &, secret_key &, std::string& seed, size_t brain_wallet_seed_size); + static void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size); + friend void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size); static void dependent_key(const secret_key& first, secret_key& second); friend void dependent_key(const secret_key& first, secret_key& second); static bool check_key(const public_key &); @@ -139,19 +135,14 @@ namespace crypto { crypto_ops::generate_keys(pub, sec); } - inline void generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed) { - crypto_ops::generate_brain_keys(pub, sec, seed); - } - - inline void keys_from_short(unsigned char* a_part, public_key &pub, secret_key &sec) - { - crypto_ops::keys_from_short(a_part, pub, sec); + inline void generate_brain_keys(public_key &pub, secret_key &sec, std::string& seed, size_t brain_wallet_seed_size) { + crypto_ops::generate_brain_keys(pub, sec, seed, brain_wallet_seed_size); } - inline void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec) + inline void keys_from_default(unsigned char* a_part, public_key &pub, secret_key &sec, size_t brain_wallet_seed_size) { - crypto_ops::keys_from_default(a_part, pub, sec); + crypto_ops::keys_from_default(a_part, pub, sec, brain_wallet_seed_size); } inline void dependent_key(const secret_key& first, secret_key& second){ diff --git a/src/currency_core/account.cpp b/src/currency_core/account.cpp index a0612a58..ce8b177c 100644 --- a/src/currency_core/account.cpp +++ b/src/currency_core/account.cpp @@ -41,9 +41,8 @@ namespace currency } //----------------------------------------------------------------- void account_base::generate() - { - //generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key); - generate_brain_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, m_seed); + { + generate_brain_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, m_seed, BRAINWALLET_DEFAULT_SEED_SIZE); dependent_key(m_keys.m_spend_secret_key, m_keys.m_view_secret_key); if (!crypto::secret_key_to_public_key(m_keys.m_view_secret_key, m_keys.m_account_address.m_view_public_key)) throw std::runtime_error("Failed to create public view key"); @@ -69,7 +68,8 @@ namespace currency std::vector v; v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size()); std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v); - //m_creation_timestamp + std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp); + seed_brain_data = seed_brain_data + timestamp_word; return seed_brain_data; } //----------------------------------------------------------------- @@ -78,11 +78,7 @@ namespace currency //CHECK_AND_ASSERT_MES(restore_data.size() == ACCOUNT_RESTORE_DATA_SIZE, false, "wrong restore data size"); if (restore_data.size() == BRAINWALLET_DEFAULT_SEED_SIZE) { - crypto::keys_from_default((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key); - } - else if(restore_data.size() == BRAINWALLET_SHORT_SEED_SIZE) - { - crypto::keys_from_short((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key); + crypto::keys_from_default((unsigned char*)restore_data.data(), m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, BRAINWALLET_DEFAULT_SEED_SIZE); } else { @@ -97,15 +93,27 @@ namespace currency return true; } //----------------------------------------------------------------- - bool account_base::restore_keys_from_braindata(const std::string& restore_data) + bool account_base::restore_keys_from_braindata(const std::string& restore_data_) { + //cut the last timestamp word from restore_dats + std::list words; + boost::split(words, restore_data_, boost::is_space()); + CHECK_AND_ASSERT_THROW_MES(words.size() == BRAINWALLET_DEFAULT_WORDS_COUNT, "Words count missmatch: " << words.size()); + + std::string timestamp_word = words.back(); + words.erase(--words.end()); + + std::string restore_data_local = boost::algorithm::join(words, " "); - std::vector bin = tools::mnemonic_encoding::text2binary(restore_data); + std::vector bin = tools::mnemonic_encoding::text2binary(restore_data_local); if (!bin.size()) return false; std::string restore_buff((const char*)&bin[0], bin.size()); - return restore_keys(restore_buff); + bool r = restore_keys(restore_buff); + CHECK_AND_ASSERT_MES(r, false, "restore_keys failed"); + m_creation_timestamp = get_timstamp_from_word(timestamp_word); + return true; } //----------------------------------------------------------------- std::string account_base::get_public_address_str() diff --git a/src/currency_core/account.h b/src/currency_core/account.h index b7569ae6..7e259731 100644 --- a/src/currency_core/account.h +++ b/src/currency_core/account.h @@ -10,9 +10,9 @@ #include "crypto/crypto.h" #include "serialization/keyvalue_serialization.h" - +#define BRAINWALLET_DEFAULT_SEED_SIZE 32 #define ACCOUNT_RESTORE_DATA_SIZE BRAINWALLET_DEFAULT_SEED_SIZE - +#define BRAINWALLET_DEFAULT_WORDS_COUNT 25 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 903683e9..673092ca 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1210,14 +1210,23 @@ namespace currency return reward; } //--------------------------------------------------------------- -// std::string get_word_from_timstamp(uint64_t timestamp) -// { -// uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0; -// date_offset = date_offset / WALLET_BRAIN_DATE_QUANTUM; -// -// return tools::mnemonic_encoding::word_by_num(timestamp); -// } + std::string get_word_from_timstamp(uint64_t timestamp) + { + uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0; + uint64_t weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM; + CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits::max(), "internal error: unable to converto to uint32, val = " << weeks_count); + uint32_t weeks_count_32 = static_cast(weeks_count); + return tools::mnemonic_encoding::word_by_num(weeks_count_32); + } + //--------------------------------------------------------------- + uint64_t get_timstamp_from_word(std::string word) + { + uint64_t count_of_weeks = tools::mnemonic_encoding::num_by_word(word); + uint64_t timestamp = count_of_weeks * WALLET_BRAIN_DATE_QUANTUM + WALLET_BRAIN_DATE_OFFSET; + + return timestamp; + } //--------------------------------------------------------------- bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed /* = nullptr */) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 6932fa85..263e258c 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -350,6 +350,8 @@ namespace currency bool fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short = false); bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h); void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map& gindices); + std::string get_word_from_timstamp(uint64_t timestamp); + uint64_t get_timstamp_from_word(std::string word); template typename std::conditional::value, const std::vector, std::vector >::type& get_txin_etc_options(t_txin_v& in)