Overhaul and fix crypto::{public_key,ec_point,etc.} types

- Remove implicit `operator bool` from ec_point/public_key/etc. which
  was causing all sorts of implicit conversion mess and bugs.
- Change ec_point/public_key/etc. to use a `std::array<unsigned char,
  32>` (via a base type) rather than a C-array of char that has to be
  reinterpret_cast<>'ed all over the place.
- Add methods to ec_point/public_key/etc. that make it work more like a
  container of bytes (`.data()`, `.size()`, `operator[]`, `begin()`,
  `end()`).
- Make a generic `crypto::null<T>` that is a constexpr all-0 `T`, rather
  than the mishmash `crypto::null_hash`, crypto::null_pkey,
  crypto:#️⃣:null(), and so on.
- Replace three metric tons of `crypto::hash blahblah =
  crypto::null_hash;` with the much simpler `crypto::hash blahblah{};`,
  because there's no need to make a copy of a null hash in all these
  cases.  (Likewise for a few other null_whatevers).
- Remove a whole bunch of `if (blahblah == crypto::null_hash)` and `if
  (blahblah != crypto::null_hash)` with the more concise `if
  (!blahblah)` and `if (blahblah)` (which are fine via the newly
  *explicit* bool conversion operators).
- `crypto::signature` becomes a 64-byte container (as above) but with
  `c()` and `r()` to get the c() and r() data pointers.  (Previously
  `.c` and `.r` were `ec_scalar`s).
- Delete with great prejudice CRYPTO_MAKE_COMPARABLE and
  CRYPTO_MAKE_HASHABLE and all the other utter trash in
  `crypto/generic-ops.h`.
