mirror of https://github.com/oxen-io/oxen-core.git
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:
parent
5b4a60b412
commit
6aa9db9538
|
@ -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 '') +
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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!");
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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> {};
|
||||
|
|
|
@ -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)
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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> {};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ×);
|
||||
|
||||
} // namespace pulse
|
||||
|
||||
template <> inline constexpr bool formattable::via_to_string<pulse::message_type> = true;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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}};
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 + "'");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
#include <cstddef>
|
||||
#include <tuple>
|
||||
|
||||
#include "crypto/generic-ops.h"
|
||||
|
||||
extern "C" {
|
||||
#include "crypto/random.h"
|
||||
#include "crypto/keccak.h"
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
#include "crypto/generic-ops.h"
|
||||
|
||||
extern "C" {
|
||||
#include "crypto/random.h"
|
||||
#include "crypto/keccak.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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("");
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
10
tests/io.h
10
tests/io.h
|
@ -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") {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue