What changed, and why it matters
This is a large code cleanup commit that reorganizes Monero's cryptographic headers to reduce how much code gets pulled in when including crypto.h. It removes a custom 'POD_CLASS' macro in favor of plain C++ structs, moves some hash-related functions from header files into a new source file, and updates many files to include only the headers they actually need. There is no direct security fix here, but the change touches sensitive cryptographic code and could in principle introduce subtle compilation or behavior differences.
Treat as a routine refactoring commit. Reviewers should verify that the moved functions are semantically identical (same arguments, same casts, same default parameters) and that all callers previously relying on the removed vector overloads correctly pass size. A normal build and unit-test run is sufficient; no emergency patching is warranted based on this commit alone.
Security signals we found
Touches cryptographic primitives (hash functions, ring signatures, ChaCha key derivation, secret-key handling)
Removes inline definitions of hash wrappers, converting them to out-of-line functions in new hash.cpp
Changes how scrubbed/mlocked array types are spelled (scrubbed_arr alias removed)
Removes vector<const public_key*> convenience overloads for ring signatures; callers now pass .data() and .size()
No explicit security claim, CVE, bug fix, or vulnerability description in commit message or diff
Evidence from the diff
The commit refactors Monero’s crypto headers to reduce transitive includes. Key changes: deletes src/common/pod-class.h and replaces POD_CLASS with ‘struct’; moves inline hash wrappers (cn_fast_hash, cn_slow_hash, tree_hash, hash stream operators) from hash.h into a new src/crypto/hash.cpp; moves rand_range and crypto stream operators from crypto.h into crypto.cpp; removes std::vector overloads for ring-signature functions; updates call sites to use raw pointer+size APIs; wraps C hash-ops declarations in namespace crypto/extern ‘C’; and adds missing explicit includes across the codebase. The commit is purely structural/cleanup with no algorithmic changes.
Changed components
src/crypto/crypto.hsrc/crypto/crypto.cppsrc/crypto/hash.hsrc/crypto/hash.cpp (new)src/crypto/hash-ops.hsrc/crypto/hash-def.h (new)src/crypto/chacha.hsrc/crypto/generic-ops.hsrc/common/pod-class.h (deleted)src/cryptonote_core/cryptonote_tx_utils.cppsrc/cryptonote_core/tx_verification_utils.cppsrc/wallet/wallet2.cppsrc/device_trezor/trezor/protocol.cpptests/unit_tests/crypto.cpptests/core_tests/transaction_tests.cppInspect captured patch +313 / −224
diff --git a/contrib/epee/include/memwipe.h b/contrib/epee/include/memwipe.h
index 8a830f8..84956ca 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 <stddef.h>
+
#ifdef __cplusplus
-#include <array>
-#include <cstddef>
+#include <type_traits>
extern "C" {
#endif
@@ -73,9 +74,6 @@ namespace tools {
template<typename T>
const T& unwrap(scrubbed<T> const& src) { return src; }
-
- template <class T, size_t N>
- using scrubbed_arr = scrubbed<std::array<T, N>>;
} // namespace tools
#endif // __cplusplus
diff --git a/contrib/epee/include/mlocker.h b/contrib/epee/include/mlocker.h
index b423e6a..9c1f22a 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 <map>
-#include <boost/thread/mutex.hpp>
+#include <cstddef>
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<size_t, unsigned int> &map();
static void lock_page(size_t page);
static void unlock_page(size_t page);
@@ -82,7 +79,4 @@ namespace epee
template<typename T>
const T& unwrap(mlocked<T> const& src) { return src; }
-
- template <class T, size_t N>
- using mlocked_arr = mlocked<std::array<T, N>>;
}
diff --git a/contrib/epee/include/profile_tools.h b/contrib/epee/include/profile_tools.h
index 2872a42..279f262 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 <boost/date_time/posix_time/posix_time_types.hpp>
+
+#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 1af08fd..3963ab6 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 <atomic>
+#include <map>
+
+#include <boost/thread/mutex.hpp>
#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<size_t, unsigned int> &mlocker::map()
+ static std::map<size_t, unsigned int> &map()
{
static std::map<size_t, unsigned int> *vmap = new std::map<size_t, unsigned int>();
return *vmap;
diff --git a/src/common/pod-class.h b/src/common/pod-class.h
deleted file mode 100644
index 4dd6171..0000000
--- a/src/common/pod-class.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2014-2024, 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.
-//
-// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-
-#pragma once
-
-#define POD_CLASS struct
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index b0006fa..9481d8d 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 6245a6d..d69d5e7 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 <array>
+#include <string>
+
#include "memwipe.h"
#include "mlocker.h"
#include "hash.h"
@@ -50,7 +53,7 @@ namespace crypto {
#if defined(__cplusplus)
}
- using chacha_key = epee::mlocked<tools::scrubbed_arr<uint8_t, CHACHA_KEY_SIZE>>;
+ using chacha_key = epee::mlocked<tools::scrubbed<std::array<uint8_t, CHACHA_KEY_SIZE>>>;
#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<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
- crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/);
+ epee::mlocked<tools::scrubbed<hash>> 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<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
- crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/, 0/*height*/);
+ epee::mlocked<tools::scrubbed<hash>> 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 4997ea8..b93c9cb 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 <cstdint>
#include <cstdlib>
#include <cstring>
+#include <random>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/shared_ptr.hpp>
#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<const unsigned char &>(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 T>
+ typename std::enable_if<std::is_integral<T>::value, T>::type rand_range(T range_min, T range_max) {
+ crypto::random_device rd;
+ std::uniform_int_distribution<T> dis(range_min, range_max);
+ return dis(rd);
+ }
+ #define INSTANTIATE_RAND_RANGE(t) template t rand_range<t>(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 92092d9..67d76a9 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 <cstddef>
-#include <iostream>
-#include <boost/optional.hpp>
+#include <iosfwd>
#include <type_traits>
-#include <vector>
-#include <random>
-#include "common/pod-class.h"
#include "memwipe.h"
#include "mlocker.h"
#include "generic-ops.h"
-#include "hex.h"
#include "hash.h"
-namespace crypto {
+//forward declarations
+namespace boost
+{
+template <typename T> class optional;
+}
- extern "C" {
-#include "random.h"
- }
+namespace crypto {
#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<tools::scrubbed<public_key>> {
+ struct public_key_memsafe : epee::mlocked<tools::scrubbed<public_key>> {
public_key_memsafe() = default;
public_key_memsafe(const public_key &original) { memcpy(this->data, original.data, 32); }
};
using secret_key = epee::mlocked<tools::scrubbed<ec_scalar>>;
- 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 T>
- typename std::enable_if<std::is_integral<T>::value, T>::type rand_range(T range_min, T range_max) {
- crypto::random_device rd;
- std::uniform_int_distribution<T> dis(range_min, range_max);
- return dis(rd);
- }
+ typename std::enable_if<std::is_integral<T>::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<const public_key *> parameters.
- */
- inline void generate_ring_signature(const hash &prefix_hash, const key_image &image,
- const std::vector<const public_key *> &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<const public_key *> &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 a238b0f..3bf0683 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 <chrono>
#include "crypto/crypto.h"
+#include <random>
namespace crypto
{
diff --git a/src/crypto/generators.cpp b/src/crypto/generators.cpp
index f2fbd4b..fa2ccb1 100644
--- a/src/crypto/generators.cpp
+++ b/src/crypto/generators.cpp
@@ -37,6 +37,7 @@ extern "C"
#include <cassert>
#include <mutex>
+#include <stdexcept>
#include <string_view>
namespace crypto
diff --git a/src/crypto/generic-ops.h b/src/crypto/generic-ops.h
index 236b881..80da7aa 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 <cstddef>
-#include <cstring>
#include <cstdint>
-#include <functional>
-#include <memory>
+#include <cstring>
#include <sodium/crypto_verify_32.h>
#include <sodium/crypto_shorthash_siphash24.h>
+// get declaration of std::hash
+#ifdef __GLIBCXX__
+namespace std _GLIBCXX_VISIBILITY(default) {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ template<typename _Tp>
+ struct hash;
+ _GLIBCXX_END_NAMESPACE_VERSION
+}
+#else
+#include <typeindex>
+#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<crypto::type> { \
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/crypto/hash-def.h b/src/crypto/hash-def.h
new file mode 100644
index 0000000..8fc66ec
--- /dev/null
+++ b/src/crypto/hash-def.h
@@ -0,0 +1,36 @@
+// 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.
+
+#pragma once
+
+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 9250e4f..6635d66 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 <cstddef>
#include <cstdint>
+namespace crypto {
+extern "C" {
+
#else
#include <assert.h>
@@ -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 0000000..260b72a
--- /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 <cstddef>
+#include <iostream>
+#include <stdexcept>
+
+#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<char *>(&hash));
+}
+//------------------------------------------------------------------------------
+hash cn_fast_hash(const void *data, std::size_t length) {
+ hash h;
+ cn_fast_hash(data, length, reinterpret_cast<char *>(&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<char *>(&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<char *>(&hash), variant, 1/*prehashed*/, height);
+}
+//------------------------------------------------------------------------------
+void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) {
+ tree_hash(reinterpret_cast<const char (*)[HASH_SIZE]>(hashes), count, reinterpret_cast<char *>(&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 2c75462..68db767 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 <iostream>
-#include <stddef.h>
-#include <stdexcept>
+#include <cstddef>
+#include <iosfwd>
-#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<char *>(&hash));
- }
-
- inline hash cn_fast_hash(const void *data, std::size_t length) {
- hash h;
- cn_fast_hash(data, length, reinterpret_cast<char *>(&h));
- return h;
- }
-
- 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");
- }
-
- 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<char *>(&hash), variant, 0/*prehashed*/, height);
- }
-
- 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<char *>(&hash), variant, 1/*prehashed*/, height);
- }
-
- inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) {
- tree_hash(reinterpret_cast<const char (*)[HASH_SIZE]>(hashes), count, reinterpret_cast<char *>(&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;
- }
+ void cn_fast_hash(const void *data, std::size_t length, hash &hash);
+
+ hash cn_fast_hash(const void *data, std::size_t length);
+
+ void cn_variant1_check(const std::size_t length, const int variant);
+
+ void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0);
+
+ void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0);
+
+ void tree_hash(const hash *hashes, std::size_t count, hash &root_hash);
+
+ 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 686796c..d0dacb0 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 <fstream>
-
-#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<tools::scrubbed_arr<char, sizeof(base_key)+1>> data;
+ epee::mlocked<tools::scrubbed<std::array<char, sizeof(base_key)+1>>> 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 8cad702..85442e5 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 affebf1..824922b 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 <string.h>
#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 6258c93..28801aa 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 2c6942c..9795250 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 13c869d..9568e8a 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<crypto::signature>& sigs = tx.signatures.back();
sigs.resize(src_entr.outputs.size());
if (!zero_secret_key)
- crypto::generate_ring_signature(tx_prefix_hash, boost::get<txin_to_key>(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<txin_to_key>(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 652965a..d7654a0 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 17b21c0..4b35691 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<tools::scrubbed_arr<char, sizeof(view_key) + sizeof(spend_key) + 1>> data;
+ epee::mlocked<tools::scrubbed<std::array<char, sizeof(view_key) + sizeof(spend_key) + 1>>> 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 e70122b..ad2f333 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 0861407..dd31b0a 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 <cassert>
#include <memory>
#include <vector>
diff --git a/src/fcmp_pp/fcmp_pp_crypto.cpp b/src/fcmp_pp/fcmp_pp_crypto.cpp
index 313c11b..3dadca3 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 <cassert>
+#include <memory>
+
namespace fcmp_pp
{
//----------------------------------------------------------------------------------------------------------------------
diff --git a/src/multisig/multisig_kex_msg.cpp b/src/multisig/multisig_kex_msg.cpp
index a6643e8..623e031 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 180449a..20fa269 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 <cstdint>
+#include <string>
#include <vector>
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index ed62d55..c01499a 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 b468245..0da3e38 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 <boost/range/adaptor/transformed.hpp>
#include <boost/filesystem.hpp>
#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 86eba93..dc25c35 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<tools::scrubbed_arr<char, HASH_SIZE+1>> cache_key_data;
+ epee::mlocked<tools::scrubbed<std::array<char, HASH_SIZE+1>>> 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<crypto::signature>());
std::vector<crypto::signature>& 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<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
std::vector<const crypto::public_key*> 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<std::pair<crypto::key_imag
error::wallet_internal_error, "Key image out of validity domain: input " + boost::lexical_cast<std::string>(n + offset) + "/"
+ boost::lexical_cast<std::string>(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<std::string>(n + offset) + "/"
+ boost::lexical_cast<std::string>(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 02e1bd2..aac08aa 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<txout_to_key>(tx_mine_4.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_5.vout[0].target).key);
output_keys.push_back(&boost::get<txout_to_key>(tx_mine_6.vout[0].target).key);
- r = crypto::check_ring_signature(pref_hash, boost::get<txin_to_key>(tx_rc1.vin[0]).k_image, output_keys, &tx_rc1.signatures[0][0]);
+ r = crypto::check_ring_signature(pref_hash, boost::get<txin_to_key>(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<size_t> outs;
diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp
index 48f2064..dde6642 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<crypto::signature>());
std::vector<crypto::signature>& sigs = m_tx.signatures.back();
sigs.resize(src_entr.outputs.size());
- generate_ring_signature(m_tx_prefix_hash, boost::get<txin_to_key>(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<txin_to_key>(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 9840be8..44c755d 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 e0e4713..3c174f1 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 b105233..cef6e17 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 <boost/algorithm/string.hpp>
+#include <boost/optional.hpp>
static inline unsigned char *operator &(crypto::ec_point &point) {
return &reinterpret_cast<unsigned char &>(point);
diff --git a/tests/unit_tests/wallet_storage.cpp b/tests/unit_tests/wallet_storage.cpp
index a0b4639..8cd943c 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<const crypto::public_key*> 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)
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.