aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/crypto/chacha.h4
-rw-r--r--src/crypto/hash-ops.h4
-rw-r--r--src/crypto/hash.h4
-rw-r--r--src/crypto/slow-hash.c89
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp3
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/debug_utilities/CMakeLists.txt2
-rw-r--r--src/device/CMakeLists.txt2
-rw-r--r--src/device/device.cpp9
-rw-r--r--src/device/device_ledger.cpp2
-rw-r--r--src/simplewallet/simplewallet.cpp4
-rw-r--r--src/wallet/api/wallet2_api.h2
-rw-r--r--src/wallet/api/wallet_manager.cpp2
-rw-r--r--src/wallet/wallet2.cpp6
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;
}