From 80d5320fff9c948f54b4379f3c2f3bc684e7f356 Mon Sep 17 00:00:00 2001 From: Sarang Noether <32460187+SarangNoether@users.noreply.github.com> Date: Wed, 1 Apr 2020 08:31:00 -0400 Subject: [PATCH] Hash domain separation --- src/cryptonote_basic/account.cpp | 6 ++---- .../cryptonote_format_utils.cpp | 2 -- src/cryptonote_config.h | 11 +++++++++++ src/device/device_default.cpp | 19 ++++++++----------- src/multisig/multisig.cpp | 7 +++++-- src/ringct/bulletproofs.cc | 4 ++-- src/rpc/rpc_payment.cpp | 4 +--- src/wallet/ringdb.cpp | 9 ++++----- src/wallet/wallet2.cpp | 6 +----- 9 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index a9aec163b..02eca289e 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -40,13 +40,11 @@ extern "C" } #include "cryptonote_basic_impl.h" #include "cryptonote_format_utils.h" +#include "cryptonote_config.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "account" -#define KEYS_ENCRYPTION_SALT 'k' - - using namespace std; DISABLE_VS_WARNINGS(4244 4345) @@ -69,7 +67,7 @@ DISABLE_VS_WARNINGS(4244 4345) static_assert(sizeof(base_key) == sizeof(crypto::hash), "chacha key and hash should be the same size"); epee::mlocked> data; memcpy(data.data(), &base_key, sizeof(base_key)); - data[sizeof(base_key)] = KEYS_ENCRYPTION_SALT; + data[sizeof(base_key)] = config::HASH_KEY_MEMORY; crypto::generate_chacha_key(data.data(), sizeof(data), key, 1); } //----------------------------------------------------------------- diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 651d61b06..80747dd89 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -44,8 +44,6 @@ using namespace epee; #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "cn" -#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d - // #define ENABLE_HASH_CASH_INTEGRITY_CHECK using namespace crypto; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 4598baad7..66af46a5f 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -204,6 +204,17 @@ namespace config std::string const GENESIS_TX = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1"; uint32_t const GENESIS_NONCE = 10000; + // Hash domain separators + const char HASH_KEY_BULLETPROOF_EXPONENT[] = "bulletproof"; + const char HASH_KEY_RINGDB[] = "ringdsb"; + const char HASH_KEY_SUBADDRESS[] = "SubAddr"; + const unsigned char HASH_KEY_ENCRYPTED_PAYMENT_ID = 0x8d; + const unsigned char HASH_KEY_WALLET = 0x8c; + const unsigned char HASH_KEY_WALLET_CACHE = 0x8d; + const unsigned char HASH_KEY_RPC_PAYMENT_NONCE = 0x58; + const unsigned char HASH_KEY_MEMORY = 'k'; + const unsigned char HASH_KEY_MULTISIG[] = {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + namespace testnet { uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 53; diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index dc06ce237..57ac7c1b2 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -36,9 +36,7 @@ #include "cryptonote_basic/subaddress_index.h" #include "cryptonote_core/cryptonote_tx_utils.h" #include "ringct/rctOps.h" - -#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d -#define CHACHA8_KEY_TAIL 0x8c +#include "cryptonote_config.h" namespace hw { @@ -107,7 +105,7 @@ namespace hw { epee::mlocked> data; memcpy(data.data(), &view_key, sizeof(view_key)); memcpy(data.data() + sizeof(view_key), &spend_key, sizeof(spend_key)); - data[sizeof(data) - 1] = CHACHA8_KEY_TAIL; + data[sizeof(data) - 1] = config::HASH_KEY_WALLET; crypto::generate_chacha_key(data.data(), sizeof(data), key, kdf_rounds); return true; } @@ -196,14 +194,13 @@ namespace hw { } crypto::secret_key device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index) { - const char prefix[] = "SubAddr"; - char data[sizeof(prefix) + sizeof(crypto::secret_key) + 2 * sizeof(uint32_t)]; - memcpy(data, prefix, sizeof(prefix)); - memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); + char data[sizeof(config::HASH_KEY_SUBADDRESS) + sizeof(crypto::secret_key) + 2 * sizeof(uint32_t)]; + memcpy(data, config::HASH_KEY_SUBADDRESS, sizeof(config::HASH_KEY_SUBADDRESS)); + memcpy(data + sizeof(config::HASH_KEY_SUBADDRESS), &a, sizeof(crypto::secret_key)); uint32_t idx = SWAP32LE(index.major); - memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &idx, sizeof(uint32_t)); + memcpy(data + sizeof(config::HASH_KEY_SUBADDRESS) + sizeof(crypto::secret_key), &idx, sizeof(uint32_t)); idx = SWAP32LE(index.minor); - memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(uint32_t), &idx, sizeof(uint32_t)); + memcpy(data + sizeof(config::HASH_KEY_SUBADDRESS) + sizeof(crypto::secret_key) + sizeof(uint32_t), &idx, sizeof(uint32_t)); crypto::secret_key m; crypto::hash_to_scalar(data, sizeof(data), m); return m; @@ -344,7 +341,7 @@ namespace hw { return false; memcpy(data, &derivation, 32); - data[32] = ENCRYPTED_PAYMENT_ID_TAIL; + data[32] = config::HASH_KEY_ENCRYPTED_PAYMENT_ID; cn_fast_hash(data, 33, hash); for (size_t b = 0; b < 8; ++b) diff --git a/src/multisig/multisig.cpp b/src/multisig/multisig.cpp index 14df4d554..999894db0 100644 --- a/src/multisig/multisig.cpp +++ b/src/multisig/multisig.cpp @@ -33,19 +33,22 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "multisig.h" +#include "cryptonote_config.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "multisig" using namespace std; -static const rct::key multisig_salt = { {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; - namespace cryptonote { //----------------------------------------------------------------- crypto::secret_key get_multisig_blinded_secret_key(const crypto::secret_key &key) { + rct::key multisig_salt; + static_assert(sizeof(rct::key) == sizeof(config::HASH_KEY_MULTISIG), "Hash domain separator is an unexpected size"); + memcpy(multisig_salt.bytes, config::HASH_KEY_MULTISIG, sizeof(rct::key)); + rct::keyV data; data.reserve(2); data.push_back(rct::sk2rct(key)); diff --git a/src/ringct/bulletproofs.cc b/src/ringct/bulletproofs.cc index 80ecc5593..c129e7886 100644 --- a/src/ringct/bulletproofs.cc +++ b/src/ringct/bulletproofs.cc @@ -100,8 +100,8 @@ static inline bool is_reduced(const rct::key &scalar) static rct::key get_exponent(const rct::key &base, size_t idx) { - static const std::string salt("bulletproof"); - std::string hashed = std::string((const char*)base.bytes, sizeof(base)) + salt + tools::get_varint_data(idx); + static const std::string domain_separator(config::HASH_KEY_BULLETPROOF_EXPONENT); + std::string hashed = std::string((const char*)base.bytes, sizeof(base)) + domain_separator + tools::get_varint_data(idx); rct::key e; ge_p3 e_p3; rct::hash_to_p3(e_p3, rct::hash2rct(crypto::cn_fast_hash(hashed.data(), hashed.size()))); diff --git a/src/rpc/rpc_payment.cpp b/src/rpc/rpc_payment.cpp index b363c27b2..2b9c19f57 100644 --- a/src/rpc/rpc_payment.cpp +++ b/src/rpc/rpc_payment.cpp @@ -54,8 +54,6 @@ #define DEFAULT_FLUSH_AGE (3600 * 24 * 180) // half a year #define DEFAULT_ZERO_FLUSH_AGE (60 * 2) // 2 minutes -#define RPC_PAYMENT_NONCE_TAIL 0x58 - namespace cryptonote { rpc_payment::client_info::client_info(): @@ -147,7 +145,7 @@ namespace cryptonote return false; char data[33]; memcpy(data, &client, 32); - data[32] = RPC_PAYMENT_NONCE_TAIL; + data[32] = config::HASH_KEY_RPC_PAYMENT_NONCE; crypto::hash hash; cn_fast_hash(data, sizeof(data), hash); extra_nonce = cryptonote::blobdata((const char*)&hash, 4); diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp index 5e88ea788..dfeb987ca 100644 --- a/src/wallet/ringdb.cpp +++ b/src/wallet/ringdb.cpp @@ -35,6 +35,7 @@ #include "misc_language.h" #include "wallet_errors.h" #include "ringdb.h" +#include "cryptonote_config.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "wallet.ringdb" @@ -105,13 +106,11 @@ std::string get_rings_filename(boost::filesystem::path filename) static crypto::chacha_iv make_iv(const crypto::key_image &key_image, const crypto::chacha_key &key, uint8_t field) { - static const char salt[] = "ringdsb"; - - uint8_t buffer[sizeof(key_image) + sizeof(key) + sizeof(salt) + sizeof(field)]; + uint8_t buffer[sizeof(key_image) + sizeof(key) + sizeof(config::HASH_KEY_RINGDB) + sizeof(field)]; memcpy(buffer, &key_image, sizeof(key_image)); memcpy(buffer + sizeof(key_image), &key, sizeof(key)); - memcpy(buffer + sizeof(key_image) + sizeof(key), salt, sizeof(salt)); - memcpy(buffer + sizeof(key_image) + sizeof(key) + sizeof(salt), &field, sizeof(field)); + memcpy(buffer + sizeof(key_image) + sizeof(key), config::HASH_KEY_RINGDB, sizeof(config::HASH_KEY_RINGDB)); + memcpy(buffer + sizeof(key_image) + sizeof(key) + sizeof(config::HASH_KEY_RINGDB), &field, sizeof(field)); crypto::hash hash; // if field is 0, backward compat mode: hash without the field crypto::cn_fast_hash(buffer, sizeof(buffer) - !field, hash.data); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 6d2fff17b..90682e60c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -102,10 +102,6 @@ using namespace cryptonote; // used to target a given block weight (additional outputs may be added on top to build fee) #define TX_WEIGHT_TARGET(bytes) (bytes*2/3) -// arbitrary, used to generate different hashes from the same input -#define CHACHA8_KEY_TAIL 0x8c -#define CACHE_KEY_TAIL 0x8d - #define UNSIGNED_TX_PREFIX "Monero unsigned tx set\004" #define SIGNED_TX_PREFIX "Monero signed tx set\004" #define MULTISIG_UNSIGNED_TX_PREFIX "Monero multisig unsigned tx set\001" @@ -3932,7 +3928,7 @@ void wallet2::setup_keys(const epee::wipeable_string &password) static_assert(HASH_SIZE == sizeof(crypto::chacha_key), "Mismatched sizes of hash and chacha key"); epee::mlocked> cache_key_data; memcpy(cache_key_data.data(), &key, HASH_SIZE); - cache_key_data[HASH_SIZE] = CACHE_KEY_TAIL; + cache_key_data[HASH_SIZE] = config::HASH_KEY_WALLET_CACHE; cn_fast_hash(cache_key_data.data(), HASH_SIZE+1, (crypto::hash&)m_cache_key); get_ringdb_key(); }