diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/crypto/chacha.h | 4 | ||||
-rw-r--r-- | src/crypto/hash-ops.h | 4 | ||||
-rw-r--r-- | src/crypto/hash.h | 4 | ||||
-rw-r--r-- | src/crypto/slow-hash.c | 89 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.cpp | 3 | ||||
-rw-r--r-- | src/cryptonote_config.h | 1 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 2 | ||||
-rw-r--r-- | src/debug_utilities/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/device/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/device/device.cpp | 9 | ||||
-rw-r--r-- | src/device/device_ledger.cpp | 2 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 6 |
15 files changed, 109 insertions, 27 deletions
diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index b45c3d7c7..22da53bd0 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -69,10 +69,10 @@ namespace crypto { chacha20(data, length, key.data(), reinterpret_cast<const uint8_t*>(&iv), cipher); } - inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, bool prehashed=false) { + inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, int cn_variant = 0, bool prehashed=false) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); tools::scrubbed_arr<char, HASH_SIZE> pwd_hash; - crypto::cn_slow_hash_pre(data, size, pwd_hash.data(), prehashed); + crypto::cn_slow_hash_pre(data, size, pwd_hash.data(), cn_variant, prehashed); memcpy(&key, pwd_hash.data(), sizeof(key)); } diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 130bf02db..934d464de 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -79,8 +79,8 @@ enum { }; void cn_fast_hash(const void *data, size_t length, char *hash); -void cn_slow_hash(const void *data, size_t length, char *hash); -void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool pre); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant); +void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool pre); void hash_extra_blake(const void *data, size_t length, char *hash); void hash_extra_groestl(const void *data, size_t length, char *hash); diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 14104699b..bf4f4c096 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -71,8 +71,8 @@ namespace crypto { return h; } - inline void cn_slow_hash(const void *data, std::size_t length, hash &hash) { - cn_slow_hash(data, length, reinterpret_cast<char *>(&hash)); + inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) { + cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant); } inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 36bfba9fd..8c7dad8e0 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -32,6 +32,8 @@ #include <stddef.h> #include <stdint.h> #include <string.h> +#include <stdio.h> +#include <unistd.h> #include "common/int-util.h" #include "hash-ops.h" @@ -47,6 +49,46 @@ extern int aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey); extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey); +#define VARIANT1_1(p) \ + do if (variant > 0) \ + { \ + const uint8_t tmp = ((const uint8_t*)(p))[11]; \ + static const uint32_t table = 0x75310; \ + const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ + ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ + } while(0) + +#define VARIANT1_2(p) \ + do if (variant > 0) \ + { \ + xor64(p, tweak1_2); \ + } while(0) + +#define VARIANT1_CHECK() \ + do if (length < 43) \ + { \ + fprintf(stderr, "Cryptonight variants need at least 43 bytes of data"); \ + _exit(1); \ + } while(0) + +#define NONCE_POINTER (((const uint8_t*)data)+35) + +#define VARIANT1_PORTABLE_INIT() \ + uint8_t tweak1_2[8]; \ + do if (variant > 0) \ + { \ + VARIANT1_CHECK(); \ + memcpy(&tweak1_2, &state.hs.b[192], sizeof(tweak1_2)); \ + xor64(tweak1_2, NONCE_POINTER); \ + } while(0) + +#define VARIANT1_INIT64() \ + if (variant > 0) \ + { \ + VARIANT1_CHECK(); \ + } \ + const uint64_t tweak1_2 = variant > 0 ? (state.hs.w[24] ^ (*((const uint64_t*)NONCE_POINTER))) : 0 + #if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))) // Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI // Fall back to more portable code is down at the bottom @@ -125,6 +167,7 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp _mm_store_si128(R128(c), _c); \ _b = _mm_xor_si128(_b, _c); \ _mm_store_si128(R128(&hp_state[j]), _b); \ + VARIANT1_1(&hp_state[j]); \ j = state_index(c); \ p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ @@ -133,6 +176,7 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp p = U64(&hp_state[j]); \ p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p + 1); \ _b = _c; \ #if defined(_MSC_VER) @@ -183,6 +227,11 @@ STATIC INLINE void xor_blocks(uint8_t *a, const uint8_t *b) U64(a)[1] ^= U64(b)[1]; } +STATIC INLINE void xor64(uint64_t *a, const uint64_t b) +{ + *a ^= b; +} + /** * @brief uses cpuid to determine if the CPU supports the AES instructions * @return true if the CPU supports AES, false otherwise @@ -515,11 +564,11 @@ void slow_hash_free_state(void) * @param length the length in bytes of the data * @param hash a pointer to a buffer in which the final 256 bit hash will be stored */ -void cn_slow_hash(const void *data, size_t length, char *hash) { - cn_slow_hash_pre(data,length,hash,false); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { + cn_slow_hash_pre(data,length,hash,variant,false); } -void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool prehashed) +void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ @@ -553,6 +602,8 @@ void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool prehashe } memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. */ @@ -676,6 +727,11 @@ void slow_hash_free_state(void) #define U64(x) ((uint64_t *) (x)) +STATIC INLINE void xor64(uint64_t *a, const uint64_t b) +{ + *a ^= b; +} + #pragma pack(push, 1) union cn_slow_hash_state { @@ -712,6 +768,7 @@ union cn_slow_hash_state vst1q_u8((uint8_t *)c, _c); \ _b = veorq_u8(_b, _c); \ vst1q_u8(&hp_state[j], _b); \ + VARIANT1_1(&hp_state[j]); \ j = state_index(c); \ p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ @@ -720,6 +777,7 @@ union cn_slow_hash_state p = U64(&hp_state[j]); \ p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p + 1); \ _b = _c; \ @@ -851,7 +909,7 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u } } -void cn_slow_hash(const void *data, size_t length, char *hash) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { RDATA_ALIGN16 uint8_t expandedKey[240]; RDATA_ALIGN16 uint8_t hp_state[MEMORY]; @@ -877,6 +935,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. */ @@ -1045,7 +1105,7 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b) U64(a)[1] ^= U64(b)[1]; } -void cn_slow_hash(const void *data, size_t length, char *hash) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; @@ -1074,6 +1134,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + aes_ctx = (oaes_ctx *) oaes_alloc(); oaes_key_import_data(aes_ctx, state.hs.b, AES_KEY_SIZE); @@ -1103,6 +1165,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) xor_blocks(b, p); swap_blocks(b, p); swap_blocks(a, b); + VARIANT1_1(p); // Iteration 2 p = &long_state[state_index(a)]; @@ -1112,6 +1175,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) swap_blocks(b, p); xor_blocks(b, p); swap_blocks(a, b); + VARIANT1_2(U64(p) + 1); } memcpy(text, state.init, INIT_SIZE_BYTE); @@ -1206,6 +1270,15 @@ static void xor_blocks(uint8_t* a, const uint8_t* b) { } } +static void xor64(uint8_t* left, const uint8_t* right) +{ + size_t i; + for (i = 0; i < 8; ++i) + { + left[i] ^= right[i]; + } +} + #pragma pack(push, 1) union cn_slow_hash_state { union hash_state hs; @@ -1216,7 +1289,7 @@ union cn_slow_hash_state { }; #pragma pack(pop) -void cn_slow_hash(const void *data, size_t length, char *hash) { +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; @@ -1233,6 +1306,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { memcpy(aes_key, state.hs.b, AES_KEY_SIZE); aes_ctx = (oaes_ctx *) oaes_alloc(); + VARIANT1_PORTABLE_INIT(); + oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { @@ -1260,6 +1335,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); + VARIANT1_1(&long_state[j * AES_BLOCK_SIZE]); /* Iteration 2 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); @@ -1267,6 +1343,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { sum_half_blocks(b, d); swap_blocks(b, c); xor_blocks(b, c); + VARIANT1_2(c + 8); copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index f462d1ca9..a10772424 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1022,7 +1022,8 @@ namespace cryptonote return true; } blobdata bd = get_block_hashing_blob(b); - crypto::cn_slow_hash(bd.data(), bd.size(), res); + const int cn_variant = b.major_version >= 7 ? b.major_version - 6 : 0; + crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant); return true; } //--------------------------------------------------------------- diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 171fc194a..0ad8a6005 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -132,6 +132,7 @@ #define HF_VERSION_DYNAMIC_FEE 4 #define HF_VERSION_MIN_MIXIN_4 6 +#define HF_VERSION_MIN_MIXIN_6 7 #define HF_VERSION_ENFORCE_RCT 6 #define PER_KB_FEE_QUANTIZATION_DECIMALS 8 diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index d88cc1bf9..c97b75f98 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2531,7 +2531,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, { size_t n_unmixable = 0, n_mixable = 0; size_t mixin = std::numeric_limits<size_t>::max(); - const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2; + const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_6 ? 6 : hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2; for (const auto& txin : tx.vin) { // non txin_to_key inputs will be rejected below diff --git a/src/debug_utilities/CMakeLists.txt b/src/debug_utilities/CMakeLists.txt index 6942399e4..1bcbfd0cf 100644 --- a/src/debug_utilities/CMakeLists.txt +++ b/src/debug_utilities/CMakeLists.txt @@ -38,6 +38,8 @@ target_link_libraries(cn_deserialize LINK_PRIVATE cryptonote_core blockchain_db + device + ringct p2p epee ${CMAKE_THREAD_LIBS_INIT}) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 26389220f..7eccc1cc2 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -70,8 +70,6 @@ target_link_libraries(device cncrypto ringct ${OPENSSL_CRYPTO_LIBRARIES} - ${GNU_READLINE_LIBRARY} - ${EPEE_READLINE} PRIVATE ${Blocks} ${EXTRA_LIBRARIES}) diff --git a/src/device/device.cpp b/src/device/device.cpp index 080d83c7e..068529388 100644 --- a/src/device/device.cpp +++ b/src/device/device.cpp @@ -32,7 +32,7 @@ #ifdef HAVE_PCSC #include "device_ledger.hpp" #endif -#include "common/scoped_message_writer.h" +#include "misc_log_ex.h" namespace hw { @@ -56,12 +56,11 @@ namespace hw { auto device = devices.registry.find(device_descriptor); if (device == devices.registry.end()) { - auto logger = tools::fail_msg_writer(); - logger << "device not found in registry '"<<device_descriptor<<"'\n" << - "known devices:"<<device_descriptor<<"'"; + MERROR("device not found in registry: '" << device_descriptor << "'\n" << + "known devices:"); for( const auto& sm_pair : devices.registry ) { - logger<< " - " << sm_pair.first ; + MERROR(" - " << sm_pair.first); } throw std::runtime_error("device not found: "+ device_descriptor); } diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index cede834a1..571d42724 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -511,7 +511,7 @@ namespace hw { char prekey[200]; memmove(prekey, &this->buffer_recv[0], 200); - crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, true); + crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, 0, true); #ifdef DEBUG_HWDEVICE hw::ledger::check32("generate_chacha_key", "key", (char*)key_x.data(), (char*)key.data()); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c78cceacd..3a81e89ed 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -86,9 +86,9 @@ typedef cryptonote::simple_wallet sw; #define EXTENDED_LOGS_FILE "wallet_details.log" -#define DEFAULT_MIX 4 +#define DEFAULT_MIX 6 -#define MIN_RING_SIZE 5 // Used to inform user about min ring size -- does not track actual protocol +#define MIN_RING_SIZE 7 // Used to inform user about min ring size -- does not track actual protocol #define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003" diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index a6320545e..36b3b9c9b 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -541,7 +541,7 @@ struct Wallet static bool addressValid(const std::string &str, NetworkType nettype); static bool addressValid(const std::string &str, bool testnet) // deprecated { - return addressValid(str, testnet ? MAINNET : TESTNET); + return addressValid(str, testnet ? TESTNET : MAINNET); } static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, NetworkType nettype, std::string &error); static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error) // deprecated diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index 5b6df8a9c..b03332f40 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -37,7 +37,7 @@ #include "common/updates.h" #include "version.h" #include "net/http_client.h" -#include "deviuce/device.hpp" +#include "device/device.hpp" #include <boost/filesystem.hpp> #include <boost/regex.hpp> diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c97f9de07..1be379afe 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5113,7 +5113,11 @@ int wallet2::get_fee_algorithm() const //------------------------------------------------------------------------------------------------------------------------------ uint64_t wallet2::adjust_mixin(uint64_t mixin) const { - if (mixin < 4 && use_fork_rules(6, 10)) { + if (mixin < 6 && use_fork_rules(7, 10)) { + MWARNING("Requested ring size " << (mixin + 1) << " too low for hard fork 7, using 7"); + mixin = 6; + } + else if (mixin < 4 && use_fork_rules(6, 10)) { MWARNING("Requested ring size " << (mixin + 1) << " too low for hard fork 6, using 5"); mixin = 4; } |