- De-inline functions in very common crypto/*.h files so that they don't
  have to get compiled 300 times.
- Remove the disgusting include-a-C-header-inside-a-C++-namespace
  garbage from some crypto headers trying to be both a C and *different*
  C++ header at once.
- Remove the toxic, disgusting, shameful `operator&` on ec_scalar, etc.
  that replace `&x` with `reinterpret_cast x into an unsigned char*`.
  This was pure toxic waste.
- changed some `<<` outputs to fmt
- Random other small changes encountered while fixing everything that
  cascaded out of the above changes.
This commit is contained in:
Jason Rhinelander 2022-10-14 22:22:44 -03:00
parent 5b4a60b412
commit 6aa9db9538
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262
110 changed files with 1339 additions and 1387 deletions

View File

@ -144,7 +144,7 @@ local mac_builder(name,
'mkdir build',
'cd build',
'cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-fcolor-diagnostics -DCMAKE_BUILD_TYPE=' + build_type + ' ' +
'-DOXEN_LOGGING_FORCE_SUBMODULES=ON' +
'-DOXEN_LOGGING_FORCE_SUBMODULES=ON ' +
'-DLOCAL_MIRROR=https://builds.lokinet.dev/deps -DUSE_LTO=' + (if lto then 'ON ' else 'OFF ') +
(if werror then '-DWARNINGS_AS_ERRORS=ON ' else '') +
(if build_tests || run_tests then '-DBUILD_TESTS=ON ' else '') +

View File

@ -86,5 +86,5 @@ namespace epee
template <class T, size_t N>
using mlocked_arr = mlocked<std::array<T, N>>;
template <typename T> constexpr bool is_byte_spannable<mlocked<T>> = is_byte_spannable<T>;
template <typename T> inline constexpr bool is_byte_spannable<mlocked<T>> = is_byte_spannable<T>;
}

View File

@ -201,7 +201,7 @@ uint64_t BlockchainDB::add_block( const std::pair<block, std::string>& blck
num_rct_outs += blk.miner_tx.vout.size();
int tx_i = 0;
crypto::hash tx_hash = crypto::null_hash;
crypto::hash tx_hash{};
for (const std::pair<transaction, std::string>& tx : txs)
{
tx_hash = blk.tx_hashes[tx_i];

View File

@ -3008,7 +3008,7 @@ crypto::hash BlockchainLMDB::top_block_hash(uint64_t *block_height) const
return get_block_hash_from_height(m_height - 1);
}
return null_hash;
return null<hash>;
}
block BlockchainLMDB::get_top_block() const
@ -5334,7 +5334,7 @@ void BlockchainLMDB::migrate_0_1()
if (!parse_and_validate_block_from_blob(bd, b))
throw0(DB_ERROR("Failed to parse block from blob retrieved from the db"));
add_transaction(null_hash, std::make_pair(b.miner_tx, tx_to_blob(b.miner_tx)));
add_transaction(null<hash>, std::make_pair(b.miner_tx, tx_to_blob(b.miner_tx)));
for (unsigned int j = 0; j<b.tx_hashes.size(); j++) {
transaction tx;
hk.mv_data = &b.tx_hashes[j];
@ -5344,7 +5344,7 @@ void BlockchainLMDB::migrate_0_1()
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
if (!parse_and_validate_tx_from_blob(bd, tx))
throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
add_transaction(null_hash, std::make_pair(std::move(tx), bd), &b.tx_hashes[j]);
add_transaction(null<hash>, std::make_pair(std::move(tx), bd), &b.tx_hashes[j]);
result = mdb_cursor_del(c_txs, 0);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to get record from txs: ", result).c_str()));
@ -6016,8 +6016,8 @@ void BlockchainLMDB::migrate_5_6()
auto const &unaligned = unaligned_signatures[i];
service_nodes::quorum_signature aligned = {};
aligned.voter_index = unaligned.voter_index;
memcpy(aligned.signature.c.data, unaligned.signature.c, sizeof(aligned.signature.c));
memcpy(aligned.signature.r.data, unaligned.signature.r, sizeof(aligned.signature.r));
memcpy(aligned.signature.c(), unaligned.signature.c, sizeof(unaligned.signature.c));
memcpy(aligned.signature.r(), unaligned.signature.r, sizeof(unaligned.signature.r));
checkpoint.signatures.push_back(aligned);
}
}

View File

@ -373,7 +373,7 @@ namespace cryptonote {
if (uint64_t tx_fees = block_reward - service_node_reward;
tx_fees > 0
&& block.service_node_winner_key // "service_node_winner_key" tracks the pulse winner; 0 if a mined block
&& crypto_core_ed25519_is_valid_point(reinterpret_cast<const unsigned char *>(block.service_node_winner_key.data))
&& crypto_core_ed25519_is_valid_point(block.service_node_winner_key.data())
) {
if (auto service_node_winner = service_nodes_state.service_nodes_infos.find(block.service_node_winner_key);

View File

@ -30,6 +30,7 @@
#define __STDC_FORMAT_MACROS // NOTE(oxen): Explicitly define the SCNu64 macro on Mingw
#endif
#include <cinttypes>
#include <unordered_map>
#include <unordered_set>
#include <boost/archive/portable_binary_iarchive.hpp>
@ -417,7 +418,7 @@ int main(int argc, char* argv[])
std::cerr << "Only one of --txid, --height, --output can be given" << std::endl;
return 1;
}
crypto::hash opt_txid = crypto::null_hash;
crypto::hash opt_txid{};
uint64_t output_amount = 0, output_offset = 0;
if (!opt_txid_string.empty())
{

View File

@ -111,7 +111,7 @@ int main(int argc, char* argv[])
std::cerr << "txid and height cannot be given at the same time" << std::endl;
return 1;
}
crypto::hash opt_txid = crypto::null_hash;
crypto::hash opt_txid{};
if (!opt_txid_string.empty())
{
if (!tools::hex_to_type(opt_txid_string, opt_txid))

View File

@ -262,9 +262,9 @@ skip:
currsz += bd.size();
for (const auto& tx_id : blk.tx_hashes)
{
if (tx_id == crypto::null_hash)
if (!tx_id)
{
throw std::runtime_error("Aborting: tx == null_hash");
throw std::runtime_error("Aborting: null txid");
}
if (!db->get_pruned_tx_blob(tx_id, bd))
{

View File

@ -106,8 +106,7 @@ void BlocksdatFile::write_block(const crypto::hash& block_hash)
crypto::cn_fast_hash(m_hashes.data(), HASH_OF_HASHES_STEP * sizeof(crypto::hash), hash);
memmove(m_hashes.data(), m_hashes.data() + HASH_OF_HASHES_STEP, (m_hashes.size() - HASH_OF_HASHES_STEP) * sizeof(crypto::hash));
m_hashes.resize(m_hashes.size() - HASH_OF_HASHES_STEP);
const std::string data(hash.data, sizeof(hash));
*m_raw_data_file << data;
m_raw_data_file->write(reinterpret_cast<const char*>(hash.data()), hash.size());
}
}

View File

@ -221,9 +221,9 @@ void BootstrapFile::write_block(block& block)
// now add all regular transactions
for (const auto& tx_id : block.tx_hashes)
{
if (tx_id == crypto::null_hash)
if (!tx_id)
{
throw std::runtime_error("Aborting: tx == null_hash");
throw std::runtime_error("Aborting: null txid");
}
transaction tx = m_blockchain_storage->get_db().get_tx(tx_id);

View File

@ -76,7 +76,7 @@ namespace cryptonote
crypto::hash get_newest_hardcoded_checkpoint(cryptonote::network_type nettype, uint64_t *height)
{
crypto::hash result = crypto::null_hash;
crypto::hash result{};
*height = 0;
if (nettype != network_type::MAINNET && nettype != network_type::TESTNET)
return result;
@ -129,7 +129,7 @@ namespace cryptonote
//---------------------------------------------------------------------------
bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str)
{
crypto::hash h = crypto::null_hash;
crypto::hash h{};
bool r = tools::hex_to_type(hash_str, h);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!");

View File

@ -10,7 +10,7 @@ namespace tools {
bool sha256sum_str(std::string_view data, crypto::hash &hash)
{
crypto_hash_sha256(
reinterpret_cast<unsigned char*>(hash.data),
hash.data(),
reinterpret_cast<const unsigned char*>(data.data()),
data.size());
return true;
@ -42,7 +42,7 @@ namespace tools {
size_left -= read_size;
}
f.close();
crypto_hash_sha256_final(&st, reinterpret_cast<unsigned char*>(hash.data));
crypto_hash_sha256_final(&st, hash.data());
return true;
}

View File

@ -90,8 +90,23 @@ namespace tools
dest += sizeof(T);
}
struct crypto_bytes_base_helper {
template <size_t S>
static std::true_type check(crypto::bytes<S, true>*);
static std::false_type check(...);
};
template <typename T>
constexpr bool is_crypto_bytes_derived = decltype(crypto_bytes_base_helper::check((T*) nullptr))::value;
// Copy the data out of a crypto::bytes<N, true>-derived type.
template <typename T, std::enable_if_t<is_crypto_bytes_derived<T>, int> = 0>
void memcpy_one(char*& dest, const T& t) {
std::memcpy(dest, t.data(), t.size());
dest += t.size();
}
// Copy a class byte-for-byte (but only if it is standard layout and has byte alignment)
template <typename T, std::enable_if_t<std::is_class<T>::value, int> = 0>
template <typename T, std::enable_if_t<std::is_class<T>::value && !is_crypto_bytes_derived<T>, int> = 0>
void memcpy_one(char*& dest, const T& t) {
// We don't *actually* require byte alignment here but it's quite possibly an error (i.e.
// passing in a type containing integer members) so disallow it.
@ -106,6 +121,13 @@ namespace tools
for (const T &t : arr)
memcpy_one(dest, t);
}
template <typename T, typename = void>
constexpr size_t memcpy_size = sizeof(T);
template <typename T>
inline constexpr size_t memcpy_size<T, std::enable_if_t<is_crypto_bytes_derived<T>>>
= T::size();
}
// Does a memcpy of one or more values into a char array; for any given values that are basic
@ -118,7 +140,7 @@ namespace tools
// you have a contained type with a larger alignment, which is probably an integer.
template <typename... T>
auto memcpy_le(const T &...t) {
std::array<char, (0 + ... + sizeof(T))> r;
std::array<char, (0 + ... + detail::memcpy_size<T>)> r;
char* dest = r.data();
(..., detail::memcpy_one(dest, t));
return r;

View File

@ -31,6 +31,7 @@ add_library(cncrypto
aesb.c
blake256.c
chacha.c
chacha.cpp
crypto-ops-data.c
crypto-ops.c
crypto.cpp
@ -40,6 +41,7 @@ add_library(cncrypto
hash-extra-jh.c
hash-extra-skein.c
hash.c
hash.cpp
hmac-keccak.c
jh.c
keccak.c

82
src/crypto/base.h Normal file
View File

@ -0,0 +1,82 @@
#pragma once
#include "common/format.h"
#include "common/formattable.h"
#include "common/hex.h"
#include <array>
#include <type_traits>
namespace crypto {
/// constexpr null (all-0) value for various crypto types; use as `crypto::null<crypto::whatever>`.
template <typename T, typename = std::enable_if_t<std::is_standard_layout_v<T> && std::is_default_constructible_v<T>>>
constexpr T null{};
// Base type for fixed-byte quantities (points, scalars, signatures, hashes). The bool controls
// whether the type should have ==, !=, std::hash, and to_hex_string.
template <size_t Bytes, bool MemcmpHashHex = false>
struct alignas(size_t) bytes {
std::array<unsigned char, Bytes> data_;
unsigned char* data() { return data_.data(); }
const unsigned char* data() const { return data_.data(); }
static constexpr size_t size() { return Bytes; }
auto begin() { return data_.begin(); }
auto begin() const { return data_.begin(); }
auto cbegin() const { return data_.cbegin(); }
auto end() { return data_.end(); }
auto end() const { return data_.end(); }
auto cend() const { return data_.cend(); }
// Set the bytes to all 0's
void zero() { data_.fill(0); }
unsigned char& operator[](size_t i) { return data_[i]; }
const unsigned char& operator[](size_t i) const { return data_[i]; }
static constexpr bool compare_hash_hex = MemcmpHashHex;
};
template <typename T, typename = void>
constexpr bool has_compare_hash_hex = false;
template <typename T>
inline constexpr bool has_compare_hash_hex<T, std::enable_if_t<T::compare_hash_hex>> = true;
template <typename Left, typename Right, typename = void>
constexpr bool are_comparable_v = false;
template <typename L, typename R>
inline constexpr bool are_comparable_v<L, R, std::enable_if_t<std::is_same_v<L, R> && has_compare_hash_hex<L>>> = true;
template <typename L, typename R, std::enable_if_t<are_comparable_v<L, R>, int> = 0>
bool operator==(const L& left, const R& right) {
return left.data_ == right.data_;
}
template <typename L, typename R, std::enable_if_t<are_comparable_v<L, R>, int> = 0>
bool operator!=(const L& left, const R& right) {
return left.data_ != right.data_;
}
template <typename L, typename R, std::enable_if_t<are_comparable_v<L, R>, int> = 0>
bool operator<(const L& left, const R& right) {
return left.data_ < right.data_;
}
template <typename T, typename = std::enable_if_t<has_compare_hash_hex<T>>>
std::string to_hex_string(const T& val) { return "<{}>"_format(tools::type_to_hex(val)); }
template <typename T>
struct raw_hasher {
static_assert(T::compare_hash_hex);
static_assert(std::is_standard_layout_v<T>);
static_assert(sizeof(T) >= sizeof(size_t));
static_assert(alignof(T) >= sizeof(size_t));
size_t operator()(const T& val) const {
return *reinterpret_cast<const size_t*>(val.data());
}
};
}
template <typename T>
inline constexpr bool formattable::via_to_hex_string<T, std::enable_if_t<crypto::has_compare_hash_hex<T>>>
= true;

43
src/crypto/chacha.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "chacha.h"
#include "hash.h"
#include "cn_heavy_hash.hpp"
namespace crypto {
static_assert(sizeof(chacha_key) == CHACHA_KEY_SIZE && sizeof(chacha_iv) == CHACHA_IV_SIZE, "Invalid structure size");
void chacha8(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) {
chacha8(data, length, key.data(), reinterpret_cast<const uint8_t*>(&iv), cipher);
}
void chacha20(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) {
chacha20(data, length, key.data(), reinterpret_cast<const uint8_t*>(&iv), cipher);
}
void generate_chacha_key(std::string password, chacha_key& key, uint64_t kdf_rounds) {
return generate_chacha_key(password.data(), password.size(), key, kdf_rounds);
}
void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) {
static_assert(sizeof(chacha_key) <= hash::size(), "Size of hash must be at least that of chacha_key");
epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
static thread_local cn_heavy_hash_v1 ctx;
ctx.hash(data, size, pwd_hash.data());
for (uint64_t n = 1; n < kdf_rounds; ++n)
ctx.hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data());
memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key));
}
void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) {
static_assert(sizeof(chacha_key) <= hash::size(), "Size of hash must be at least that of chacha_key");
epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash;
static thread_local cn_heavy_hash_v1 ctx;
ctx.hash(data, size, pwd_hash.data(), true);
for (uint64_t n = 1; n < kdf_rounds; ++n)
ctx.hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data());
memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key));
}
}

View File

@ -36,21 +36,20 @@
#define CHACHA_KEY_SIZE 32
#define CHACHA_IV_SIZE 8
#if defined(__cplusplus)
#include <memory.h>
#ifdef __cplusplus
extern "C" {
#endif
void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher);
void chacha20(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher);
#ifdef __cplusplus
}
#include "epee/memwipe.h"
#include "epee/mlocker.h"
#include "hash.h"
#include "cn_heavy_hash.hpp"
namespace crypto {
extern "C" {
#endif
void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher);
void chacha20(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher);
#if defined(__cplusplus)
}
using chacha_key = epee::mlocked<tools::scrubbed_arr<uint8_t, CHACHA_KEY_SIZE>>;
@ -58,39 +57,15 @@ namespace crypto {
uint8_t data[CHACHA_IV_SIZE];
};
static_assert(sizeof(chacha_key) == CHACHA_KEY_SIZE && sizeof(chacha_iv) == CHACHA_IV_SIZE, "Invalid structure size");
using ::chacha8;
using ::chacha20;
inline void chacha8(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) {
chacha8(data, length, key.data(), reinterpret_cast<const uint8_t*>(&iv), cipher);
}
void chacha8(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher);
void chacha20(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher);
inline void chacha20(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) {
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, 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;
static thread_local cn_heavy_hash_v1 ctx;
ctx.hash(data, size, pwd_hash.data());
for (uint64_t n = 1; n < kdf_rounds; ++n)
ctx.hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data());
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;
static thread_local cn_heavy_hash_v1 ctx;
ctx.hash(data, size, pwd_hash.data(), true);
for (uint64_t n = 1; n < kdf_rounds; ++n)
ctx.hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data());
memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key));
}
inline void generate_chacha_key(std::string password, chacha_key& key, uint64_t kdf_rounds) {
return generate_chacha_key(password.data(), password.size(), key, kdf_rounds);
}
void generate_chacha_key(std::string password, chacha_key& key, uint64_t kdf_rounds);
void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds);
void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds);
}
#endif

View File

@ -695,7 +695,7 @@ void monero_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_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
void cn_monero_hash(const void *data, size_t length, unsigned char *hash, int variant, int prehashed)
{
RDATA_ALIGN16 uint8_t expandedKey[AES_EXPANDED_KEY_SIZE]; /* These buffers are aligned to use later with SSE functions */
@ -1061,7 +1061,7 @@ STATIC INLINE void aligned_free(void *ptr)
}
#endif /* FORCE_USE_HEAP */
void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
void cn_monero_hash(const void *data, size_t length, unsigned char *hash, int variant, int prehashed)
{
RDATA_ALIGN16 uint8_t expandedKey[240];
@ -1276,7 +1276,7 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b)
U64(a)[1] ^= U64(b)[1];
}
void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed)
void cn_monero_hash(const void *data, size_t length, unsigned char *hash, int variant, int prehashed)
{
uint8_t text[INIT_SIZE_BYTE];
uint8_t a[AES_BLOCK_SIZE];
@ -1468,7 +1468,7 @@ union cn_monero_hash_state {
};
#pragma pack(pop)
void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed) {
void cn_monero_hash(const void *data, size_t length, unsigned char *hash, int variant, int prehashed) {
#ifndef FORCE_USE_HEAP
uint8_t long_state[MEMORY];
#else

View File

@ -408,7 +408,7 @@ void slow_hash_free_state(uint32_t page_size)
* @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_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
void cn_turtle_hash(const void *data, size_t length, unsigned char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
{
uint32_t TOTALBLOCKS = (CN_TURTLE_PAGE_SIZE / AES_BLOCK_SIZE);
uint32_t init_rounds = (scratchpad / INIT_SIZE_BYTE);
@ -428,7 +428,7 @@ void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int
size_t i, j;
uint64_t *p = NULL;
static void (*const extra_hashes[4])(const void *, size_t, char *) =
static void (*const extra_hashes[4])(const void *, size_t, unsigned char *) =
{
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};

View File

@ -217,7 +217,7 @@ STATIC INLINE void aligned_free(void *ptr)
}
#endif /* FORCE_USE_HEAP */
void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
void cn_turtle_hash(const void *data, size_t length, unsigned char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
{
uint32_t TOTALBLOCKS = (CN_TURTLE_PAGE_SIZE / AES_BLOCK_SIZE);
uint32_t init_rounds = (scratchpad / INIT_SIZE_BYTE);
@ -244,7 +244,7 @@ void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int
size_t i, j;
uint64_t *p = NULL;
static void (*const extra_hashes[4])(const void *, size_t, char *) =
static void (*const extra_hashes[4])(const void *, size_t, unsigned char *) =
{
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};
@ -438,7 +438,7 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b)
U64(a)[1] ^= U64(b)[1];
}
void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
void cn_turtle_hash(const void *data, size_t length, unsigned char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
{
fprintf(stderr, "%s:%d OMG", __FILE__, __LINE__);
uint32_t init_rounds = (scratchpad / INIT_SIZE_BYTE);
@ -458,7 +458,7 @@ void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int
size_t i, j;
uint8_t *p = NULL;
static void (*const extra_hashes[4])(const void *, size_t, char *) =
static void (*const extra_hashes[4])(const void *, size_t, unsigned char *) =
{
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};

View File

@ -1,6 +1,6 @@
// Portable implementation as a fallback
static void (*const extra_hashes[4])(const void *, size_t, char *) = {
static void (*const extra_hashes[4])(const void *, size_t, unsigned char *) = {
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};
@ -72,7 +72,7 @@ union cn_turtle_hash_state {
};
#pragma pack(pop)
void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
void cn_turtle_hash(const void *data, size_t length, unsigned char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations)
{
uint32_t init_rounds = (scratchpad / INIT_SIZE_BYTE);
uint32_t aes_rounds = (iterations / 2);

View File

@ -38,11 +38,17 @@
#include <memory>
#include <stdexcept>
#include <sodium/utils.h>
#include <sodium/crypto_sign_ed25519.h>
#include <sodium/crypto_verify_32.h>
#include "common/varint.h"
#include "epee/warnings.h"
#include "crypto.h"
extern "C" {
#include "keccak.h"
#include "crypto-ops.h"
#include "random.h"
}
#include "hash.h"
@ -60,43 +66,26 @@ namespace {
namespace crypto {
using std::abort;
using std::int32_t;
using std::int64_t;
using std::size_t;
using std::uint32_t;
using std::uint64_t;
static_assert(sizeof(bytes<32>) == 32 && std::has_unique_object_representations_v<bytes<32>>);
static_assert(sizeof(bytes<64>) == 64 && std::has_unique_object_representations_v<bytes<64>>);
static_assert(sizeof(ec_point) == 32 && std::has_unique_object_representations_v<ec_point>);
static_assert(sizeof(ec_scalar) == 32 && std::has_unique_object_representations_v<ec_scalar>);
static_assert(sizeof(public_key) == 32 && std::has_unique_object_representations_v<public_key>);
static_assert(sizeof(secret_key_) == 32 && std::has_unique_object_representations_v<secret_key_>);
static_assert(sizeof(secret_key) == sizeof(secret_key_));
static_assert(sizeof(key_derivation) == 32 && std::has_unique_object_representations_v<key_derivation>);
static_assert(sizeof(key_image) == 32 && std::has_unique_object_representations_v<key_image>);
static_assert(sizeof(signature) == 64 && std::has_unique_object_representations_v<signature>);
static_assert(sizeof(ed25519_public_key) == crypto_sign_ed25519_PUBLICKEYBYTES && std::has_unique_object_representations_v<ed25519_public_key>);
static_assert(sizeof(ed25519_secret_key_) == crypto_sign_ed25519_SECRETKEYBYTES && std::has_unique_object_representations_v<ed25519_secret_key_>);
static_assert(sizeof(ed25519_signature) == 64 && std::has_unique_object_representations_v<ed25519_signature>);
extern "C" {
#include "crypto-ops.h"
#include "random.h"
bool ec_scalar::operator==(const ec_scalar& x) const {
return crypto_verify_32(data(), x.data()) == 0;
}
// These nasty dirty hacks are unspeakable disgusting. This is only here because all of these
// have a `.data` element, but it is a `char` instead of an `unsigned char`. So rather than
// change it to `unsigned char`, the author decided that he should overload `&` to do a
// reinterpret_cast. WTF.
//
// TODO: fix this garbage by making the ec_ types use unsigned char instead of char.
// EW!
static inline unsigned char *operator &(ec_point &point) {
return &reinterpret_cast<unsigned char &>(point);
}
// EW!
static inline const unsigned char *operator &(const ec_point &point) {
return &reinterpret_cast<const unsigned char &>(point);
}
// EW!
static inline unsigned char *operator &(ec_scalar &scalar) {
return &reinterpret_cast<unsigned char &>(scalar);
}
// EW!
static inline const unsigned char *operator &(const ec_scalar &scalar) {
return &reinterpret_cast<const unsigned char &>(scalar);
ec_scalar::operator bool() const {
return !sodium_is_zero(data(), size());
}
static std::mutex random_mutex;
@ -144,7 +133,7 @@ namespace crypto {
}
/* generate a random ]0..L[ scalar */
void random_scalar(ec_scalar &res) {
random_scalar(reinterpret_cast<unsigned char*>(res.data));
random_scalar(res.data());
}
ec_scalar random_scalar() {
@ -154,8 +143,14 @@ namespace crypto {
}
void hash_to_scalar(const void *data, size_t length, ec_scalar &res) {
cn_fast_hash(data, length, reinterpret_cast<hash &>(res));
sc_reduce32(&res);
cn_fast_hash(data, length, res.data());
sc_reduce32(res.data());
}
ec_scalar hash_to_scalar(const void *data, size_t length) {
ec_scalar x;
hash_to_scalar(data, length, x);
return x;
}
/*
@ -175,26 +170,26 @@ namespace crypto {
random_scalar(rng);
}
sec = rng;
sc_reduce32(&unwrap(sec)); // reduce in case second round of keys (sendkeys)
sc_reduce32(sec.data()); // reduce in case second round of keys (sendkeys)
ge_scalarmult_base(&point, &unwrap(sec));
ge_p3_tobytes(&pub, &point);
ge_scalarmult_base(&point, sec.data());
ge_p3_tobytes(pub.data(), &point);
return rng;
}
bool check_key(const public_key &key) {
ge_p3 point;
return ge_frombytes_vartime(&point, &key) == 0;
return ge_frombytes_vartime(&point, key.data()) == 0;
}
bool secret_key_to_public_key(const secret_key &sec, public_key &pub) {
ge_p3 point;
if (sc_check(&unwrap(sec)) != 0) {
if (sc_check(sec.data()) != 0) {
return false;
}
ge_scalarmult_base(&point, &unwrap(sec));
ge_p3_tobytes(&pub, &point);
ge_scalarmult_base(&point, sec.data());
ge_p3_tobytes(pub.data(), &point);
return true;
}
@ -209,14 +204,14 @@ namespace crypto {
ge_p3 point;
ge_p2 point2;
ge_p1p1 point3;
assert(sc_check(&key2) == 0);
if (ge_frombytes_vartime(&point, &key1) != 0) {
assert(sc_check(key2.data()) == 0);
if (ge_frombytes_vartime(&point, key1.data()) != 0) {
return false;
}
ge_scalarmult(&point2, &unwrap(key2), &point);
ge_scalarmult(&point2, key2.data(), &point);
ge_mul8(&point3, &point2);
ge_p1p1_to_p2(&point2, &point3);
ge_tobytes(&derivation, &point2);
ge_tobytes(derivation.data(), &point2);
return true;
}
@ -228,7 +223,7 @@ namespace crypto {
char *end = buf.output_index;
buf.derivation = derivation;
tools::write_varint(end, output_index);
hash_to_scalar(&buf, end - reinterpret_cast<char *>(&buf), res);
res = hash_to_scalar(&buf, end - reinterpret_cast<char *>(&buf));
}
bool derive_public_key(const key_derivation &derivation, size_t output_index,
@ -239,24 +234,24 @@ namespace crypto {
ge_cached point3;
ge_p1p1 point4;
ge_p2 point5;
if (ge_frombytes_vartime(&point1, &base) != 0) {
if (ge_frombytes_vartime(&point1, base.data()) != 0) {
return false;
}
derivation_to_scalar(derivation, output_index, scalar);
ge_scalarmult_base(&point2, &scalar);
ge_scalarmult_base(&point2, scalar.data());
ge_p3_to_cached(&point3, &point2);
ge_add(&point4, &point1, &point3);
ge_p1p1_to_p2(&point5, &point4);
ge_tobytes(&derived_key, &point5);
ge_tobytes(derived_key.data(), &point5);
return true;
}
void derive_secret_key(const key_derivation &derivation, size_t output_index,
const secret_key &base, secret_key &derived_key) {
ec_scalar scalar;
assert(sc_check(&base) == 0);
assert(sc_check(base.data()) == 0);
derivation_to_scalar(derivation, output_index, scalar);
sc_add(&unwrap(derived_key), &unwrap(base), &scalar);
sc_add(derived_key.data(), base.data(), scalar.data());
}
bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key) {
@ -266,15 +261,15 @@ namespace crypto {
ge_cached point3;
ge_p1p1 point4;
ge_p2 point5;
if (ge_frombytes_vartime(&point1, &out_key) != 0) {
if (ge_frombytes_vartime(&point1, out_key.data()) != 0) {
return false;
}
derivation_to_scalar(derivation, output_index, scalar);
ge_scalarmult_base(&point2, &scalar);
ge_scalarmult_base(&point2, scalar.data());
ge_p3_to_cached(&point3, &point2);
ge_sub(&point4, &point1, &point3);
ge_p1p1_to_p2(&point5, &point4);
ge_tobytes(&derived_key, &point5);
ge_tobytes(derived_key.data(), &point5);
return true;
}
@ -299,56 +294,64 @@ namespace crypto {
{
ge_p3 t;
public_key t2;
assert(sc_check(&sec) == 0);
ge_scalarmult_base(&t, &sec);
ge_p3_tobytes(&t2, &t);
assert(sc_check(sec.data()) == 0);
ge_scalarmult_base(&t, sec.data());
ge_p3_tobytes(t2.data(), &t);
assert(pub == t2);
}
#endif
buf.h = prefix_hash;
buf.key = pub;
signature sig;
try_again:
random_scalar(k);
ge_scalarmult_base(&tmp3, &k);
ge_p3_tobytes(&buf.comm, &tmp3);
hash_to_scalar(&buf, sizeof(s_comm), sig.c);
if (!sc_isnonzero((const unsigned char*)sig.c.data))
goto try_again;
sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k);
if (!sc_isnonzero((const unsigned char*)sig.r.data))
goto try_again;
memwipe(&k, sizeof(k));
return sig;
while (true)
{
random_scalar(k);
ge_scalarmult_base(&tmp3, k.data());
ge_p3_tobytes(buf.comm.data(), &tmp3);
sig.c(hash_to_scalar(&buf, sizeof(s_comm)));
if (!sc_isnonzero(sig.c()))
continue;
sc_mulsub(sig.r(), sig.c(), sec.data(), k.data());
if (!sc_isnonzero(sig.r()))
continue;
memwipe(k.data(), k.size());
return sig;
}
}
void generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig) {
sig = generate_signature(prefix_hash, pub, sec);
}
static constexpr ec_point infinity = {{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
static constexpr ec_point get_infinity() {
ec_point inf{};
inf.data_[0] = 1;
return inf;
}
constexpr ec_point infinity = get_infinity();
bool check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) {
ge_p2 tmp2;
ge_p3 tmp3;
ec_scalar c;
s_comm buf;
assert(check_key(pub));
buf.h = prefix_hash;
buf.key = pub;
if (ge_frombytes_vartime(&tmp3, &pub) != 0) {
if (ge_frombytes_vartime(&tmp3, pub.data()) != 0) {
return false;
}
if (sc_check(&sig.c) != 0 || sc_check(&sig.r) != 0 || !sc_isnonzero(&sig.c)) {
if (sc_check(sig.c()) != 0 || sc_check(sig.r()) != 0 || !sc_isnonzero(sig.c())) {
return false;
}
ge_double_scalarmult_base_vartime(&tmp2, &sig.c, &tmp3, &sig.r); // tmp2 = sig.c A + sig.r G
ge_tobytes(&buf.comm, &tmp2);
if (memcmp(&buf.comm, &infinity, 32) == 0)
ge_double_scalarmult_base_vartime(&tmp2, sig.c(), &tmp3, sig.r()); // tmp2 = sig.c A + sig.r G
ge_tobytes(buf.comm.data(), &tmp2);
if (memcmp(buf.comm.data(), infinity.data(), 32) == 0)
return false;
hash_to_scalar(&buf, sizeof(s_comm), c);
sc_sub(&c, &c, &sig.c);
return sc_isnonzero(&c) == 0;
ec_scalar c = hash_to_scalar(&buf, sizeof(s_comm));
sc_sub(c.data(), c.data(), sig.c());
return sc_isnonzero(c.data()) == 0;
}
void generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const std::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
@ -357,33 +360,33 @@ namespace crypto {
ge_p3 A_p3;
ge_p3 B_p3;
ge_p3 D_p3;
if (ge_frombytes_vartime(&R_p3, &R) != 0) throw std::runtime_error("tx pubkey is invalid");
if (ge_frombytes_vartime(&A_p3, &A) != 0) throw std::runtime_error("recipient view pubkey is invalid");
if (B && ge_frombytes_vartime(&B_p3, &*B) != 0) throw std::runtime_error("recipient spend pubkey is invalid");
if (ge_frombytes_vartime(&D_p3, &D) != 0) throw std::runtime_error("key derivation is invalid");
if (ge_frombytes_vartime(&R_p3, R.data()) != 0) throw std::runtime_error("tx pubkey is invalid");
if (ge_frombytes_vartime(&A_p3, A.data()) != 0) throw std::runtime_error("recipient view pubkey is invalid");
if (B && ge_frombytes_vartime(&B_p3, B->data()) != 0) throw std::runtime_error("recipient spend pubkey is invalid");
if (ge_frombytes_vartime(&D_p3, D.data()) != 0) throw std::runtime_error("key derivation is invalid");
#if !defined(NDEBUG)
{
assert(sc_check(&r) == 0);
assert(sc_check(r.data()) == 0);
// check R == r*G or R == r*B
public_key dbg_R;
if (B)
{
ge_p2 dbg_R_p2;
ge_scalarmult(&dbg_R_p2, &r, &B_p3);
ge_tobytes(&dbg_R, &dbg_R_p2);
ge_scalarmult(&dbg_R_p2, r.data(), &B_p3);
ge_tobytes(dbg_R.data(), &dbg_R_p2);
}
else
{
ge_p3 dbg_R_p3;
ge_scalarmult_base(&dbg_R_p3, &r);
ge_p3_tobytes(&dbg_R, &dbg_R_p3);
ge_scalarmult_base(&dbg_R_p3, r.data());
ge_p3_tobytes(dbg_R.data(), &dbg_R_p3);
}
assert(R == dbg_R);
// check D == r*A
ge_p2 dbg_D_p2;
ge_scalarmult(&dbg_D_p2, &r, &A_p3);
ge_scalarmult(&dbg_D_p2, r.data(), &A_p3);
public_key dbg_D;
ge_tobytes(&dbg_D, &dbg_D_p2);
ge_tobytes(dbg_D.data(), &dbg_D_p2);
assert(D == dbg_D);
}
#endif
@ -399,29 +402,29 @@ namespace crypto {
{
// compute X = k*B
ge_p2 X_p2;
ge_scalarmult(&X_p2, &k, &B_p3);
ge_tobytes(&buf.X, &X_p2);
ge_scalarmult(&X_p2, k.data(), &B_p3);
ge_tobytes(buf.X.data(), &X_p2);
}
else
{
// compute X = k*G
ge_p3 X_p3;
ge_scalarmult_base(&X_p3, &k);
ge_p3_tobytes(&buf.X, &X_p3);
ge_scalarmult_base(&X_p3, k.data());
ge_p3_tobytes(buf.X.data(), &X_p3);
}
// compute Y = k*A
ge_p2 Y_p2;
ge_scalarmult(&Y_p2, &k, &A_p3);
ge_tobytes(&buf.Y, &Y_p2);
ge_scalarmult(&Y_p2, k.data(), &A_p3);
ge_tobytes(buf.Y.data(), &Y_p2);
// sig.c = Hs(Msg || D || X || Y)
hash_to_scalar(&buf, sizeof(buf), sig.c);
sig.c(hash_to_scalar(&buf, sizeof(buf)));
// sig.r = k - sig.c*r
sc_mulsub(&sig.r, &sig.c, &unwrap(r), &k);
sc_mulsub(sig.r(), sig.c(), r.data(), k.data());
memwipe(&k, sizeof(k));
memwipe(k.data(), k.size());
}
bool check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const std::optional<public_key> &B, const public_key &D, const signature &sig) {
@ -430,20 +433,20 @@ namespace crypto {
ge_p3 A_p3;
ge_p3 B_p3;
ge_p3 D_p3;
if (ge_frombytes_vartime(&R_p3, &R) != 0) return false;
if (ge_frombytes_vartime(&A_p3, &A) != 0) return false;
if (B && ge_frombytes_vartime(&B_p3, &*B) != 0) return false;
if (ge_frombytes_vartime(&D_p3, &D) != 0) return false;
if (sc_check(&sig.c) != 0 || sc_check(&sig.r) != 0) return false;
if (ge_frombytes_vartime(&R_p3, R.data()) != 0) return false;
if (ge_frombytes_vartime(&A_p3, A.data()) != 0) return false;
if (B && ge_frombytes_vartime(&B_p3, B->data()) != 0) return false;
if (ge_frombytes_vartime(&D_p3, D.data()) != 0) return false;
if (sc_check(sig.c()) != 0 || sc_check(sig.r()) != 0) return false;
// compute sig.c*R
ge_p3 cR_p3;
{
ge_p2 cR_p2;
ge_scalarmult(&cR_p2, &sig.c, &R_p3);
ge_scalarmult(&cR_p2, sig.c(), &R_p3);
public_key cR;
ge_tobytes(&cR, &cR_p2);
if (ge_frombytes_vartime(&cR_p3, &cR) != 0) return false;
ge_tobytes(cR.data(), &cR_p2);
if (ge_frombytes_vartime(&cR_p3, cR.data()) != 0) return false;
}
ge_p1p1 X_p1p1;
@ -451,11 +454,11 @@ namespace crypto {
{
// compute X = sig.c*R + sig.r*B
ge_p2 rB_p2;
ge_scalarmult(&rB_p2, &sig.r, &B_p3);
ge_scalarmult(&rB_p2, sig.r(), &B_p3);
public_key rB;
ge_tobytes(&rB, &rB_p2);
ge_tobytes(rB.data(), &rB_p2);
ge_p3 rB_p3;
if (ge_frombytes_vartime(&rB_p3, &rB) != 0) return false;
if (ge_frombytes_vartime(&rB_p3, rB.data()) != 0) return false;
ge_cached rB_cached;
ge_p3_to_cached(&rB_cached, &rB_p3);
ge_add(&X_p1p1, &cR_p3, &rB_cached);
@ -464,7 +467,7 @@ namespace crypto {
{
// compute X = sig.c*R + sig.r*G
ge_p3 rG_p3;
ge_scalarmult_base(&rG_p3, &sig.r);
ge_scalarmult_base(&rG_p3, sig.r());
ge_cached rG_cached;
ge_p3_to_cached(&rG_cached, &rG_p3);
ge_add(&X_p1p1, &cR_p3, &rG_cached);
@ -474,21 +477,21 @@ namespace crypto {
// compute sig.c*D
ge_p2 cD_p2;
ge_scalarmult(&cD_p2, &sig.c, &D_p3);
ge_scalarmult(&cD_p2, sig.c(), &D_p3);
// compute sig.r*A
ge_p2 rA_p2;
ge_scalarmult(&rA_p2, &sig.r, &A_p3);
ge_scalarmult(&rA_p2, sig.r(), &A_p3);
// compute Y = sig.c*D + sig.r*A
public_key cD;
public_key rA;
ge_tobytes(&cD, &cD_p2);
ge_tobytes(&rA, &rA_p2);
ge_tobytes(cD.data(), &cD_p2);
ge_tobytes(rA.data(), &rA_p2);
ge_p3 cD_p3;
ge_p3 rA_p3;
if (ge_frombytes_vartime(&cD_p3, &cD) != 0) return false;
if (ge_frombytes_vartime(&rA_p3, &rA) != 0) return false;
if (ge_frombytes_vartime(&cD_p3, cD.data()) != 0) return false;
if (ge_frombytes_vartime(&rA_p3, rA.data()) != 0) return false;
ge_cached rA_cached;
ge_p3_to_cached(&rA_cached, &rA_p3);
ge_p1p1 Y_p1p1;
@ -500,14 +503,13 @@ namespace crypto {
s_comm_2 buf;
buf.msg = prefix_hash;
buf.D = D;
ge_tobytes(&buf.X, &X_p2);
ge_tobytes(&buf.Y, &Y_p2);
ec_scalar c2;
hash_to_scalar(&buf, sizeof(s_comm_2), c2);
ge_tobytes(buf.X.data(), &X_p2);
ge_tobytes(buf.Y.data(), &Y_p2);
ec_scalar c2 = hash_to_scalar(&buf, sizeof(s_comm_2));
// test if c2 == sig.c
sc_sub(&c2, &c2, &sig.c);
return sc_isnonzero(&c2) == 0;
sc_sub(c2.data(), c2.data(), sig.c());
return sc_isnonzero(c2.data()) == 0;
}
static void hash_to_ec(const public_key &key, ge_p3 &res) {
@ -523,10 +525,10 @@ namespace crypto {
void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) {
ge_p3 point;
ge_p2 point2;
assert(sc_check(&sec) == 0);
assert(sc_check(sec.data()) == 0);
hash_to_ec(pub, point);
ge_scalarmult(&point2, &unwrap(sec), &point);
ge_tobytes(&image, &point2);
ge_scalarmult(&point2, sec.data(), &point);
ge_tobytes(image.data(), &point2);
}
struct rs_comm {
@ -542,8 +544,8 @@ namespace crypto {
static_assert(sizeof(ab[0]) == 64); // Ensure no padding
keccak_update(&state, reinterpret_cast<const uint8_t*>(ab.data()), 64*ab.size());
ec_scalar result;
keccak_finish(&state, reinterpret_cast<uint8_t*>(&result));
sc_reduce32(&result);
keccak_finish(&state, result.data());
sc_reduce32(result.data());
return result;
};
};
@ -563,9 +565,9 @@ namespace crypto {
ge_p3 t;
public_key t2;
key_image t3;
assert(sc_check(&sec) == 0);
ge_scalarmult_base(&t, &sec);
ge_p3_tobytes(&t2, &t);
assert(sc_check(sec.data()) == 0);
ge_scalarmult_base(&t, sec.data());
ge_p3_tobytes(t2.data(), &t);
assert(*pubs[sec_index] == t2);
generate_key_image(*pubs[sec_index], sec, t3);
assert(image == t3);
@ -575,13 +577,12 @@ namespace crypto {
}
#endif
ge_p3 image_unp; // I
if (ge_frombytes_vartime(&image_unp, &image) != 0) {
if (ge_frombytes_vartime(&image_unp, image.data()) != 0) {
local_abort("invalid key image");
}
ge_dsmp image_pre;
ge_dsm_precomp(image_pre, &image_unp);
ec_scalar sum;
sc_0(&sum); // will be sum of cj, j≠s
ec_scalar sum = null<ec_scalar>; // will be sum of cj, j≠s
rs_comm rs{prefix_hash, pubs.size()};
ec_scalar qs;
@ -590,32 +591,32 @@ namespace crypto {
ge_p3 tmp3;
if (i == sec_index) { // this is the true key image
random_scalar(qs); // qs = random
ge_scalarmult_base(&tmp3, &qs); // Ls = qs G
ge_p3_tobytes(&rs.ab[i].first, &tmp3);
ge_scalarmult_base(&tmp3, qs.data()); // Ls = qs G
ge_p3_tobytes(rs.ab[i].first.data(), &tmp3);
hash_to_ec(*pubs[i], tmp3); // Hp(Ps)
ge_scalarmult(&tmp2, &qs, &tmp3); // Rs = qs Hp(Ps)
ge_tobytes(&rs.ab[i].second, &tmp2);
ge_scalarmult(&tmp2, qs.data(), &tmp3); // Rs = qs Hp(Ps)
ge_tobytes(rs.ab[i].second.data(), &tmp2);
// We don't set ci, ri yet because we first need the sum of all the other cj's/rj's
} else {
random_scalar(sig[i].c); // ci = wi = random
random_scalar(sig[i].r); // ri = qi = random
if (ge_frombytes_vartime(&tmp3, &*pubs[i]) != 0) {
memwipe(&qs, sizeof(qs));
random_scalar(sig[i].c()); // ci = wi = random
random_scalar(sig[i].r()); // ri = qi = random
if (ge_frombytes_vartime(&tmp3, pubs[i]->data()) != 0) {
memwipe(qs.data(), qs.size());
local_abort("invalid pubkey");
}
ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r); // Li = cj Pj + rj G = qj G + wj Pj
ge_tobytes(&rs.ab[i].first, &tmp2);
ge_double_scalarmult_base_vartime(&tmp2, sig[i].c(), &tmp3, sig[i].r()); // Li = cj Pj + rj G = qj G + wj Pj
ge_tobytes(rs.ab[i].first.data(), &tmp2);
hash_to_ec(*pubs[i], tmp3); // Hp(Pj)
ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre); // Ri = qj Hp(Pj) + wj I
ge_tobytes(&rs.ab[i].second, &tmp2);
sc_add(&sum, &sum, &sig[i].c);
ge_double_scalarmult_precomp_vartime(&tmp2, sig[i].r(), &tmp3, sig[i].c(), image_pre); // Ri = qj Hp(Pj) + wj I
ge_tobytes(rs.ab[i].second.data(), &tmp2);
sc_add(sum.data(), sum.data(), sig[i].c());
}
}
ec_scalar c = rs.hash_to_scalar(); // c = Hs(prefix_hash || L0 || ... || L{n-1} || R0 || ... || R{n-1})
sc_sub(&sig[sec_index].c, &c, &sum); // cs = c - sum(ci, i≠s) = c - sum(wi)
sc_mulsub(&sig[sec_index].r, &sig[sec_index].c, &unwrap(sec), &qs); // rs = qs - cs*x
sc_sub(sig[sec_index].c(), c.data(), sum.data()); // cs = c - sum(ci, i≠s) = c - sum(wi)
sc_mulsub(sig[sec_index].r(), sig[sec_index].c(), sec.data(), qs.data()); // rs = qs - cs*x
memwipe(&qs, sizeof(qs));
memwipe(qs.data(), qs.size());
}
bool check_ring_signature(
@ -629,34 +630,33 @@ namespace crypto {
}
#endif
ge_p3 image_unp;
if (ge_frombytes_vartime(&image_unp, &image) != 0) {
if (ge_frombytes_vartime(&image_unp, image.data()) != 0) {
return false;
}
ge_dsmp image_pre;
ge_dsm_precomp(image_pre, &image_unp);
ec_scalar sum;
sc_0(&sum);
ec_scalar sum = null<ec_scalar>;
rs_comm rs{prefix_hash, pubs.size()};
for (size_t i = 0; i < pubs.size(); i++) {
ge_p2 tmp2;
ge_p3 tmp3;
if (sc_check(&sig[i].c) != 0 || sc_check(&sig[i].r) != 0) {
if (sc_check(sig[i].c()) != 0 || sc_check(sig[i].r()) != 0) {
return false;
}
if (ge_frombytes_vartime(&tmp3, &*pubs[i]) != 0) {
if (ge_frombytes_vartime(&tmp3, pubs[i]->data()) != 0) {
return false;
}
ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r);
ge_tobytes(&rs.ab[i].first, &tmp2);
ge_double_scalarmult_base_vartime(&tmp2, sig[i].c(), &tmp3, sig[i].r());
ge_tobytes(rs.ab[i].first.data(), &tmp2);
hash_to_ec(*pubs[i], tmp3);
ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre);
ge_tobytes(&rs.ab[i].second, &tmp2);
sc_add(&sum, &sum, &sig[i].c);
ge_double_scalarmult_precomp_vartime(&tmp2, sig[i].r(), &tmp3, sig[i].c(), image_pre);
ge_tobytes(rs.ab[i].second.data(), &tmp2);
sc_add(sum.data(), sum.data(), sig[i].c());
}
ec_scalar h = rs.hash_to_scalar();
sc_sub(&h, &h, &sum);
return sc_isnonzero(&h) == 0;
sc_sub(h.data(), h.data(), sum.data());
return sc_isnonzero(h.data()) == 0;
}
void generate_key_image_signature(
@ -669,19 +669,19 @@ namespace crypto {
rs_comm rs{reinterpret_cast<const hash&>(image), 1};
ge_p3 tmp3;
ge_scalarmult_base(&tmp3, &k); // L = kG
ge_p3_tobytes(&rs.ab[0].first, &tmp3); // store L
ge_scalarmult_base(&tmp3, k.data()); // L = kG
ge_p3_tobytes(rs.ab[0].first.data(), &tmp3); // store L
hash_to_ec(pub, tmp3); // H(A)
ge_p2 tmp2;
ge_scalarmult(&tmp2, &k, &tmp3); // R = kH(A)
ge_tobytes(&rs.ab[0].second, &tmp2); // store R
ge_scalarmult(&tmp2, k.data(), &tmp3); // R = kH(A)
ge_tobytes(rs.ab[0].second.data(), &tmp2); // store R
sig.c = rs.hash_to_scalar(); // c = H(I || L || R) = H(I || kG || kH(A))
sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k); // r = k - ac = k - aH(I || kG || kH(A))
sig.c(rs.hash_to_scalar()); // c = H(I || L || R) = H(I || kG || kH(A))
sc_mulsub(sig.r(), sig.c(), sec.data(), k.data()); // r = k - ac = k - aH(I || kG || kH(A))
memwipe(&k, sizeof(k));
memwipe(k.data(), k.size());
}
bool check_key_image_signature(
@ -691,14 +691,14 @@ namespace crypto {
assert(check_key(pub));
ge_p3 image_unp;
if (ge_frombytes_vartime(&image_unp, &image) != 0 || sc_check(&sig.c) != 0 || sc_check(&sig.r) != 0)
if (ge_frombytes_vartime(&image_unp, image.data()) != 0 || sc_check(sig.c()) != 0 || sc_check(sig.r()) != 0)
return false;
ge_dsmp image_pre;
ge_dsm_precomp(image_pre, &image_unp);
rs_comm rs{reinterpret_cast<const hash&>(image), 1};
ge_p3 tmp3;
if (ge_frombytes_vartime(&tmp3, &pub) != 0)
if (ge_frombytes_vartime(&tmp3, pub.data()) != 0)
return false;
ge_p2 tmp2;
@ -706,8 +706,8 @@ namespace crypto {
// The signature r was constructed as r = k - ac, so:
// k = ac + r
// kG = cA + rG = L
ge_double_scalarmult_base_vartime(&tmp2, &sig.c, &tmp3, &sig.r); // L = cA + rG
ge_tobytes(&rs.ab[0].first, &tmp2); // store L
ge_double_scalarmult_base_vartime(&tmp2, sig.c(), &tmp3, sig.r()); // L = cA + rG
ge_tobytes(rs.ab[0].first.data(), &tmp2); // store L
// Step two: reconstruct the signer's R = kH(A)
// The signature r was constructed as r = k - ac, so:
@ -715,14 +715,14 @@ namespace crypto {
// and since aH(A) == I (the key image, by definition):
// kH(A) = rH(A) + cI = R
hash_to_ec(pub, tmp3); // H(A)
ge_double_scalarmult_precomp_vartime(&tmp2, &sig.r, &tmp3, &sig.c, image_pre); // R = rH(A) + cI
ge_tobytes(&rs.ab[0].second, &tmp2); // store R
ge_double_scalarmult_precomp_vartime(&tmp2, sig.r(), &tmp3, sig.c(), image_pre); // R = rH(A) + cI
ge_tobytes(rs.ab[0].second.data(), &tmp2); // store R
// Now we can calculate our own H(I || L || R), and compare it to the signature's c (which was
// set to the signer's H(I || L || R) calculation).
ec_scalar h = rs.hash_to_scalar();
sc_sub(&h, &h, &sig.c);
return sc_isnonzero(&h) == 0;
sc_sub(h.data(), h.data(), sig.c());
return sc_isnonzero(h.data()) == 0;
}
}

View File

@ -39,103 +39,76 @@
#include "epee/memwipe.h"
#include "epee/mlocker.h"
#include "generic-ops.h"
#include "common/hex.h"
#include "common/format.h"
#include "common/formattable.h"
#include "hash.h"
#include "base.h"
extern "C" {
#include "random.h"
}
namespace crypto {
extern "C" {
#include "random.h"
}
struct alignas(size_t) ec_point {
char data[32];
// Returns true if non-null, i.e. not 0.
operator bool() const { static constexpr char null[32] = {0}; return memcmp(data, null, sizeof(data)); }
struct ec_point : bytes<32, true> {
// Returns true if non-null, i.e. not all 0.
explicit operator bool() const { return data_ != null<ec_point>.data_; }
};
struct alignas(size_t) ec_scalar {
char data[32];
struct ec_scalar : bytes<32> {
// constant-time (via libsodium)
bool operator==(const ec_scalar& x) const;
bool operator!=(const ec_scalar& x) const { return !(*this == x); }
// constant-time returns true if not all 0.
explicit operator bool() const;
};
struct public_key : ec_point {};
using secret_key = epee::mlocked<tools::scrubbed<ec_scalar>>;
struct secret_key_ : ec_scalar {};
using secret_key = epee::mlocked<tools::scrubbed<secret_key_>>;
struct public_keyV {
std::vector<public_key> keys;
int rows;
};
struct secret_keyV {
std::vector<secret_key> keys;
int rows;
};
struct public_keyM {
int cols;
int rows;
std::vector<secret_keyV> column_vectors;
};
template <> inline const secret_key null<secret_key>{};
struct key_derivation: ec_point {};
struct key_image: ec_point {};
struct signature {
ec_scalar c, r;
struct signature : bytes<64, true> {
// Returns or sets the "c" part of the signature bytes
unsigned char* c() { return data(); }
const unsigned char* c() const { return data(); }
void c(const ec_scalar& c) { std::copy(c.data(), c.data() + c.size(), data()); }
// Returns or sets the "r" part of the signature bytes
unsigned char* r() { return data() + 32; }
const unsigned char* r() const { return data() + 32; }
void r(const ec_scalar& r) { std::copy(r.data(), r.data() + r.size(), data()); }
// Returns true if non-null, i.e. not 0.
operator bool() const { static constexpr char null[64] = {0}; return memcmp(this, null, sizeof(null)); }
explicit operator bool() const { return data_ != null<signature>.data_; }
};
// The sizes below are all provided by sodium.h, but we don't want to depend on it here; we check
// that they agree with the actual constants from sodium.h when compiling cryptonote_core.cpp.
struct alignas(size_t) ed25519_public_key {
unsigned char data[32]; // 32 = crypto_sign_ed25519_PUBLICKEYBYTES
static constexpr ed25519_public_key null() { return {0}; }
/// Returns true if non-null
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
};
struct ed25519_public_key : ec_point {};
struct alignas(size_t) ed25519_secret_key_ {
// 64 = crypto_sign_ed25519_SECRETKEYBYTES (but we don't depend on libsodium header here)
unsigned char data[64];
};
// 64 = crypto_sign_ed25519_SECRETKEYBYTES (but we don't depend on libsodium header here)
struct ed25519_secret_key_ : bytes<64> {};
using ed25519_secret_key = epee::mlocked<tools::scrubbed<ed25519_secret_key_>>;
struct alignas(size_t) ed25519_signature {
unsigned char data[64]; // 64 = crypto_sign_BYTES
static constexpr ed25519_signature null() { return {0}; }
struct ed25519_signature : bytes<64, true> {
// Returns true if non-null, i.e. not 0.
operator bool() const { auto z = null(); return memcmp(this, &z, sizeof(z)); }
explicit operator bool() const { return data_ != null<ed25519_signature>.data_; }
};
struct alignas(size_t) x25519_public_key {
unsigned char data[32]; // crypto_scalarmult_curve25519_BYTES
static constexpr x25519_public_key null() { return {0}; }
/// Returns true if non-null
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
};
struct x25519_public_key : ec_point {};
struct alignas(size_t) x25519_secret_key_ {
unsigned char data[32]; // crypto_scalarmult_curve25519_BYTES
};
struct x25519_secret_key_ : bytes<32> {};
using x25519_secret_key = epee::mlocked<tools::scrubbed<x25519_secret_key_>>;
void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
ec_scalar hash_to_scalar(const void* data, size_t length);
void random_scalar(unsigned char* bytes);
void random_scalar(ec_scalar& res);
ec_scalar random_scalar();
static_assert(sizeof(ec_point) == 32 && sizeof(ec_scalar) == 32 &&
sizeof(public_key) == 32 && sizeof(secret_key) == 32 &&
sizeof(key_derivation) == 32 && sizeof(key_image) == 32 &&
sizeof(signature) == 64, "Invalid structure size");
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes);
void add_extra_entropy_thread_safe(const void *ptr, size_t bytes);
@ -286,27 +259,12 @@ namespace crypto {
const public_key& pub,
const signature& sig);
inline std::string to_string(const ec_point& P) { return "<{}>"_format(tools::type_to_hex(P)); }
inline std::string to_string(const signature& s) { return "<{}>"_format(tools::type_to_hex(s)); }
inline std::string to_string(const ed25519_public_key& P) { return "<{}>"_format(tools::type_to_hex(P)); }
inline std::string to_string(const x25519_public_key& P) { return "<{}>"_format(tools::type_to_hex(P)); }
constexpr inline crypto::public_key null_pkey{};
const inline crypto::secret_key null_skey{};
}
CRYPTO_MAKE_HASHABLE(public_key)
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)
CRYPTO_MAKE_HASHABLE(key_image)
CRYPTO_MAKE_HASHABLE(signature)
CRYPTO_MAKE_HASHABLE(ed25519_public_key)
CRYPTO_MAKE_HASHABLE(x25519_public_key)
// ec_point is formattable via to_string, as are any subclasses (such as public_key):
template <typename T>
inline constexpr bool formattable::via_to_string<T,
std::enable_if_t<std::is_base_of_v<crypto::ec_point, T>>
> = true;
template <> inline constexpr bool formattable::via_to_string<crypto::signature> = true;
template <> inline constexpr bool formattable::via_to_string<crypto::ed25519_public_key> = true;
template <> inline constexpr bool formattable::via_to_string<crypto::x25519_public_key> = true;
template <> struct std::hash<crypto::ec_point> : crypto::raw_hasher<crypto::ec_point> {};
template <> struct std::hash<crypto::public_key> : crypto::raw_hasher<crypto::public_key> {};
template <> struct std::hash<crypto::key_image> : crypto::raw_hasher<crypto::key_image> {};
template <> struct std::hash<crypto::signature> : crypto::raw_hasher<crypto::signature> {};
template <> struct std::hash<crypto::ed25519_public_key> : crypto::raw_hasher<crypto::ed25519_public_key> {};
template <> struct std::hash<crypto::x25519_public_key> : crypto::raw_hasher<crypto::x25519_public_key> {};
template <> struct std::hash<crypto::ed25519_signature> : crypto::raw_hasher<crypto::ed25519_signature> {};

View File

@ -1,81 +0,0 @@
// Copyright (c) 2014-2019, 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
#include <cstddef>
#include <cstring>
#include <functional>
#include <sodium/crypto_verify_32.h>
#define CRYPTO_MAKE_COMPARABLE(type) \
namespace crypto { \
inline bool operator==(const type &_v1, const type &_v2) { \
return !memcmp(&_v1, &_v2, sizeof(_v1)); \
} \
inline bool operator!=(const type &_v1, const type &_v2) { \
return !operator==(_v1, _v2); \
} \
inline bool operator<(const type &_v1, const type &_v2) { \
return memcmp(&_v1, &_v2, sizeof(_v1)) < 0; \
} \
}
#define CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \
namespace crypto { \
inline bool operator==(const type &_v1, const type &_v2) { \
static_assert(sizeof(_v1) == 32, "constant time comparison is only implenmted for 32 bytes"); \
return crypto_verify_32((const unsigned char*)&_v1, (const unsigned char*)&_v2) == 0; \
} \
inline bool operator!=(const type &_v1, const type &_v2) { \
return !operator==(_v1, _v2); \
} \
}
#define CRYPTO_DEFINE_HASH_FUNCTIONS(type) \
namespace std { \
template<> \
struct hash<crypto::type> { \
static_assert(sizeof(crypto::type) >= sizeof(std::size_t) && alignof(crypto::type) >= alignof(std::size_t), \
"Size and alignment of " #type " must be at least that of size_t"); \
std::size_t operator()(const crypto::type &_v) const { \
return reinterpret_cast<const std::size_t &>(_v); \
} \
}; \
}
#define CRYPTO_MAKE_HASHABLE(type) \
CRYPTO_MAKE_COMPARABLE(type) \
CRYPTO_DEFINE_HASH_FUNCTIONS(type)
#define CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(type) \
CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \
CRYPTO_DEFINE_HASH_FUNCTIONS(type)

View File

@ -35,7 +35,7 @@
#include "jh.h"
#include "hash-ops.h"
void hash_extra_jh(const void *data, size_t length, char *hash) {
int r = jh_hash(HASH_SIZE * 8, data, 8 * length, (uint8_t*)hash);
void hash_extra_jh(const void *data, size_t length, unsigned char *hash) {
int r = jh_hash(HASH_SIZE * 8, data, 8 * length, hash);
assert(SUCCESS == r);
}

View File

@ -35,7 +35,7 @@
#include "hash-ops.h"
#include "skein.h"
void hash_extra_skein(const void *data, size_t length, char *hash) {
int r = skein_hash(8 * HASH_SIZE, data, 8 * length, (uint8_t*)hash);
void hash_extra_skein(const void *data, size_t length, unsigned char *hash) {
int r = skein_hash(8 * HASH_SIZE, data, 8 * length, hash);
assert(SKEIN_SUCCESS == r);
}

View File

@ -37,10 +37,6 @@
#include <stddef.h>
#include <stdint.h>
static inline void *padd(void *p, size_t i) {
return (char *) p + i;
}
#pragma pack(push, 1)
union hash_state {
uint8_t b[200];
@ -61,22 +57,22 @@ enum
};
#define CN_TURTLE_PAGE_SIZE 262144
void cn_fast_hash(const void *data, size_t length, char *hash);
void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations);
void cn_fast_hash(const void *data, size_t length, unsigned char *hash);
void cn_turtle_hash(const void *data, size_t length, unsigned char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations);
#ifdef ENABLE_MONERO_SLOW_HASH
void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed);
void cn_monero_hash(const void *data, size_t length, unsigned char *hash, int variant, int prehashed);
#endif
void hash_extra_blake(const void *data, size_t length, char *hash);
void hash_extra_groestl(const void *data, size_t length, char *hash);
void hash_extra_jh(const void *data, size_t length, char *hash);
void hash_extra_skein(const void *data, size_t length, char *hash);
void hash_extra_blake(const void *data, size_t length, unsigned char *hash);
void hash_extra_groestl(const void *data, size_t length, unsigned char *hash);
void hash_extra_jh(const void *data, size_t length, unsigned char *hash);
void hash_extra_skein(const void *data, size_t length, unsigned char *hash);
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);
void tree_hash(const unsigned char (*hashes)[HASH_SIZE], size_t count, unsigned char *root_hash);
void rx_slow_hash_allocate_state(void);
void rx_slow_hash_free_state(void);
uint64_t rx_seedheight(const uint64_t height);
void rx_seedheights(const uint64_t height, uint64_t *seed_height, uint64_t *next_height);
void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length, char *hash, int miners, int is_alt);
void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const unsigned char *seedhash, const void *data, size_t length, unsigned char *hash, int miners, int is_alt);
void rx_reorg(const uint64_t split_height);

View File

@ -51,7 +51,7 @@ void hash_process(union hash_state *state, const uint8_t *buf, size_t count) {
keccak1600(buf, count, (uint8_t*)state);
}
void cn_fast_hash(const void *data, size_t length, char *hash) {
void cn_fast_hash(const void *data, size_t length, unsigned char *hash) {
union hash_state state;
hash_process(&state, data, length);
memcpy(hash, &state, HASH_SIZE);

85
src/crypto/hash.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "hash.h"
#include "crypto/cn_heavy_hash.hpp"
namespace crypto {
static_assert(sizeof(hash) == HASH_SIZE, "Invalid structure size");
static_assert(sizeof(hash8) == 8, "Invalid structure size");
constexpr size_t SIZE_TS_IN_HASH = crypto::hash::size() / sizeof(size_t);
static_assert(SIZE_TS_IN_HASH * sizeof(size_t) == sizeof(crypto::hash) && alignof(crypto::hash) >= alignof(size_t),
"Expected crypto::hash size/alignment not satisfied");
crypto::hash& crypto::hash::operator^=(const crypto::hash& b) {
const auto* src = reinterpret_cast<const size_t*>(b.data());
auto* dest = reinterpret_cast<size_t*>(data());
for (size_t i = 0; i < SIZE_TS_IN_HASH; ++i)
dest[i] ^= src[i];
return *this;
}
crypto::hash crypto::hash::operator^(const crypto::hash& b) const {
crypto::hash c = *this;
c ^= b;
return c;
}
crypto::hash& crypto::hash::operator=(const crypto::hash8& h) {
zero();
std::copy(h.data(), h.data() + h.size(), data());
return *this;
}
void cn_slow_hash(const void* data, std::size_t length, hash& hash, cn_slow_hash_type type) {
switch(type)
{
case cn_slow_hash_type::heavy_v1:
case cn_slow_hash_type::heavy_v2:
{
static thread_local cn_heavy_hash_v2 v2;
static thread_local cn_heavy_hash_v1 v1 = cn_heavy_hash_v1::make_borrowed(v2);
if (type == cn_slow_hash_type::heavy_v1) v1.hash(data, length, hash.data());
else v2.hash(data, length, hash.data());
}
break;
#ifdef ENABLE_MONERO_SLOW_HASH
case cn_slow_hash_type::cryptonight_v0:
case cn_slow_hash_type::cryptonight_v1_prehashed:
{
int variant = 0, prehashed = 0;
if (type == cn_slow_hash_type::cryptonight_v1_prehashed)
{
prehashed = 1;
variant = 1;
}
else if (type == cn_slow_hash_type::cryptonight_v0_prehashed)
{
prehashed = 1;
}
cn_monero_hash(data, length, hash.data(), variant, prehashed);
}
break;
#endif
case cn_slow_hash_type::turtle_lite_v2:
default:
{
constexpr uint32_t CN_TURTLE_SCRATCHPAD = 262144;
constexpr uint32_t CN_TURTLE_ITERATIONS = 131072;
cn_turtle_hash(data,
length,
hash.data(),
1, // light
2, // variant
0, // pre-hashed
CN_TURTLE_SCRATCHPAD, CN_TURTLE_ITERATIONS);
}
break;
}
}
}

View File

@ -33,41 +33,42 @@
#include <cstddef>
#include <ostream>
#include "generic-ops.h"
#include "common/hex.h"
#include "common/formattable.h"
#include "common/format.h"
#include "crypto/cn_heavy_hash.hpp"
#include "base.h"
extern "C" {
#include "hash-ops.h"
}
namespace crypto {
extern "C" {
#include "hash-ops.h"
}
struct alignas(size_t) hash {
char data[HASH_SIZE];
static constexpr hash null() { return {0}; }
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
};
struct hash8 {
char data[8];
struct hash8 : bytes<8, true> {
explicit operator bool() const { return data_ != null<hash8>.data_; }
};
static_assert(sizeof(hash) == HASH_SIZE, "Invalid structure size");
static_assert(sizeof(hash8) == 8, "Invalid structure size");
struct hash : bytes<HASH_SIZE, true> {
explicit operator bool() const { return data_ != null<hash>.data_; }
// Combine hashes together via XORs.
hash& operator^=(const crypto::hash& h);
hash operator^(const crypto::hash& h) const;
// Assigning a hash8 copies the 8 bytes from the hash8 into the first 8 bytes of the hash and
// zeros the rest.
hash& operator=(const crypto::hash8& h);
};
/*
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));
using ::cn_fast_hash;
inline void cn_fast_hash(const void* data, std::size_t length, hash& hash) {
cn_fast_hash(data, length, hash.data());
}
inline hash cn_fast_hash(const void *data, std::size_t length) {
inline hash cn_fast_hash(const void* data, std::size_t length) {
hash h;
cn_fast_hash(data, length, reinterpret_cast<char *>(&h));
cn_fast_hash(data, length, h);
return h;
}
@ -75,99 +76,24 @@ namespace crypto {
{
#ifdef ENABLE_MONERO_SLOW_HASH
// NOTE: Monero's slow hash for Android only, we still use the old hashing algorithm for hashing the KeyStore containing private keys
cryptonight_v0,
cryptonight_v0 = 0,
cryptonight_v0_prehashed,
cryptonight_v1_prehashed,
#endif
heavy_v1,
heavy_v1 = 3,
heavy_v2,
turtle_lite_v2,
};
inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, cn_slow_hash_type type) {
switch(type)
{
case cn_slow_hash_type::heavy_v1:
case cn_slow_hash_type::heavy_v2:
{
static thread_local cn_heavy_hash_v2 v2;
static thread_local cn_heavy_hash_v1 v1 = cn_heavy_hash_v1::make_borrowed(v2);
if (type == cn_slow_hash_type::heavy_v1) v1.hash(data, length, hash.data);
else v2.hash(data, length, hash.data);
}
break;
#ifdef ENABLE_MONERO_SLOW_HASH
case cn_slow_hash_type::cryptonight_v0:
case cn_slow_hash_type::cryptonight_v1_prehashed:
{
int variant = 0, prehashed = 0;
if (type == cn_slow_hash_type::cryptonight_v1_prehashed)
{
prehashed = 1;
variant = 1;
}
else if (type == cn_slow_hash_type::cryptonight_v0_prehashed)
{
prehashed = 1;
}
cn_monero_hash(data, length, hash.data, variant, prehashed);
}
break;
#endif
case cn_slow_hash_type::turtle_lite_v2:
default:
{
const uint32_t CN_TURTLE_SCRATCHPAD = 262144;
const uint32_t CN_TURTLE_ITERATIONS = 131072;
cn_turtle_hash(data,
length,
hash.data,
1, // light
2, // variant
0, // pre-hashed
CN_TURTLE_SCRATCHPAD, CN_TURTLE_ITERATIONS);
}
break;
}
}
void cn_slow_hash(const void* data, std::size_t length, hash& hash, cn_slow_hash_type type);
using ::tree_hash;
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));
tree_hash(reinterpret_cast<const unsigned char (*)[HASH_SIZE]>(hashes), count, root_hash.data());
}
constexpr size_t SIZE_TS_IN_HASH = sizeof(crypto::hash) / sizeof(size_t);
static_assert(SIZE_TS_IN_HASH * sizeof(size_t) == sizeof(crypto::hash) && alignof(crypto::hash) >= alignof(size_t),
"Expected crypto::hash size/alignment not satisfied");
// Combine hashes together via XORs.
inline crypto::hash& operator^=(crypto::hash& a, const crypto::hash& b) {
size_t (&dest)[SIZE_TS_IN_HASH] = reinterpret_cast<size_t (&)[SIZE_TS_IN_HASH]>(a);
const size_t (&src)[SIZE_TS_IN_HASH] = reinterpret_cast<const size_t (&)[SIZE_TS_IN_HASH]>(b);
for (size_t i = 0; i < SIZE_TS_IN_HASH; ++i)
dest[i] ^= src[i];
return a;
}
inline crypto::hash operator^(const crypto::hash& a, const crypto::hash& b) {
crypto::hash c = a;
c ^= b;
return c;
}
inline std::string to_hex_string(const crypto::hash& h) { return "<{}>"_format(tools::type_to_hex(h)); }
inline std::string to_hex_string(const crypto::hash8& h) { return "<{}>"_format(tools::type_to_hex(h)); }
constexpr inline crypto::hash null_hash = {};
constexpr inline crypto::hash8 null_hash8 = {};
}
CRYPTO_MAKE_HASHABLE(hash)
CRYPTO_MAKE_COMPARABLE(hash8)
template <> inline constexpr bool formattable::via_to_hex_string<crypto::hash> = true;
template <> inline constexpr bool formattable::via_to_hex_string<crypto::hash8> = true;
template <> struct std::hash<crypto::hash> : crypto::raw_hasher<crypto::hash> {};
template <> struct std::hash<crypto::hash8> : crypto::raw_hasher<crypto::hash8> {};

View File

@ -84,7 +84,7 @@ static void generate_system_random_bytes(size_t n, void *result) {
} else if (res == 0) {
errx(EXIT_FAILURE, "read /dev/urandom: end of file");
} else {
result = padd(result, (size_t) res);
result = (char *) result + res;
n -= (size_t) res;
}
}
@ -141,7 +141,7 @@ void generate_random_bytes_not_thread_safe(size_t n, void *result) {
return;
} else {
memcpy(result, &state, HASH_DATA_AREA);
result = padd(result, HASH_DATA_AREA);
result = (char *) result + HASH_DATA_AREA;
n -= HASH_DATA_AREA;
}
}

View File

@ -188,8 +188,8 @@ static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_
rx_dataset_height = seedheight;
}
void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length,
char *hash, int miners, int is_alt) {
void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const unsigned char *seedhash, const void *data, size_t length,
unsigned char *hash, int miners, int is_alt) {
uint64_t s_height = rx_seedheight(mainheight);
int toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) != 0;
randomx_flags flags = enabled_flags() & ~disabled_flags();

View File

@ -59,7 +59,7 @@ size_t tree_hash_cnt(size_t count) {
return pow >> 1;
}
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) {
void tree_hash(const unsigned char (*hashes)[HASH_SIZE], size_t count, unsigned char *root_hash) {
// The blockchain block at height 202612 https://moneroblocks.info/block/202612
// contained 514 transactions, that triggered bad calculation of variable "cnt" in the original version of this function
// as from CryptoNote code.
@ -83,7 +83,7 @@ void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) {
size_t cnt = tree_hash_cnt( count );
char *ints = calloc(cnt, HASH_SIZE); // zero out as extra protection for using uninitialized mem
unsigned char *ints = calloc(cnt, HASH_SIZE); // zero out as extra protection for using uninitialized mem
assert(ints);
memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE);

View File

@ -89,13 +89,13 @@ DISABLE_VS_WARNINGS(4244 4345)
epee::wipeable_string key_stream = get_key_stream(key, m_encryption_iv, sizeof(crypto::secret_key) * (2 + m_multisig_keys.size()));
const char *ptr = key_stream.data();
for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
m_spend_secret_key.data[i] ^= *ptr++;
m_spend_secret_key[i] ^= *ptr++;
for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
m_view_secret_key.data[i] ^= *ptr++;
m_view_secret_key[i] ^= *ptr++;
for (crypto::secret_key &k: m_multisig_keys)
{
for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
k.data[i] ^= *ptr++;
k[i] ^= *ptr++;
}
}
//-----------------------------------------------------------------
@ -117,7 +117,7 @@ DISABLE_VS_WARNINGS(4244 4345)
const char *ptr = key_stream.data();
ptr += sizeof(crypto::secret_key);
for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
m_view_secret_key.data[i] ^= *ptr++;
m_view_secret_key[i] ^= *ptr++;
}
//-----------------------------------------------------------------
void account_keys::decrypt_viewkey(const crypto::chacha_key &key)

View File

@ -63,7 +63,7 @@ namespace cryptonote
uint64_t m_last_response_height{0};
std::optional<std::chrono::steady_clock::time_point> m_last_request_time;
epee::copyable_atomic m_callback_request_count{0}; //in debug purpose: problem with double callback rise
crypto::hash m_last_known_hash{crypto::null_hash};
crypto::hash m_last_known_hash{};
uint32_t m_pruning_seed{0};
bool m_anchor{false};
//size_t m_score{0}; TODO: add score calculations

View File

@ -165,7 +165,7 @@ void block::set_hash_valid(bool v) const
uint64_t account_public_address::modulus(uint64_t interval) const
{
uint64_t address_as_integer = 0;
std::memcpy(&address_as_integer, m_view_public_key.data, sizeof(address_as_integer));
std::memcpy(&address_as_integer, m_view_public_key.data(), sizeof(address_as_integer));
oxenc::host_to_little_inplace(address_as_integer);
return address_as_integer % interval;
}

View File

@ -111,7 +111,7 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx, hw::device &hwdev)
{
crypto::hash h = null_hash;
crypto::hash h{};
get_transaction_prefix_hash(tx, h, hwdev);
return h;
}
@ -119,7 +119,7 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
{
crypto::hash h = null_hash;
crypto::hash h{};
get_transaction_prefix_hash(tx, h);
return h;
}
@ -300,11 +300,11 @@ namespace cryptonote
return true;
}
if (ack.m_spend_secret_key == crypto::null_skey)
if (!ack.m_spend_secret_key)
{
// for watch-only wallet, simply copy the known output pubkey
in_ephemeral.pub = out_key;
in_ephemeral.sec = crypto::null_skey;
in_ephemeral.sec.zero();
}
else
{
@ -561,7 +561,7 @@ namespace cryptonote
tx_extra_pub_key pub_key_field;
if (get_field_from_tx_extra(tx_extra, pub_key_field, pk_index))
return pub_key_field.pub_key;
return null_pkey;
return null<public_key>;
}
//---------------------------------------------------------------
crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx_prefix, size_t pk_index)
@ -765,7 +765,7 @@ namespace cryptonote
tx_extra_service_node_winner winner;
if (get_field_from_tx_extra(tx_extra, winner))
return winner.m_service_node_key;
return crypto::null_pkey;
return null<public_key>;
}
//---------------------------------------------------------------
void add_oxen_name_system_to_tx_extra(std::vector<uint8_t> &tx_extra, tx_extra_oxen_name_system const &entry)
@ -1022,7 +1022,7 @@ namespace cryptonote
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<size_t>& outs, uint64_t& money_transfered)
{
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
if(null_pkey == tx_pub_key)
if (!tx_pub_key)
return false;
std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx);
return lookup_acc_outs(acc, tx, tx_pub_key, additional_tx_pub_keys, outs, money_transfered);
@ -1194,7 +1194,7 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::hash get_transaction_hash(const transaction& t)
{
crypto::hash h = null_hash;
crypto::hash h{};
get_transaction_hash(t, h, NULL);
CHECK_AND_ASSERT_THROW_MES(get_transaction_hash(t, h, NULL), "Failed to calculate transaction hash");
return h;
@ -1265,7 +1265,7 @@ namespace cryptonote
// prunable rct
if (t.rct_signatures.type == rct::RCTType::Null)
hashes[2] = crypto::null_hash;
hashes[2].zero();
else
hashes[2] = pruned_data_hash;
@ -1321,7 +1321,7 @@ namespace cryptonote
// prunable rct
if (t.rct_signatures.type == rct::RCTType::Null)
{
hashes[2] = crypto::null_hash;
hashes[2].zero();
}
else if (!calculate_transaction_prunable_hash(t, &blob, hashes[2]))
{
@ -1412,7 +1412,7 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::hash get_block_hash(const block& b)
{
crypto::hash p = null_hash;
crypto::hash p{};
get_block_hash(b, p);
return p;
}
@ -1496,7 +1496,7 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes)
{
crypto::hash h = null_hash;
crypto::hash h{};
get_tx_tree_hash(tx_hashes, h);
return h;
}
@ -1505,7 +1505,7 @@ namespace cryptonote
{
std::vector<crypto::hash> txs_ids;
txs_ids.reserve(1 + b.tx_hashes.size());
crypto::hash h = null_hash;
crypto::hash h{};
size_t bl_sz = 0;
CHECK_AND_ASSERT_THROW_MES(get_transaction_hash(b.miner_tx, h, bl_sz), "Failed to calculate transaction hash");
txs_ids.push_back(h);
@ -1518,7 +1518,7 @@ namespace cryptonote
{
crypto::hash hash;
crypto::cn_slow_hash(passphrase.data(), passphrase.size(), hash, crypto::cn_slow_hash_type::heavy_v1);
sc_add((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data);
sc_add(key.data(), key.data(), hash.data());
return key;
}
//---------------------------------------------------------------
@ -1526,27 +1526,8 @@ namespace cryptonote
{
crypto::hash hash;
crypto::cn_slow_hash(passphrase.data(), passphrase.size(), hash, crypto::cn_slow_hash_type::heavy_v1);
sc_sub((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data);
sc_sub(key.data(), key.data(), hash.data());
return key;
}
}
std::string ons::generic_owner::to_string(cryptonote::network_type nettype) const
{
if (type == ons::generic_owner_sig_type::monero)
return cryptonote::get_account_address_as_str(nettype, wallet.is_subaddress, wallet.address);
else
return tools::type_to_hex(ed25519);
}
bool ons::generic_owner::operator==(generic_owner const &other) const
{
if (type != other.type)
return false;
if (type == ons::generic_owner_sig_type::monero)
return wallet.is_subaddress == other.wallet.is_subaddress && wallet.address == other.wallet.address;
else
return ed25519 == other.ed25519;
}

View File

@ -1,4 +1,5 @@
#include "tx_extra.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
namespace cryptonote {
@ -101,3 +102,26 @@ std::vector<std::string> coded_reasons(uint16_t decomm_reason) {
}
}
namespace ons {
std::string generic_owner::to_string(cryptonote::network_type nettype) const
{
if (type == generic_owner_sig_type::monero)
return cryptonote::get_account_address_as_str(nettype, wallet.is_subaddress, wallet.address);
else
return tools::type_to_hex(ed25519);
}
bool generic_owner::operator==(const generic_owner& other) const
{
if (type != other.type)
return false;
if (type == generic_owner_sig_type::monero)
return wallet.is_subaddress == other.wallet.is_subaddress && wallet.address == other.wallet.address;
else
return ed25519 == other.ed25519;
}
}

View File

@ -111,7 +111,7 @@ struct alignas(size_t) generic_owner
char padding02_[7];
std::string to_string(cryptonote::network_type nettype) const;
explicit operator bool() const { return (type == generic_owner_sig_type::monero) ? wallet.address != cryptonote::null_address : ed25519; }
explicit operator bool() const { return (type == generic_owner_sig_type::monero) ? wallet.address != cryptonote::null_address : (bool) ed25519; }
bool operator==(generic_owner const &other) const;
bool operator!=(generic_owner const &other) const { return !(*this == other); }
@ -521,11 +521,11 @@ namespace cryptonote
// The value we sign when signing an unlock request. For backwards compatibility we send this as a
// "nonce" (although it isn't and never was a nonce), which is required to be an unsigned 32-bit
// value. We could just as easily sign with crypto::null_hash, but using a distinct value makes it
// value. We could just as easily sign with a null crypto::null, but using a distinct value makes it
// slightly less likely that we could end up using the same message as some other signing process.
static constexpr crypto::hash HASH{
static constexpr crypto::hash HASH{{
'U','N','L','K','U','N','L','K','U','N','L','K','U','N','L','K',
'U','N','L','K','U','N','L','K','U','N','L','K','U','N','L','K'};
'U','N','L','K','U','N','L','K','U','N','L','K','U','N','L','K'}};
// For now, we still have to send that (not a) "nonce" value in the unlock tx on the wire, but
// future HF versions could remove it from the wire (though at 4 bytes it isn't worth doing
// until we also need to make some other change to unlocks here). So for now, we always send
@ -556,7 +556,7 @@ namespace cryptonote
uint8_t version = 0;
ons::mapping_type type;
crypto::hash name_hash;
crypto::hash prev_txid = crypto::null_hash; // previous txid that purchased the mapping
crypto::hash prev_txid = crypto::null<crypto::hash>; // previous txid that purchased the mapping
ons::extra_field fields;
ons::generic_owner owner = {};
ons::generic_owner backup_owner = {};

View File

@ -42,6 +42,7 @@
#include "common/string_util.h"
#include "common/median.h"
#include "common/fs-format.h"
#include "crypto/crypto.h"
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "cryptonote_basic/hardfork.h"
@ -117,7 +118,7 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool, service_nodes::service_node_list
m_max_prepare_blocks_threads(4), m_db_sync_on_blocks(true), m_db_sync_threshold(1), m_db_sync_mode(db_async), m_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_bytes_to_sync(0), m_cancel(false),
m_long_term_block_weights_window(LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE),
m_long_term_effective_median_block_weight(0),
m_long_term_block_weights_cache_tip_hash(crypto::null_hash),
m_long_term_block_weights_cache_tip_hash{},
m_long_term_block_weights_cache_rolling_median(LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE),
m_service_node_list(service_node_list),
m_btc_valid(false),
@ -899,7 +900,7 @@ crypto::hash Blockchain::get_block_id_by_height(uint64_t height) const
log::error(logcat, std::string("Something went wrong fetching block hash by height"));
throw;
}
return null_hash;
return null<hash>;
}
//------------------------------------------------------------------
crypto::hash Blockchain::get_pending_block_id_by_height(uint64_t height) const
@ -1470,7 +1471,7 @@ uint64_t Blockchain::get_long_term_block_weight_median(uint64_t start_height, si
bool cached = false;
uint64_t blockchain_height = m_db->height();
uint64_t tip_height = start_height + count - 1;
crypto::hash tip_hash = crypto::null_hash;
crypto::hash tip_hash{};
if (tip_height < blockchain_height && count == (size_t)m_long_term_block_weights_cache_rolling_median.size())
{
tip_hash = m_db->get_block_hash_from_height(tip_height);
@ -1710,7 +1711,7 @@ bool Blockchain::create_block_template_internal(block& b, const crypto::hash *fr
if (miner_tx_context.pulse)
b.service_node_winner_key = miner_tx_context.pulse_block_producer.key;
else
b.service_node_winner_key = {0};
b.service_node_winner_key = crypto::null<crypto::public_key>;
b.reward = block_rewards;
b.height = height;
@ -1783,7 +1784,7 @@ bool Blockchain::build_alt_chain(const crypto::hash &prev_id,
int alt_checkpoint_count = 0;
int checkpoint_count = 0;
crypto::hash prev_hash = crypto::null_hash;
crypto::hash prev_hash{};
block_extended_info bei = {};
std::string checkpoint_blob;
for(bool found = m_db->get_alt_block(prev_id, &data, &blob, &checkpoint_blob);
@ -2507,7 +2508,7 @@ bool Blockchain::get_outs(const rpc::GET_OUTPUTS_BIN::request& req, rpc::GET_OUT
return false;
}
for (const auto &t: data)
res.outs.push_back({t.pubkey, t.commitment, is_output_spendtime_unlocked(t.unlock_time), t.height, crypto::null_hash});
res.outs.push_back({t.pubkey, t.commitment, is_output_spendtime_unlocked(t.unlock_time), t.height, crypto::null<crypto::hash>});
if (req.get_txid)
{
@ -2752,7 +2753,7 @@ bool Blockchain::get_split_transactions_blobs(const std::vector<crypto::hash>& t
std::string tx;
if (m_db->get_pruned_tx_blob(tx_hash, tx))
{
auto& [hash, pruned, pruned_hash, prunable] = txs.emplace_back(tx_hash, std::move(tx), crypto::null_hash, std::string());
auto& [hash, pruned, pruned_hash, prunable] = txs.emplace_back(tx_hash, std::move(tx), crypto::null<crypto::hash>, std::string());
if (!is_v1_tx(pruned) && !m_db->get_prunable_tx_hash(tx_hash, pruned_hash))
{
log::error(logcat, "Prunable data hash not found for {}", tx_hash);
@ -2886,7 +2887,7 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons
blocks.back().first.first = m_db->get_block_blob_from_height(i);
block b;
CHECK_AND_ASSERT_MES(parse_and_validate_block_from_blob(blocks.back().first.first, b), false, "internal error, invalid block");
blocks.back().first.second = get_miner_tx_hash ? cryptonote::get_transaction_hash(b.miner_tx) : crypto::null_hash;
blocks.back().first.second = get_miner_tx_hash ? cryptonote::get_transaction_hash(b.miner_tx) : crypto::null<crypto::hash>;
std::vector<std::string> txs;
if (pruned)
{
@ -3082,7 +3083,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh
// check if we're doing per-block checkpointing
if (m_db->height() < m_blocks_hash_check.size() && kept_by_block)
{
max_used_block_id = null_hash;
max_used_block_id = null<hash>;
max_used_block_height = 0;
return true;
}
@ -4065,7 +4066,7 @@ bool Blockchain::flush_txes_from_pool(const std::vector<crypto::hash> &txids)
Blockchain::block_pow_verified Blockchain::verify_block_pow(cryptonote::block const &blk, difficulty_type difficulty, uint64_t chain_height, bool alt_block)
{
block_pow_verified result = {};
std::memset(result.proof_of_work.data, 0xff, sizeof(result.proof_of_work.data));
std::memset(result.proof_of_work.data(), 0xff, result.proof_of_work.size());
crypto::hash const blk_hash = cryptonote::get_block_hash(blk);
uint64_t const blk_height = cryptonote::get_block_height(blk);
@ -4109,7 +4110,7 @@ Blockchain::block_pow_verified Blockchain::verify_block_pow(cryptonote::block co
if (chain_height < m_blocks_hash_check.size())
{
const auto &expected_hash = m_blocks_hash_check[chain_height];
if (expected_hash != crypto::null_hash)
if (expected_hash)
{
if (blk_hash != expected_hash)
{
@ -5041,7 +5042,7 @@ uint64_t Blockchain::prevalidate_block_hashes(uint64_t height, const std::vector
size_t end = n * HASH_OF_HASHES_STEP + HASH_OF_HASHES_STEP;
for (size_t i = n * HASH_OF_HASHES_STEP; i < end; ++i)
{
CHECK_AND_ASSERT_MES(m_blocks_hash_check[i] == crypto::null_hash || m_blocks_hash_check[i] == data[i - first_index * HASH_OF_HASHES_STEP],
CHECK_AND_ASSERT_MES(!m_blocks_hash_check[i] || m_blocks_hash_check[i] == data[i - first_index * HASH_OF_HASHES_STEP],
0, "Consistency failure in m_blocks_hash_check construction");
m_blocks_hash_check[i] = data[i - first_index * HASH_OF_HASHES_STEP];
}
@ -5702,10 +5703,10 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get
for (uint32_t i = 0; i < nblocks; i++)
{
crypto::hash& hash = m_blocks_hash_of_hashes.emplace_back();
std::memcpy(hash.data, checkpoints.data(), sizeof(hash.data));
checkpoints.remove_prefix(sizeof(hash.data));
std::memcpy(hash.data(), checkpoints.data(), hash.size());
checkpoints.remove_prefix(hash.size());
}
m_blocks_hash_check.resize(m_blocks_hash_of_hashes.size() * HASH_OF_HASHES_STEP, crypto::null_hash);
m_blocks_hash_check.resize(m_blocks_hash_of_hashes.size() * HASH_OF_HASHES_STEP, null<hash>);
log::info(logcat, "{} block hashes loaded", nblocks);
// FIXME: clear tx_pool because the process might have been

View File

@ -1112,7 +1112,7 @@ namespace cryptonote
// NOTE: Cache Invalidation Checks
uint64_t m_timestamps_and_difficulties_height{0};
crypto::hash m_difficulty_for_next_block_top_hash{crypto::null_hash};
crypto::hash m_difficulty_for_next_block_top_hash{};
difficulty_type m_difficulty_for_next_miner_block{1};
} m_cache;

View File

@ -897,15 +897,15 @@ namespace cryptonote
// Ed25519 signing).
//
if (!init_key(m_config_folder / "key_ed25519", keys.key_ed25519, keys.pub_ed25519,
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_sk_to_pk(pk.data, sk.data); return true; },
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_keypair(pk.data, sk.data); })
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_sk_to_pk(pk.data(), sk.data()); return true; },
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_keypair(pk.data(), sk.data()); })
)
return false;
// Standard x25519 keys generated from the ed25519 keypair, used for encrypted communication between SNs
int rc = crypto_sign_ed25519_pk_to_curve25519(keys.pub_x25519.data, keys.pub_ed25519.data);
int rc = crypto_sign_ed25519_pk_to_curve25519(keys.pub_x25519.data(), keys.pub_ed25519.data());
CHECK_AND_ASSERT_MES(rc == 0, false, "failed to convert ed25519 pubkey to x25519");
crypto_sign_ed25519_sk_to_curve25519(keys.key_x25519.data, keys.key_ed25519.data);
crypto_sign_ed25519_sk_to_curve25519(keys.key_x25519.data(), keys.key_ed25519.data());
// Legacy primary SN key file; we only load this if it exists, otherwise we use `key_ed25519`
// for the primary SN keypair. (This key predates the Ed25519 keys and so is needed for
@ -917,7 +917,7 @@ namespace cryptonote
epee::wipeable_string privkey_signhash;
privkey_signhash.resize(crypto_hash_sha512_BYTES);
unsigned char* pk_sh_data = reinterpret_cast<unsigned char*>(privkey_signhash.data());
crypto_hash_sha512(pk_sh_data, keys.key_ed25519.data, 32 /* first 32 bytes are the seed to be SHA512 hashed (the last 32 are just the pubkey) */);
crypto_hash_sha512(pk_sh_data, keys.key_ed25519.data(), 32 /* first 32 bytes are the seed to be SHA512 hashed (the last 32 are just the pubkey) */);
// Clamp private key (as libsodium does and expects -- see https://www.jcraige.com/an-explainer-on-ed25519-clamping if you want the broader reasons)
pk_sh_data[0] &= 248;
pk_sh_data[31] &= 63; // (some implementations put 127 here, but with the |64 in the next line it is the same thing)
@ -925,10 +925,11 @@ namespace cryptonote
// Monero crypto requires a pointless check that the secret key is < basepoint, so calculate
// it mod basepoint to make it happy:
sc_reduce32(pk_sh_data);
std::memcpy(keys.key.data, pk_sh_data, 32);
std::memcpy(keys.key.data(), pk_sh_data, 32);
if (!crypto::secret_key_to_public_key(keys.key, keys.pub))
throw std::runtime_error{"Failed to derive primary key from ed25519 key"};
assert(0 == std::memcmp(keys.pub.data, keys.pub_ed25519.data, 32));
if (std::memcmp(keys.pub.data(), keys.pub_ed25519.data(), 32))
throw std::runtime_error{"Internal error: unexpected primary pubkey and ed25519 pubkey mismatch"};
} else if (!init_key(m_config_folder / "key", keys.key, keys.pub,
crypto::secret_key_to_public_key,
[](crypto::secret_key &key, crypto::public_key &pubkey) {
@ -936,8 +937,8 @@ namespace cryptonote
}))
return false;
} else {
keys.key = crypto::null_skey;
keys.pub = crypto::null_pkey;
keys.key.zero();
keys.pub.zero();
}
if (m_service_node) {
@ -979,7 +980,7 @@ namespace cryptonote
AuthLevel auth = default_auth;
if (x25519_pubkey_str.size() == sizeof(crypto::x25519_public_key)) {
crypto::x25519_public_key x25519_pubkey;
std::memcpy(x25519_pubkey.data, x25519_pubkey_str.data(), x25519_pubkey_str.size());
std::memcpy(x25519_pubkey.data(), x25519_pubkey_str.data(), x25519_pubkey_str.size());
auto user_auth = omq_check_access(x25519_pubkey);
if (user_auth >= AuthLevel::basic) {
if (user_auth > auth)
@ -1936,7 +1937,7 @@ namespace cryptonote
if (!parse_and_validate_tx_from_blob(tx_blob, tx, tx_hash))
{
log::error(logcat, "Failed to parse relayed transaction");
return crypto::null_hash;
return crypto::null<crypto::hash>;
}
txs.push_back(std::make_pair(tx_hash, std::move(tx_blob)));
m_mempool.set_relayed(txs);
@ -2265,7 +2266,7 @@ namespace cryptonote
return;
auto pubkey = m_service_node_list.get_pubkey_from_x25519(m_service_keys.pub_x25519);
if (pubkey != crypto::null_pkey && pubkey != m_service_keys.pub && m_service_node_list.is_service_node(pubkey, false /*don't require active*/))
if (pubkey && pubkey != m_service_keys.pub && m_service_node_list.is_service_node(pubkey, false /*don't require active*/))
{
log::info(logcat, fg(fmt::terminal_color::red),
"Failed to submit uptime proof: another service node on the network is using the same ed/x25519 keys as this service node. This typically means both have the same 'key_ed25519' private key file.");

View File

@ -368,7 +368,7 @@ namespace cryptonote
virtual bool create_miner_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const std::string& ex_nonce);
/**
* @brief called when a transaction is relayed; return the hash of the parsed tx, or null_hash
* @brief called when a transaction is relayed; return the hash of the parsed tx, or null hash
* on parse failure.
*/
virtual crypto::hash on_transaction_relayed(const std::string& tx);

View File

@ -90,11 +90,11 @@ namespace cryptonote
{
uint64_t height_byte = height & ((uint64_t)0xFF << (i*8));
uint8_t byte = height_byte >> i*8;
sec.data[i] = byte;
sec[i] = byte;
}
for (int i=8; i < 32; i++)
{
sec.data[i] = 0x00;
sec[i] = 0x00;
}
generate_keys(k.pub, k.sec, k.sec, true);
@ -587,7 +587,7 @@ namespace cryptonote
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const std::optional<cryptonote::tx_destination_entry>& change_addr)
{
account_public_address addr = {null_pkey, null_pkey};
account_public_address addr{};
size_t count = 0;
bool found_change = false;
for (const auto &i : destinations)
@ -602,7 +602,7 @@ namespace cryptonote
if (i.addr == addr)
continue;
if (count > 0)
return null_pkey;
return null<public_key>;
addr = i.addr;
++count;
}
@ -665,13 +665,13 @@ namespace cryptonote
tx_extra_nonce extra_nonce;
if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
{
crypto::hash payment_id = null_hash;
crypto::hash8 payment_id8 = null_hash8;
crypto::hash payment_id{};
crypto::hash8 payment_id8{};
if (get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
{
log::debug(globallogcat, "Encrypting payment id {}", payment_id8);
crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, change_addr);
if (view_key_pub == null_pkey)
if (!view_key_pub)
{
log::error(globallogcat, "Destinations have to have exactly one output to support encrypted payment ids");
return false;
@ -709,9 +709,9 @@ namespace cryptonote
// if we have neither long nor short payment id, add a dummy short one,
// this should end up being the vast majority of txes as time goes on
std::string extra_nonce;
crypto::hash8 payment_id8 = null_hash8;
crypto::hash8 payment_id8{};
crypto::public_key view_key_pub = get_destination_view_key_pub(destinations, change_addr);
if (view_key_pub == null_pkey)
if (!view_key_pub)
{
log::error(globallogcat, "Failed to get key to encrypt dummy payment id with");
}
@ -923,10 +923,7 @@ namespace cryptonote
}
// check for watch only wallet
bool zero_secret_key = true;
for (size_t i = 0; i < sizeof(sender_account_keys.m_spend_secret_key); ++i)
zero_secret_key &= (sender_account_keys.m_spend_secret_key.data[i] == 0);
if (zero_secret_key)
if (!sender_account_keys.m_spend_secret_key)
{
log::debug(globallogcat, "Null secret key, skipping signatures");
}
@ -1088,7 +1085,15 @@ namespace cryptonote
else
{
std::string bd = get_block_hashing_blob(b);
rx_slow_hash(randomx_context.current_blockchain_height, randomx_context.seed_height, randomx_context.seed_block_hash.data, bd.data(), bd.size(), result.data, 0, 1);
rx_slow_hash(
randomx_context.current_blockchain_height,
randomx_context.seed_height,
randomx_context.seed_block_hash.data(),
bd.data(),
bd.size(),
result.data(),
0,
1);
}
return result;
@ -1127,10 +1132,10 @@ namespace cryptonote
{
rx_slow_hash(randomx_context.current_blockchain_height,
randomx_context.seed_height,
randomx_context.seed_block_hash.data,
randomx_context.seed_block_hash.data(),
bd.data(),
bd.size(),
result.data,
result.data(),
miners,
0);
return result;

View File

@ -219,6 +219,7 @@ struct blob_view {
std::string_view data;
/// Constructor that simply forwards anything to the `data` (string_view) member constructor
template <typename... T> explicit blob_view(T&&... args) : data{std::forward<T>(args)...} {}
blob_view(const unsigned char* data, size_t size) : blob_view{reinterpret_cast<const char*>(data), size} {}
};
// Binds a blob wrapped in a blob_view decorator
@ -402,7 +403,7 @@ mapping_record sql_get_mapping_from_statement(sql_compiled_statement& statement)
result.name_hash.append(value.data(), value.size());
}
if (!sql_copy_blob(statement, mapping_record_column::txid, result.txid.data, sizeof(result.txid)))
if (!sql_copy_blob(statement, mapping_record_column::txid, result.txid.data(), result.txid.size()))
return result;
int owner_column = tools::enum_count<mapping_record_column>;
@ -451,7 +452,7 @@ bool sql_run_statement(ons_sql_type type, sql_compiled_statement& statement, voi
{
auto *entry = reinterpret_cast<settings_record *>(context);
get(statement, ons_db_setting_column::top_height, entry->top_height);
if (!sql_copy_blob(statement, ons_db_setting_column::top_hash, entry->top_hash.data, sizeof(entry->top_hash.data)))
if (!sql_copy_blob(statement, ons_db_setting_column::top_hash, entry->top_hash.data(), entry->top_hash.size()))
return false;
get(statement, ons_db_setting_column::version, entry->version);
data_loaded = true;
@ -681,7 +682,7 @@ ons::generic_signature make_ed25519_signature(crypto::hash const &hash, crypto::
{
ons::generic_signature result = {};
result.type = ons::generic_owner_sig_type::ed25519;
crypto_sign_detached(result.ed25519.data, NULL, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash), skey.data);
crypto_sign_detached(result.ed25519.data(), NULL, hash.data(), hash.size(), skey.data());
return result;
}
@ -710,9 +711,9 @@ bool parse_owner_to_generic_owner(cryptonote::network_type nettype, std::string_
{
result = ons::make_monero_owner(parsed_addr.address, parsed_addr.is_subaddress);
}
else if (owner.size() == 2*sizeof(ed_owner.data) && oxenc::is_hex(owner))
else if (owner.size() == 2*ed_owner.size() && oxenc::is_hex(owner))
{
oxenc::from_hex(owner.begin(), owner.end(), ed_owner.data);
oxenc::from_hex(owner.begin(), owner.end(), ed_owner.data());
result = ons::make_ed25519_owner(ed_owner);
}
else
@ -926,13 +927,13 @@ bool mapping_value::validate(cryptonote::network_type nettype, mapping_type type
identifier |= ONS_WALLET_TYPE_INTEGRATED;
}
iter = std::copy_n(&identifier, 1, iter);
iter = std::copy_n(addr_info.address.m_spend_public_key.data, sizeof(addr_info.address.m_spend_public_key.data), iter);
iter = std::copy_n(addr_info.address.m_view_public_key.data, sizeof(addr_info.address.m_view_public_key.data), iter);
iter = std::copy_n(addr_info.address.m_spend_public_key.data(), addr_info.address.m_spend_public_key.size(), iter);
iter = std::copy_n(addr_info.address.m_view_public_key.data(), addr_info.address.m_view_public_key.size(), iter);
size_t counter = 65;
assert(std::distance(blob->buffer.begin(), iter) == static_cast<int>(counter));
if (addr_info.has_payment_id) {
std::copy_n(addr_info.payment_id.data, sizeof(addr_info.payment_id.data), iter);
std::copy_n(addr_info.payment_id.data(), addr_info.payment_id.size(), iter);
counter+=sizeof(addr_info.payment_id);
}
@ -1073,13 +1074,13 @@ static bool verify_ons_signature(crypto::hash const &hash, ons::generic_signatur
}
else
{
return (crypto_sign_verify_detached(signature.data, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash.data), owner.ed25519.data) == 0);
return (crypto_sign_verify_detached(signature.data, hash.data(), hash.size(), owner.ed25519.data()) == 0);
}
}
static bool validate_against_previous_mapping(ons::name_system_db &ons_db, uint64_t blockchain_height, cryptonote::transaction const &tx, cryptonote::tx_extra_oxen_name_system const &ons_extra, std::string *reason)
{
crypto::hash expected_prev_txid = crypto::null_hash;
crypto::hash expected_prev_txid{};
std::string name_hash = hash_to_base64(ons_extra.name_hash);
ons::mapping_record mapping = ons_db.get_mapping(ons_extra.type, name_hash);
@ -1120,7 +1121,7 @@ static bool validate_against_previous_mapping(ons::name_system_db &ons_db, uint6
return false;
crypto::hash hash;
crypto_generichash(reinterpret_cast<unsigned char*>(hash.data), sizeof(hash), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr /*key*/, 0 /*key_len*/);
crypto_generichash(hash.data(), hash.size(), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr /*key*/, 0 /*key_len*/);
if (check_condition(!verify_ons_signature(hash, ons_extra.signature, mapping.owner) &&
!verify_ons_signature(hash, ons_extra.signature, mapping.backup_owner), reason,
@ -1264,7 +1265,7 @@ bool name_system_db::validate_ons_tx(hf hf_version, uint64_t blockchain_height,
// ONS Field(s) Validation
// -----------------------------------------------------------------------------------------------
{
if (check_condition((ons_extra.name_hash == null_name_hash || ons_extra.name_hash == crypto::null_hash), reason,
if (check_condition((ons_extra.name_hash == null_name_hash || !ons_extra.name_hash), reason,
"{}, {} specified the null name hash", tx, ons_extra_string(nettype, ons_extra)))
return false;
@ -1349,12 +1350,12 @@ crypto::hash name_to_hash(std::string_view name, const std::optional<crypto::has
assert(std::none_of(name.begin(), name.end(), [](char c) { return std::isupper(c); }));
crypto::hash result = {};
static_assert(sizeof(result) >= crypto_generichash_BYTES, "Sodium can generate arbitrary length hashes, but recommend the minimum size for a secure hash must be >= crypto_generichash_BYTES");
crypto_generichash_blake2b(reinterpret_cast<unsigned char *>(result.data),
sizeof(result),
crypto_generichash_blake2b(result.data(),
result.size(),
reinterpret_cast<const unsigned char *>(name.data()),
static_cast<unsigned long long>(name.size()),
key ? reinterpret_cast<const unsigned char*>(key->data) : nullptr,
key ? sizeof(key->data) : 0);
key ? key->data() : nullptr,
key ? key->size() : 0);
return result;
}
@ -1370,7 +1371,8 @@ struct alignas(size_t) secretbox_secret_key {
secretbox_secret_key& operator=(const crypto::hash& h) {
static_assert(sizeof(secretbox_secret_key::data) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
std::memcpy(data, h.data, sizeof(data));
static_assert(sizeof(secretbox_secret_key::data) == crypto::hash::size());
std::memcpy(data, h.data(), sizeof(data));
return *this;
}
};
@ -1558,12 +1560,12 @@ std::optional<cryptonote::address_parse_info> mapping_value::get_wallet_address_
cryptonote::address_parse_info addr_info{};
auto* bufpos = &buffer[1];
std::memcpy(&addr_info.address.m_spend_public_key.data, bufpos, 32);
std::memcpy(addr_info.address.m_spend_public_key.data(), bufpos, 32);
bufpos += 32;
std::memcpy(&addr_info.address.m_view_public_key.data, bufpos, 32);
std::memcpy(addr_info.address.m_view_public_key.data(), bufpos, 32);
if (buffer[0] == ONS_WALLET_TYPE_INTEGRATED) {
bufpos += 32;
std::copy_n(bufpos,8,addr_info.payment_id.data);
std::copy_n(bufpos, 8, addr_info.payment_id.data());
addr_info.has_payment_id = true;
} else if (buffer[0] == ONS_WALLET_TYPE_SUBADDRESS) {
addr_info.is_subaddress = true;
@ -1989,7 +1991,7 @@ std::pair<std::string, std::vector<update_variant>> update_record_query(name_sys
INSERT INTO mappings (type, name_hash, txid, update_height, expiration_height, owner_id, backup_owner_id, encrypted_value)
SELECT type, name_hash, ?, ?)";
bind.emplace_back(blob_view{tx_hash.data, sizeof(tx_hash)});
bind.emplace_back(blob_view{tx_hash.data(), tx_hash.size()});
bind.emplace_back(height);
constexpr auto suffix = " FROM mappings WHERE type = ? AND name_hash = ? ORDER BY update_height DESC LIMIT 1"sv;
@ -2222,7 +2224,7 @@ bool name_system_db::save_mapping(crypto::hash const &tx_hash, cryptonote::tx_ex
bind(statement, mapping_record_column::type, db_mapping_type(src.type));
bind(statement, mapping_record_column::name_hash, name_hash);
bind(statement, mapping_record_column::encrypted_value, blob_view{src.encrypted_value});
bind(statement, mapping_record_column::txid, blob_view{tx_hash.data, sizeof(tx_hash)});
bind(statement, mapping_record_column::txid, blob_view{tx_hash.data(), tx_hash.size()});
bind(statement, mapping_record_column::update_height, height);
bind(statement, mapping_record_column::expiration_height, expiration);
bind(statement, mapping_record_column::owner_id, owner_id);
@ -2236,7 +2238,7 @@ bool name_system_db::save_settings(uint64_t top_height, crypto::hash const &top_
{
auto& statement = save_settings_sql;
bind(statement, ons_db_setting_column::top_height, top_height);
bind(statement, ons_db_setting_column::top_hash, blob_view{top_hash.data, sizeof(top_hash)});
bind(statement, ons_db_setting_column::top_hash, blob_view{top_hash.data(), top_hash.size()});
bind(statement, ons_db_setting_column::version, version);
bool result = sql_run_statement(ons_sql_type::save_setting, statement, nullptr);
return result;

View File

@ -322,7 +322,7 @@ struct name_system_db
private:
cryptonote::network_type nettype;
uint64_t last_processed_height = 0;
crypto::hash last_processed_hash = crypto::null_hash;
crypto::hash last_processed_hash{};
sql_compiled_statement save_owner_sql{*this};
sql_compiled_statement save_mapping_sql{*this};
sql_compiled_statement save_settings_sql{*this};

View File

@ -228,23 +228,17 @@ crypto::hash blake2b_hash(void const *data, size_t size)
{
crypto::hash result = {};
static_assert(sizeof(result) == crypto_generichash_BYTES);
crypto_generichash(reinterpret_cast<unsigned char *>(result.data), sizeof(result), reinterpret_cast<unsigned char const *>(data), size, nullptr /*key*/, 0 /*key length*/);
crypto_generichash(result.data(), result.size(), reinterpret_cast<unsigned char const *>(data), size, nullptr /*key*/, 0 /*key length*/);
return result;
}
std::string log_prefix(round_context const &context)
{
std::stringstream result;
result << "Pulse B" << context.wait_for_next_block.height << " R";
if (context.state >= round_state::prepare_for_round)
result << +context.prepare_for_round.round;
else
result << "0";
result << ": ";
if (context.prepare_for_round.node_name.size()) result << context.prepare_for_round.node_name << " ";
result << "'" << round_state_string(context.state) << "' ";
return result.str();
return "Pulse B{} R{}: {}'{}' "_format(
context.wait_for_next_block.height,
context.state >= round_state::prepare_for_round ? +context.prepare_for_round.round : 0,
context.prepare_for_round.node_name.empty() ? "" : "{} "_format(context.prepare_for_round.node_name),
round_state_string(context.state));
}
std::bitset<sizeof(uint16_t) * 8> bitset_view16(uint16_t val)
@ -278,14 +272,14 @@ crypto::hash msg_signature_hash(crypto::hash const &top_block_hash, pulse::messa
case pulse::message_type::handshake:
{
auto buf = tools::memcpy_le(top_block_hash.data, msg.quorum_position, msg.round);
auto buf = tools::memcpy_le(top_block_hash, msg.quorum_position, msg.round);
result = blake2b_hash(buf.data(), buf.size());
}
break;
case pulse::message_type::handshake_bitset:
{
auto buf = tools::memcpy_le(msg.handshakes.validator_bitset, top_block_hash.data, msg.quorum_position, msg.round);
auto buf = tools::memcpy_le(msg.handshakes.validator_bitset, top_block_hash, msg.quorum_position, msg.round);
result = blake2b_hash(buf.data(), buf.size());
}
break;
@ -293,21 +287,21 @@ crypto::hash msg_signature_hash(crypto::hash const &top_block_hash, pulse::messa
case pulse::message_type::block_template:
{
crypto::hash block_hash = blake2b_hash(msg.block_template.blob.data(), msg.block_template.blob.size());
auto buf = tools::memcpy_le(msg.round, block_hash.data);
auto buf = tools::memcpy_le(msg.round, block_hash);
result = blake2b_hash(buf.data(), buf.size());
}
break;
case pulse::message_type::random_value_hash:
{
auto buf = tools::memcpy_le(top_block_hash.data, msg.quorum_position, msg.round, msg.random_value_hash.hash.data);
auto buf = tools::memcpy_le(top_block_hash, msg.quorum_position, msg.round, msg.random_value_hash.hash);
result = blake2b_hash(buf.data(), buf.size());
}
break;
case pulse::message_type::random_value:
{
auto buf = tools::memcpy_le(top_block_hash.data, msg.quorum_position, msg.round, msg.random_value.value.data);
auto buf = tools::memcpy_le(top_block_hash, msg.quorum_position, msg.round, msg.random_value.value.data);
result = blake2b_hash(buf.data(), buf.size());
}
break;
@ -315,7 +309,7 @@ crypto::hash msg_signature_hash(crypto::hash const &top_block_hash, pulse::messa
case pulse::message_type::signed_block:
{
crypto::signature const &final_signature = msg.signed_block.signature_of_final_block_hash;
auto buf = tools::memcpy_le(top_block_hash.data, msg.quorum_position, msg.round, final_signature.c.data, final_signature.r.data);
auto buf = tools::memcpy_le(top_block_hash, msg.quorum_position, msg.round, final_signature);
result = blake2b_hash(buf.data(), buf.size());
}
break;
@ -332,27 +326,14 @@ std::string msg_source_string(round_context const &context, pulse::message const
{
if (msg.quorum_position >= context.prepare_for_round.quorum.validators.size()) return "XX";
std::stringstream stream;
stream << "'" << message_type_string(msg.type) << " at round " << +msg.round << " from " << msg.quorum_position;
if (context.state >= round_state::prepare_for_round)
{
if (msg.quorum_position < context.prepare_for_round.quorum.validators.size())
{
crypto::public_key const &key = context.prepare_for_round.quorum.validators[msg.quorum_position];
stream << ":" << key;
}
}
return stream.str();
return "'{}' at round {:d} from {:d}{}"_format(
msg.type, msg.round, msg.quorum_position,
context.state >= round_state::prepare_for_round && msg.quorum_position < context.prepare_for_round.quorum.validators.size()
? ":{}"_format(context.prepare_for_round.quorum.validators[msg.quorum_position]) : "");
}
bool msg_signature_check(pulse::message const &msg, crypto::hash const &top_block_hash, service_nodes::quorum const &quorum, std::string *error)
{
std::stringstream stream;
OXEN_DEFER {
if (error) *error = stream.str();
};
// Get Service Node Key
crypto::public_key const *key = nullptr;
switch (msg.type)
@ -360,7 +341,7 @@ bool msg_signature_check(pulse::message const &msg, crypto::hash const &top_bloc
case pulse::message_type::invalid:
{
assert("Invalid Code Path" == nullptr);
if (error) stream << log_prefix(context) << "Unhandled message type '" << pulse::message_type_string(msg.type) << "' can not verify signature.";
if (error) *error = "{}Unhandled message type '{}' can not verify signature."_format(log_prefix(context), msg.type);
return false;
}
break;
@ -373,7 +354,7 @@ bool msg_signature_check(pulse::message const &msg, crypto::hash const &top_bloc
{
if (msg.quorum_position >= static_cast<int>(quorum.validators.size()))
{
if (error) stream << log_prefix(context) << "Quorum position " << msg.quorum_position << " in Pulse message indexes oob";
if (error) *error = "{}Quorum position {} in Pulse message indexes oob"_format(log_prefix(context), msg.quorum_position);
return false;
}
@ -385,7 +366,7 @@ bool msg_signature_check(pulse::message const &msg, crypto::hash const &top_bloc
{
if (msg.quorum_position != 0)
{
if (error) stream << log_prefix(context) << "Quorum position " << msg.quorum_position << " in Pulse message indexes oob";
if (error) *error = "{}Quorum position {} in Pulse message indexes oob"_format(log_prefix(context), msg.quorum_position);
return false;
}
@ -396,7 +377,8 @@ bool msg_signature_check(pulse::message const &msg, crypto::hash const &top_bloc
if (!crypto::check_signature(msg_signature_hash(top_block_hash, msg), *key, msg.signature))
{
if (error) stream << log_prefix(context) << "Signature for " << msg_source_string(context, msg) << " at height " << context.wait_for_next_block.height << "; is invalid";
if (error) *error = "{}Signature for {} at height {} is invalid"_format(
log_prefix(context), msg_source_string(context, msg), context.wait_for_next_block.height);
return false;
}
@ -1055,7 +1037,7 @@ round_state wait_for_next_block(uint64_t hf16_height, round_context &context, cr
}
crypto::hash prev_hash = blockchain.get_block_id_by_height(chain_height - 1);
if (prev_hash == crypto::null_hash)
if (!prev_hash)
{
for (static uint64_t last_height = 0; last_height != chain_height; last_height = chain_height)
log::debug(logcat, "{}Failed to query the block hash for height {}", log_prefix(context), chain_height - 1);
@ -1574,14 +1556,14 @@ round_state send_and_wait_for_random_value(round_context &context, service_nodes
}
}
crypto_generichash_final(&state, reinterpret_cast<unsigned char *>(final_hash.data), sizeof(final_hash));
crypto_generichash_final(&state, final_hash.data(), final_hash.size());
}
// Add final random value to the block
context.transient.signed_block.final_block = std::move(context.transient.wait_for_block_template.block);
cryptonote::block &final_block = context.transient.signed_block.final_block;
static_assert(sizeof(final_hash) >= sizeof(final_block.pulse.random_value.data));
std::memcpy(final_block.pulse.random_value.data, final_hash.data, sizeof(final_block.pulse.random_value.data));
std::memcpy(final_block.pulse.random_value.data, final_hash.data(), sizeof(final_block.pulse.random_value.data));
// Generate the signature of the final block (without any of the other
// Service Node signatures because we allow the first

View File

@ -7,6 +7,7 @@
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "crypto/crypto.h"
#include "common/formattable.h"
namespace cryptonote
{
@ -38,7 +39,7 @@ enum struct message_type : uint8_t
signed_block,
};
constexpr std::string_view message_type_string(message_type type)
constexpr std::string_view to_string(message_type type)
{
switch(type)
{
@ -107,3 +108,5 @@ bool convert_time_to_round(pulse::time_point const &time, pulse::time_point cons
bool get_round_timings(cryptonote::Blockchain const &blockchain, uint64_t height, uint64_t prev_timestamp, pulse::timings &times);
} // namespace pulse
template <> inline constexpr bool formattable::via_to_string<pulse::message_type> = true;

View File

@ -1358,31 +1358,24 @@ namespace service_nodes
static std::string dump_pulse_block_data(cryptonote::block const &block, service_nodes::quorum const *quorum)
{
std::stringstream stream;
std::bitset<8 * sizeof(block.pulse.validator_bitset)> const validator_bitset = block.pulse.validator_bitset;
stream << "Block(" << cryptonote::get_block_height(block) << "): " << cryptonote::get_block_hash(block) << "\n";
stream << "Leader: ";
if (quorum) stream << (quorum->workers.empty() ? "(invalid leader)" : oxenc::to_hex(tools::view_guts(quorum->workers[0]))) << "\n";
else stream << "(invalid quorum)\n";
stream << "Round: " << +block.pulse.round << "\n";
stream << "Validator Bitset: " << validator_bitset << "\n";
stream << "Signatures: ";
if (block.signatures.empty()) stream << "(none)";
for (service_nodes::quorum_signature const &entry : block.signatures)
std::string s = "Block({}): {}\nLeader: {}\nRound: {:d}\nValidator Bitset: {}\nSignatures:"_format(
cryptonote::get_block_height(block),
cryptonote::get_block_hash(block),
!quorum ? "(invalid quorum)" : quorum->workers.empty() ? "(invalid leader)" :
oxenc::to_hex(tools::view_guts(quorum->workers[0])),
validator_bitset.to_string());
auto append = std::back_inserter(s);
if (block.signatures.empty())
fmt::format_to(append, " (none)");
for (const auto& sig : block.signatures)
{
stream << "\n";
stream << " [" << +entry.voter_index << "] validator: ";
if (quorum)
{
stream << ((entry.voter_index >= quorum->validators.size()) ? "(invalid quorum index)" : oxenc::to_hex(tools::view_guts(quorum->validators[entry.voter_index])));
stream << ", signature: " << oxenc::to_hex(tools::view_guts(entry.signature));
}
else stream << "(invalid quorum)";
fmt::format_to(append, "\n [{:d}] validator: {}", sig.voter_index,
!quorum ? "(invalid quorum)" :
sig.voter_index >= quorum->validators.size() ? "(invalid quorum index)" :
"{}: {}"_format(quorum->validators[sig.voter_index], sig.signature));
}
return stream.str();
return s;
}
static bool verify_block_components(cryptonote::network_type nettype,
@ -1790,7 +1783,7 @@ namespace service_nodes
else
{
uint64_t seed = 0;
std::memcpy(&seed, hash.data, sizeof(seed));
std::memcpy(&seed, hash.data(), sizeof(seed));
oxenc::little_to_host_inplace(seed);
seed += static_cast<uint64_t>(type);
result.seed(seed);
@ -1853,17 +1846,17 @@ namespace service_nodes
{
std::array<uint8_t, 1 + sizeof(block.pulse.random_value)> src = {pulse_round};
std::copy(std::begin(block.pulse.random_value.data), std::end(block.pulse.random_value.data), src.begin() + 1);
crypto::cn_fast_hash(src.data(), src.size(), hash.data);
crypto::cn_fast_hash(src.data(), src.size(), hash);
}
else
{
crypto::hash block_hash = cryptonote::get_block_hash(block);
std::array<uint8_t, 1 + sizeof(hash)> src = {pulse_round};
std::copy(std::begin(block_hash.data), std::end(block_hash.data), src.begin() + 1);
crypto::cn_fast_hash(src.data(), src.size(), hash.data);
std::copy(std::begin(block_hash), std::end(block_hash), src.begin() + 1);
crypto::cn_fast_hash(src.data(), src.size(), hash);
}
assert(hash != crypto::null_hash);
assert(hash);
result.push_back(hash);
}
@ -2014,7 +2007,7 @@ namespace service_nodes
static void generate_other_quorums(service_node_list::state_t &state, std::vector<pubkey_and_sninfo> const &active_snode_list, cryptonote::network_type nettype, hf hf_version)
{
assert(state.block_hash != crypto::null_hash);
assert(state.block_hash);
// The two quorums here have different selection criteria: the entire checkpoint quorum and the
// state change *validators* want only active service nodes, but the state change *workers*
@ -2247,7 +2240,7 @@ namespace service_nodes
{
crypto::hash const block_hash = cryptonote::get_block_hash(block);
uint64_t seed = 0;
std::memcpy(&seed, block_hash.data, sizeof(seed));
std::memcpy(&seed, block_hash.data(), sizeof(seed));
/// Gather existing swarms from infos
swarm_snode_map_t existing_swarms;
@ -2441,10 +2434,10 @@ namespace service_nodes
service_nodes::payout service_node_list::state_t::get_block_leader() const
{
crypto::public_key key = crypto::null_pkey;
crypto::public_key key{};
service_node_info const *info = nullptr;
{
auto oldest_waiting = std::make_tuple(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint32_t>::max(), crypto::null_pkey);
auto oldest_waiting = std::make_tuple(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint32_t>::max(), crypto::null<crypto::public_key>);
for (const auto &info_it : service_nodes_infos)
{
const auto &sninfo = *info_it.second;
@ -2461,7 +2454,7 @@ namespace service_nodes
key = std::get<2>(oldest_waiting);
}
if (key == crypto::null_pkey)
if (!key)
return service_nodes::null_payout;
return service_node_payout_portions(key, *info);
}
@ -2929,7 +2922,7 @@ namespace service_nodes
size_t buf_size;
crypto::hash result;
auto buf = tools::memcpy_le(proof.pubkey.data, proof.timestamp, proof.public_ip, proof.storage_https_port, proof.pubkey_ed25519.data, proof.qnet_port, proof.storage_omq_port);
auto buf = tools::memcpy_le(proof.pubkey, proof.timestamp, proof.public_ip, proof.storage_https_port, proof.pubkey_ed25519, proof.qnet_port, proof.storage_omq_port);
buf_size = buf.size();
crypto::cn_fast_hash(buf.data(), buf_size, result);
return result;
@ -2952,7 +2945,7 @@ namespace service_nodes
crypto::hash hash = hash_uptime_proof(result);
crypto::generate_signature(hash, keys.pub, keys.key, result.sig);
crypto_sign_detached(result.sig_ed25519.data, NULL, reinterpret_cast<unsigned char *>(hash.data), sizeof(hash.data), keys.key_ed25519.data);
crypto_sign_detached(result.sig_ed25519.data(), NULL, hash.data(), hash.size(), keys.key_ed25519.data());
return result;
}
@ -3069,12 +3062,12 @@ namespace service_nodes
void proof_info::update_pubkey(const crypto::ed25519_public_key &pk) {
if (pk == proof->pubkey_ed25519)
return;
if (pk && 0 == crypto_sign_ed25519_pk_to_curve25519(pubkey_x25519.data, pk.data)) {
if (pk && 0 == crypto_sign_ed25519_pk_to_curve25519(pubkey_x25519.data(), pk.data())) {
proof->pubkey_ed25519 = pk;
} else {
log::warning(logcat, "Failed to derive x25519 pubkey from ed25519 pubkey {}", proof->pubkey_ed25519);
pubkey_x25519 = crypto::x25519_public_key::null();
proof->pubkey_ed25519 = crypto::ed25519_public_key::null();
pubkey_x25519.zero();
proof->pubkey_ed25519.zero();
}
}
@ -3125,20 +3118,20 @@ namespace service_nodes
return false;
}
crypto::x25519_public_key derived_x25519_pubkey = crypto::x25519_public_key::null();
crypto::x25519_public_key derived_x25519_pubkey{};
if (!proof.pubkey_ed25519)
{
log::debug(logcat, "Rejecting uptime proof from {}: required ed25519 auxiliary pubkey {} not included in proof", proof.pubkey, proof.pubkey_ed25519);
return false;
}
if (0 != crypto_sign_verify_detached(proof.sig_ed25519.data, reinterpret_cast<unsigned char *>(hash.data), sizeof(hash.data), proof.pubkey_ed25519.data))
if (0 != crypto_sign_verify_detached(proof.sig_ed25519.data(), hash.data(), hash.size(), proof.pubkey_ed25519.data()))
{
log::debug(logcat, "Rejecting uptime proof from {}: ed25519 signature validation failed", proof.pubkey);
return false;
}
if (0 != crypto_sign_ed25519_pk_to_curve25519(derived_x25519_pubkey.data, proof.pubkey_ed25519.data) || !derived_x25519_pubkey)
if (0 != crypto_sign_ed25519_pk_to_curve25519(derived_x25519_pubkey.data(), proof.pubkey_ed25519.data()) || !derived_x25519_pubkey)
{
log::debug(logcat, "Rejecting uptime proof from {}: invalid ed25519 pubkey included in proof (x25519 derivation failed)", proof.pubkey);
return false;
@ -3255,20 +3248,20 @@ namespace service_nodes
return false;
}
crypto::x25519_public_key derived_x25519_pubkey = crypto::x25519_public_key::null();
crypto::x25519_public_key derived_x25519_pubkey{};
if (!proof->pubkey_ed25519)
{
log::debug(logcat, "Rejecting uptime proof from {}: required ed25519 auxiliary pubkey {} not included in proof", proof->pubkey, proof->pubkey_ed25519);
return false;
}
if (0 != crypto_sign_verify_detached(proof->sig_ed25519.data, reinterpret_cast<unsigned char *>(hash.data), sizeof(hash.data), proof->pubkey_ed25519.data))
if (0 != crypto_sign_verify_detached(proof->sig_ed25519.data(), hash.data(), hash.size(), proof->pubkey_ed25519.data()))
{
log::debug(logcat, "Rejecting uptime proof from {}: ed25519 signature validation failed", proof->pubkey);
return false;
}
if (0 != crypto_sign_ed25519_pk_to_curve25519(derived_x25519_pubkey.data, proof->pubkey_ed25519.data) || !derived_x25519_pubkey)
if (0 != crypto_sign_ed25519_pk_to_curve25519(derived_x25519_pubkey.data(), proof->pubkey_ed25519.data()) || !derived_x25519_pubkey)
{
log::debug(logcat, "Rejecting uptime proof from {}: invalid ed25519 pubkey included in proof (x25519 derivation failed)", proof->pubkey);
return false;
@ -3364,7 +3357,7 @@ namespace service_nodes
auto it = x25519_to_pub.find(x25519);
if (it != x25519_to_pub.end())
return it->second.first;
return crypto::null_pkey;
return crypto::null<crypto::public_key>;
}
crypto::public_key service_node_list::get_random_pubkey() {
@ -3395,7 +3388,7 @@ namespace service_nodes
if (xpk.size() != sizeof(crypto::x25519_public_key))
return "";
crypto::x25519_public_key x25519_pub;
std::memcpy(x25519_pub.data, xpk.data(), xpk.size());
std::memcpy(x25519_pub.data(), xpk.data(), xpk.size());
auto pubkey = get_pubkey_from_x25519(x25519_pub);
if (!pubkey) {
@ -3728,7 +3721,7 @@ namespace service_nodes
for (size_t i = 0; i < last_index; i++)
{
state_serialized &entry = data_in.states[i];
if (entry.block_hash == crypto::null_hash) entry.block_hash = m_blockchain.get_block_id_by_height(entry.height);
if (!entry.block_hash) entry.block_hash = m_blockchain.get_block_id_by_height(entry.height);
m_transient.state_history.emplace_hint(m_transient.state_history.end(), this, std::move(entry));
}

View File

@ -149,7 +149,7 @@ namespace service_nodes
std::unique_ptr<uptime_proof::Proof> proof{};
// Derived from pubkey_ed25519, not serialized
crypto::x25519_public_key pubkey_x25519 = crypto::x25519_public_key::null();
crypto::x25519_public_key pubkey_x25519 = crypto::null<crypto::x25519_public_key>;
// Updates pubkey_ed25519 to the given key, re-deriving the x25519 key if it actually changes
// (does nothing if the key is the same as the current value). If x25519 derivation fails then
@ -316,7 +316,7 @@ namespace service_nodes
if (version >= version_t::v1_add_registration_hf_version)
VARINT_FIELD(registration_hf_version);
if (version >= version_t::v2_ed25519 && version < version_t::v4_noproofs) {
crypto::ed25519_public_key fake_pk = crypto::ed25519_public_key::null();
crypto::ed25519_public_key fake_pk = crypto::null<crypto::ed25519_public_key>;
FIELD_N("pubkey_ed25519", fake_pk)
if (version >= version_t::v3_quorumnet) {
uint16_t fake_port = 0;
@ -647,7 +647,7 @@ namespace service_nodes
using block_height = uint64_t;
struct state_t
{
crypto::hash block_hash{crypto::null_hash};
crypto::hash block_hash{};
bool only_loaded_quorums{false};
service_nodes_infos_t service_nodes_infos;
std::vector<key_image_blacklist_entry> key_image_blacklist;
@ -823,5 +823,5 @@ namespace service_nodes
payout service_node_payout_portions(const crypto::public_key& key, const service_node_info& info);
const static payout_entry null_payout_entry = {cryptonote::null_address, cryptonote::old::STAKING_PORTIONS};
const static payout null_payout = {crypto::null_pkey, {null_payout_entry}};
const static payout null_payout = {crypto::null<crypto::public_key>, {null_payout_entry}};
}

View File

@ -45,6 +45,16 @@ namespace service_nodes
{
static auto logcat = log::Cat("quorum_cop");
std::string quorum::to_string() const {
std::string result;
auto append = std::back_inserter(result);
for (size_t i = 0; i < validators.size(); i++)
fmt::format_to(append, "V[{}] {}\n", i, validators[i]);
for (size_t i = 0; i < workers.size(); i++)
fmt::format_to(append, "W[{}] {}\n", i, workers[i]);
return result;
}
std::optional<std::vector<std::string_view>> service_node_test_results::why() const
{
if (passed())

View File

@ -52,15 +52,7 @@ namespace service_nodes
std::vector<crypto::public_key> validators; // Array of public keys identifying service nodes who validate and sign.
std::vector<crypto::public_key> workers; // Array of public keys of tested service nodes (if applicable).
//
inline std::string to_string() const
{
std::stringstream result;
for (size_t i = 0; i < validators.size(); i++)
result << "V[" << i << "] " << validators[i] << "\n";
for (size_t i = 0; i < workers.size(); i++)
result << "W[" << std::to_string(i) + "] " << workers[i] << "\n";
return result.str();
};
std::string to_string() const;
BEGIN_SERIALIZE()
FIELD(validators)

View File

@ -184,7 +184,7 @@ crypto::hash generate_request_stake_unlock_hash(uint32_t nonce)
crypto::hash result;
oxenc::host_to_little_inplace(nonce);
for (size_t i = 0; i < 8; i++)
reinterpret_cast<uint32_t*>(result.data)[i] = nonce;
reinterpret_cast<uint32_t*>(result.data())[i] = nonce;
return result;
}

View File

@ -458,8 +458,8 @@ namespace service_nodes
if (!result)
return result;
crypto::public_key key = crypto::null_pkey;
crypto::hash hash = crypto::null_hash;
crypto::public_key key{};
crypto::hash hash{};
switch(vote.type)
{

View File

@ -51,17 +51,17 @@ crypto::public_key blink_tx::get_sn_pubkey(subquorum q, int position, const serv
// TODO FIXME XXX - we don't want a failure here; if this happens we need to go back into state
// history to retrieve the state info. (Or maybe this can't happen?)
log::error(globallogcat, "FIXME: could not get blink quorum for blink_tx");
return crypto::null_pkey;
return crypto::null<crypto::public_key>;
}
if (position < (int) blink_quorum->validators.size())
return blink_quorum->validators[position];
return crypto::null_pkey;
return crypto::null<crypto::public_key>;
};
crypto::hash blink_tx::hash(bool approved) const {
auto buf = tools::memcpy_le(height, get_txhash().data, uint8_t{approved});
auto buf = tools::memcpy_le(height, get_txhash(), uint8_t{approved});
crypto::hash blink_hash;
crypto::cn_fast_hash(buf.data(), buf.size(), blink_hash);
return blink_hash;

View File

@ -362,7 +362,7 @@ namespace cryptonote
time_t receive_time = time(nullptr);
crypto::hash max_used_block_id = null_hash;
crypto::hash max_used_block_id{};
uint64_t max_used_block_height = 0;
cryptonote::txpool_tx_meta_t meta;
bool inputs_okay = check_tx_inputs([&tx]()->cryptonote::transaction&{ return tx; }, id, max_used_block_height, max_used_block_id, tvc, opts.kept_by_block,
@ -376,10 +376,10 @@ namespace cryptonote
{
meta.weight = tx_weight;
meta.fee = fee;
meta.max_used_block_id = null_hash;
meta.max_used_block_id = null<hash>;
meta.max_used_block_height = 0;
meta.last_failed_height = 0;
meta.last_failed_id = null_hash;
meta.last_failed_id = null<hash>;
meta.kept_by_block = opts.kept_by_block;
meta.receive_time = receive_time;
meta.last_relayed_time = time(NULL);
@ -423,7 +423,7 @@ namespace cryptonote
meta.max_used_block_id = max_used_block_id;
meta.max_used_block_height = max_used_block_height;
meta.last_failed_height = 0;
meta.last_failed_id = null_hash;
meta.last_failed_id = null<hash>;
meta.receive_time = receive_time;
meta.last_relayed_time = time(NULL);
meta.relayed = opts.relayed;
@ -474,7 +474,7 @@ namespace cryptonote
//---------------------------------------------------------------------------------
bool tx_memory_pool::add_tx(transaction &tx, tx_verification_context& tvc, const tx_pool_options &opts, hf version)
{
crypto::hash h = null_hash;
crypto::hash h{};
size_t blob_size = 0;
std::string bl;
t_serializable_object_to_blob(tx, bl);
@ -1055,7 +1055,7 @@ namespace cryptonote
tx_verification_context tvc;
uint64_t max_used_block_height = 0;
crypto::hash max_used_block_id = null_hash;
crypto::hash max_used_block_id{};
if (!m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id, tvc, /*kept_by_block*/ false))
{
log::info(logcat, "TX type: {} considered for relaying failed tx inputs check, txid: {}, reason: {}", tx.type, txid, print_tx_verification_context(tvc, &tx));
@ -1554,10 +1554,10 @@ end:
//not the best implementation at this time, sorry :(
//check is ring_signature already checked ?
if(txd.max_used_block_id == null_hash)
if(!txd.max_used_block_id)
{//not checked, lets try to check
if(txd.last_failed_id != null_hash && m_blockchain.get_current_blockchain_height() > txd.last_failed_height && txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height))
if(txd.last_failed_id && m_blockchain.get_current_blockchain_height() > txd.last_failed_height && txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height))
return false;//we already sure that this tx is broken for this height
tx_verification_context tvc;

View File

@ -38,7 +38,7 @@ Proof::Proof(
crypto::hash hash = hash_uptime_proof();
crypto::generate_signature(hash, keys.pub, keys.key, sig);
crypto_sign_detached(sig_ed25519.data, NULL, reinterpret_cast<unsigned char *>(hash.data), sizeof(hash.data), keys.key_ed25519.data);
crypto_sign_detached(sig_ed25519.data(), nullptr, hash.data(), hash.size(), keys.key_ed25519.data());
}
//Deserialize from a btencoded string into our Proof instance
@ -66,7 +66,7 @@ Proof::Proof(const std::string& serialized_proof)
if (auto it = bt_proof.find("pk"); it != bt_proof.end())
pubkey = tools::make_from_guts<crypto::public_key>(var::get<std::string>(bt_proof.at("pk")));
else
std::memcpy(pubkey.data, pubkey_ed25519.data, 32);
std::memcpy(pubkey.data(), pubkey_ed25519.data(), 32);
//qnet_port
qnet_port = get_int<unsigned>(bt_proof.at("q"));
//storage_omq_port

View File

@ -406,7 +406,7 @@ size_t block_queue::get_num_filled_spans() const
crypto::hash block_queue::get_last_known_hash(const boost::uuids::uuid &connection_id) const
{
std::unique_lock lock{mutex};
crypto::hash hash = crypto::null_hash;
crypto::hash hash{};
uint64_t highest_height = 0;
for (const auto &span: blocks)
{

View File

@ -1139,7 +1139,7 @@ namespace cryptonote
size_t size = blocks_size + others_size;
for (const auto &element : arg.missed_ids)
size += sizeof(element.data);
size += element.size();
size += sizeof(arg.current_blockchain_height);
{
@ -2203,7 +2203,7 @@ skip:
if (!start_from_current_chain)
{
// we'll want to start off from where we are on that peer, which may not be added yet
if (context.m_last_known_hash != crypto::null_hash && r.block_ids.front() != context.m_last_known_hash)
if (context.m_last_known_hash && r.block_ids.front() != context.m_last_known_hash)
r.block_ids.push_front(context.m_last_known_hash);
}

View File

@ -113,9 +113,9 @@ std::string get_data_as_string(const T &key) {
}
crypto::x25519_public_key x25519_from_string(std::string_view pubkey) {
crypto::x25519_public_key x25519_pub = crypto::x25519_public_key::null();
crypto::x25519_public_key x25519_pub{};
if (pubkey.size() == sizeof(crypto::x25519_public_key))
std::memcpy(x25519_pub.data, pubkey.data(), pubkey.size());
std::memcpy(x25519_pub.data(), pubkey.data(), pubkey.size());
return x25519_pub;
}
@ -455,7 +455,7 @@ bt_dict serialize_vote(const quorum_vote_t &vote) {
{"s", get_data_as_string(vote.signature)},
};
if (vote.type == quorum_type::checkpointing)
result["bh"] = std::string{vote.checkpoint.block_hash.data, sizeof(crypto::hash)};
result["bh"] = std::string{tools::view_guts(vote.checkpoint.block_hash)};
else {
result["wi"] = vote.state_change.worker_index;
result["sc"] = static_cast<std::underlying_type_t<new_state>>(vote.state_change.state);
@ -478,8 +478,8 @@ quorum_vote_t deserialize_vote(std::string_view v) {
std::memcpy(&vote.signature, sig.data(), sizeof(vote.signature));
if (vote.type == quorum_type::checkpointing) {
auto &bh = var::get<std::string>(d.at("bh"));
if (bh.size() != sizeof(vote.checkpoint.block_hash.data)) throw std::invalid_argument("invalid vote checkpoint block hash");
std::memcpy(vote.checkpoint.block_hash.data, bh.data(), sizeof(vote.checkpoint.block_hash.data));
if (bh.size() != vote.checkpoint.block_hash.size()) throw std::invalid_argument("invalid vote checkpoint block hash");
std::memcpy(vote.checkpoint.block_hash.data(), bh.data(), bh.size());
} else {
vote.state_change.worker_index = get_int<uint16_t>(d.at("wi"));
vote.state_change.state = get_enum<new_state>(d, "sc");
@ -897,7 +897,7 @@ void handle_blink(Message& m, QnetState& qnet) {
auto &tx_hash_str = var::get<std::string>(data.at("#"));
bool already_approved = false, already_rejected = false;
if (tx_hash_str.size() == sizeof(crypto::hash)) {
std::memcpy(tx_hash.data, tx_hash_str.data(), sizeof(crypto::hash));
std::memcpy(tx_hash.data(), tx_hash_str.data(), tx_hash_str.size());
std::shared_lock lock{qnet.mutex};
auto bit = qnet.blinks.find(blink_height);
if (bit != qnet.blinks.end()) {
@ -927,7 +927,7 @@ void handle_blink(Message& m, QnetState& qnet) {
}
}
}
log::trace(logcat, "Blink tx hash: {}", to_hex(tx_hash.data));
log::trace(logcat, "Blink tx hash: {}", tx_hash);
} else {
log::info(logcat, "Rejecting blink tx: invalid tx hash included in request");
if (tag)
@ -1137,7 +1137,7 @@ void handle_blink_signature(Message& m, QnetState& qnet) {
if (hash_str.size() != sizeof(crypto::hash))
throw std::invalid_argument("Invalid blink signature data: invalid tx hash");
crypto::hash tx_hash;
std::memcpy(tx_hash.data, hash_str.data(), sizeof(crypto::hash));
std::memcpy(tx_hash.data(), hash_str.data(), hash_str.size());
// h - height
if (!data.skip_until("h")) throw std::invalid_argument("Invalid blink signature data: missing required field 'h'");
@ -1635,7 +1635,7 @@ void handle_pulse_random_value_hash(Message &m, QnetState &qnet)
if (str.size() != sizeof(msg.random_value_hash.hash))
throw std::invalid_argument("Invalid hash data size: " + std::to_string(str.size()));
std::memcpy(msg.random_value_hash.hash.data, str.data(), str.size());
std::memcpy(msg.random_value_hash.hash.data(), str.data(), str.size());
} else {
throw std::invalid_argument(std::string(INVALID_ARG_PREFIX) + tag + "'");
}

View File

@ -89,7 +89,7 @@ namespace {
info.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&info))
{
tools::fail_msg_writer() << "Admin relaunch failed: " << get_last_error();
tools::fail_msg_writer("Admin relaunch failed: {}", get_last_error());
return false;
}
else
@ -122,7 +122,7 @@ bool check_admin(bool & result)
, &p_administrators_group
))
{
tools::fail_msg_writer() << "Security Identifier creation failed: " << get_last_error();
tools::fail_msg_writer("Security Identifier creation failed: {}", get_last_error());
return false;
}
@ -132,7 +132,7 @@ bool check_admin(bool & result)
, &is_admin
))
{
tools::fail_msg_writer() << "Permissions check failed: " << get_last_error();
tools::fail_msg_writer("Permissions check failed: {}", get_last_error());
return false;
}
@ -179,7 +179,7 @@ bool install_service(char const *service_name, std::string const &arguments)
};
if (p_manager == nullptr)
{
tools::fail_msg_writer() << "Couldn't connect to service manager: " << get_last_error();
tools::fail_msg_writer("Couldn't connect to service manager: {}", get_last_error());
return false;
}
@ -205,11 +205,11 @@ bool install_service(char const *service_name, std::string const &arguments)
};
if (p_service == nullptr)
{
tools::fail_msg_writer() << "Couldn't create service: " << get_last_error();
tools::fail_msg_writer("Couldn't create service: {}", get_last_error());
return false;
}
tools::success_msg_writer() << "Service installed";
tools::success_msg_writer("Service installed");
pause_to_display_admin_window_messages();
@ -218,7 +218,7 @@ bool install_service(char const *service_name, std::string const &arguments)
bool start_service(char const *service_name)
{
tools::msg_writer() << "Starting service";
tools::msg_writer("Starting service");
SERVICE_STATUS_PROCESS service_status = {};
DWORD unused = 0;
@ -233,7 +233,7 @@ bool start_service(char const *service_name)
};
if (p_manager == nullptr)
{
tools::fail_msg_writer() << "Couldn't connect to service manager: " << get_last_error();
tools::fail_msg_writer("Couldn't connect to service manager: {}", get_last_error());
return false;
}
@ -248,7 +248,7 @@ bool start_service(char const *service_name)
};
if (p_service == nullptr)
{
tools::fail_msg_writer() << "Couldn't find service: " << get_last_error();
tools::fail_msg_writer("Couldn't find service: {}", get_last_error());
return false;
}
@ -258,11 +258,11 @@ bool start_service(char const *service_name)
, nullptr
))
{
tools::fail_msg_writer() << "Service start request failed: " << get_last_error();
tools::fail_msg_writer("Service start request failed: {}", get_last_error());
return false;
}
tools::success_msg_writer() << "Service started";
tools::success_msg_writer("Service started");
pause_to_display_admin_window_messages();
@ -271,7 +271,7 @@ bool start_service(char const *service_name)
bool stop_service(char const *service_name)
{
tools::msg_writer() << "Stopping service";
tools::msg_writer("Stopping service");
service_handle p_manager{
OpenSCManager(
@ -283,7 +283,7 @@ bool stop_service(char const *service_name)
};
if (p_manager == nullptr)
{
tools::fail_msg_writer() << "Couldn't connect to service manager: " << get_last_error();
tools::fail_msg_writer("Couldn't connect to service manager: {}", get_last_error());
return false;
}
@ -297,18 +297,18 @@ bool stop_service(char const *service_name)
};
if (p_service == nullptr)
{
tools::fail_msg_writer() << "Couldn't find service: " << get_last_error();
tools::fail_msg_writer("Couldn't find service: {}", get_last_error());
return false;
}
SERVICE_STATUS status = {};
if (!ControlService(p_service.get(), SERVICE_CONTROL_STOP, &status))
{
tools::fail_msg_writer() << "Couldn't request service stop: " << get_last_error();
tools::fail_msg_writer("Couldn't request service stop: {}", get_last_error());
return false;
}
tools::success_msg_writer() << "Service stopped";
tools::success_msg_writer("Service stopped");
pause_to_display_admin_window_messages();
@ -327,7 +327,7 @@ bool uninstall_service(char const *service_name)
};
if (p_manager == nullptr)
{
tools::fail_msg_writer() << "Couldn't connect to service manager: " << get_last_error();
tools::fail_msg_writer("Couldn't connect to service manager: {}", get_last_error());
return false;
}
@ -341,18 +341,18 @@ bool uninstall_service(char const *service_name)
};
if (p_service == nullptr)
{
tools::fail_msg_writer() << "Couldn't find service: " << get_last_error();
tools::fail_msg_writer("Couldn't find service: {}", get_last_error());
return false;
}
SERVICE_STATUS status = {};
if (!DeleteService(p_service.get()))
{
tools::fail_msg_writer() << "Couldn't uninstall service: " << get_last_error();
tools::fail_msg_writer("Couldn't uninstall service: {}", get_last_error());
return false;
}
tools::success_msg_writer() << "Service uninstalled";
tools::success_msg_writer("Service uninstalled");
pause_to_display_admin_window_messages();

View File

@ -52,57 +52,50 @@ static std::string extra_nonce_to_string(const cryptonote::tx_extra_nonce &extra
}
struct extra_printer {
void operator()(const tx_extra_padding& x) { std::cout << "padding: " << x.size << " bytes"; }
void operator()(const tx_extra_pub_key& x) { std::cout << "pub key: " << x.pub_key; }
void operator()(const tx_extra_nonce& x) { std::cout << "nonce: " << extra_nonce_to_string(x); }
void operator()(const tx_extra_merge_mining_tag& x) { std::cout << "merge mining tag: depth " << x.depth << ", merkle root " << x.merkle_root; }
void operator()(const tx_extra_additional_pub_keys& x) {
std::cout << "additional tx pubkeys: ";
bool first = true;
for (auto& pk : x.data) {
if (first) first = false;
else std::cout << ", ";
std::cout << pk;
}
}
void operator()(const tx_extra_mysterious_minergate& x) { std::cout << "minergate custom: " << oxenc::to_hex(x.data); }
void operator()(const tx_extra_service_node_winner& x) { std::cout << "SN reward winner: " << x.m_service_node_key; }
void operator()(const tx_extra_service_node_register& x) { std::cout << "SN registration data"; } // TODO: could parse this further
void operator()(const tx_extra_service_node_pubkey& x) { std::cout << "SN pubkey: " << x.m_service_node_key; }
void operator()(const tx_extra_service_node_contributor& x) { std::cout << "SN contribution"; } // Can't actually print the address without knowing the network type
void operator()(const tx_extra_service_node_deregister_old& x) { std::cout << "SN deregistration (pre-HF12)"; }
void operator()(const tx_extra_tx_secret_key& x) { std::cout << "TX secret key: " << tools::type_to_hex(x.key); }
void operator()(const tx_extra_tx_key_image_proofs& x) { std::cout << "TX key image proofs (" << x.proofs.size() << ")"; }
void operator()(const tx_extra_tx_key_image_unlock& x) { std::cout << "TX key image unlock: " << x.key_image; }
void operator()(const tx_extra_burn& x) { std::cout << "Transaction burned fee/payment: " << print_money(x.amount); }
void operator()(const tx_extra_oxen_name_system& x) {
std::cout << "ONS " << (x.is_buying() ? "registration" : x.is_updating() ? "update" : "(unknown)");
std::string operator()(const tx_extra_padding& x) { return "padding: {} bytes"_format(x.size); }
std::string operator()(const tx_extra_pub_key& x) { return "pub key: {}"_format(x.pub_key); }
std::string operator()(const tx_extra_nonce& x) { return "nonce: {}"_format(extra_nonce_to_string(x)); }
std::string operator()(const tx_extra_merge_mining_tag& x) { return "merge mining tag: depth {}, markle root {}"_format(x.depth, x.merkle_root); }
std::string operator()(const tx_extra_additional_pub_keys& x) { return "additional tx pubkeys: {}"_format(fmt::join(x.data, ", ")); }
std::string operator()(const tx_extra_mysterious_minergate& x) { return "minergate custom: {}"_format(oxenc::to_hex(x.data)); }
std::string operator()(const tx_extra_service_node_winner& x) { return "SN reward winner: {}"_format(x.m_service_node_key); }
std::string operator()(const tx_extra_service_node_register& x) { return "SN registration data"; } // TODO: could parse this further
std::string operator()(const tx_extra_service_node_pubkey& x) { return "SN pubkey: {}"_format(x.m_service_node_key); }
std::string operator()(const tx_extra_service_node_contributor& x) { return "SN contribution"; } // Can't actually print the address without knowing the network type
std::string operator()(const tx_extra_service_node_deregister_old& x) { return "SN deregistration (pre-HF12)"; }
std::string operator()(const tx_extra_tx_secret_key& x) { return "TX secret key: {}" + tools::type_to_hex(x.key); }
std::string operator()(const tx_extra_tx_key_image_proofs& x) { return "TX key image proofs ({})"_format(x.proofs.size()); }
std::string operator()(const tx_extra_tx_key_image_unlock& x) { return "TX key image unlock: {}"_format(x.key_image); }
std::string operator()(const tx_extra_burn& x) { return "Transaction burned fee/payment: {}"_format(print_money(x.amount)); }
std::string operator()(const tx_extra_oxen_name_system& x) {
std::string val = "ONS {}"_format(x.is_buying() ? "registration" : x.is_updating() ? "update" : "(unknown)");
switch (x.type)
{
case ons::mapping_type::lokinet: std::cout << " - Lokinet (1y)"; break;
case ons::mapping_type::lokinet_2years: std::cout << " - Lokinet (2y)"; break;
case ons::mapping_type::lokinet_5years: std::cout << " - Lokinet (5y)"; break;
case ons::mapping_type::lokinet_10years: std::cout << " - Lokinet (10y)"; break;
case ons::mapping_type::session: std::cout << " - Session address"; break;
case ons::mapping_type::wallet: std::cout << " - Wallet address"; break;
case ons::mapping_type::lokinet: val += " - Lokinet (1y)"; break;
case ons::mapping_type::lokinet_2years: val += " - Lokinet (2y)"; break;
case ons::mapping_type::lokinet_5years: val += " - Lokinet (5y)"; break;
case ons::mapping_type::lokinet_10years: val += " - Lokinet (10y)"; break;
case ons::mapping_type::session: val += " - Session address"; break;
case ons::mapping_type::wallet: val += " - Wallet address"; break;
case ons::mapping_type::update_record_internal:
case ons::mapping_type::_count:
break;
}
return val;
}
void operator()(const tx_extra_service_node_state_change& x) {
std::cout << "SN state change: ";
std::string operator()(const tx_extra_service_node_state_change& x) {
std::string_view type;
switch (x.state)
{
case service_nodes::new_state::decommission: std::cout << "decommission"; break;
case service_nodes::new_state::recommission: std::cout << "recommission"; break;
case service_nodes::new_state::deregister: std::cout << "deregister"; break;
case service_nodes::new_state::ip_change_penalty: std::cout << "ip change penalty"; break;
case service_nodes::new_state::_count: std::cout << "(unknown)"; break;
case service_nodes::new_state::decommission: type = "decommission"; break;
case service_nodes::new_state::recommission: type = "recommission"; break;
case service_nodes::new_state::deregister: type = "deregister"; break;
case service_nodes::new_state::ip_change_penalty: type = "ip change penalty"; break;
case service_nodes::new_state::_count: type = "(unknown)"; break;
}
std::cout << " for block height " << x.block_height << ", SN index " << x.service_node_index;
return "SN state change: {} for block height {}, SN index {}"_format(
type, x.block_height, x.service_node_index);
}
template <typename T> void operator()(const T&) { std::cout << "unknown"; }
};
@ -112,7 +105,7 @@ static void print_extra_fields(const std::vector<cryptonote::tx_extra_field> &fi
for (size_t n = 0; n < fields.size(); ++n)
{
std::cout << "- " << n << ": ";
var::visit(extra_printer{}, fields[n]);
std::cout << var::visit(extra_printer{}, fields[n]);
std::cout << "\n";
}
}
@ -246,12 +239,15 @@ int main(int argc, char* argv[])
{
addr_decoded = true;
cryptonote::account_public_address const &address = addr_info.address;
std::cout << "Network Type: " << network_type_str(static_cast<cryptonote::network_type>(nettype)) << "\n";
std::cout << "Address: " << input << "\n";
std::cout << "Subaddress: " << (addr_info.is_subaddress ? "Yes" : "No") << "\n";
std::cout << "Payment ID: " << (addr_info.has_payment_id ? tools::type_to_hex(addr_info.payment_id) : "(none)") << "\n";
std::cout << "Spend Public Key: " << address.m_spend_public_key << "\n";
std::cout << "View Public Key: " << address.m_view_public_key << "\n";
fmt::print("Network Type: {}\n", network_type_str(nettype));
fmt::print("Address: {}\n", input);
fmt::print("Subaddress: {}\n", addr_info.is_subaddress ? "Yes" : "No");
if (addr_info.has_payment_id)
fmt::print("Payment ID: {}\n", addr_info.payment_id);
else
fmt::print("Payment ID: (none)\n");
fmt::print("Spend Public Key: {}\n", address.m_spend_public_key);
fmt::print("View Public Key: {}\n", address.m_view_public_key);
}
}

View File

@ -42,19 +42,6 @@
namespace hw::core {
/* ===================================================================== */
/* === Misc ==== */
/* ===================================================================== */
// EW, this crap is NASTY. See the comment/TODO in crypto/crypto.cpp (which is where this
// nasty crap was copied from).
static inline unsigned char* operator &(crypto::ec_scalar &scalar) {
return &reinterpret_cast<unsigned char &>(scalar);
}
static inline const unsigned char *operator &(const crypto::ec_scalar &scalar) {
return &reinterpret_cast<const unsigned char &>(scalar);
}
/* ======================================================================= */
/* SETUP/TEARDOWN */
/* ======================================================================= */
@ -143,7 +130,7 @@ namespace hw::core {
ge_p3 p3;
ge_cached cached;
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0,
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, keys.m_account_address.m_spend_public_key.data()) == 0,
"ge_frombytes_vartime failed to convert spend public key");
ge_p3_to_cached(&cached, &p3);
@ -158,14 +145,14 @@ namespace hw::core {
crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index);
// M = m*G
ge_scalarmult_base(&p3, (const unsigned char*)m.data);
ge_scalarmult_base(&p3, m.data());
// D = B + M
crypto::public_key D;
ge_p1p1 p1p1;
ge_add(&p1p1, &p3, &cached);
ge_p1p1_to_p3(&p3, &p1p1);
ge_p3_tobytes((unsigned char*)D.data, &p3);
ge_p3_tobytes(D.data(), &p3);
pkeys.push_back(D);
}
@ -222,7 +209,7 @@ namespace hw::core {
}
bool device_default::sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) {
sc_add(&r, &a, &b);
sc_add(r.data(), a.data(), b.data());
return true;
}
@ -274,7 +261,7 @@ namespace hw::core {
bool device_default::generate_ons_signature(std::string_view sig_data, const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index, crypto::signature& sig) {
crypto::hash hash;
crypto_generichash(reinterpret_cast<unsigned char*>(hash.data), sizeof(hash), reinterpret_cast<const unsigned char*>(sig_data.data()), sig_data.size(), nullptr, 0);
crypto_generichash(hash.data(), hash.size(), reinterpret_cast<const unsigned char*>(sig_data.data()), sig_data.size(), nullptr, 0);
crypto::secret_key skey = keys.m_spend_secret_key;
if (!index.is_zero())
@ -383,7 +370,7 @@ namespace hw::core {
cn_fast_hash(data, 33, hash);
for (size_t b = 0; b < 8; ++b)
payment_id.data[b] ^= hash.data[b];
payment_id[b] ^= hash[b];
return true;
}

View File

@ -227,7 +227,7 @@ namespace hw::ledger {
/* === Internal Helpers ==== */
/* ===================================================================== */
static bool is_fake_view_key(const crypto::secret_key &sec) {
return sec == crypto::null_skey;
return !sec;
}
bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) {
@ -699,8 +699,8 @@ namespace hw::ledger {
send_simple(INS_GET_KEY, 1);
int offset = 0;
receive_bytes(pubkey.m_view_public_key.data, 32, offset);
receive_bytes(pubkey.m_spend_public_key.data, 32, offset);
receive_bytes(pubkey.m_view_public_key.data(), 32, offset);
receive_bytes(pubkey.m_spend_public_key.data(), 32, offset);
return true;
}
@ -709,22 +709,22 @@ namespace hw::ledger {
auto locks = tools::unique_locks(device_locker, command_locker);
//secret key are represented as fake key on the wallet side
memcpy(vkey.data, dummy_view_key, 32);
memcpy(skey.data, dummy_spend_key, 32);
memcpy(vkey.data(), dummy_view_key, 32);
memcpy(skey.data(), dummy_spend_key, 32);
//spcialkey, normal conf handled in decrypt
send_simple(INS_GET_KEY, 0x02);
//View key is retrieved, if allowed, to speed up blockchain parsing
receive_bytes(viewkey.data, 32);
receive_bytes(viewkey.data(), 32);
has_view_key = !is_fake_view_key(viewkey);
log::debug(logcat, "{}", (has_view_key ? "Have view key" : "Have no view key"));
#ifdef DEBUG_HWDEVICE
send_simple(INS_GET_KEY, 0x04);
int offset = 0;
receive_bytes(dbg_viewkey.data, 32, offset);
receive_bytes(dbg_spendkey.data, 32, offset);
receive_bytes(dbg_viewkey.data(), 32, offset);
receive_bytes(dbg_spendkey.data(), 32, offset);
#endif
return true;
@ -759,7 +759,7 @@ namespace hw::ledger {
send_bytes(&index, sizeof(index), offset);
//payment ID
send_bytes(payment_id ? payment_id->data : crypto::null_hash8.data, 8, offset);
send_bytes(payment_id ? payment_id->data() : crypto::null<crypto::hash8>.data(), 8, offset);
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Timeout/Error on display address.");
}
@ -774,12 +774,12 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
crypto::key_derivation derivation_x =
(mode_ == mode::TRANSACTION_PARSE && has_view_key) ? derivation : decrypt(derivation);
log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub.data, 32);
log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32);
log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub.data(), 32);
log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data(), 32);
log_message( "derive_subaddress_public_key: [[IN]] index ", std::to_string(output_index));
crypto::public_key derived_pub_x;
debug_device->derive_subaddress_public_key(pub, derivation_x, output_index, derived_pub_x);
log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32);
log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data(), 32);
#endif
if (mode_ == mode::TRANSACTION_PARSE && has_view_key) {
@ -791,19 +791,19 @@ namespace hw::ledger {
int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY);
//pub
send_bytes(pub.data, 32, offset);
send_bytes(pub.data(), 32, offset);
//derivation
send_secret(derivation.data, offset);
send_secret(derivation.data(), offset);
//index
send_u32(output_index, offset);
finish_and_exchange(offset);
//pub key
receive_bytes(derived_pub.data, 32);
receive_bytes(derived_pub.data(), 32);
}
#ifdef DEBUG_HWDEVICE
check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data, derived_pub.data);
check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data(), derived_pub.data());
#endif
return true;
@ -815,11 +815,11 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const cryptonote::account_keys keys_x = decrypt(keys);
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data, 32);
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data(), 32);
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data(), 32);
log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
crypto::public_key D_x = debug_device->get_subaddress_spend_public_key(keys_x, index);
log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data(), 32);
#endif
if (index.is_zero()) {
@ -833,11 +833,11 @@ namespace hw::ledger {
finish_and_exchange(offset);
receive_bytes(D.data, 32);
receive_bytes(D.data(), 32);
}
#ifdef DEBUG_HWDEVICE
check32("get_subaddress_spend_public_key", "D", D_x.data, D.data);
check32("get_subaddress_spend_public_key", "D", D_x.data(), D.data());
#endif
return D;
@ -859,14 +859,14 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const cryptonote::account_keys keys_x = decrypt(keys);
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_secret_key ", keys_x.m_spend_secret_key.data, 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data(), 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data(), 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_secret_key ", keys_x.m_spend_secret_key.data(), 32);
log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data(), 32);
log_message( "get_subaddress: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
cryptonote::account_public_address address_x = debug_device->get_subaddress(keys_x, index);
log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32);
log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32);
log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data(), 32);
log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data(), 32);
#endif
if (index.is_zero()) {
@ -880,13 +880,13 @@ namespace hw::ledger {
finish_and_exchange(offset);
offset = 0;
receive_bytes(address.m_view_public_key.data, 32, offset);
receive_bytes(address.m_spend_public_key.data, 32, offset);
receive_bytes(address.m_view_public_key.data(), 32, offset);
receive_bytes(address.m_spend_public_key.data(), 32, offset);
}
#ifdef DEBUG_HWDEVICE
check32("get_subaddress", "address.m_view_public_key.data", address_x.m_view_public_key.data, address.m_view_public_key.data);
check32("get_subaddress", "address.m_spend_public_key.data", address_x.m_spend_public_key.data, address.m_spend_public_key.data);
check32("get_subaddress", "address.m_view_public_key.data", address_x.m_view_public_key.data(), address.m_view_public_key.data());
check32("get_subaddress", "address.m_spend_public_key.data", address_x.m_spend_public_key.data(), address.m_spend_public_key.data());
#endif
return address;
@ -899,14 +899,14 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::secret_key sec_x = decrypt(sec);
log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data(), 32);
crypto::secret_key sub_sec_x = debug_device->get_subaddress_secret_key(sec_x, index);
log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
//sec
send_secret(sec.data, offset);
send_secret(sec.data(), offset);
//index
static_assert(sizeof(cryptonote::subaddress_index) == 8);
send_bytes(&index, sizeof(index), offset);
@ -914,11 +914,11 @@ namespace hw::ledger {
finish_and_exchange(offset);
offset = 0;
receive_secret(sub_sec.data, offset);
receive_secret(sub_sec.data(), offset);
#ifdef DEBUG_HWDEVICE
crypto::secret_key sub_sec_clear = decrypt(sub_sec);
check32("get_subaddress_secret_key", "sub_sec", sub_sec_x.data, sub_sec_clear.data);
check32("get_subaddress_secret_key", "sub_sec", sub_sec_x.data(), sub_sec_clear.data());
#endif
return sub_sec;
@ -934,9 +934,9 @@ namespace hw::ledger {
offset = set_command_header_noopt(INS_VERIFY_KEY);
//sec
send_secret(secret_key.data, offset);
send_secret(secret_key.data(), offset);
//pub
send_bytes(public_key.data, 32, offset);
send_bytes(public_key.data(), 32, offset);
finish_and_exchange(offset);
@ -1010,29 +1010,29 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::secret_key a_x = decrypt(a);
const crypto::secret_key b_x = decrypt(b);
log_hexbuffer("sc_secret_add: [[IN]] a ", a_x.data, 32);
log_hexbuffer("sc_secret_add: [[IN]] b ", b_x.data, 32);
log_hexbuffer("sc_secret_add: [[IN]] a ", a_x.data(), 32);
log_hexbuffer("sc_secret_add: [[IN]] b ", b_x.data(), 32);
crypto::secret_key r_x;
rct::key aG_x;
debug_device->sc_secret_add(r_x, a_x, b_x);
log_hexbuffer("sc_secret_add: [[OUT]] aG", r_x.data, 32);
log_hexbuffer("sc_secret_add: [[OUT]] aG", r_x.data(), 32);
#endif
offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
//sec key
send_secret(a.data, offset);
send_secret(a.data(), offset);
//sec key
send_secret(b.data, offset);
send_secret(b.data(), offset);
finish_and_exchange(offset);
//sec key
offset = 0;
receive_secret(r.data, offset);
receive_secret(r.data(), offset);
#ifdef DEBUG_HWDEVICE
crypto::secret_key r_clear = decrypt(r);
check32("sc_secret_add", "r", r_x.data, r_clear.data);
check32("sc_secret_add", "r", r_x.data(), r_clear.data());
#endif
return true;
@ -1051,7 +1051,7 @@ namespace hw::ledger {
crypto::secret_key recovery_key_x;
if (recover) {
recovery_key_x = decrypt(recovery_key);
log_hexbuffer("generate_keys: [[IN]] pub", recovery_key_x.data, 32);
log_hexbuffer("generate_keys: [[IN]] pub", recovery_key_x.data(), 32);
}
#endif
@ -1059,17 +1059,17 @@ namespace hw::ledger {
offset = 0;
//pub key
receive_bytes(pub.data, 32, offset);
receive_secret(sec.data, offset);
receive_bytes(pub.data(), 32, offset);
receive_secret(sec.data(), offset);
#ifdef DEBUG_HWDEVICE
crypto::secret_key sec_clear = decrypt(sec);
sec_x = sec_clear;
log_hexbuffer("generate_keys: [[OUT]] pub", pub.data, 32);
log_hexbuffer("generate_keys: [[OUT]] sec", sec_clear.data, 32);
log_hexbuffer("generate_keys: [[OUT]] pub", pub.data(), 32);
log_hexbuffer("generate_keys: [[OUT]] sec", sec_clear.data(), 32);
crypto::secret_key_to_public_key(sec_x,pub_x);
check32("generate_keys", "pub", pub_x.data, pub.data);
check32("generate_keys", "pub", pub_x.data(), pub.data());
#endif
return sec;
@ -1088,12 +1088,12 @@ namespace hw::ledger {
bool r = false;
#ifdef DEBUG_HWDEVICE
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub.data, 32);
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub.data(), 32);
const crypto::secret_key sec_x = (sec == rct::rct2sk(rct::I)) ? sec : decrypt(sec);
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data(), 32);
crypto::key_derivation derivation_x;
debug_device->generate_key_derivation(pub, sec_x, derivation_x);
log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32);
log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data(), 32);
#endif
if (mode_ == mode::TRANSACTION_PARSE && has_view_key) {
@ -1106,22 +1106,22 @@ namespace hw::ledger {
} else {
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
//pub
send_bytes(pub.data, 32, offset);
send_bytes(pub.data(), 32, offset);
//sec
send_secret(sec.data, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
offset = 0;
//derivation data
receive_secret(derivation.data, offset);
receive_secret(derivation.data(), offset);
r = true;
}
#ifdef DEBUG_HWDEVICE
crypto::key_derivation derivation_clear =
(mode_ == mode::TRANSACTION_PARSE && has_view_key) ? derivation : decrypt(derivation);
check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data);
check32("generate_key_derivation", "derivation", derivation_x.data(), derivation_clear.data());
#endif
return r;
@ -1142,7 +1142,7 @@ namespace hw::ledger {
}
}
CHECK_AND_ASSERT_THROW_MES(pkey, "Mismatched derivation on scan info");
return generate_key_derivation(*pkey, crypto::null_skey, derivation);
return generate_key_derivation(*pkey, crypto::null<crypto::secret_key>, derivation);
}
bool device_ledger::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) {
@ -1150,16 +1150,16 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::key_derivation derivation_x = decrypt(derivation);
log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32);
log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data(), 32);
log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index));
crypto::ec_scalar res_x;
debug_device->derivation_to_scalar(derivation_x, output_index, res_x);
log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32);
log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
//derivation
send_secret(derivation.data, offset);
send_secret(derivation.data(), offset);
//index
send_u32(output_index, offset);
@ -1168,11 +1168,11 @@ namespace hw::ledger {
//derivation data
offset = 0;
receive_secret(res.data, offset);
receive_secret(res.data(), offset);
#ifdef DEBUG_HWDEVICE
crypto::ec_scalar res_clear = decrypt(res);
check32("derivation_to_scalar", "res", res_x.data, res_clear.data);
check32("derivation_to_scalar", "res", res_x.data(), res_clear.data());
#endif
return true;
@ -1184,31 +1184,31 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::key_derivation derivation_x = decrypt(derivation);
const crypto::secret_key sec_x = decrypt(sec);
log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32);
log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data(), 32);
log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index));
log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data(), 32);
crypto::secret_key derived_sec_x;
debug_device->derive_secret_key(derivation_x, output_index, sec_x, derived_sec_x);
log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32);
log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
//derivation
send_secret(derivation.data, offset);
send_secret(derivation.data(), offset);
//index
send_u32(output_index, offset);
//sec
send_secret(sec.data, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
offset = 0;
//sec key
receive_secret(derived_sec.data, offset);
receive_secret(derived_sec.data(), offset);
#ifdef DEBUG_HWDEVICE
crypto::secret_key derived_sec_clear = decrypt(derived_sec);
check32("derive_secret_key", "derived_sec", derived_sec_x.data, derived_sec_clear.data);
check32("derive_secret_key", "derived_sec", derived_sec_x.data(), derived_sec_clear.data());
#endif
return true;
@ -1219,29 +1219,29 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::key_derivation derivation_x = decrypt(derivation);
log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32);
log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data(), 32);
log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index));
log_hexbuffer("derive_public_key: [[IN]] pub ", pub.data, 32);
log_hexbuffer("derive_public_key: [[IN]] pub ", pub.data(), 32);
crypto::public_key derived_pub_x;
debug_device->derive_public_key(derivation_x, output_index, pub, derived_pub_x);
log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32);
log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
//derivation
send_secret(derivation.data, offset);
send_secret(derivation.data(), offset);
//index
send_u32(output_index, offset);
//pub
send_bytes(pub.data, 32, offset);
send_bytes(pub.data(), 32, offset);
finish_and_exchange(offset);
//pub key
receive_bytes(derived_pub.data, 32);
receive_bytes(derived_pub.data(), 32);
#ifdef DEBUG_HWDEVICE
check32("derive_public_key", "derived_pub", derived_pub_x.data, derived_pub.data);
check32("derive_public_key", "derived_pub", derived_pub_x.data(), derived_pub.data());
#endif
return true;
@ -1252,10 +1252,10 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::secret_key sec_x = decrypt(sec);
log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data(), 32);
crypto::public_key pub_x;
bool rc = debug_device->secret_key_to_public_key(sec_x, pub_x);
log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32);
log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data(), 32);
if (!rc){
log_message("FAIL secret_key_to_public_key", "secret_key rejected");
}
@ -1263,15 +1263,15 @@ namespace hw::ledger {
int offset = set_command_header_noopt(INS_SECRET_KEY_TO_PUBLIC_KEY);
//sec key
send_secret(sec.data, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
//pub key
receive_bytes(pub.data, 32);
receive_bytes(pub.data(), 32);
#ifdef DEBUG_HWDEVICE
check32("secret_key_to_public_key", "pub", pub_x.data, pub.data);
check32("secret_key_to_public_key", "pub", pub_x.data(), pub.data());
#endif
return true;
@ -1282,26 +1282,26 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::secret_key sec_x = decrypt(sec);
log_hexbuffer("generate_key_image: [[IN]] pub ", pub.data, 32);
log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("generate_key_image: [[IN]] pub ", pub.data(), 32);
log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data(), 32);
crypto::key_image image_x;
debug_device->generate_key_image(pub, sec_x, image_x);
log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32);
log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE);
//pub
send_bytes(pub.data, 32, offset);
send_bytes(pub.data(), 32, offset);
//sec
send_secret(sec.data, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
//key image
receive_bytes(image.data, 32);
receive_bytes(image.data(), 32);
#ifdef DEBUG_HWDEVICE
check32("generate_key_image", "image", image_x.data, image.data);
check32("generate_key_image", "image", image_x.data(), image.data());
#endif
return true;
@ -1311,9 +1311,9 @@ namespace hw::ledger {
auto locks = tools::unique_locks(device_locker, command_locker);
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE_SIGNATURE);
send_bytes(image.data, 32, offset);
send_bytes(pub.data, 32, offset);
send_secret(sec.data, offset);
send_bytes(image.data(), 32, offset);
send_bytes(pub.data(), 32, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
@ -1323,10 +1323,10 @@ namespace hw::ledger {
// We can't check the actual returned signature byte values because a random component is
// involved, but we *can* attempt to verify the signature
bool good = crypto::check_key_image_signature(image, pub, sig);
log_hexbuffer("generate_key_image_signature: key image", image.data, 32);
log_hexbuffer("generate_key_image_signature: pubkey", pub.data, 32);
log_hexbuffer("generate_key_image_signature: signature.c", sig.c.data, 32);
log_hexbuffer("generate_key_image_signature: signature.r", sig.r.data, 32);
log_hexbuffer("generate_key_image_signature: key image", image.data(), 32);
log_hexbuffer("generate_key_image_signature: pubkey", pub.data(), 32);
log_hexbuffer("generate_key_image_signature: signature.c", sig.c(), 32);
log_hexbuffer("generate_key_image_signature: signature.r", sig.r(), 32);
log_message("generate_key_image_signature: signature returned from device", good ? "passed" : "FAILED");
#endif
@ -1337,9 +1337,9 @@ namespace hw::ledger {
auto locks = tools::unique_locks(device_locker, command_locker);
#ifdef DEBUG_HWDEVICE
log_hexbuffer("generate_unlock_signature: [[IN]] pub ", pub.data, 32);
log_hexbuffer("generate_unlock_signature: [[IN]] pub ", pub.data(), 32);
const crypto::secret_key sec_x = decrypt(sec);
log_hexbuffer("generate_unlock_signature: [[IN]] sec ", sec_x.data, 32);
log_hexbuffer("generate_unlock_signature: [[IN]] sec ", sec_x.data(), 32);
#endif
// Ask for confirmation:
@ -1348,8 +1348,8 @@ namespace hw::ledger {
// If we got permission then we can ask for the actual signature:
offset = set_command_header_noopt(INS_GEN_UNLOCK_SIGNATURE, 1);
send_bytes(pub.data, 32, offset);
send_secret(sec.data, offset);
send_bytes(pub.data(), 32, offset);
send_secret(sec.data(), offset);
finish_and_exchange(offset);
receive_bytes(reinterpret_cast<char*>(&sig), 64);
@ -1358,8 +1358,8 @@ namespace hw::ledger {
// We can't check the actual returned signature byte values because a random component is
// involved, but we *can* attempt to verify the signature
bool good = crypto::check_signature(cryptonote::tx_extra_tx_key_image_unlock::HASH, pub, sig);
log_hexbuffer("generate_unlock_signature: signature.c", sig.c.data, 32);
log_hexbuffer("generate_unlock_signature: signature.r", sig.r.data, 32);
log_hexbuffer("generate_unlock_signature: signature.c", sig.c(), 32);
log_hexbuffer("generate_unlock_signature: signature.r", sig.r(), 32);
log_message("generate_unlock_signature: signature returned from device", good ? "passed" : "FAILED");
#endif
@ -1402,39 +1402,39 @@ namespace hw::ledger {
const crypto::public_key D_x = D;
const crypto::secret_key r_x = decrypt(r);
crypto::signature sig_x;
log_hexbuffer("generate_tx_proof: [[IN]] prefix_hash ", prefix_hash_x.data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] R ", R_x.data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] A ", A_x.data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] prefix_hash ", prefix_hash_x.data(), 32);
log_hexbuffer("generate_tx_proof: [[IN]] R ", R_x.data(), 32);
log_hexbuffer("generate_tx_proof: [[IN]] A ", A_x.data(), 32);
if (B_x)
log_hexbuffer("generate_tx_proof: [[IN]] B ", B_x->data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] D ", D_x.data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] r ", r_x.data, 32);
log_hexbuffer("generate_tx_proof: [[IN]] B ", B_x->data(), 32);
log_hexbuffer("generate_tx_proof: [[IN]] D ", D_x.data(), 32);
log_hexbuffer("generate_tx_proof: [[IN]] r ", r_x.data(), 32);
#endif
int offset = set_command_header(INS_GET_TX_PROOF);
//options
buffer_send[offset++] = B ? 0x01 : 0x00;
send_bytes(prefix_hash.data, 32, offset); // prefix_hash
send_bytes(R.data, 32, offset); // R
send_bytes(A.data, 32, offset); // A
send_bytes(B ? B->data : crypto::null_pkey.data, 32, offset); // B
send_bytes(D.data, 32, offset); // D
send_secret(r.data, offset); // r
send_bytes(prefix_hash.data(), 32, offset); // prefix_hash
send_bytes(R.data(), 32, offset); // R
send_bytes(A.data(), 32, offset); // A
send_bytes(B ? B->data() : crypto::null<crypto::public_key>.data(), 32, offset); // B
send_bytes(D.data(), 32, offset); // D
send_secret(r.data(), offset); // r
finish_and_exchange(offset);
offset = 0;
receive_bytes(sig.c.data, 32, offset);
receive_bytes(sig.r.data, 32, offset);
receive_bytes(sig.c(), 32, offset);
receive_bytes(sig.r(), 32, offset);
#ifdef DEBUG_HWDEVICE
log_hexbuffer("GENERATE_TX_PROOF: **c** ", sig.c.data, sizeof(sig.c.data));
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r.data, sizeof(sig.r.data));
log_hexbuffer("GENERATE_TX_PROOF: **c** ", sig.c(), 32);
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r(), 32);
debug_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
log::debug(logcat, "FAIL is normal if random is not fixed in proof");
check32("generate_tx_proof", "c", sig_x.c.data, sig.c.data);
check32("generate_tx_proof", "r", sig_x.r.data, sig.r.data);
check32("generate_tx_proof", "c", sig_x.c(), sig.c());
check32("generate_tx_proof", "r", sig_x.r(), sig.r());
#endif
}
@ -1455,14 +1455,14 @@ namespace hw::ledger {
//skip R, receive: r, r_hmac, fake_a, a_hmac, fake_b, hmac_b
unsigned char tmp[32];
offset = 32;
receive_secret(tx_key.data, offset);
receive_secret(tx_key.data(), offset);
receive_secret(tmp, offset);
receive_secret(tmp, offset);
#ifdef DEBUG_HWDEVICE
const crypto::secret_key r_x = decrypt(tx_key);
log_hexbuffer("open_tx: [[OUT]] R ", buffer_recv, 32);
log_hexbuffer("open_tx: [[OUT]] r ", r_x.data, 32);
log_hexbuffer("open_tx: [[OUT]] r ", r_x.data(), 32);
#endif
return true;
}
@ -1509,7 +1509,9 @@ namespace hw::ledger {
try {
tx_prefix = serialization::dump_binary(const_cast<cryptonote::transaction_prefix&>(tx));
} catch (const std::exception& e) {
ASSERT_MES_AND_THROW("unable to serialize transaction prefix: " << e.what());
auto err = "unable to serialize transaction prefix: "_format(e.what());
log::error(logcat, err);
throw std::runtime_error{err};
}
unsigned char* send = buffer_send + set_command_header_noopt(INS_PREFIX_HASH, 1);
@ -1533,10 +1535,10 @@ namespace hw::ledger {
// hash the full prefix
exchange_multipart_data(INS_PREFIX_HASH, 2, tx_prefix, KECCAK_HASH_CHUNK_SIZE);
receive_bytes(h.data, 32);
receive_bytes(h.data(), 32);
#ifdef DEBUG_HWDEVICE
check8("prefix_hash", "h", h_x.data, h.data);
check8("prefix_hash", "h", h_x.data(), h.data());
#endif
}
@ -1545,24 +1547,24 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
const crypto::secret_key secret_key_x = decrypt(secret_key);
log_hexbuffer("encrypt_payment_id: [[IN]] payment_id ", payment_id.data, 32);
log_hexbuffer("encrypt_payment_id: [[IN]] public_key ", public_key.data, 32);
log_hexbuffer("encrypt_payment_id: [[IN]] secret_key ", secret_key_x.data, 32);
log_hexbuffer("encrypt_payment_id: [[IN]] payment_id ", payment_id.data(), 32);
log_hexbuffer("encrypt_payment_id: [[IN]] public_key ", public_key.data(), 32);
log_hexbuffer("encrypt_payment_id: [[IN]] secret_key ", secret_key_x.data(), 32);
crypto::hash8 payment_id_x = payment_id;
debug_device->encrypt_payment_id(payment_id_x, public_key, secret_key_x);
log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data, 32);
log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data(), 32);
#endif
int offset = set_command_header_noopt(INS_ENCRYPT_PAYMENT_ID);
send_bytes(public_key.data, 32, offset); // pub
send_secret(secret_key.data, offset); //sec
send_bytes(payment_id.data, 8, offset); //id
send_bytes(public_key.data(), 32, offset); // pub
send_secret(secret_key.data(), offset); //sec
send_bytes(payment_id.data(), 8, offset); //id
finish_and_exchange(offset);
receive_bytes(payment_id.data, 8);
receive_bytes(payment_id.data(), 8);
#ifdef DEBUG_HWDEVICE
check8("stealth", "payment_id", payment_id_x.data, payment_id.data);
check8("stealth", "payment_id", payment_id_x.data(), payment_id.data());
#endif
return true;
@ -1588,7 +1590,7 @@ namespace hw::ledger {
#ifdef DEBUG_HWDEVICE
cryptonote::account_keys sender_account_keys_x = decrypt(sender_account_keys);
std::memmove(sender_account_keys_x.m_view_secret_key.data, dbg_viewkey.data, 32);
std::memmove(sender_account_keys_x.m_view_secret_key.data(), dbg_viewkey.data(), 32);
const crypto::secret_key tx_key_x = decrypt(tx_key);
@ -1598,20 +1600,20 @@ namespace hw::ledger {
}
log_message("generate_output_ephemeral_keys: [[IN]] tx_version", std::to_string(tx_version));
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.view", sender_account_keys.m_sview_secret_key.data, 32);
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.spend", sender_account_keys.m_spend_secret_key.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] txkey_pub", txkey_pub.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] tx_key", tx_key_x.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.view", dst_entr.addr.m_view_public_key.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.spend", dst_entr.addr.m_spend_public_key.data, 32);
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.view", sender_account_keys.m_sview_secret_key.data(), 32);
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.spend", sender_account_keys.m_spend_secret_key.data(), 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] txkey_pub", txkey_pub.data(), 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] tx_key", tx_key_x.data(), 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.view", dst_entr.addr.m_view_public_key.data(), 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.spend", dst_entr.addr.m_spend_public_key.data(), 32);
if (change_addr) {
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.view", change_addr->addr.m_view_public_key.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.spend", change_addr->addr.m_spend_public_key.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.view", change_addr->addr.m_view_public_key.data(), 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.spend", change_addr->addr.m_spend_public_key.data(), 32);
}
log_message("generate_output_ephemeral_keys: [[IN]] output_index", std::to_string(output_index));
log_message("generate_output_ephemeral_keys: [[IN]] need_additional_txkeys", std::to_string(need_additional_txkeys));
if (need_additional_txkeys) {
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data(), 32);
}
std::vector<crypto::public_key> additional_tx_public_keys_x;
std::vector<rct::key> amount_keys_x;
@ -1619,10 +1621,10 @@ namespace hw::ledger {
debug_device->generate_output_ephemeral_keys(tx_version, found_change, sender_account_keys_x, txkey_pub, tx_key_x, dst_entr, change_addr, output_index, need_additional_txkeys, additional_tx_keys_x,
additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x);
if(need_additional_txkeys) {
log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data, 32);
log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data(), 32);
}
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] amount_keys ", amount_keys_x.back().bytes, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data, 32);
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data(), 32);
#endif
CHECK_AND_ASSERT_THROW_MES(tx_version > 1, "TX version not supported"<<tx_version);
@ -1640,17 +1642,17 @@ namespace hw::ledger {
int offset = set_command_header_noopt(INS_GEN_TXOUT_KEYS);
send_u32(tx_version, offset); //tx_version
send_secret(tx_key.data, offset); //tx_key
send_bytes(txkey_pub.data, 32, offset); //txkey_pub
send_bytes(dst_entr.addr.m_view_public_key.data, 32, offset); //Aout
send_bytes(dst_entr.addr.m_spend_public_key.data, 32, offset); //Bout
send_secret(tx_key.data(), offset); //tx_key
send_bytes(txkey_pub.data(), 32, offset); //txkey_pub
send_bytes(dst_entr.addr.m_view_public_key.data(), 32, offset); //Aout
send_bytes(dst_entr.addr.m_spend_public_key.data(), 32, offset); //Bout
send_u32(output_index, offset); //output index
buffer_send[offset++] = is_change; //is_change
buffer_send[offset++] = dst_entr.is_subaddress; //is_subaddress
buffer_send[offset++] = need_additional_txkeys; //need_additional_key
//additional_tx_key
if (need_additional_txkeys)
send_secret(additional_txkey.sec.data, offset);
send_secret(additional_txkey.sec.data(), offset);
finish_and_exchange(offset);
@ -1661,18 +1663,18 @@ namespace hw::ledger {
{
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
crypto::secret_key scalar1;
receive_secret(scalar1.data, offset);
receive_secret(scalar1.data(), offset);
amount_keys.push_back(rct::sk2rct(scalar1));
recv_len -= 32;
}
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
receive_bytes(out_eph_public_key.data, 32, offset);
receive_bytes(out_eph_public_key.data(), 32, offset);
recv_len -= 32;
if (need_additional_txkeys)
{
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
receive_bytes(additional_txkey.pub.data, 32, offset);
receive_bytes(additional_txkey.pub.data(), 32, offset);
additional_tx_public_keys.push_back(additional_txkey.pub);
recv_len -= 32;
}
@ -1687,9 +1689,9 @@ namespace hw::ledger {
log_hexbuffer("generate_output_ephemeral_keys: clear amount_key", amount_back.bytes, 32);
check32("generate_output_ephemeral_keys", "amount_key", amount_keys_x.back().bytes, amount_back.bytes);
if (need_additional_txkeys) {
check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data, additional_tx_public_keys.back().data);
check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data(), additional_tx_public_keys.back().data());
}
check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data);
check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data(), out_eph_public_key.data());
#endif
return true;
@ -1841,10 +1843,10 @@ namespace hw::ledger {
send_secret(outKeys.AKout.bytes, offset); //AKout
send_bytes(&data[C_offset], 32, offset); //C
C_offset += 32;
send_bytes(crypto::null_hash.data, 32, offset); // k
send_bytes(crypto::null<crypto::hash>.data(), 32, offset); // k
send_bytes(&data[kv_offset], 8, offset); // v
kv_offset += 8;
send_bytes(crypto::null_hash.data, 24, offset); // v padding
send_bytes(crypto::null<crypto::hash>.data(), 24, offset); // v padding
// check transaction user input
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Transaction denied on device.");
@ -1983,7 +1985,7 @@ namespace hw::ledger {
// This will fail if this isn't an open stake tx.
send_simple(INS_GET_TX_SECRET_KEY);
// The ledger provides us with the (unencrypted) tx secret key if we're allowed to have it
receive_bytes(key.data, 32);
receive_bytes(key.data(), 32);
return true;
}

View File

@ -371,7 +371,7 @@ namespace
* \param language_name Seed language name
* \return true if successful false if not. Unsuccessful if wrong key size.
*/
bool bytes_to_words(const char *src, size_t len, epee::wipeable_string& words,
bool bytes_to_words(const unsigned char *src, size_t len, epee::wipeable_string& words,
const std::string &language_name)
{
@ -424,14 +424,14 @@ namespace
bool bytes_to_words(const crypto::secret_key& src, epee::wipeable_string& words,
const std::string &language_name)
{
return bytes_to_words(src.data, sizeof(src), words, language_name);
return bytes_to_words(src.data(), src.size(), words, language_name);
}
std::string bytes_to_words(const crypto::secret_key& src,
const std::string &language_name)
{
epee::wipeable_string epee_words;
if (!bytes_to_words(src.data, sizeof(src), epee_words, language_name))
if (!bytes_to_words(src.data(), src.size(), epee_words, language_name))
throw std::runtime_error("Failed to create seed from key for language: " + language_name);
return std::string(epee_words.view());
}

View File

@ -91,7 +91,7 @@ namespace crypto
* \param language_name Seed language name
* \return true if successful false if not. Unsuccessful if wrong key size.
*/
bool bytes_to_words(const char *src, size_t len, epee::wipeable_string& words,
bool bytes_to_words(const unsigned char *src, size_t len, epee::wipeable_string& words,
const std::string &language_name);
/*!

View File

@ -81,7 +81,7 @@ namespace cryptonote
crypto::secret_key msk = get_multisig_blinded_secret_key(rct::rct2sk(sk));
memwipe(&sk, sizeof(sk));
multisig_keys.push_back(msk);
sc_add(spend_skey.bytes, spend_skey.bytes, (const unsigned char*)msk.data);
sc_add(spend_skey.bytes, spend_skey.bytes, msk.data());
}
}
//-----------------------------------------------------------------
@ -103,7 +103,7 @@ namespace cryptonote
rct::key secret_key = rct::zero();
for (const auto &k: multisig_keys)
{
sc_add(secret_key.bytes, secret_key.bytes, (const unsigned char*)k.data);
sc_add(secret_key.bytes, secret_key.bytes, k.data());
}
return rct::rct2sk(secret_key);
@ -126,7 +126,7 @@ namespace cryptonote
{
crypto::secret_key view_skey = get_multisig_blinded_secret_key(skey);
for (const auto &k: skeys)
sc_add(reinterpret_cast<unsigned char*>(view_skey.data), rct::sk2rct(view_skey).bytes, rct::sk2rct(k).bytes);
sc_add(view_skey.data(), rct::sk2rct(view_skey).bytes, rct::sk2rct(k).bytes);
return view_skey;
}
//-----------------------------------------------------------------

View File

@ -37,8 +37,6 @@
#include <cstddef>
#include <tuple>
#include "crypto/generic-ops.h"
extern "C" {
#include "crypto/random.h"
#include "crypto/keccak.h"

View File

@ -36,8 +36,6 @@
#include <vector>
#include <tuple>
#include "crypto/generic-ops.h"
extern "C" {
#include "crypto/random.h"
#include "crypto/keccak.h"

View File

@ -40,7 +40,6 @@ extern "C" {
#include "crypto/random.h"
#include "crypto/keccak.h"
}
#include "crypto/generic-ops.h"
#include "crypto/crypto.h"
#include "common/hex.h"

View File

@ -347,8 +347,7 @@ namespace cryptonote::rpc {
res.blocks.back().txs.reserve(bd.second.size());
for (auto& [txhash, txdata] : bd.second)
{
auto& entry = res.blocks.back().txs.emplace_back(std::move(txdata), crypto::null_hash);
size += entry.size();
size += res.blocks.back().txs.emplace_back(std::move(txdata)).size();
}
const size_t n_txes_to_lookup = bd.second.size() + (req.no_miner_tx ? 0 : 1);
@ -876,7 +875,7 @@ namespace cryptonote::rpc {
// If the transaction was pruned then the prunable part will be empty but the prunable hash
// will be non-null. (Some txes, like coinbase txes, are non-prunable and will have empty
// *and* null prunable hash).
bool prunable = prunable_hash != crypto::null_hash;
bool prunable = (bool) prunable_hash;
bool pruned = prunable && prunable_data.empty();
if (pruned || (prunable && (get.request.split || get.request.prune)))
@ -1972,8 +1971,8 @@ namespace cryptonote::rpc {
std::mutex mutex;
std::vector<std::uint64_t> cached_distribution;
std::uint64_t cached_from = 0, cached_to = 0, cached_start_height = 0, cached_base = 0;
crypto::hash cached_m10_hash = crypto::null_hash;
crypto::hash cached_top_hash = crypto::null_hash;
crypto::hash cached_m10_hash{};
crypto::hash cached_top_hash{};
bool cached = false;
} output_dist_cache;
}
@ -1991,7 +1990,7 @@ namespace cryptonote::rpc {
auto& d = output_dist_cache;
const std::unique_lock lock{d.mutex};
crypto::hash top_hash = crypto::null_hash;
crypto::hash top_hash{};
if (d.cached_to < blockchain_height)
top_hash = get_hash(d.cached_to);
if (d.cached && amount == 0 && d.cached_from == from_height && d.cached_to == to_height && d.cached_top_hash == top_hash)
@ -2013,7 +2012,7 @@ namespace cryptonote::rpc {
{
d.cached_to -= 10;
d.cached_top_hash = hash10;
d.cached_m10_hash = crypto::null_hash;
d.cached_m10_hash = crypto::null<crypto::hash>;
CHECK_AND_ASSERT_MES(d.cached_distribution.size() >= 10, std::nullopt, "Cached distribution size does not match cached bounds");
for (int p = 0; p < 10; ++p)
d.cached_distribution.pop_back();
@ -2051,7 +2050,7 @@ namespace cryptonote::rpc {
d.cached_from = from_height;
d.cached_to = to_height;
d.cached_top_hash = get_hash(d.cached_to);
d.cached_m10_hash = d.cached_to >= 10 ? get_hash(d.cached_to - 10) : crypto::null_hash;
d.cached_m10_hash = d.cached_to >= 10 ? get_hash(d.cached_to - 10) : crypto::null<crypto::hash>;
d.cached_distribution = distribution;
d.cached_start_height = start_height;
d.cached_base = base;
@ -2368,10 +2367,10 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_SERVICE_PRIVKEYS& get_service_privkeys, rpc_context context)
{
const auto& keys = m_core.get_service_keys();
if (keys.key != crypto::null_skey)
get_service_privkeys.response["service_node_privkey"] = tools::type_to_hex(keys.key.data);
get_service_privkeys.response["service_node_ed25519_privkey"] = tools::type_to_hex(keys.key_ed25519.data);
get_service_privkeys.response["service_node_x25519_privkey"] = tools::type_to_hex(keys.key_x25519.data);
if (keys.key)
get_service_privkeys.response["service_node_privkey"] = tools::type_to_hex(keys.key);
get_service_privkeys.response["service_node_ed25519_privkey"] = tools::type_to_hex(keys.key_ed25519);
get_service_privkeys.response["service_node_x25519_privkey"] = tools::type_to_hex(keys.key_x25519);
get_service_privkeys.response["status"] = STATUS_OK;
return;
}

View File

@ -1823,7 +1823,7 @@ namespace cryptonote::rpc {
/// If specified then only return results if the current top block hash is different than the
/// hash given here. This is intended to allow quick polling of results without needing to do
/// anything if the block (and thus SN registrations) have not changed since the last request.
crypto::hash poll_block_hash = crypto::hash::null();
crypto::hash poll_block_hash{};
} request;
};

View File

@ -174,7 +174,7 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
{
crypto::x25519_public_key my_pubkey;
const std::string& pk = omq.get_pubkey();
std::copy(pk.begin(), pk.end(), my_pubkey.data);
std::copy(pk.begin(), pk.end(), my_pubkey.data());
auth.emplace(std::move(my_pubkey), AuthLevel::admin);
}
@ -311,7 +311,7 @@ void omq_rpc::send_block_notifications(const block& block)
auto& omq = core_.get_omq();
std::string height = "{}"_format(get_block_height(block));
send_notifies(subs_mutex_, block_subs_, "block", [&](auto& conn, auto& sub) {
omq.send(conn, "notify.block", height, std::string_view{block.hash.data, sizeof(block.hash.data)});
omq.send(conn, "notify.block", height, tools::view_guts(block.hash));
});
}
@ -320,7 +320,7 @@ void omq_rpc::send_mempool_notifications(const crypto::hash& id, const transacti
auto& omq = core_.get_omq();
send_notifies(subs_mutex_, mempool_subs_, "mempool", [&](auto& conn, auto& sub) {
if (sub.type == mempool_sub_type::all || opts.approved_blink)
omq.send(conn, "notify.mempool", std::string_view{id.data, sizeof(id.data)}, blob);
omq.send(conn, "notify.mempool", tools::view_guts(id), blob);
});
}
@ -413,7 +413,7 @@ void omq_rpc::on_get_blocks(oxenmq::Message& m)
return;
}
block_bt["hash"] = std::string_view{hash.data, sizeof(hash.data)};
block_bt["hash"] = tools::view_guts(hash);
block_bt["height"] = i;
block_bt["timestamp"] = b.timestamp;
@ -442,7 +442,7 @@ void omq_rpc::on_get_blocks(oxenmq::Message& m)
}
tx_bt["global_indices"] = bt_list(indices.begin(), indices.end());
tx_bt["hash"] = std::string{miner_tx_hash.data, sizeof(miner_tx_hash.data)};
tx_bt["hash"] = std::string{tools::view_guts(miner_tx_hash)};
tx_bt["tx"] = tx_to_blob(b.miner_tx);
tx_list_bt.push_back(std::move(tx_bt));
@ -463,7 +463,7 @@ void omq_rpc::on_get_blocks(oxenmq::Message& m)
}
tx_bt["global_indices"] = bt_list(indices.begin(), indices.end());
tx_bt["hash"] = std::string{txhash.data, sizeof(txhash.data)};
tx_bt["hash"] = std::string{tools::view_guts(txhash)};
tx_bt["tx"] = std::move(txs[tx_index]);
tx_list_bt.push_back(std::move(tx_bt));

View File

@ -523,7 +523,7 @@ namespace
}
catch (const tools::error::tx_rejected& e)
{
fail_msg_writer() << (boost::format(sw::tr("transaction %s was rejected by daemon")) % get_transaction_hash(e.tx())).str();
fail_msg_writer() << (boost::format(sw::tr("transaction %s was rejected by daemon")) % "{}"_format(get_transaction_hash(e.tx()))).str();
std::string reason = e.reason();
if (!reason.empty())
fail_msg_writer() << sw::tr("Reason: ") << reason;
@ -585,9 +585,8 @@ namespace
void print_secret_key(const crypto::secret_key &k)
{
std::string_view data{k.data, sizeof(k.data)};
std::ostream_iterator<char> osi{std::cout};
oxenc::to_hex(data.begin(), data.end(), osi);
oxenc::to_hex(k.begin(), k.end(), osi);
}
bool long_payment_id_failure(bool ret)
@ -3551,7 +3550,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{
crypto::secret_key key;
crypto::cn_slow_hash(seed_pass.data(), seed_pass.size(), (crypto::hash&)key, crypto::cn_slow_hash_type::heavy_v1);
sc_reduce32((unsigned char*)key.data);
sc_reduce32(key.data());
multisig_keys = m_wallet->decrypt(std::string(multisig_keys.data(), multisig_keys.size()), key, true);
}
else
@ -4795,7 +4794,7 @@ void simple_wallet::on_money_received(uint64_t height, const crypto::hash &txid,
parse_tx_extra(tx.extra, tx_extra_fields); // failure ok
tx_extra_nonce extra_nonce;
tx_extra_pub_key extra_pub_key;
crypto::hash8 payment_id8 = crypto::null_hash8;
crypto::hash8 payment_id8{};
if (find_tx_extra_field_by_type(tx_extra_fields, extra_pub_key))
{
const crypto::public_key &tx_pub_key = extra_pub_key.pub_key;
@ -4808,11 +4807,11 @@ void simple_wallet::on_money_received(uint64_t height, const crypto::hash &txid,
}
}
if (payment_id8 != crypto::null_hash8)
if (payment_id8)
message_writer() <<
tr("NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead");
crypto::hash payment_id = crypto::null_hash;
crypto::hash payment_id{};
if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
message_writer(fmt::terminal_color::red) <<
tr("WARNING: this transaction uses an unencrypted payment ID: these are obsolete and ignored. Use subaddresses instead.");
@ -5227,7 +5226,11 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
}
std::string extra_string;
if (verbose)
extra_string += (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? tools::type_to_hex(td.m_key_image) : td.m_key_image_partial ? (tools::type_to_hex(td.m_key_image) + "/p") : std::string(64, '?'))).str();
extra_string += "{:68}{:68}"_format(
td.get_public_key(),
(td.m_key_image_known ? tools::type_to_hex(td.m_key_image) :
td.m_key_image_partial ? tools::type_to_hex(td.m_key_image) + "/p" :
std::string(64, '?')));
if (uses)
{
std::vector<uint64_t> heights;
@ -5242,15 +5245,15 @@ bool simple_wallet::show_incoming_transfers(const std::vector<std::string>& args
extra_string += std::string("\n ") + tr("Used at heights: ") + line.first + "\n " + line.second;
}
message_writer(td.m_spent ? fmt::terminal_color::magenta : fmt::terminal_color::green) <<
boost::format("%21s%8s%12s%8s%16u%68s%16u%s") %
print_money(td.amount()) %
(td.m_spent ? tr("T") : tr("F")) %
(m_wallet->frozen(td) ? tr("[frozen]") : m_wallet->is_transfer_unlocked(td) ? tr("unlocked") : tr("locked")) %
(td.is_rct() ? tr("RingCT") : tr("-")) %
td.m_global_output_index %
td.m_txid %
td.m_subaddr_index.minor %
extra_string;
"{:21}{:8}{:12}{:8}{:16d}{:68s}{:16d}{}"_format(
print_money(td.amount()),
td.m_spent ? tr("T") : tr("F"),
tr(m_wallet->frozen(td) ? "[frozen]" : m_wallet->is_transfer_unlocked(td) ? "unlocked" : "locked"),
tr(td.is_rct() ? "RingCT" : "-"),
td.m_global_output_index,
td.m_txid,
td.m_subaddr_index.minor,
extra_string);
++transfers_found;
}
}
@ -5290,8 +5293,9 @@ bool simple_wallet::show_payments(const std::vector<std::string> &args)
rdln::suspend_readline pause_readline;
message_writer() << boost::format("%68s%68s%12s%21s%16s%16s") %
tr("payment") % tr("transaction") % tr("height") % tr("amount") % tr("unlock time") % tr("addr index");
constexpr auto payment_format = "{:68}{:68}{:12}{:21}{:16}{:16}"sv;
message_writer() << fmt::format(payment_format,
tr("payment"), tr("transaction"), tr("height"), tr("amount"), tr("unlock time"), tr("addr index"));
bool payments_found = false;
for(std::string arg : args)
@ -5313,14 +5317,13 @@ bool simple_wallet::show_payments(const std::vector<std::string> &args)
{
payments_found = true;
}
success_msg_writer(true) <<
boost::format("%68s%68s%12s%21s%16s%16s") %
payment_id %
pd.m_tx_hash %
pd.m_block_height %
print_money(pd.m_amount) %
pd.m_unlock_time %
pd.m_subaddr_index.minor;
success_msg_writer(true) << fmt::format(payment_format,
payment_id,
pd.m_tx_hash,
pd.m_block_height,
print_money(pd.m_amount),
pd.m_unlock_time,
pd.m_subaddr_index.minor);
}
}
else
@ -5503,7 +5506,7 @@ bool simple_wallet::process_ring_members(const std::vector<tools::wallet2::pendi
const cryptonote::transaction& tx = ptx_vector[n].tx;
const wallet::tx_construction_data& construction_data = ptx_vector[n].construction_data;
if (verbose)
ostr << boost::format(tr("\nTransaction %llu/%llu: txid=%s")) % (n + 1) % ptx_vector.size() % cryptonote::get_transaction_hash(tx);
ostr << boost::format(tr("\nTransaction %llu/%llu: txid=%s")) % (n + 1) % ptx_vector.size() % "{}"_format(cryptonote::get_transaction_hash(tx));
// for each input
std::vector<uint64_t> spent_key_height(tx.vin.size());
std::vector<crypto::hash> spent_key_txid (tx.vin.size());
@ -7778,7 +7781,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
std::vector<tx_extra_field> tx_extra_fields;
bool has_encrypted_payment_id = false;
crypto::hash8 payment_id8 = crypto::null_hash8;
crypto::hash8 payment_id8{};
if (cryptonote::parse_tx_extra(cd.extra, tx_extra_fields))
{
tx_extra_nonce extra_nonce;

View File

@ -138,7 +138,7 @@ bool PendingTransactionImpl::commit(std::string_view filename_, bool overwrite,
m_status = {Status_Error, tr("no connection to daemon. Please make sure daemon is running.")};
} catch (const tools::error::tx_rejected& e) {
m_status.first = Status_Error;
m_status.second += (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())).str();
m_status.second += (boost::format(tr("transaction %s was rejected by daemon with status: ")) % "{}"_format(get_transaction_hash(e.tx()))).str();
m_status.second += e.status();
if (auto& reason = e.reason(); !reason.empty())
m_status.second += tr(". Reason: ") + reason;

View File

@ -101,7 +101,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu
std::vector<cryptonote::tx_extra_field> tx_extra_fields;
bool has_encrypted_payment_id = false;
crypto::hash8 payment_id8 = crypto::null_hash8;
crypto::hash8 payment_id8{};
if (cryptonote::parse_tx_extra(cd.extra, tx_extra_fields))
{
cryptonote::tx_extra_nonce extra_nonce;
@ -255,24 +255,24 @@ std::vector<std::string> UnsignedTransactionImpl::paymentId() const
{
std::vector<std::string> result;
for (const auto &utx: m_unsigned_tx_set.txes) {
crypto::hash payment_id = crypto::null_hash;
crypto::hash payment_id{};
cryptonote::tx_extra_nonce extra_nonce;
std::vector<cryptonote::tx_extra_field> tx_extra_fields;
cryptonote::parse_tx_extra(utx.extra, tx_extra_fields);
if (cryptonote::find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
{
crypto::hash8 payment_id8 = crypto::null_hash8;
crypto::hash8 payment_id8{};
if(cryptonote::get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
{
// We can't decrypt short pid without recipient key.
memcpy(payment_id.data, payment_id8.data, 8);
memcpy(payment_id.data(), payment_id8.data(), payment_id8.size());
}
else if (!cryptonote::get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
{
payment_id = crypto::null_hash;
payment_id.zero();
}
}
if(payment_id != crypto::null_hash)
if (payment_id)
result.push_back(tools::type_to_hex(payment_id));
else
result.push_back("");

View File

@ -50,6 +50,7 @@
#include "mnemonics/electrum-words.h"
#include "mnemonics/english.h"
#include <boost/format.hpp>
#include <cinttypes>
#include <sstream>
#include <unordered_map>
#include <thread>
@ -1703,7 +1704,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<std:
setStatusError(tr("transaction was not constructed"));
} catch (const tools::error::tx_rejected& e) {
std::ostringstream writer;
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % "{}"_format(get_transaction_hash(e.tx()))) << e.status();
setStatusError(writer.str());
} catch (const tools::error::tx_sum_overflow& e) {
setStatusError(e.what());
@ -1795,7 +1796,7 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
setStatusError(tr("transaction was not constructed"));
} catch (const tools::error::tx_rejected& e) {
std::ostringstream writer;
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % "{}"_format(get_transaction_hash(e.tx()))) << e.status();
setStatusError(writer.str());
} catch (const tools::error::tx_sum_overflow& e) {
setStatusError(e.what());

View File

@ -401,8 +401,8 @@ void message_store::stop_auto_config()
m_transporter.delete_transport_address(m.auto_config_transport_address);
}
m.auto_config_token.clear();
m.auto_config_public_key = crypto::null_pkey;
m.auto_config_secret_key = crypto::null_skey;
m.auto_config_public_key.zero();
m.auto_config_secret_key.zero();
m.auto_config_transport_address.clear();
m.auto_config_running = false;
}
@ -532,7 +532,7 @@ size_t message_store::add_message(const multisig_wallet_state &state,
m.round = 0;
}
m.signature_count = 0; // Future expansion for signature counting when signing txs
m.hash = crypto::null_hash;
m.hash = crypto::null<crypto::hash>;
m_messages.push_back(m);
// Save for every new message right away (at least while in beta)

View File

@ -139,8 +139,8 @@ namespace mms
memset(&monero_address, 0, sizeof(cryptonote::account_public_address));
me = false;
index = 0;
auto_config_public_key = crypto::null_pkey;
auto_config_secret_key = crypto::null_skey;
auto_config_public_key.zero();
auto_config_secret_key.zero();
auto_config_running = false;
};
};

View File

@ -116,7 +116,7 @@ crypto::chacha_iv make_iv(const crypto::key_image &key_image, const crypto::chac
memcpy(buffer + sizeof(key_image) + sizeof(key) + cryptonote::hashkey::RINGDB.size(), &field, sizeof(field));
crypto::hash hash;
// if field is 0, backward compat mode: hash without the field
crypto::cn_fast_hash(buffer, sizeof(buffer) - !field, hash.data);
crypto::cn_fast_hash(buffer, sizeof(buffer) - !field, hash.data());
static_assert(sizeof(hash) >= CHACHA_IV_SIZE, "Incompatible hash and chacha IV sizes");
crypto::chacha_iv iv;
memcpy(&iv, &hash, CHACHA_IV_SIZE);

View File

@ -560,7 +560,7 @@ std::pair<std::unique_ptr<tools::wallet2>, tools::password_container> generate_f
if(!tools::hex_to_type(field_viewkey, viewkey))
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse view key secret key"));
crypto::public_key pkey;
if (viewkey == crypto::null_skey)
if (!viewkey)
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("view secret key may not be all zeroes"));
if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key"));
@ -574,7 +574,7 @@ std::pair<std::unique_ptr<tools::wallet2>, tools::password_container> generate_f
if(!tools::hex_to_type(field_spendkey, spendkey))
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse spend key secret key"));
crypto::public_key pkey;
if (spendkey == crypto::null_skey)
if (!spendkey)
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("spend secret key may not be all zeroes"));
if (!crypto::secret_key_to_public_key(spendkey, pkey)) {
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key"));
@ -851,7 +851,7 @@ bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pend
wallet::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
{
wallet::tx_construction_data construction_data = ptx.construction_data;
crypto::hash8 payment_id = null_hash8;
crypto::hash8 payment_id{};
if (get_short_payment_id(payment_id, ptx, hwdev))
{
// Remove encrypted
@ -1101,7 +1101,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_multisig(false),
m_multisig_threshold(0),
m_node_rpc_proxy(m_http_client),
m_account_public_address{crypto::null_pkey, crypto::null_pkey},
m_account_public_address{crypto::null<crypto::public_key>, crypto::null<crypto::public_key>},
m_subaddress_lookahead_major(SUBADDRESS_LOOKAHEAD_MAJOR),
m_subaddress_lookahead_minor(SUBADDRESS_LOOKAHEAD_MINOR),
m_original_keys_available(false),
@ -1310,7 +1310,7 @@ bool wallet2::is_deterministic() const
crypto::secret_key second;
keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key));
sc_reduce32((uint8_t *)&second);
return memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0;
return second == get_account().get_keys().m_view_secret_key;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase) const
@ -1382,7 +1382,7 @@ bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeabl
{
crypto::secret_key key;
crypto::cn_slow_hash(passphrase.data(), passphrase.size(), (crypto::hash&)key, crypto::cn_slow_hash_type::heavy_v1);
sc_reduce32((unsigned char*)key.data);
sc_reduce32(key.data());
data = encrypt(data.view(), key, true);
}
@ -1394,7 +1394,7 @@ bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeabl
}
else
{
if (!crypto::ElectrumWords::bytes_to_words(data.data(), data.size(), seed, seed_language))
if (!crypto::ElectrumWords::bytes_to_words(reinterpret_cast<const unsigned char*>(data.data()), data.size(), seed, seed_language))
{
std::cout << "Failed to encode seed";
return false;
@ -1772,7 +1772,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
if (m_multisig)
{
tx_scan_info.in_ephemeral.pub = var::get<cryptonote::txout_to_key>(tx.vout[vout_index].target).key;
tx_scan_info.in_ephemeral.sec = crypto::null_skey;
tx_scan_info.in_ephemeral.sec.zero();
tx_scan_info.ki = rct::rct2ki(rct::zero());
}
else
@ -1874,7 +1874,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
// i.e. duplicated key images
std::vector<tx_money_got_in_out> tx_money_got_in_outs;
tx_money_got_in_outs.reserve(tx.vout.size());
crypto::public_key tx_pub_key = null_pkey;
crypto::public_key tx_pub_key = crypto::null<crypto::public_key>;
bool notify = false;
std::vector<tx_extra_field> local_tx_extra_fields;
@ -2426,19 +2426,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
just_confirmed->m_change = sub_change;
// create payment_details for each incoming transfer to a subaddress index
crypto::hash payment_id = null_hash;
crypto::hash payment_id{};
if (tx_money_got_in_outs.size() > 0 || earliest_blink_got_mined_transfers_index != NO_BLINK_MINED_INDEX)
{
tx_extra_nonce extra_nonce;
if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
{
crypto::hash8 payment_id8 = null_hash8;
crypto::hash8 payment_id8{};
if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
{
// We got a payment ID to go with this tx
log::debug(logcat, "Found encrypted payment ID: {}", payment_id8);
log::info(logcat, "Consider using subaddresses instead of encrypted payment IDs");
if (tx_pub_key != null_pkey)
if (tx_pub_key)
{
if (!m_account.get_device().decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key))
{
@ -2447,10 +2447,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
else
{
log::debug(logcat, "Decrypted payment ID: {}", payment_id8);
// put the 64 bit decrypted payment id in the first 8 bytes
memcpy(payment_id.data, payment_id8.data, 8);
// rest is already 0, but guard against code changes above
memset(payment_id.data + 8, 0, 24);
payment_id = payment_id8;
}
}
else
@ -2465,7 +2462,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
{
log::debug(logcat, "Found unencrypted payment ID in tx {} (ignored)", txid);
log::warning(logcat, "Found OBSOLETE AND IGNORED unencrypted payment ID: these are bad for privacy, use subaddresses instead");
payment_id = crypto::null_hash;
payment_id = null<hash>;
}
else
{
@ -3074,7 +3071,7 @@ bool wallet2::long_poll_pool_state()
THROW_WALLET_EXCEPTION_IF(res.status == rpc::STATUS_BUSY, error::daemon_busy, "get_transaction_pool_hashes.bin");
THROW_WALLET_EXCEPTION_IF(res.status != rpc::STATUS_OK, error::get_tx_pool_error, res.status);
crypto::hash checksum = crypto::null_hash;
crypto::hash checksum{};
for (crypto::hash const &hash : res.tx_hashes)
checksum ^= hash;
{
@ -3082,7 +3079,7 @@ bool wallet2::long_poll_pool_state()
m_long_poll_tx_pool_checksum = checksum;
}
return checksum != crypto::null_hash;
return (bool) checksum;
}
void wallet2::cancel_long_poll()
@ -3337,7 +3334,7 @@ void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height,
// we will drop all these, so don't bother getting them
uint64_t missing_blocks = checkpoint_height - m_blockchain.size();
while (missing_blocks-- > 0)
m_blockchain.push_back(crypto::null_hash); // maybe a bit suboptimal, but deque won't do huge reallocs like vector
m_blockchain.push_back(null<hash>); // maybe a bit suboptimal, but deque won't do huge reallocs like vector
m_blockchain.push_back(checkpoint_hash);
m_blockchain.trim(checkpoint_height);
m_cached_height = m_blockchain.size();
@ -3399,7 +3396,7 @@ bool wallet2::add_address_book_row(const cryptonote::account_public_address &add
wallet2::address_book_row a;
a.m_address = address;
a.m_has_payment_id = !!payment_id;
a.m_payment_id = payment_id ? *payment_id : crypto::null_hash8;
a.m_payment_id = payment_id ? *payment_id : null<hash8>;
a.m_description = description;
a.m_is_subaddress = is_subaddress;
@ -3415,7 +3412,7 @@ bool wallet2::set_address_book_row(size_t row_id, const cryptonote::account_publ
wallet2::address_book_row a;
a.m_address = address;
a.m_has_payment_id = !!payment_id;
a.m_payment_id = payment_id ? *payment_id : crypto::null_hash8;
a.m_payment_id = payment_id ? *payment_id : null<hash8>;
a.m_description = description;
a.m_is_subaddress = is_subaddress;
@ -3461,7 +3458,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
blocks_fetched = 0;
uint64_t added_blocks = 0;
size_t try_count = 0;
crypto::hash last_tx_hash_id = m_transfers.size() ? m_transfers.back().m_txid : null_hash;
crypto::hash last_tx_hash_id = m_transfers.size() ? m_transfers.back().m_txid : null<hash>;
std::list<crypto::hash> short_chain_history;
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool::waiter waiter;
@ -3623,7 +3620,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
}
}
}
if(last_tx_hash_id != (m_transfers.size() ? m_transfers.back().m_txid : null_hash))
if(last_tx_hash_id != (m_transfers.size() ? m_transfers.back().m_txid : null<hash>))
received_money = true;
uint64_t immutable_height = 0;
@ -5048,7 +5045,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
auto derivations = cryptonote::generate_multisig_derivations(get_account().get_keys(), spend_keys);
spend_pkey = rct::identity();
multisig_signers = std::vector<crypto::public_key>(spend_keys.size() + 1, crypto::null_pkey);
multisig_signers = std::vector<crypto::public_key>(spend_keys.size() + 1, crypto::null<crypto::public_key>);
if (threshold == spend_keys.size())
{
@ -5364,7 +5361,7 @@ bool wallet2::unpack_extra_multisig_info(const std::vector<std::string>& info,
std::unordered_set<crypto::public_key> &pkeys) const
{
// parse all multisig info
signers.resize(info.size(), crypto::null_pkey);
signers.resize(info.size(), crypto::null<crypto::public_key>);
for (size_t i = 0; i < info.size(); ++i)
{
if (!verify_extra_multisig_info(info[i], pkeys, signers[i]))
@ -5578,8 +5575,7 @@ bool wallet2::parse_payment_id(std::string_view payment_id_str, crypto::hash& pa
crypto::hash8 payment_id8;
if (tools::hex_to_type(payment_id_str, payment_id8))
{
payment_id = crypto::null_hash;
std::memcpy(payment_id.data, payment_id8.data, sizeof(payment_id8));
payment_id = payment_id8;
return true;
}
return false;
@ -6905,25 +6901,25 @@ crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(ptx.tx.extra, tx_extra_fields); // ok if partially parsed
tx_extra_nonce extra_nonce;
crypto::hash payment_id = null_hash;
crypto::hash payment_id{};
if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
{
crypto::hash8 payment_id8 = null_hash8;
crypto::hash8 payment_id8{};
if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
{
if (ptx.dests.empty())
{
log::warning(logcat, "Encrypted payment id found, but no destinations public key, cannot decrypt");
return crypto::null_hash;
return null<hash>;
}
if (m_account.get_device().decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key))
{
memcpy(payment_id.data, payment_id8.data, 8);
payment_id = payment_id8;
}
}
else if (!get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id))
{
payment_id = crypto::null_hash;
payment_id = null<hash>;
}
}
return payment_id;
@ -6975,7 +6971,7 @@ void wallet2::commit_tx(pending_tx& ptx, bool blink)
crypto::hash txid;
txid = get_transaction_hash(ptx.tx);
crypto::hash payment_id = crypto::null_hash;
crypto::hash payment_id{};
std::vector<cryptonote::tx_destination_entry> dests;
uint64_t amount_in = 0;
if (store_tx_info())
@ -6986,7 +6982,7 @@ void wallet2::commit_tx(pending_tx& ptx, bool blink)
amount_in += m_transfers[idx].amount();
}
add_unconfirmed_tx(ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount, ptx.construction_data.subaddr_account, ptx.construction_data.subaddr_indices);
if (store_tx_info() && ptx.tx_key != crypto::null_skey)
if (store_tx_info() && ptx.tx_key)
{
m_tx_keys.insert(std::make_pair(txid, ptx.tx_key));
m_additional_tx_keys.insert(std::make_pair(txid, ptx.additional_tx_keys));
@ -7178,7 +7174,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
// normally, the tx keys are saved in commit_tx, when the tx is actually sent to the daemon.
// we can't do that here since the tx will be sent from the compromised wallet, which we don't want
// to see that info, so we save it here
if (store_tx_info() && tx_key != crypto::null_skey)
if (store_tx_info() && tx_key)
{
const crypto::hash txid = get_transaction_hash(ptx.tx);
m_tx_keys.insert(std::make_pair(txid, tx_key));
@ -7189,7 +7185,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
bool all_are_txin_to_key = std::all_of(ptx.tx.vin.begin(), ptx.tx.vin.end(), [&](const txin_v& s_e) -> bool
{
CHECKED_GET_SPECIFIC_VARIANT(s_e, txin_to_key, in, false);
key_images << in.k_image << ' ';
key_images << "{} "_format(in.k_image);
return true;
});
THROW_WALLET_EXCEPTION_IF(!all_are_txin_to_key, error::unexpected_txin_type, ptx.tx);
@ -9019,7 +9015,7 @@ bool wallet2::ons_make_update_mapping_signature(ons::mapping_type type,
ons_prepared_args prepared_args = prepare_tx_extra_oxen_name_system_values(*this, type, tx_priority_unimportant, name, value, owner, backup_owner, make_signature, ons::ons_tx_type::update, account_index, reason, &response);
if (!prepared_args) return false;
if (prepared_args.prev_txid == crypto::null_hash)
if (!prepared_args.prev_txid)
{
if (reason) *reason = "name=\"" + name + std::string("\" does not have a corresponding ONS record, the mapping is available for purchase, update signature is not required.");
return false;
@ -10054,7 +10050,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
bool all_are_txin_to_key = std::all_of(tx.vin.begin(), tx.vin.end(), [&](const txin_v& s_e) -> bool
{
CHECKED_GET_SPECIFIC_VARIANT(s_e, txin_to_key, in, false);
key_images << in.k_image << ' ';
key_images << "{} "_format(in.k_image);
return true;
});
THROW_WALLET_EXCEPTION_IF(!all_are_txin_to_key, error::unexpected_txin_type, tx);
@ -10588,7 +10584,7 @@ void wallet2::light_wallet_get_address_txs()
if(total_sent == 0 && total_received == 0)
continue;
crypto::hash payment_id = null_hash;
crypto::hash payment_id;
crypto::hash tx_hash;
THROW_WALLET_EXCEPTION_IF(t.payment_id.size() != 64 || !oxenc::is_hex(t.payment_id), error::wallet_internal_error, "Invalid payment_id field");
@ -11966,7 +11962,7 @@ bool wallet2::get_tx_key_cached(const crypto::hash &txid, crypto::secret_key &tx
if (i == m_tx_keys.end())
return false;
tx_key = i->second;
if (tx_key == crypto::null_skey)
if (!tx_key)
return false;
const auto j = m_additional_tx_keys.find(txid);
if (j != m_additional_tx_keys.end())
@ -12030,7 +12026,7 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, s
THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error,
"Failed to get the right transaction from daemon");
tx_key_data.tx_prefix_hash = std::string(tx_prefix_hash.data, 32);
tx_key_data.tx_prefix_hash = std::string{reinterpret_cast<const char*>(tx_prefix_hash.data()), tx_prefix_hash.size()};
}
std::vector<crypto::secret_key> tx_keys;
@ -12041,7 +12037,7 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, s
return false;
}
if (tx_keys[0] == crypto::null_skey)
if (!tx_keys[0])
{
return false;
}
@ -12390,7 +12386,7 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac
THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "Failed to get the right transaction from daemon");
// determine if the address is found in the subaddress hash table (i.e. whether the proof is outbound or inbound)
crypto::secret_key tx_key = crypto::null_skey;
crypto::secret_key tx_key{};
std::vector<crypto::secret_key> additional_tx_keys;
const bool is_out = m_subaddresses.count(address.m_spend_public_key) == 0;
if (is_out)
@ -12458,7 +12454,7 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
else
{
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
THROW_WALLET_EXCEPTION_IF(tx_pub_key == null_pkey, error::wallet_internal_error, "Tx pubkey was not found");
THROW_WALLET_EXCEPTION_IF(!tx_pub_key, error::wallet_internal_error, "Tx pubkey was not found");
std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx);
const size_t num_sigs = 1 + additional_tx_pub_keys.size();
@ -12583,7 +12579,7 @@ bool wallet2::check_tx_proof(const cryptonote::transaction &tx, const cryptonote
}
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
THROW_WALLET_EXCEPTION_IF(tx_pub_key == null_pkey, error::wallet_internal_error, "Tx pubkey was not found");
THROW_WALLET_EXCEPTION_IF(!tx_pub_key, error::wallet_internal_error, "Tx pubkey was not found");
std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx);
THROW_WALLET_EXCEPTION_IF(additional_tx_pub_keys.size() + 1 != num_sigs, error::wallet_internal_error, "Signature size mismatch with additional tx pubkeys");
@ -12698,7 +12694,7 @@ std::string wallet2::get_reserve_proof(const std::optional<std::pair<uint32_t, u
// get tx pub key
const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(td.m_tx, td.m_pk_index);
THROW_WALLET_EXCEPTION_IF(tx_pub_key == crypto::null_pkey, error::wallet_internal_error, "The tx public key isn't found");
THROW_WALLET_EXCEPTION_IF(!tx_pub_key, error::wallet_internal_error, "The tx public key isn't found");
const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(td.m_tx);
// determine which tx pub key was used for deriving the output key
@ -12866,7 +12862,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
else
{
const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
THROW_WALLET_EXCEPTION_IF(tx_pub_key == crypto::null_pkey, error::wallet_internal_error, "The tx public key isn't found");
THROW_WALLET_EXCEPTION_IF(!tx_pub_key, error::wallet_internal_error, "The tx public key isn't found");
ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, std::nullopt, proof.shared_secret, proof.shared_secret_sig);
}
@ -13653,10 +13649,9 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
pd.m_change = (uint64_t)-1; // change is unknown
pd.m_amount_in = pd.m_amount_out = td.amount(); // fee is unknown
pd.m_block_height = 0; // spent block height is unknown
const crypto::hash &spent_txid = crypto::null_hash; // spent txid is unknown
bool stake = service_nodes::tx_get_staking_components(td.m_tx, nullptr /*stake*/, td.m_txid);
pd.m_pay_type = stake ? wallet::pay_type::stake : wallet::pay_type::out;
m_confirmed_txs.emplace(spent_txid, pd);
m_confirmed_txs.emplace(null<hash>, pd);
}
}
@ -13733,7 +13728,7 @@ std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> wallet2::export_bloc
std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> bc;
auto& [offset, genesis_hash, hashes] = bc;
offset = m_blockchain.offset();
genesis_hash = m_blockchain.empty() ? crypto::null_hash: m_blockchain.genesis();
genesis_hash = m_blockchain.empty() ? null<hash> : m_blockchain.genesis();
for (size_t n = m_blockchain.offset(); n < m_blockchain.size(); ++n)
hashes.push_back(m_blockchain[n]);
return bc;
@ -14687,11 +14682,11 @@ void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &h
{
KECCAK_CTX state;
keccak_init(&state);
keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data));
keccak_update(&state, (const uint8_t *) transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
keccak_update(&state, (const uint8_t *) transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
keccak_update(&state, (const uint8_t *) transfer.m_amount, sizeof(transfer.m_amount));
keccak_finish(&state, (uint8_t *) hash.data);
keccak_update(&state, transfer.m_txid.data(), transfer.m_txid.size());
keccak_update(&state, reinterpret_cast<const unsigned char*>(&transfer.m_internal_output_index), sizeof(transfer.m_internal_output_index));
keccak_update(&state, reinterpret_cast<const unsigned char*>(&transfer.m_global_output_index), sizeof(transfer.m_global_output_index));
keccak_update(&state, reinterpret_cast<const unsigned char*>(&transfer.m_amount), sizeof(transfer.m_amount));
keccak_finish(&state, hash.data());
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const
@ -14709,12 +14704,12 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
}
hash_m_transfer(transfer, tmp_hash);
keccak_update(&state, (const uint8_t *) transfer.m_block_height, sizeof(transfer.m_block_height));
keccak_update(&state, (const uint8_t *) tmp_hash.data, sizeof(tmp_hash.data));
keccak_update(&state, reinterpret_cast<const unsigned char*>(&transfer.m_block_height), sizeof(transfer.m_block_height));
keccak_update(&state, reinterpret_cast<const unsigned char*>(tmp_hash.data()), tmp_hash.size());
current_height += 1;
}
keccak_finish(&state, (uint8_t *) hash.data);
keccak_finish(&state, hash.data());
return current_height;
}

View File

@ -193,7 +193,7 @@ private:
class hashchain
{
public:
hashchain(): m_genesis(crypto::null_hash), m_offset(0) {}
hashchain(): m_genesis(crypto::null<crypto::hash>), m_offset(0) {}
size_t size() const { return m_blockchain.size() + m_offset; }
size_t offset() const { return m_offset; }
@ -373,7 +373,7 @@ private:
uint64_t m_change = std::numeric_limits<std::uint64_t>::max();
uint64_t m_block_height = 0;
std::vector<cryptonote::tx_destination_entry> m_dests;
crypto::hash m_payment_id = crypto::null_hash;
crypto::hash m_payment_id = crypto::null<crypto::hash>;
uint64_t m_timestamp = 0;
uint64_t m_unlock_time = 0; // NOTE(oxen): Not used after TX v2.
std::vector<uint64_t> m_unlock_times;
@ -1934,20 +1934,20 @@ namespace boost::serialization
{
crypto::hash payment_id;
a & payment_id;
x.m_has_payment_id = !(payment_id == crypto::null_hash);
x.m_has_payment_id = (bool) payment_id;
if (x.m_has_payment_id)
{
bool is_long = false;
for (int i = 8; i < 32; ++i)
is_long |= payment_id.data[i];
is_long |= payment_id[i];
if (is_long)
{
oxen::log::warning(oxen::log::Cat("wallet.wallet2"), "Long payment ID ignored on address book load");
x.m_payment_id = crypto::null_hash8;
x.m_payment_id.zero();
x.m_has_payment_id = false;
}
else
memcpy(x.m_payment_id.data, payment_id.data, 8);
memcpy(x.m_payment_id.data(), payment_id.data(), 8);
}
}
a & x.m_description;

View File

@ -894,7 +894,7 @@ namespace
//------------------------------------------------------------------------------------------------------------------------------
void wallet_rpc_server::validate_transfer(const std::list<wallet::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination)
{
crypto::hash8 integrated_payment_id = crypto::null_hash8;
crypto::hash8 integrated_payment_id{};
std::string extra_nonce;
for (auto it = destinations.begin(); it != destinations.end(); it++)
{
@ -910,7 +910,7 @@ namespace
if (info.has_payment_id)
{
if (!payment_id.empty() || integrated_payment_id != crypto::null_hash8)
if (!payment_id.empty() || integrated_payment_id)
throw wallet_rpc_error{error_code::WRONG_PAYMENT_ID, "A single payment id is allowed per transaction"};
integrated_payment_id = info.payment_id;
cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, integrated_payment_id);
@ -977,10 +977,10 @@ namespace
}
void append_hex_tx_keys(std::string& to, const crypto::secret_key& k, const std::vector<crypto::secret_key>& more) {
to.reserve(to.size() + oxenc::to_hex_size(sizeof(k.data) * (1 + more.size())));
oxenc::to_hex(std::begin(k.data), std::end(k.data), std::back_inserter(to));
to.reserve(to.size() + oxenc::to_hex_size(k.size() * (1 + more.size())));
oxenc::to_hex(k.begin(), k.end(), std::back_inserter(to));
for (const auto& key : more)
oxenc::to_hex(std::begin(key.data), std::end(key.data), std::back_inserter(to));
oxenc::to_hex(key.begin(), key.end(), std::back_inserter(to));
}
std::string hex_tx_keys(const crypto::secret_key& k, const std::vector<crypto::secret_key>& more) {
std::string s;
@ -1205,7 +1205,7 @@ namespace
std::vector<cryptonote::tx_extra_field> tx_extra_fields;
bool has_encrypted_payment_id = false;
crypto::hash8 payment_id8 = crypto::null_hash8;
crypto::hash8 payment_id8{};
if (cryptonote::parse_tx_extra(cd.extra, tx_extra_fields))
{
cryptonote::tx_extra_nonce extra_nonce;
@ -1214,7 +1214,7 @@ namespace
crypto::hash payment_id;
if(cryptonote::get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
{
if (payment_id8 != crypto::null_hash8)
if (payment_id8)
{
desc.payment_id = tools::type_to_hex(payment_id8);
has_encrypted_payment_id = true;
@ -1529,8 +1529,7 @@ namespace
std::string payment_id_blob;
if (!tools::hex_to_type(req.payment_id, payment_id)) {
if (crypto::hash8 payment_id8; tools::hex_to_type(req.payment_id, payment_id8)) {
memcpy(payment_id.data, payment_id8.data, 8);
memset(payment_id.data + 8, 0, 24);
payment_id = payment_id8;
} else {
throw wallet_rpc_error{error_code::WRONG_PAYMENT_ID, "Payment ID has invalid format"};
}
@ -1598,8 +1597,7 @@ namespace
r = tools::hex_to_type(payment_id_str, payment_id8);
if (r)
{
memcpy(payment_id.data, payment_id8.data, 8);
memset(payment_id.data + 8, 0, 24);
payment_id = payment_id8;
}
}
else
@ -1703,16 +1701,16 @@ namespace
else if (req.key_type == "view_key")
{
res.key.reserve(64);
const auto& vsk_data = m_wallet->get_account().get_keys().m_view_secret_key.data;
oxenc::to_hex(std::begin(vsk_data), std::end(vsk_data), std::back_inserter(res.key));
const auto& vsk = m_wallet->get_account().get_keys().m_view_secret_key;
oxenc::to_hex(vsk.begin(), vsk.end(), std::back_inserter(res.key));
}
else if (req.key_type == "spend_key")
{
if (m_wallet->watch_only())
throw wallet_rpc_error{error_code::WATCH_ONLY, "The wallet is watch-only. Cannot retrieve spend key."};
res.key.reserve(64);
const auto& ssk_data = m_wallet->get_account().get_keys().m_spend_secret_key.data;
oxenc::to_hex(std::begin(ssk_data), std::end(ssk_data), std::back_inserter(res.key));
const auto& ssk = m_wallet->get_account().get_keys().m_spend_secret_key;
oxenc::to_hex(ssk.begin(), ssk.end(), std::back_inserter(res.key));
}
else
throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "key_type " + req.key_type + " not found"};
@ -1842,13 +1840,13 @@ namespace
if (tx_keys.size() < 64 || tx_keys.size() % 64 || !oxenc::is_hex(tx_keys))
throw wallet_rpc_error{error_code::WRONG_KEY, "Tx key has invalid format"};
crypto::secret_key tx_key;
oxenc::from_hex(tx_keys.begin(), tx_keys.begin() + 64, tx_key.data);
oxenc::from_hex(tx_keys.begin(), tx_keys.begin() + 64, tx_key.begin());
tx_keys.remove_prefix(64);
std::vector<crypto::secret_key> additional_tx_keys;
while (!tx_keys.empty())
{
oxenc::from_hex(tx_keys.begin(), tx_keys.begin() + 64, additional_tx_keys.emplace_back().data);
oxenc::from_hex(tx_keys.begin(), tx_keys.begin() + 64, additional_tx_keys.emplace_back().begin());
tx_keys.remove_prefix(64);
}

View File

@ -206,7 +206,7 @@ namespace wallet
crypto::hash
Keyring::get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx)
{
crypto::hash h = crypto::null_hash;
crypto::hash h{};
key_device.get_transaction_prefix_hash(tx, h);
return h;
}

View File

@ -88,13 +88,13 @@ public:
return ret;
}
virtual crypto::hash get_block_hash_from_height(const uint64_t &height) const override {
crypto::hash hash = crypto::null_hash;
*(uint64_t*)&hash = height;
crypto::hash hash{};
*reinterpret_cast<uint64_t*>(hash.data()) = height;
return hash;
}
virtual crypto::hash top_block_hash(uint64_t *block_height = NULL) const override {
uint64_t h = height();
crypto::hash top = crypto::null_hash;
crypto::hash top{};
if (h)
*(uint64_t*)&top = h - 1;
if (block_height)

View File

@ -164,17 +164,12 @@ std::vector<cryptonote::tx_verification_batch_info> tests::proxy_core::parse_inc
for (size_t i = 0; i < tx_blobs.size(); i++) {
auto &txi = tx_info[i];
crypto::hash tx_prefix_hash = null_hash;
crypto::hash tx_prefix_hash{};
if (opts.kept_by_block) {
txi.result = txi.parsed = true;
} else if (parse_and_validate_tx_from_blob(tx_blobs[i], txi.tx, txi.tx_hash, tx_prefix_hash)) {
std::cout << "TX\n\n";
std::cout << txi.tx_hash << "\n";
std::cout << tx_prefix_hash << "\n";
std::cout << tx_blobs[i].size() << "\n";
//std::cout << oxenc::to_hex(tx_blob) << "\n\n";
std::cout << obj_to_json_str(txi.tx) << "\n";
std::cout << "\nENDTX\n";
fmt::print("TX\n\n{}\n{}\n{}\n{}\n\nENDTX\n",
txi.tx_hash, tx_prefix_hash, tx_blobs[i].size(), obj_to_json_str(txi.tx));
txi.result = txi.parsed = true;
txi.blob = &tx_blobs[i];
} else {
@ -228,13 +223,8 @@ bool tests::proxy_core::handle_incoming_block(const std::string& block_blob, con
crypto::hash h = get_block_hash(b);
crypto::hash lh = get_block_longhash_w_blockchain(network_type::FAKECHAIN, NULL, b, 0, 0);
std::cout << "BLOCK\n\n";
std::cout << h << '\n';
std::cout << lh << '\n';
std::cout << get_transaction_hash(b.miner_tx) << '\n';
std::cout << get_object_blobsize(b.miner_tx) << '\n';
std::cout << obj_to_json_str(b) << '\n';
std::cout << "\nENDBLOCK\n\n";
fmt::print("BLOCK\n\n{}\n{}\n{}\n{}\n{}\n\nENDBLOCK\n\n",
h, lh, get_transaction_hash(b.miner_tx), get_object_blobsize(b.miner_tx), obj_to_json_str(b));
if (!add_block(h, lh, b, block_blob, checkpoint))
return false;
@ -284,7 +274,7 @@ void tests::proxy_core::build_short_history(std::list<crypto::hash> &m_history,
m_history.push_front(cit->first);
size_t n = 1 << m_history.size();
while (m_hash2blkidx.end() != cit && crypto::null_hash != cit->second.blk.prev_id && n > 0) {
while (m_hash2blkidx.end() != cit && cit->second.blk.prev_id && n > 0) {
n--;
cit = m_hash2blkidx.find(cit->second.blk.prev_id);
}
@ -294,10 +284,10 @@ void tests::proxy_core::build_short_history(std::list<crypto::hash> &m_history,
bool tests::proxy_core::add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const std::string &_blob, cryptonote::checkpoint_t const *) {
size_t height = 0;
if (crypto::null_hash != _blk.prev_id) {
if (_blk.prev_id) {
std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(_blk.prev_id);
if (m_hash2blkidx.end() == cit) {
std::cerr << "ERROR: can't find previous block with id \"" << _blk.prev_id << "\"\n";
fmt::print(stderr, "ERROR: can't find previous block with id \"{}\"\n", _blk.prev_id);
return false;
}

View File

@ -50,7 +50,7 @@ namespace tests
std::string blob;
std::list<cryptonote::transaction> txes;
block_index() : height(0), id(crypto::null_hash), longhash(crypto::null_hash) { }
block_index() : height(0), id{}, longhash{} { }
block_index(size_t _height, const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const std::string &_blob, const std::list<cryptonote::transaction> &_txes)
: height(_height), id(_id), longhash(_longhash), blk(_blk), blob(_blob), txes(_txes) { }
};
@ -99,7 +99,7 @@ namespace tests
bool cleanup_handle_incoming_blocks(bool force_sync = false) { return true; }
uint64_t get_target_blockchain_height() const { return 1; }
size_t get_block_sync_size(uint64_t height) const { return cryptonote::BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; }
virtual crypto::hash on_transaction_relayed(const std::string& tx) { return crypto::null_hash; }
virtual crypto::hash on_transaction_relayed(const std::string& tx) { return crypto::null<crypto::hash>; }
cryptonote::network_type get_nettype() const { return cryptonote::network_type::MAINNET; }
bool get_blocks(uint64_t start_offset, size_t count, std::vector<std::pair<std::string, cryptonote::block>>& blocks, std::vector<std::string>& txs) const { return false; }
bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::vector<cryptonote::transaction>& txs, std::unordered_set<crypto::hash>* missed_txs = nullptr) const { return false; }

View File

@ -251,11 +251,11 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
// that it looks obviously fake, then fill the rest with randomness (so that it is still
// unique).
for (size_t i = 0; i < 8; i++)
tx_hash.data[i] = 0x01 + (0x22 * i);
tx_hash[i] = 0x01 + (0x22 * i);
static std::mt19937_64 rng{std::random_device{}()};
std::uniform_int_distribution<char> unif{std::numeric_limits<char>::min()};
for (size_t i = 8; i < sizeof(tx_hash.data); i++)
tx_hash.data[i] = unif(rng);
for (size_t i = 8; i < tx_hash.size(); i++)
tx_hash[i] = unif(rng);
}
starting_rct_tx_hashes.push_back(tx_hash);
oxen::log::warning(globallogcat, "Test tx: {}", obj_to_json_str(rct_txes.back()));

View File

@ -706,7 +706,7 @@ cryptonote::transaction oxen_chain_generator::create_oxen_name_system_tx(crypton
auto lcname = tools::lowercase_ascii_string(name);
crypto::hash name_hash = ons::name_to_hash(lcname);
std::string name_base64_hash = ons::name_to_base64_hash(lcname);
crypto::hash prev_txid = crypto::null_hash;
crypto::hash prev_txid{};
if (ons::mapping_record mapping = ons_db_->get_mapping(type, name_base64_hash, new_height))
prev_txid = mapping.txid;
@ -767,7 +767,7 @@ cryptonote::transaction oxen_chain_generator::create_oxen_name_system_tx_update(
auto data = ons::tx_extra_signature(encrypted_value.to_view(), owner, backup_owner, prev_txid);
crypto::hash hash{};
if (!data.empty())
crypto_generichash(reinterpret_cast<unsigned char*>(hash.data), sizeof(hash), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr, 0);
crypto_generichash(hash.data(), hash.size(), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr, 0);
generate_signature(hash, src.get_keys().m_account_address.m_spend_public_key, src.get_keys().m_spend_secret_key, signature->monero);
signature->type = ons::generic_owner_sig_type::monero;
}
@ -849,7 +849,7 @@ static void fill_nonce_with_test_generator(test_generator *generator, cryptonote
cryptonote::randomx_longhash_context randomx_context = {};
if (generator->m_hf_version >= hf::hf12_checkpointing)
{
randomx_context.seed_height = crypto::rx_seedheight(height);
randomx_context.seed_height = rx_seedheight(height);
cryptonote::block prev = blk;
do
{
@ -876,7 +876,7 @@ void fill_nonce_with_oxen_generator(oxen_chain_generator const *generator, crypt
cryptonote::randomx_longhash_context randomx_context = {};
if (generator->blocks().size() && generator->hardfork() >= hf::hf12_checkpointing)
{
randomx_context.seed_height = crypto::rx_seedheight(height);
randomx_context.seed_height = rx_seedheight(height);
randomx_context.seed_block_hash = cryptonote::get_block_hash(generator->blocks()[randomx_context.seed_height].block);
randomx_context.current_blockchain_height = height;
}
@ -899,14 +899,15 @@ oxen_blockchain_entry oxen_chain_generator::create_genesis_block(const cryptonot
blk.major_version = hf_version_;
blk.minor_version = static_cast<uint8_t>(hf_version_);
blk.timestamp = timestamp;
blk.prev_id = crypto::null_hash;
blk.prev_id.zero();
// TODO(doyle): Does this evaluate to 0? If so we can simplify this a lot more
size_t target_block_weight = get_transaction_weight(blk.miner_tx);
while (true)
{
auto [constructed, block_rewards] = construct_miner_tx(height,
[[maybe_unused]] auto [constructed, block_rewards] = construct_miner_tx(
height,
0 /*median_weight*/,
0 /*already_generated_coins*/,
target_block_weight,
@ -1237,7 +1238,7 @@ std::vector<uint64_t> oxen_chain_generator::last_n_block_weights(uint64_t height
void test_generator::get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const
{
crypto::hash curr = head;
while (crypto::null_hash != curr && blockchain.size() < n)
while (curr && blockchain.size() < n)
{
auto it = m_blocks_info.find(curr);
if (m_blocks_info.end() == it)
@ -1258,7 +1259,7 @@ void test_generator::get_block_chain(std::vector<cryptonote::block> &blockchain,
size_t n) const
{
crypto::hash curr = head;
while (crypto::null_hash != curr && blockchain.size() < n)
while (curr && blockchain.size() < n)
{
auto it = m_blocks_info.find(curr);
if (m_blocks_info.end() == it)
@ -1455,7 +1456,7 @@ bool test_generator::construct_block(cryptonote::block &blk,
{
std::vector<uint64_t> block_weights;
std::list<cryptonote::transaction> tx_list;
return construct_block(blk, 0, crypto::null_hash, miner_acc, timestamp, 0, block_weights, tx_list);
return construct_block(blk, 0, crypto::null<crypto::hash>, miner_acc, timestamp, 0, block_weights, tx_list);
}
bool test_generator::construct_block(cryptonote::block &blk,
@ -2048,9 +2049,9 @@ std::string block_tracker::dump_data()
ss << " idx: " << oi.idx
<< ", rct: " << oi.rct
<< ", xmr: " << oi.amount
<< ", key: " << dump_keys(out.key.data)
<< ", key: " << dump_keys(out.key.data())
<< ", msk: " << dump_keys(oi.comm.bytes)
<< ", txid: " << dump_keys(oi.p_tx->hash.data)
<< ", txid: " << dump_keys(oi.p_tx->hash.data())
<< '\n';
}
}
@ -2510,7 +2511,7 @@ bool find_block_chain(const std::vector<test_event_entry> &events, std::vector<c
{
blockchain.push_back(*it->second);
id = it->second->prev_id;
if (crypto::null_hash == id)
if (!id)
{
b_success = true;
break;
@ -2568,7 +2569,7 @@ bool find_block_chain(const std::vector<test_event_entry> &events, std::vector<c
{
blockchain.push_back(it->second);
id = it->second->prev_id;
if (crypto::null_hash == id)
if (!id)
{
b_success = true;
break;

View File

@ -359,22 +359,12 @@ public:
}
};
template<typename T>
std::string dump_keys(T * buff32)
// Dumps the 32-byte contents of some pointer as: [0x01,0xf1,0xbb,....,0xff].
// (I have no idea why this makes any sense, look, squirrel!)
inline std::string dump_keys(const void* buff32)
{
std::ostringstream ss;
char buff[10];
ss << "[";
for(int i = 0; i < 32; i++)
{
snprintf(buff, 10, "0x%02x", ((uint8_t)buff32[i] & 0xff));
ss << buff;
if (i < 31)
ss << ",";
}
ss << "]";
return ss.str();
auto* begin = reinterpret_cast<const unsigned char*>(buff32);
return "[{:#04x}]"_format(fmt::join(begin, begin+32, ","));
}
struct output_index {
@ -454,7 +444,7 @@ struct output_index {
typedef std::tuple<uint64_t, crypto::public_key, rct::key> get_outs_entry;
typedef std::pair<crypto::hash, size_t> output_hasher;
struct output_hasher_hasher { size_t operator()(const output_hasher &h) const { return *reinterpret_cast<const size_t *>(h.first.data) + h.second; } };
struct output_hasher_hasher { size_t operator()(const output_hasher &h) const { return *reinterpret_cast<const size_t *>(h.first.data()) + h.second; } };
typedef std::map<uint64_t, std::vector<size_t> > map_output_t;
typedef std::map<uint64_t, std::vector<output_index> > map_output_idx_t;
typedef std::unordered_map<crypto::hash, cryptonote::block> map_block_t;

View File

@ -40,6 +40,12 @@ using namespace cryptonote;
//#define NO_MULTISIG
struct secret_key_hasher {
size_t operator()(const crypto::secret_key& k) const {
return *reinterpret_cast<const size_t*>(k.data());
}
};
void make_multisig_accounts(std::vector<cryptonote::account_base>& account, uint32_t threshold)
{
std::vector<crypto::secret_key> all_view_keys;
@ -96,7 +102,7 @@ void make_multisig_accounts(std::vector<cryptonote::account_base>& account, uint
std::unordered_set<crypto::public_key> all_multisig_keys;
for (size_t msidx = 0; msidx < account.size(); ++msidx)
{
std::unordered_set<crypto::secret_key> view_keys(all_view_keys.begin(), all_view_keys.end());
std::unordered_set<crypto::secret_key, secret_key_hasher> view_keys(all_view_keys.begin(), all_view_keys.end());
view_keys.erase(all_view_keys[msidx]);
crypto::secret_key view_skey = cryptonote::generate_multisig_view_secret_key(account[msidx].get_keys().m_view_secret_key, std::vector<secret_key>(view_keys.begin(), view_keys.end()));
@ -388,7 +394,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
#ifndef NO_MULTISIG
// sign
std::unordered_set<crypto::secret_key> used_keys;
std::unordered_set<crypto::secret_key, secret_key_hasher> used_keys;
const std::vector<crypto::secret_key> &msk0 = miner_account[creator].get_multisig_keys();
for (const auto &sk: msk0)
used_keys.insert(sk);

View File

@ -1070,8 +1070,10 @@ static ons_keys_t make_ons_keys(cryptonote::account_base const &src)
auto iter = result.wallet_value.buffer.begin();
uint8_t identifier = 0;
iter = std::copy_n(&identifier, 1, iter);
iter = std::copy_n(src.get_keys().m_account_address.m_spend_public_key.data, sizeof(src.get_keys().m_account_address.m_spend_public_key.data), iter);
iter = std::copy_n(src.get_keys().m_account_address.m_view_public_key.data, sizeof(src.get_keys().m_account_address.m_view_public_key.data), iter);
auto& spubkey = src.get_keys().m_account_address.m_spend_public_key;
iter = std::copy(spubkey.begin(), spubkey.end(), iter);
auto& vpubkey = src.get_keys().m_account_address.m_view_public_key;
iter = std::copy(vpubkey.begin(), vpubkey.end(), iter);
// NOTE: Just needs a 32 byte key. Reuse spend key
memcpy(&result.lokinet_value.buffer[0], (char *)&result.owner.wallet.address.m_spend_public_key, result.lokinet_value.len);
@ -1551,7 +1553,7 @@ bool oxen_name_system_invalid_tx_extra_params::generate(std::vector<test_event_e
// Blockchain name empty
{
cryptonote::tx_extra_oxen_name_system data = valid_data;
data.name_hash = {};
data.name_hash.zero();
data.encrypted_value = miner_key.wallet_value.make_encrypted("").to_string();
make_ons_tx_with_custom_extra(gen, events, miner, data, false, "(Blockchain) Empty wallet name in ONS is invalid");
}
@ -1579,7 +1581,7 @@ bool oxen_name_system_invalid_tx_extra_params::generate(std::vector<test_event_e
// Lokinet name empty
{
cryptonote::tx_extra_oxen_name_system data = valid_data;
data.name_hash = {};
data.name_hash.zero();
data.encrypted_value = miner_key.lokinet_value.make_encrypted("").to_string();
make_ons_tx_with_custom_extra(gen, events, miner, data, false, "(Lokinet) Empty domain name in ONS is invalid");
}
@ -1624,7 +1626,7 @@ bool oxen_name_system_invalid_tx_extra_params::generate(std::vector<test_event_e
// Session name empty
{
cryptonote::tx_extra_oxen_name_system data = valid_data;
data.name_hash = {};
data.name_hash.zero();
data.encrypted_value = miner_key.session_value.make_encrypted("").to_string();
make_ons_tx_with_custom_extra(gen, events, miner, data, false, "(Session) Name empty");
}
@ -2119,7 +2121,7 @@ static crypto::hash ons_signature_hash(Args&&... args) {
crypto::hash hash{};
auto data = ons::tx_extra_signature(std::forward<Args>(args)...);
if (!data.empty())
crypto_generichash(reinterpret_cast<unsigned char*>(hash.data), sizeof(hash), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr, 0);
crypto_generichash(hash.data(), hash.size(), reinterpret_cast<const unsigned char*>(data.data()), data.size(), nullptr, 0);
return hash;
}
@ -2148,8 +2150,8 @@ bool oxen_name_system_update_mapping_multiple_owners::generate(std::vector<test_
crypto::ed25519_secret_key owner1_key;
crypto::ed25519_secret_key owner2_key;
crypto_sign_ed25519_keypair(owner1.ed25519.data, owner1_key.data);
crypto_sign_ed25519_keypair(owner2.ed25519.data, owner2_key.data);
crypto_sign_ed25519_keypair(owner1.ed25519.data(), owner1_key.data());
crypto_sign_ed25519_keypair(owner2.ed25519.data(), owner2_key.data());
owner1.type = ons::generic_owner_sig_type::ed25519;
owner2.type = ons::generic_owner_sig_type::ed25519;
@ -2277,7 +2279,7 @@ bool oxen_name_system_update_mapping_multiple_owners::generate(std::vector<test_
ons::generic_owner owner2 = ons::make_monero_owner(account2.get_keys().m_account_address, false /*subaddress*/);
crypto::ed25519_secret_key owner1_key;
crypto_sign_ed25519_keypair(owner1.ed25519.data, owner1_key.data);
crypto_sign_ed25519_keypair(owner1.ed25519.data(), owner1_key.data());
owner1.type = ons::generic_owner_sig_type::ed25519;
std::string name = "hello_driver";
@ -2337,7 +2339,7 @@ bool oxen_name_system_update_mapping_multiple_owners::generate(std::vector<test_
ons::generic_owner owner2;
crypto::ed25519_secret_key owner2_key;
crypto_sign_ed25519_keypair(owner2.ed25519.data, owner2_key.data);
crypto_sign_ed25519_keypair(owner2.ed25519.data(), owner2_key.data());
owner2.type = ons::generic_owner_sig_type::ed25519;
std::string name = "hello_passenger";

View File

@ -508,8 +508,13 @@ bool gen_rct_tx_pre_rct_altered_extra::generate(std::vector<test_event_entry>& e
const int out_idx[] = {0, -1};
const uint64_t amount_paid = 10000;
bool failed = false;
return generate_with(events, out_idx, mixin, amount_paid, false,
NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
return generate_with(events, out_idx, mixin, amount_paid, false, nullptr,
[&failed](transaction &tx) {
std::string extra_nonce;
crypto::hash pid{};
set_payment_id_to_tx_extra_nonce(extra_nonce, pid);
if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true;
}) && !failed;
}
bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& events) const
@ -518,8 +523,13 @@ bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& event
const int out_idx[] = {1, -1};
const uint64_t amount_paid = 10000;
bool failed = false;
return generate_with(events, out_idx, mixin, amount_paid, false,
NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
return generate_with(events, out_idx, mixin, amount_paid, false, nullptr,
[&failed](transaction &tx) {
std::string extra_nonce;
crypto::hash pid{};
set_payment_id_to_tx_extra_nonce(extra_nonce, pid);
if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true;
}) && !failed;
}
bool gen_rct_tx_uses_output_too_early::generate(std::vector<test_event_entry>& events) const

View File

@ -112,7 +112,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
continue;
}
if (selected_kis.find(td.m_key_image) != selected_kis.end()){
oxen::log::error(globallogcat, "Should not happen (selected KI): {} ki: {}", i, dump_keys(td.m_key_image.data));
oxen::log::error(globallogcat, "Should not happen (selected KI): {} ki: {}", i, dump_keys(td.m_key_image.data()));
continue;
}
@ -131,7 +131,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
}
}
oxen::log::debug(globallogcat, "Selected {} from tx: {} ki: {} amnt: {} rct: {} glob: {}", i, dump_keys(td.m_txid.data), dump_keys(td.m_key_image.data), td.amount(), td.is_rct(), td.m_global_output_index);
oxen::log::debug(globallogcat, "Selected {} from tx: {} ki: {} amnt: {} rct: {} glob: {}", i, dump_keys(td.m_txid.data()), dump_keys(td.m_key_image.data()), td.amount(), td.is_rct(), td.m_global_output_index);
sum += td.amount();
cur_utxo += 1;
@ -142,7 +142,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
selected_kis.insert(td.m_key_image);
} catch(const std::exception &e){
oxen::log::trace(globallogcat, "Output {}, from: {} amnt: {}, rct: {}, glob: {} is not applicable: {}", i, dump_keys(td.m_txid.data), td.amount(), td.is_rct(), td.m_global_output_index, e.what());
oxen::log::trace(globallogcat, "Output {}, from: {} amnt: {}, rct: {}, glob: {} is not applicable: {}", i, dump_keys(td.m_txid.data()), td.amount(), td.is_rct(), td.m_global_output_index, e.what());
}
}
@ -201,7 +201,7 @@ void wallet_tools::gen_block_data(block_tracker &bt, const cryptonote::block *bl
for (const auto &h : bl->tx_hashes) {
const map_hash2tx_t::const_iterator cit = mtx.find(h);
CHECK_AND_ASSERT_THROW_MES(mtx.end() != cit, "block contains an unknown tx hash @ " << height << ", " << h);
CHECK_AND_ASSERT_THROW_MES(mtx.end() != cit, "block contains an unknown tx hash @ {}, {}"_format(height, h));
vtx.push_back(cit->second);
}

View File

@ -33,17 +33,17 @@
#include "crypto-tests.h"
bool check_scalar(const crypto::ec_scalar &scalar) {
return crypto::sc_check(crypto::operator &(scalar)) == 0;
return sc_check(scalar.data()) == 0;
}
void hash_to_point(const crypto::hash &h, crypto::ec_point &res) {
crypto::ge_p2 point;
crypto::ge_fromfe_frombytes_vartime(&point, reinterpret_cast<const unsigned char *>(&h));
crypto::ge_tobytes(crypto::operator &(res), &point);
ge_p2 point;
ge_fromfe_frombytes_vartime(&point, reinterpret_cast<const unsigned char *>(&h));
ge_tobytes(res.data(), &point);
}
void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res) {
crypto::ge_p3 tmp;
ge_p3 tmp;
crypto::hash_to_ec(key, tmp);
crypto::ge_p3_tobytes(crypto::operator &(res), &tmp);
ge_p3_tobytes(res.data(), &tmp);
}

View File

@ -49,18 +49,6 @@ using namespace std::literals;
using namespace crypto;
typedef crypto::hash chash;
bool operator !=(const ec_scalar &a, const ec_scalar &b) {
return 0 != memcmp(&a, &b, sizeof(ec_scalar));
}
bool operator !=(const ec_point &a, const ec_point &b) {
return 0 != memcmp(&a, &b, sizeof(ec_point));
}
bool operator !=(const key_derivation &a, const key_derivation &b) {
return 0 != memcmp(&a, &b, sizeof(key_derivation));
}
DISABLE_GCC_WARNING(maybe-uninitialized)
size_t lineno;

View File

@ -45,9 +45,6 @@
using namespace crypto;
typedef crypto::hash chash;
using std::cerr;
using std::endl;
#define X_MACRO \
HASH_X_MACRO(invalid, "INVALID") \
HASH_X_MACRO(fast, "fast") \
@ -74,10 +71,8 @@ int test_variant2_int_sqrt();
int test_variant2_int_sqrt_ref();
int main(int argc, char *argv[]) {
TRY_ENTRY();
std::fstream input;
std::vector<char> data;
std::vector<unsigned char> data;
chash expected, actual;
size_t test = 0;
bool error = false;
@ -91,28 +86,17 @@ int main(int argc, char *argv[]) {
std::fesetround(round_modes[i]);
const int result = test_variant2_int_sqrt();
if (result != 0) {
cerr << "FPU round mode was set to ";
switch (round_modes[i]) {
case FE_DOWNWARD:
cerr << "FE_DOWNWARD";
break;
case FE_TONEAREST:
cerr << "FE_TONEAREST";
break;
case FE_UPWARD:
cerr << "FE_UPWARD";
break;
default:
cerr << "unknown";
break;
}
cerr << endl;
fmt::print(stderr, "FPU round mode was set to {}\n",
round_modes[i] == FE_DOWNWARD ? "FE_DOWNWARD" :
round_modes[i] == FE_TONEAREST ? "FE_TONEAREST" :
round_modes[i] == FE_UPWARD ? "FE_UPWARD" :
"unknown");
return result;
}
}
return 0;
}
cerr << "Wrong number of arguments" << endl;
fmt::print(stderr, "Wrong arguments. Usage: {} TESTTYPE test-file.txt\n");
return 1;
}
@ -128,7 +112,7 @@ int main(int argc, char *argv[]) {
if (type == hash_type::invalid)
{
cerr << "Unknown hashing function" << endl;
std::cerr << "Unknown hashing function\n";
return 1;
}
@ -146,7 +130,7 @@ int main(int argc, char *argv[]) {
void const *buf = data.data();
size_t len = data.size();
auto *actual_byte_ptr = reinterpret_cast<char *>(&actual);
auto *actual_byte_ptr = actual.data();
switch(type)
{
case hash_type::fast: cn_fast_hash(buf, len, actual_byte_ptr); break;
@ -154,7 +138,7 @@ int main(int argc, char *argv[]) {
{
if ((len & 31) != 0)
throw std::ios_base::failure("Invalid input length for tree_hash");
tree_hash((const char (*)[crypto::HASH_SIZE]) buf, len >> 5, actual_byte_ptr);
tree_hash((const unsigned char (*)[HASH_SIZE]) buf, len >> 5, actual_byte_ptr);
}
break;
@ -165,38 +149,17 @@ int main(int argc, char *argv[]) {
case hash_type::heavy_v1: cn_slow_hash (buf, len, actual, cn_slow_hash_type::heavy_v1); break;
case hash_type::heavy_v2: cn_slow_hash (buf, len, actual, cn_slow_hash_type::heavy_v2); break;
case hash_type::turtle_light_v2: cn_slow_hash (buf, len, actual, cn_slow_hash_type::turtle_lite_v2); break;
default:
{
cerr << "Unknown hashing function" << endl;
return 1;
}
};
default: throw std::runtime_error{"Unknown hashing function"};
}
if (expected != actual) {
size_t i;
cerr << "Hash mismatch on test " << test << endl << "Input: ";
if (data.size() == 0) {
cerr << "empty";
} else {
for (i = 0; i < data.size(); i++) {
cerr << std::setbase(16) << std::setw(2) << std::setfill('0') << int(static_cast<unsigned char>(data[i]));
}
}
cerr << endl << "Expected hash: ";
for (i = 0; i < 32; i++) {
cerr << std::setbase(16) << std::setw(2) << std::setfill('0') << int(reinterpret_cast<unsigned char *>(&expected)[i]);
}
cerr << endl << "Actual hash: ";
for (i = 0; i < 32; i++) {
cerr << std::setbase(16) << std::setw(2) << std::setfill('0') << int(reinterpret_cast<unsigned char *>(&actual)[i]);
}
cerr << endl;
fmt::print(stderr, "Hash mismatch on test {}\nInput: {}\nExpected hash: {}\nActual hash: {}\n",
test, (data.empty() ? "Empty" : oxenc::to_hex(data.begin(), data.end())), expected, actual);
error = true;
}
}
return error ? 1 : 0;
CATCH_ENTRY_L0("main", 1);
}
#if defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))
@ -218,9 +181,9 @@ static inline bool test_variant2_int_sqrt_sse(const uint64_t sqrt_input, const u
VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2();
VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result);
if (sqrt_result != correct_result) {
cerr << "Integer sqrt (SSE2 version) returned incorrect result for N = " << sqrt_input << endl;
cerr << "Expected result: " << correct_result << endl;
cerr << "Returned result: " << sqrt_result << endl;
std::cerr << "Integer sqrt (SSE2 version) returned incorrect result for N = " << sqrt_input << "\n";
std::cerr << "Expected result: " << correct_result << "\n";
std::cerr << "Returned result: " << sqrt_result << "\n";
return false;
}
#endif
@ -235,9 +198,9 @@ static inline bool test_variant2_int_sqrt_fp64(const uint64_t sqrt_input, const
VARIANT2_INTEGER_MATH_SQRT_STEP_FP64();
VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result);
if (sqrt_result != correct_result) {
cerr << "Integer sqrt (FP64 version) returned incorrect result for N = " << sqrt_input << endl;
cerr << "Expected result: " << correct_result << endl;
cerr << "Returned result: " << sqrt_result << endl;
std::cerr << "Integer sqrt (FP64 version) returned incorrect result for N = " << sqrt_input << "\n";
std::cerr << "Expected result: " << correct_result << "\n";
std::cerr << "Returned result: " << sqrt_result << "\n";
return false;
}
#endif
@ -250,9 +213,9 @@ static inline bool test_variant2_int_sqrt_ref(const uint64_t sqrt_input, const u
uint64_t sqrt_result;
VARIANT2_INTEGER_MATH_SQRT_STEP_REF();
if (sqrt_result != correct_result) {
cerr << "Integer sqrt (reference version) returned incorrect result for N = " << sqrt_input << endl;
cerr << "Expected result: " << correct_result << endl;
cerr << "Returned result: " << sqrt_result << endl;
std::cerr << "Integer sqrt (reference version) returned incorrect result for N = " << sqrt_input << "\n";
std::cerr << "Expected result: " << correct_result << "\n";
std::cerr << "Returned result: " << sqrt_result << "\n";
return false;
}

View File

@ -35,11 +35,12 @@
#include <vector>
#include <oxenc/hex.h>
inline bool hexdecode(const char *from, std::size_t length, void *to) {
const char* end = from + 2*length;
template <typename Char>
inline bool hexdecode(const Char *from, std::size_t length, void *to) {
const Char* end = from + 2*length;
if (!oxenc::is_hex(from, end))
return false;
oxenc::from_hex(from, end, reinterpret_cast<char*>(to));
oxenc::from_hex(from, end, reinterpret_cast<Char*>(to));
return true;
}
@ -73,7 +74,8 @@ void get(std::istream &input, T &res) {
getvar(input, sizeof(T), &res);
}
inline void get(std::istream &input, std::vector<char> &res) {
template <typename Char, std::enable_if_t<sizeof(Char) == 1 && std::is_scalar_v<Char>, int> = 0>
inline void get(std::istream &input, std::vector<Char> &res) {
std::string sres;
input >> sres;
if (sres == "x") {

View File

@ -445,7 +445,7 @@ bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pend
static tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
{
tools::wallet2::tx_construction_data construction_data = ptx.construction_data;
crypto::hash8 payment_id = crypto::null_hash8;
crypto::hash8 payment_id{};
if (get_short_payment_id(payment_id, ptx, hwdev))
{
// Remove encrypted

View File

@ -32,6 +32,7 @@
#include <sstream>
#include <string>
#include "common/string_util.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
namespace
@ -76,8 +77,36 @@ TEST(Crypto, null_keys)
{
char zero[32];
memset(zero, 0, 32);
ASSERT_EQ(memcmp(crypto::null_skey.data, zero, 32), 0);
ASSERT_EQ(memcmp(crypto::null_pkey.data, zero, 32), 0);
ASSERT_EQ(memcmp(crypto::null<crypto::secret_key>.data(), zero, 32), 0);
ASSERT_EQ(memcmp(crypto::null<crypto::public_key>.data(), zero, 32), 0);
ASSERT_EQ(memcmp(crypto::public_key{}.data(), zero, 32), 0);
ASSERT_EQ(memcmp(crypto::secret_key{}.data(), zero, 32), 0);
}
TEST(Crypto, equality)
{
crypto::public_key pk1{};
std::copy(source.data(), source.data() + 32, pk1.begin());
ASSERT_EQ("{}"_format(pk1), "<{}>"_format(hex_full.substr(0, 64)));
crypto::public_key pk2 = pk1;
ASSERT_EQ(tools::view_guts(pk1), tools::view_guts(pk2));
EXPECT_EQ(pk1, pk2);
crypto::public_key pk3;
std::copy(source.data(), source.data() + 32, pk3.begin());
ASSERT_EQ(tools::view_guts(pk1), tools::view_guts(pk3));
EXPECT_EQ(pk1, pk3);
pk3.zero();
ASSERT_EQ("{}"_format(pk3), "<{:064x}>"_format(0));
ASSERT_NE(tools::view_guts(pk1), tools::view_guts(pk3));
EXPECT_NE(pk1, pk3);
EXPECT_LT(pk3, pk1);
std::copy(source.data() + 32, source.data() + 64, pk2.begin());
ASSERT_EQ("{}"_format(pk2), "<{}>"_format(hex_full.substr(64)));
EXPECT_NE(pk1, pk2);
EXPECT_LT(pk2, pk1);
EXPECT_FALSE(pk1 == pk2);
EXPECT_FALSE(pk1 < pk2);
}
TEST(Crypto, verify_32)

Some files were not shown because too many files have changed in this diff Show More