diff --git a/contrib/epee/include/memwipe.h b/contrib/epee/include/memwipe.h index 8a830f837..84956ca8e 100644 --- a/contrib/epee/include/memwipe.h +++ b/contrib/epee/include/memwipe.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2024, The Monero Project +// Copyright (c) 2017-2026, The Monero Project // // All rights reserved. // @@ -30,9 +30,10 @@ #pragma once +#include + #ifdef __cplusplus -#include -#include +#include extern "C" { #endif @@ -73,9 +74,6 @@ namespace tools { template const T& unwrap(scrubbed const& src) { return src; } - - template - using scrubbed_arr = scrubbed>; } // namespace tools #endif // __cplusplus diff --git a/contrib/epee/include/mlocker.h b/contrib/epee/include/mlocker.h index b423e6acb..9c1f22a89 100644 --- a/contrib/epee/include/mlocker.h +++ b/contrib/epee/include/mlocker.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2024, The Monero Project +// Copyright (c) 2018-2026, The Monero Project // // All rights reserved. @@ -29,8 +29,7 @@ #pragma once -#include -#include +#include namespace epee { @@ -51,8 +50,6 @@ namespace epee static size_t page_size; static size_t num_locked_objects; - static boost::mutex &mutex(); - static std::map &map(); static void lock_page(size_t page); static void unlock_page(size_t page); @@ -82,7 +79,4 @@ namespace epee template const T& unwrap(mlocked const& src) { return src; } - - template - using mlocked_arr = mlocked>; } diff --git a/contrib/epee/include/profile_tools.h b/contrib/epee/include/profile_tools.h index 2872a429d..279f26292 100644 --- a/contrib/epee/include/profile_tools.h +++ b/contrib/epee/include/profile_tools.h @@ -28,6 +28,9 @@ #ifndef _PROFILE_TOOLS_H_ #define _PROFILE_TOOLS_H_ +#include + +#include "misc_log_ex.h" #include "time_helper.h" namespace epee diff --git a/contrib/epee/src/mlocker.cpp b/contrib/epee/src/mlocker.cpp index 1af08fdfb..3963ab627 100644 --- a/contrib/epee/src/mlocker.cpp +++ b/contrib/epee/src/mlocker.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2024, The Monero Project +// Copyright (c) 2018-2026, The Monero Project // // All rights reserved. @@ -40,6 +40,9 @@ #include "mlocker.h" #include +#include + +#include #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "mlocker" @@ -94,12 +97,12 @@ namespace epee size_t mlocker::page_size = 0; size_t mlocker::num_locked_objects = 0; - boost::mutex &mlocker::mutex() + static boost::mutex &mutex() { static boost::mutex *vmutex = new boost::mutex(); return *vmutex; } - std::map &mlocker::map() + static std::map &map() { static std::map *vmap = new std::map(); return *vmap; diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index b0006faba..9481d8ddc 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2024, The Monero Project +# Copyright (c) 2014-2026, The Monero Project # # All rights reserved. # @@ -41,6 +41,7 @@ set(crypto_sources hash-extra-jh.c hash-extra-skein.c hash.c + hash.cpp hmac-keccak.c jh.c keccak.c diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index 6245a6dd7..d69d5e715 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -38,6 +38,9 @@ #if defined(__cplusplus) +#include +#include + #include "memwipe.h" #include "mlocker.h" #include "hash.h" @@ -50,7 +53,7 @@ namespace crypto { #if defined(__cplusplus) } - using chacha_key = epee::mlocked>; + using chacha_key = epee::mlocked>>; #pragma pack(push, 1) // MS VC 2012 doesn't interpret `class chacha_iv` as POD in spite of [9.0.10], so it is a struct @@ -71,20 +74,20 @@ namespace crypto { inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); - epee::mlocked> pwd_hash; - crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); + epee::mlocked> pwd_hash; + crypto::cn_slow_hash(data, size, pwd_hash, 0/*variant*/, 0/*height*/); for (uint64_t n = 1; n < kdf_rounds; ++n) - crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); - memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); + crypto::cn_slow_hash(pwd_hash.data, HASH_SIZE, pwd_hash, 0/*variant*/, 0/*height*/); + memcpy(&unwrap(unwrap(key)), pwd_hash.data, sizeof(key)); } inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); - epee::mlocked> pwd_hash; - crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/, 0/*height*/); + epee::mlocked> pwd_hash; + crypto::cn_slow_hash_prehashed(data, size, pwd_hash, 0/*variant*/, 0/*height*/); for (uint64_t n = 1; n < kdf_rounds; ++n) - crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); - memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); + crypto::cn_slow_hash(pwd_hash.data, HASH_SIZE, pwd_hash, 0/*variant*/, 0/*height*/); + memcpy(&unwrap(unwrap(key)), pwd_hash.data, sizeof(key)); } inline void generate_chacha_key(std::string password, chacha_key& key, uint64_t kdf_rounds) { diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 4997ea8a9..b93c9cbb1 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -34,11 +34,13 @@ #include #include #include +#include #include #include #include #include "common/varint.h" +#include "hex.h" #include "warnings.h" #include "crypto.h" #include "hash.h" @@ -91,7 +93,7 @@ namespace crypto { return &reinterpret_cast(scalar); } - boost::mutex &get_random_lock() + static boost::mutex &get_random_lock() { static boost::mutex random_lock; return random_lock; @@ -109,6 +111,48 @@ namespace crypto { add_extra_entropy_not_thread_safe(ptr, bytes); } + template + typename std::enable_if::value, T>::type rand_range(T range_min, T range_max) { + crypto::random_device rd; + std::uniform_int_distribution dis(range_min, range_max); + return dis(rd); + } + #define INSTANTIATE_RAND_RANGE(t) template t rand_range(t,t); + INSTANTIATE_RAND_RANGE(long) + INSTANTIATE_RAND_RANGE(long long) + INSTANTIATE_RAND_RANGE(unsigned) + INSTANTIATE_RAND_RANGE(unsigned long) + INSTANTIATE_RAND_RANGE(unsigned long long) + #undef INSTANTIATE_RAND_RANGE + + std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + + std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v) { + epee::to_hex::formatted(o, epee::as_byte_span(unwrap(unwrap(v.sk)))); return o; + } + + std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + + std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + + std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + + std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + + std::ostream &operator <<(std::ostream &o, const crypto::ec_point &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; + } + static inline bool less32(const unsigned char *k0, const unsigned char *k1) { for (int n = 31; n >= 0; --n) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 92092d9b4..67d76a9ae 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -31,64 +31,61 @@ #pragma once #include -#include -#include +#include #include -#include -#include -#include "common/pod-class.h" #include "memwipe.h" #include "mlocker.h" #include "generic-ops.h" -#include "hex.h" #include "hash.h" +//forward declarations +namespace boost +{ +template class optional; +} + namespace crypto { - extern "C" { -#include "random.h" - } - #pragma pack(push, 1) - POD_CLASS ec_point { + struct ec_point { char data[32]; }; - POD_CLASS ec_scalar { + struct ec_scalar { char data[32]; }; // x or y coordinate - POD_CLASS ec_coord { + struct ec_coord { char data[32]; }; - POD_CLASS public_key: ec_point { + struct public_key: ec_point { friend class crypto_ops; }; - POD_CLASS public_key_memsafe : epee::mlocked> { + struct public_key_memsafe : epee::mlocked> { public_key_memsafe() = default; public_key_memsafe(const public_key &original) { memcpy(this->data, original.data, 32); } }; using secret_key = epee::mlocked>; - POD_CLASS key_derivation: ec_point { + struct key_derivation: ec_point { friend class crypto_ops; }; - POD_CLASS key_image: ec_point { + struct key_image: ec_point { friend class crypto_ops; }; - POD_CLASS signature { + struct signature { ec_scalar c, r; friend class crypto_ops; }; - POD_CLASS view_tag { + struct view_tag { char data; }; #pragma pack(pop) @@ -184,11 +181,7 @@ namespace crypto { /* Generate a random value between range_min and range_max */ template - typename std::enable_if::value, T>::type rand_range(T range_min, T range_max) { - crypto::random_device rd; - std::uniform_int_distribution dis(range_min, range_max); - return dis(rd); - } + typename std::enable_if::value, T>::type rand_range(T range_min, T range_max); /* Generate a random index between 0 and sz-1 */ @@ -287,20 +280,6 @@ namespace crypto { return crypto_ops::check_ring_signature(prefix_hash, image, pubs, pubs_count, sig); } - /* Variants with vector parameters. - */ - inline void generate_ring_signature(const hash &prefix_hash, const key_image &image, - const std::vector &pubs, - const secret_key &sec, std::size_t sec_index, - signature *sig) { - generate_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sec, sec_index, sig); - } - inline bool check_ring_signature(const hash &prefix_hash, const key_image &image, - const std::vector &pubs, - const signature *sig) { - return check_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sig); - } - /* Derive a 1-byte view tag from the sender-receiver shared secret to reduce scanning time. * When scanning outputs that were not sent to the user, checking the view tag for a match removes the need to proceed with expensive EC operations * for an expected 99.6% of outputs (expected false positive rate = 1/2^8 = 1/256 = 0.4% = 100% - 99.6%). @@ -313,33 +292,19 @@ namespace crypto { crypto_ops::unbiased_hash_to_ec(preimage, length, res); } - inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } + std::ostream &operator <<(std::ostream &o, const crypto::public_key &v); /* Do NOT overload the << operator for crypto::secret_key here. Use secret_key_explicit_print_ref * instead to prevent accidental implicit dumping of secret key material to the logs (which has * happened before). For the same reason, do not overload it for crypto::ec_scalar either since * crypto::secret_key is a subclass. I'm not sorry that it's obtuse; that's the point, bozo. */ struct secret_key_explicit_print_ref { const crypto::secret_key &sk; }; - inline std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v) { - epee::to_hex::formatted(o, epee::as_byte_span(unwrap(unwrap(v.sk)))); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::ec_point &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } + std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v); + std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v); + std::ostream &operator <<(std::ostream &o, const crypto::key_image &v); + std::ostream &operator <<(std::ostream &o, const crypto::signature &v); + std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v); + std::ostream &operator <<(std::ostream &o, const crypto::ec_point &v); const extern crypto::public_key null_pkey; const extern crypto::secret_key null_skey; diff --git a/src/crypto/duration.h b/src/crypto/duration.h index a238b0f6d..3bf068396 100644 --- a/src/crypto/duration.h +++ b/src/crypto/duration.h @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024, The Monero Project +// Copyright (c) 2020-2026, The Monero Project // // All rights reserved. // @@ -30,6 +30,7 @@ #include #include "crypto/crypto.h" +#include namespace crypto { diff --git a/src/crypto/generators.cpp b/src/crypto/generators.cpp index f2fbd4bc7..fa2ccb13c 100644 --- a/src/crypto/generators.cpp +++ b/src/crypto/generators.cpp @@ -37,6 +37,7 @@ extern "C" #include #include +#include #include namespace crypto diff --git a/src/crypto/generic-ops.h b/src/crypto/generic-ops.h index 236b88173..80da7aaab 100644 --- a/src/crypto/generic-ops.h +++ b/src/crypto/generic-ops.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -31,13 +31,23 @@ #pragma once #include -#include #include -#include -#include +#include #include #include +// get declaration of std::hash +#ifdef __GLIBCXX__ +namespace std _GLIBCXX_VISIBILITY(default) { + _GLIBCXX_BEGIN_NAMESPACE_VERSION + template + struct hash; + _GLIBCXX_END_NAMESPACE_VERSION +} +#else +#include +#endif + #include "random.h" #define CRYPTO_MAKE_COMPARABLE(type) \ @@ -76,14 +86,14 @@ namespace crypto { #define CRYPTO_DEFINE_HASH_FUNCTIONS(type) \ namespace crypto { \ inline std::size_t hash_value(const type &_v) { \ - return siphash_to_size_t(std::addressof(_v), sizeof(_v)); \ + return siphash_to_size_t(&_v, sizeof(_v)); \ } \ } \ namespace std { \ template<> \ struct hash { \ std::size_t operator()(const crypto::type &_v) const { \ - return ::crypto::siphash_to_size_t(std::addressof(_v), sizeof(_v)); \ + return ::crypto::siphash_to_size_t(&_v, sizeof(_v)); \ } \ }; \ } diff --git a/src/common/pod-class.h b/src/crypto/hash-def.h similarity index 89% rename from src/common/pod-class.h rename to src/crypto/hash-def.h index 4dd617134..8fc66ecbe 100644 --- a/src/common/pod-class.h +++ b/src/crypto/hash-def.h @@ -1,21 +1,21 @@ -// Copyright (c) 2014-2024, The Monero Project -// +// Copyright (c) 2026, The Monero Project +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -25,9 +25,12 @@ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #pragma once -#define POD_CLASS struct +enum { + HASH_SIZE = 32, + HASH_DATA_AREA = 136 +}; + +#define RX_BLOCK_VERSION 12 diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 9250e4f93..6635d6613 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -35,6 +35,9 @@ #include #include +namespace crypto { +extern "C" { + #else #include @@ -78,10 +81,7 @@ void hash_process(union hash_state *state, const uint8_t *buf, size_t count); #endif -enum { - HASH_SIZE = 32, - HASH_DATA_AREA = 136 -}; +#include "hash-def.h" void cn_fast_hash(const void *data, size_t length, char *hash); void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); @@ -97,7 +97,6 @@ bool tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, char root[HASH_SIZE]); bool is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path); -#define RX_BLOCK_VERSION 12 void rx_slow_hash_allocate_state(void); void rx_slow_hash_free_state(void); uint64_t rx_seedheight(const uint64_t height); @@ -108,3 +107,8 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r void rx_set_miner_thread(uint32_t value, size_t max_dataset_init_threads); uint32_t rx_get_miner_thread(void); + +#if defined(__cplusplus) +} //extern "C" +} //namespace crypto +#endif diff --git a/src/crypto/hash.cpp b/src/crypto/hash.cpp new file mode 100644 index 000000000..260b72a99 --- /dev/null +++ b/src/crypto/hash.cpp @@ -0,0 +1,80 @@ +// Copyright (c) 2026, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "hash-ops.h" +#include "hash.h" + +#include +#include +#include + +#include "hex.h" + +namespace crypto +{ +//------------------------------------------------------------------------------ +void cn_fast_hash(const void *data, std::size_t length, hash &hash) { + cn_fast_hash(data, length, reinterpret_cast(&hash)); +} +//------------------------------------------------------------------------------ +hash cn_fast_hash(const void *data, std::size_t length) { + hash h; + cn_fast_hash(data, length, reinterpret_cast(&h)); + return h; +} +//------------------------------------------------------------------------------ +void cn_variant1_check(const std::size_t length, const int variant) +{ + // see VARIANT1_CHECK in slow-hash.c + if (variant == 1 && length < 43) + throw std::logic_error("Cryptonight variant 1 is undefined for inputs of less than 43 bytes"); +} +//------------------------------------------------------------------------------ +void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant, uint64_t height) { + cn_variant1_check(length, variant); + cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/, height); +} +//------------------------------------------------------------------------------ +void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant, uint64_t height) { + cn_variant1_check(length, variant); + cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/, height); +} +//------------------------------------------------------------------------------ +void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { + tree_hash(reinterpret_cast(hashes), count, reinterpret_cast(&root_hash)); +} +//------------------------------------------------------------------------------ +std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; +} +//------------------------------------------------------------------------------ +std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { + epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; +} +//------------------------------------------------------------------------------ +} //namespace crypto diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 2c75462e3..68db767d1 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -30,25 +30,20 @@ #pragma once -#include -#include -#include +#include +#include -#include "common/pod-class.h" #include "generic-ops.h" -#include "hex.h" namespace crypto { - extern "C" { -#include "hash-ops.h" - } +#include "hash-def.h" #pragma pack(push, 1) - POD_CLASS hash { + struct hash { char data[HASH_SIZE]; }; - POD_CLASS hash8 { + struct hash8 { char data[8]; }; #pragma pack(pop) @@ -60,43 +55,20 @@ namespace crypto { Cryptonight hash functions */ - inline void cn_fast_hash(const void *data, std::size_t length, hash &hash) { - cn_fast_hash(data, length, reinterpret_cast(&hash)); - } + void cn_fast_hash(const void *data, std::size_t length, hash &hash); - inline hash cn_fast_hash(const void *data, std::size_t length) { - hash h; - cn_fast_hash(data, length, reinterpret_cast(&h)); - return h; - } + hash cn_fast_hash(const void *data, std::size_t length); - static void cn_variant1_check(const std::size_t length, const int variant) - { - // see VARIANT1_CHECK in slow-hash.c - if (variant == 1 && length < 43) - throw std::logic_error("Cryptonight variant 1 is undefined for inputs of less than 43 bytes"); - } + void cn_variant1_check(const std::size_t length, const int variant); - inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { - cn_variant1_check(length, variant); - cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/, height); - } + void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0); - inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { - cn_variant1_check(length, variant); - cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/, height); - } + void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0); - inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { - tree_hash(reinterpret_cast(hashes), count, reinterpret_cast(&root_hash)); - } + void tree_hash(const hash *hashes, std::size_t count, hash &root_hash); - inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } - inline std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { - epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; - } + std::ostream &operator <<(std::ostream &o, const crypto::hash &v); + std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v); constexpr static crypto::hash null_hash = {}; constexpr static crypto::hash8 null_hash8 = {}; diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index 686796ce4..d0dacb058 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -28,9 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include - -#include "include_base_utils.h" #include "account.h" #include "warnings.h" #include "crypto/crypto.h" @@ -65,7 +62,7 @@ DISABLE_VS_WARNINGS(4244 4345) static void derive_key(const crypto::chacha_key &base_key, crypto::chacha_key &key) { static_assert(sizeof(base_key) == sizeof(crypto::hash), "chacha key and hash should be the same size"); - epee::mlocked> data; + epee::mlocked>> data; memcpy(data.data(), &base_key, sizeof(base_key)); 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 8cad702a5..85442e53d 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -38,6 +38,7 @@ #include "cryptonote_config.h" #include "crypto/crypto.h" #include "crypto/hash.h" +#include "crypto/hash-ops.h" #include "ringct/rctOps.h" using namespace epee; diff --git a/src/cryptonote_basic/merge_mining.cpp b/src/cryptonote_basic/merge_mining.cpp index affebf19d..824922b95 100644 --- a/src/cryptonote_basic/merge_mining.cpp +++ b/src/cryptonote_basic/merge_mining.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024, The Monero Project +// Copyright (c) 2020-2026, The Monero Project // // All rights reserved. // @@ -29,7 +29,7 @@ #include #include "misc_log_ex.h" #include "int-util.h" -#include "crypto/crypto.h" +#include "crypto/hash-ops.h" #include "common/util.h" #include "merge_mining.h" diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 6258c93f5..28801aadb 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -82,7 +82,7 @@ using namespace epee; #include "miner.h" -#include "crypto/hash.h" +#include "crypto/hash-ops.h" extern "C" void slow_hash_allocate_state(); diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 2c6942ca2..979525028 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -47,7 +47,7 @@ #include "int-util.h" #include "common/threadpool.h" #include "warnings.h" -#include "crypto/hash.h" +#include "crypto/hash-ops.h" #include "cryptonote_core.h" #include "common/perf_timer.h" #include "common/notify.h" diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 13c869d70..9568e8a7a 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -41,7 +41,7 @@ using namespace epee; #include "cryptonote_basic/miner.h" #include "cryptonote_basic/tx_extra.h" #include "crypto/crypto.h" -#include "crypto/hash.h" +#include "crypto/hash-ops.h" #include "crypto/wire.h" #include "misc_language.h" #include "ringct/rctSigs.h" @@ -539,7 +539,7 @@ namespace cryptonote std::vector& sigs = tx.signatures.back(); sigs.resize(src_entr.outputs.size()); if (!zero_secret_key) - crypto::generate_ring_signature(tx_prefix_hash, boost::get(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data()); + crypto::generate_ring_signature(tx_prefix_hash, boost::get(tx.vin[i]).k_image, keys_ptrs.data(), keys_ptrs.size(), in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data()); ss_ring_s << "signatures:" << ENDL; std::for_each(sigs.begin(), sigs.end(), [&](const crypto::signature& s){ss_ring_s << s << ENDL;}); ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << crypto::secret_key_explicit_print_ref{in_contexts[i].in_ephemeral.sec} << ENDL << "real_output: " << src_entr.real_output << ENDL; diff --git a/src/cryptonote_core/tx_verification_utils.cpp b/src/cryptonote_core/tx_verification_utils.cpp index 652965a71..d7654a009 100644 --- a/src/cryptonote_core/tx_verification_utils.cpp +++ b/src/cryptonote_core/tx_verification_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024, The Monero Project +// Copyright (c) 2023-2026, The Monero Project // // All rights reserved. // @@ -197,7 +197,8 @@ static bool tx_ver_legacy_ring_sigs(transaction& tx, const rct::ctkeyM& mix_ring const bool ver = crypto::check_ring_signature(tx_prefix_hash, pin->k_image, - p_output_keys, + p_output_keys.data(), + p_output_keys.size(), tx.signatures.at(input_idx).data()); if (!ver) { diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index 17b21c0ff..4b35691f4 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2024, The Monero Project +// Copyright (c) 2017-2026, The Monero Project // // All rights reserved. // @@ -117,7 +117,7 @@ namespace hw { bool device_default::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key, uint64_t kdf_rounds) { const crypto::secret_key &view_key = keys.m_view_secret_key; const crypto::secret_key &spend_key = keys.m_spend_secret_key; - epee::mlocked> data; + 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] = config::HASH_KEY_WALLET; diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp index e70122b79..ad2f3332e 100644 --- a/src/device_trezor/trezor/protocol.cpp +++ b/src/device_trezor/trezor/protocol.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2024, The Monero Project +// Copyright (c) 2017-2026, The Monero Project // // All rights reserved. // @@ -254,7 +254,7 @@ namespace ki { CHECK_AND_ASSERT_THROW_MES(rct::scalarmultKey(rct::ki2rct(ki), rct::curveOrder()) == rct::identity(), "Key image out of validity domain: key image " << epee::string_tools::pod_to_hex(ki)); - CHECK_AND_ASSERT_THROW_MES(::crypto::check_ring_signature((const ::crypto::hash&)ki, ki, pkeys, &sig), + CHECK_AND_ASSERT_THROW_MES(::crypto::check_ring_signature((const ::crypto::hash&)ki, ki, pkeys.data(), pkeys.size(), &sig), "Signature failed for key image " << epee::string_tools::pod_to_hex(ki) << ", signature " + epee::string_tools::pod_to_hex(sig) << ", pubkey " + epee::string_tools::pod_to_hex(*pkeys[0])); diff --git a/src/fcmp_pp/curve_trees.h b/src/fcmp_pp/curve_trees.h index 0861407da..dd31b0a28 100644 --- a/src/fcmp_pp/curve_trees.h +++ b/src/fcmp_pp/curve_trees.h @@ -33,6 +33,7 @@ #include "tower_cycle.h" #include "misc_log_ex.h" +#include #include #include diff --git a/src/fcmp_pp/fcmp_pp_crypto.cpp b/src/fcmp_pp/fcmp_pp_crypto.cpp index 313c11bb7..3dadca3cf 100644 --- a/src/fcmp_pp/fcmp_pp_crypto.cpp +++ b/src/fcmp_pp/fcmp_pp_crypto.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024, The Monero Project +// Copyright (c) 2024-2026, The Monero Project // // All rights reserved. // @@ -28,6 +28,9 @@ #include "fcmp_pp_crypto.h" +#include +#include + namespace fcmp_pp { //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/multisig/multisig_kex_msg.cpp b/src/multisig/multisig_kex_msg.cpp index a6643e8fc..623e031ab 100644 --- a/src/multisig/multisig_kex_msg.cpp +++ b/src/multisig/multisig_kex_msg.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024, The Monero Project +// Copyright (c) 2021-2026, The Monero Project // // All rights reserved. // diff --git a/src/multisig/multisig_kex_msg.h b/src/multisig/multisig_kex_msg.h index 180449a34..20fa26959 100644 --- a/src/multisig/multisig_kex_msg.h +++ b/src/multisig/multisig_kex_msg.h @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024, The Monero Project +// Copyright (c) 2021-2026, The Monero Project // // All rights reserved. // @@ -31,6 +31,7 @@ #include "crypto/crypto.h" #include +#include #include diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index ed62d5513..c01499ac9 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -50,7 +50,7 @@ using namespace epee; #include "net/local_ip.h" #include "net/parse.h" #include "storages/http_abstract_invoke.h" -#include "crypto/hash.h" +#include "crypto/hash-ops.h" #include "rpc/rpc_args.h" #include "rpc/rpc_handler.h" #include "core_rpc_server_error_codes.h" diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp index b4682452d..0da3e387e 100644 --- a/src/wallet/ringdb.cpp +++ b/src/wallet/ringdb.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2024, The Monero Project +// Copyright (c) 2018-2026, The Monero Project // // All rights reserved. // @@ -31,6 +31,7 @@ #include #include #include "common/util.h" +#include "crypto/hash-ops.h" #include "misc_log_ex.h" #include "scope_guard.h" #include "wallet_errors.h" diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 86eba9354..dc25c351c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -1028,7 +1028,7 @@ crypto::chacha_key derive_cache_key(const crypto::chacha_key& keys_data_key, con static_assert(HASH_SIZE == sizeof(crypto::chacha_key), "Mismatched sizes of hash and chacha key"); crypto::chacha_key cache_key; - epee::mlocked> cache_key_data; + epee::mlocked>> cache_key_data; memcpy(cache_key_data.data(), &keys_data_key, HASH_SIZE); cache_key_data[HASH_SIZE] = domain_separator; cn_fast_hash(cache_key_data.data(), HASH_SIZE+1, (crypto::hash&) cache_key); @@ -11887,7 +11887,7 @@ std::string wallet2::get_spend_proof(const crypto::hash &txid, const std::string signatures.push_back(std::vector()); std::vector& sigs = signatures.back(); sigs.resize(in_key->key_offsets.size()); - crypto::generate_ring_signature(sig_prefix_hash, in_key->k_image, p_output_keys, in_ephemeral.sec, sec_index, sigs.data()); + generate_ring_signature(sig_prefix_hash, in_key->k_image, p_output_keys.data(), p_output_keys.size(), in_ephemeral.sec, sec_index, sigs.data()); } std::string sig_str = "SpendProofV1"; @@ -11998,7 +11998,7 @@ bool wallet2::check_spend_proof(const crypto::hash &txid, const std::string &mes p_output_keys.push_back(&out.key); // check this ring - if (!crypto::check_ring_signature(sig_prefix_hash, in_key->k_image, p_output_keys, sig_iter->data())) + if (!crypto::check_ring_signature(sig_prefix_hash, in_key->k_image, p_output_keys.data(), p_output_keys.size(), sig_iter->data())) return false; ++sig_iter; } @@ -13172,7 +13172,7 @@ std::pair> std::vector key_ptrs; key_ptrs.push_back(&pkey); - crypto::generate_ring_signature((const crypto::hash&)ki, ki, key_ptrs, in_ephemeral.sec, 0, &signature); + crypto::generate_ring_signature((const crypto::hash&)ki, ki, key_ptrs.data(), key_ptrs.size(), in_ephemeral.sec, 0, &signature); ski.push_back(std::make_pair(ki, signature)); } @@ -13274,7 +13274,7 @@ uint64_t wallet2::import_key_images(const std::vector(n + offset) + "/" + boost::lexical_cast(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image)); - THROW_WALLET_EXCEPTION_IF(!crypto::check_ring_signature((const crypto::hash&)key_image, key_image, pkeys, &signature), + THROW_WALLET_EXCEPTION_IF(!crypto::check_ring_signature((const crypto::hash&)key_image, key_image, pkeys.data(), pkeys.size(), &signature), error::signature_check_failed, boost::lexical_cast(n + offset) + "/" + boost::lexical_cast(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image) + ", signature " + epee::string_tools::pod_to_hex(signature) + ", pubkey " + epee::string_tools::pod_to_hex(*pkeys[0])); diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index 02e1bd244..aac08aad8 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -113,7 +113,7 @@ bool test_transaction_generation_and_ring_signature() output_keys.push_back(&boost::get(tx_mine_4.vout[0].target).key); output_keys.push_back(&boost::get(tx_mine_5.vout[0].target).key); output_keys.push_back(&boost::get(tx_mine_6.vout[0].target).key); - r = crypto::check_ring_signature(pref_hash, boost::get(tx_rc1.vin[0]).k_image, output_keys, &tx_rc1.signatures[0][0]); + r = crypto::check_ring_signature(pref_hash, boost::get(tx_rc1.vin[0]).k_image, output_keys.data(), output_keys.size(), &tx_rc1.signatures[0][0]); CHECK_AND_ASSERT_MES(r, false, "failed to check ring signature"); std::vector outs; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 48f2064b0..dde6642ab 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -124,7 +124,7 @@ namespace m_tx.signatures.push_back(std::vector()); std::vector& sigs = m_tx.signatures.back(); sigs.resize(src_entr.outputs.size()); - generate_ring_signature(m_tx_prefix_hash, boost::get(m_tx.vin[i]).k_image, keys_ptrs, m_in_contexts[i].sec, src_entr.real_output, sigs.data()); + generate_ring_signature(m_tx_prefix_hash, boost::get(m_tx.vin[i]).k_image, keys_ptrs.data(), keys_ptrs.size(), m_in_contexts[i].sec, src_entr.real_output, sigs.data()); i++; } } diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index 9840be875..44c755da6 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2024, The Monero Project +// Copyright (c) 2014-2026, The Monero Project // // All rights reserved. // @@ -42,6 +42,7 @@ #include "misc_log_ex.h" #include "warnings.h" #include "crypto/hash.h" +#include "crypto/hash-ops.h" #include "crypto/variant2_int_sqrt.h" #include "crypto/blake2b.h" #include "../io.h" diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp index e0e47130c..3c174f1d6 100644 --- a/tests/unit_tests/crypto.cpp +++ b/tests/unit_tests/crypto.cpp @@ -38,6 +38,7 @@ extern "C" #include "crypto/crypto-ops.h" } #include "crypto/generators.h" +#include "crypto/hash-ops.h" #include "cryptonote_basic/merge_mining.h" #include "fcmp_pp/fcmp_pp_crypto.h" #include "ringct/rctOps.h" diff --git a/tests/unit_tests/tx_proof.cpp b/tests/unit_tests/tx_proof.cpp index b1052334a..cef6e17d1 100644 --- a/tests/unit_tests/tx_proof.cpp +++ b/tests/unit_tests/tx_proof.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2024, The Monero Project +// Copyright (c) 2018-2026, The Monero Project // // All rights reserved. @@ -34,7 +34,7 @@ extern "C" { #include "crypto/crypto-ops.h" } #include "crypto/hash.h" -#include +#include static inline unsigned char *operator &(crypto::ec_point &point) { return &reinterpret_cast(point); diff --git a/tests/unit_tests/wallet_storage.cpp b/tests/unit_tests/wallet_storage.cpp index a0b4639e4..8cd943c02 100644 --- a/tests/unit_tests/wallet_storage.cpp +++ b/tests/unit_tests/wallet_storage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024, The Monero Project +// Copyright (c) 2023-2026, The Monero Project // // All rights reserved. // @@ -182,7 +182,7 @@ TEST(wallet_storage, export_key_images_uses_generated_key_image) std::vector key_ptrs; key_ptrs.push_back(&pkey); EXPECT_TRUE(crypto::check_ring_signature((const crypto::hash&)exported_key_image, - exported_key_image, key_ptrs, &exported.second.front().second)); + exported_key_image, key_ptrs.data(), key_ptrs.size(), &exported.second.front().second)); } TEST(wallet_storage, change_password_same_file)