2019-04-12 06:36:43 +02:00
|
|
|
// Copyright (c) 2017-2019, The Monero Project
|
2018-04-10 06:49:20 +02:00
|
|
|
// Copyright (c) 2018, The Loki Project
|
2018-02-20 17:01:27 +01:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
|
2022-10-08 04:30:29 +02:00
|
|
|
#include "common/string_util.h"
|
2021-06-25 22:14:00 +02:00
|
|
|
#include "device/io_ledger_tcp.hpp"
|
2021-06-25 17:07:57 +02:00
|
|
|
#include "io_hid.hpp"
|
2018-12-11 10:20:21 +01:00
|
|
|
#include "version.h"
|
2018-02-20 17:01:27 +01:00
|
|
|
#include "device_ledger.hpp"
|
|
|
|
#include "ringct/rctOps.h"
|
2018-03-05 08:16:30 +01:00
|
|
|
#include "cryptonote_basic/account.h"
|
|
|
|
#include "cryptonote_basic/subaddress_index.h"
|
2018-12-11 10:20:21 +01:00
|
|
|
#include "cryptonote_core/cryptonote_tx_utils.h"
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
#include "common/lock.h"
|
2020-07-20 04:29:01 +02:00
|
|
|
#include "common/varint.h"
|
2020-11-27 22:55:46 +01:00
|
|
|
#include <chrono>
|
2022-09-13 08:57:56 +02:00
|
|
|
#include "logging/oxen_logger.h"
|
2022-05-17 17:59:30 +02:00
|
|
|
#include <oxenc/endian.h>
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-12-07 04:20:49 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
#include <sodium/crypto_generichash.h>
|
|
|
|
#endif
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
namespace hw::ledger {
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
#ifdef WITH_DEVICE_LEDGER
|
|
|
|
|
2022-09-23 01:27:12 +02:00
|
|
|
static auto logcat = log::Cat("device.ledger");
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* === Debug ==== */
|
|
|
|
/* ===================================================================== */
|
2018-05-23 10:22:55 +02:00
|
|
|
|
2020-12-08 20:34:57 +01:00
|
|
|
namespace {
|
2020-11-28 03:59:45 +01:00
|
|
|
|
2020-12-08 20:34:57 +01:00
|
|
|
bool apdu_verbose = true;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 00:53:05 +01:00
|
|
|
#define LEDGER_STATUS(status) {status, #status##sv}
|
|
|
|
constexpr std::pair<unsigned int, std::string_view> status_codes[] = {
|
2020-11-29 23:27:34 +01:00
|
|
|
LEDGER_STATUS(SW_SECURITY_PIN_LOCKED),
|
2020-02-07 15:20:38 +01:00
|
|
|
LEDGER_STATUS(SW_SECURITY_LOAD_KEY),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_COMMITMENT_CONTROL),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_AMOUNT_CHAIN_CONTROL),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_COMMITMENT_CHAIN_CONTROL),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_OUTKEYS_CHAIN_CONTROL),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_MAXOUTPUT_REACHED),
|
2020-11-29 23:27:34 +01:00
|
|
|
LEDGER_STATUS(SW_SECURITY_HMAC),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_RANGE_VALUE),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_INTERNAL),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_MAX_SIGNATURE_REACHED),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_PREFIX_HASH),
|
|
|
|
LEDGER_STATUS(SW_SECURITY_LOCKED),
|
|
|
|
|
2020-02-07 15:20:38 +01:00
|
|
|
LEDGER_STATUS(SW_COMMAND_NOT_ALLOWED),
|
2020-11-29 23:27:34 +01:00
|
|
|
LEDGER_STATUS(SW_SUBCOMMAND_NOT_ALLOWED),
|
|
|
|
LEDGER_STATUS(SW_DENY),
|
|
|
|
LEDGER_STATUS(SW_KEY_NOT_SET),
|
2020-02-07 15:20:38 +01:00
|
|
|
LEDGER_STATUS(SW_WRONG_DATA),
|
2020-11-29 23:27:34 +01:00
|
|
|
LEDGER_STATUS(SW_WRONG_DATA_RANGE),
|
|
|
|
LEDGER_STATUS(SW_IO_FULL),
|
|
|
|
|
|
|
|
LEDGER_STATUS(SW_CLIENT_NOT_SUPPORTED),
|
|
|
|
|
2020-02-07 15:20:38 +01:00
|
|
|
LEDGER_STATUS(SW_WRONG_P1P2),
|
|
|
|
LEDGER_STATUS(SW_INS_NOT_SUPPORTED),
|
2020-11-29 23:27:34 +01:00
|
|
|
LEDGER_STATUS(SW_PROTOCOL_NOT_SUPPORTED),
|
|
|
|
|
2020-02-07 15:20:38 +01:00
|
|
|
LEDGER_STATUS(SW_UNKNOWN),
|
|
|
|
};
|
|
|
|
|
2020-12-08 20:34:57 +01:00
|
|
|
std::string status_string(unsigned int code)
|
2020-02-07 15:20:38 +01:00
|
|
|
{
|
2020-11-28 00:53:05 +01:00
|
|
|
for (auto& [code_, str] : status_codes)
|
|
|
|
if (code_ == code)
|
2020-12-08 20:34:57 +01:00
|
|
|
return std::string{str};
|
|
|
|
if ((code & 0xff00) == SW_WRONG_LENGTH)
|
|
|
|
return "SW_WRONG_LENGTH(" + std::to_string(code & 0xff) + ")";
|
|
|
|
return "UNKNOWN"s;
|
2020-02-07 15:20:38 +01:00
|
|
|
}
|
|
|
|
|
2020-12-08 20:34:57 +01:00
|
|
|
} // anon namespace
|
|
|
|
|
|
|
|
void set_apdu_verbose(bool verbose) {
|
|
|
|
apdu_verbose = verbose;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
crypto::secret_key dbg_viewkey;
|
|
|
|
crypto::secret_key dbg_spendkey;
|
|
|
|
#endif
|
2020-11-28 00:53:05 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
/* ===================================================================== */
|
|
|
|
/* === hmacmap ==== */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
|
|
|
|
SecHMAC::SecHMAC(const uint8_t s[32], const uint8_t h[32]) {
|
2020-11-28 03:59:45 +01:00
|
|
|
std::memcpy(sec, s, 32);
|
|
|
|
std::memcpy(hmac, h, 32);
|
2019-09-25 14:31:14 +02:00
|
|
|
}
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
void HMACmap::find_mac(const uint8_t sec[32], uint8_t hmac[32]) {
|
2019-09-25 14:31:14 +02:00
|
|
|
size_t sz = hmacs.size();
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("find_mac: lookup for ", sec,32);
|
2021-06-25 17:07:57 +02:00
|
|
|
for (auto& h : hmacs) {
|
|
|
|
log_hexbuffer("find_mac: - try ", h.sec, 32);
|
|
|
|
if (memcmp(sec, h.sec, 32) == 0) {
|
|
|
|
std::memcpy(hmac, h.hmac, 32);
|
|
|
|
log_hexbuffer("find_mac: - found ", h.hmac, 32);
|
2019-09-25 14:31:14 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
throw std::runtime_error("Protocol error: try to send untrusted secret");
|
|
|
|
}
|
|
|
|
|
|
|
|
void HMACmap::add_mac(const uint8_t sec[32], const uint8_t hmac[32]) {
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("add_mac: sec ", sec, 32);
|
|
|
|
log_hexbuffer("add_mac: hmac ", hmac, 32);
|
2019-09-25 14:31:14 +02:00
|
|
|
hmacs.push_back(SecHMAC(sec,hmac));
|
|
|
|
}
|
|
|
|
|
|
|
|
void HMACmap::clear() {
|
|
|
|
hmacs.clear();
|
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ===================================================================== */
|
|
|
|
/* === Keymap ==== */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const bool is_change, const bool need_additional_txkeys, const size_t real_output_index, const rct::key& P, const rct::key& AK) {
|
2018-02-20 17:01:27 +01:00
|
|
|
Aout = A;
|
|
|
|
Bout = B;
|
2018-03-05 14:46:15 +01:00
|
|
|
is_subaddress = is_subaddr;
|
2018-12-11 10:20:21 +01:00
|
|
|
is_change_address = is_change;
|
|
|
|
additional_key = need_additional_txkeys;
|
2018-02-20 17:01:27 +01:00
|
|
|
index = real_output_index;
|
|
|
|
Pout = P;
|
|
|
|
AKout = AK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ABPkeys::ABPkeys(const ABPkeys& keys) {
|
2018-03-05 14:46:15 +01:00
|
|
|
Aout = keys.Aout;
|
|
|
|
Bout = keys.Bout;
|
|
|
|
is_subaddress = keys.is_subaddress;
|
2018-12-11 10:20:21 +01:00
|
|
|
is_change_address = keys.is_change_address;
|
|
|
|
additional_key = keys.additional_key;
|
2018-02-20 17:01:27 +01:00
|
|
|
index = keys.index;
|
2018-03-05 14:46:15 +01:00
|
|
|
Pout = keys.Pout;
|
2018-02-20 17:01:27 +01:00
|
|
|
AKout = keys.AKout;
|
|
|
|
}
|
|
|
|
|
2019-06-08 17:58:33 +02:00
|
|
|
ABPkeys &ABPkeys::operator=(const ABPkeys& keys) {
|
|
|
|
if (&keys == this)
|
|
|
|
return *this;
|
|
|
|
Aout = keys.Aout;
|
|
|
|
Bout = keys.Bout;
|
|
|
|
is_subaddress = keys.is_subaddress;
|
|
|
|
is_change_address = keys.is_change_address;
|
|
|
|
additional_key = keys.additional_key;
|
|
|
|
index = keys.index;
|
|
|
|
Pout = keys.Pout;
|
|
|
|
AKout = keys.AKout;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
bool Keymap::find(const rct::key& P, ABPkeys& keys) const {
|
2021-06-25 17:07:57 +02:00
|
|
|
for (auto& abp : ABP) {
|
|
|
|
if (abp.Pout == P) {
|
|
|
|
keys = abp;
|
2018-02-20 17:01:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Keymap::add(const ABPkeys& keys) {
|
|
|
|
ABP.push_back(keys);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Keymap::clear() {
|
|
|
|
ABP.clear();
|
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2018-02-20 17:01:27 +01:00
|
|
|
void Keymap::log() {
|
|
|
|
log_message("keymap", "content");
|
|
|
|
size_t sz = ABP.size();
|
|
|
|
for (size_t i=0; i<sz; i++) {
|
|
|
|
log_message(" keymap", std::to_string(i));
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer(" Aout", ABP[i].Aout.bytes, 32);
|
|
|
|
log_hexbuffer(" Bout", ABP[i].Bout.bytes, 32);
|
2018-03-05 14:46:15 +01:00
|
|
|
log_message (" is_sub", std::to_string(ABP[i].is_subaddress));
|
2018-02-20 17:01:27 +01:00
|
|
|
log_message (" index", std::to_string(ABP[i].index));
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer(" Pout", ABP[i].Pout.bytes, 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
2018-03-26 12:55:48 +02:00
|
|
|
/* === Internal Helpers ==== */
|
|
|
|
/* ===================================================================== */
|
|
|
|
static bool is_fake_view_key(const crypto::secret_key &sec) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
return !sec;
|
2018-03-26 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2018-04-09 16:07:11 +02:00
|
|
|
bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) {
|
2018-06-13 19:23:06 +02:00
|
|
|
static_assert(sizeof(crypto::key_derivation) == 32, "key_derivation must be 32 bytes");
|
2020-11-28 00:34:49 +01:00
|
|
|
return !crypto_verify_32(reinterpret_cast<const unsigned char*>(&d0), reinterpret_cast<const unsigned char*>(&d1));
|
2018-04-09 16:07:11 +02:00
|
|
|
}
|
|
|
|
|
2018-03-26 12:55:48 +02:00
|
|
|
/* ===================================================================== */
|
|
|
|
/* === Device ==== */
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
static int device_id = 0;
|
|
|
|
|
2020-11-27 03:56:41 +01:00
|
|
|
#define PROTOCOL_VERSION 1
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-28 00:35:10 +01:00
|
|
|
#ifdef NDEBUG
|
|
|
|
#define LEDGER_INS(name, code) \
|
|
|
|
static constexpr uint8_t INS_##name = code
|
|
|
|
#else
|
|
|
|
// Reverse lookup table for commands -> names, only available in debug compilations
|
|
|
|
static std::unordered_map<uint8_t, std::string_view> debug_ins_names;
|
|
|
|
static uint8_t debug_record_ins(uint8_t code, std::string_view name) { debug_ins_names.emplace(code, name); return code; }
|
|
|
|
|
|
|
|
#define LEDGER_INS(name, code) \
|
|
|
|
static const uint8_t INS_##name = debug_record_ins(code, #name##sv)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
LEDGER_INS(RESET, 0x02);
|
|
|
|
|
|
|
|
LEDGER_INS(GET_NETWORK, 0x10);
|
|
|
|
|
|
|
|
LEDGER_INS(GET_KEY, 0x20);
|
|
|
|
LEDGER_INS(DISPLAY_ADDRESS, 0x21);
|
|
|
|
LEDGER_INS(PUT_KEY, 0x22);
|
|
|
|
LEDGER_INS(GET_CHACHA8_PREKEY, 0x24);
|
|
|
|
LEDGER_INS(VERIFY_KEY, 0x26);
|
|
|
|
|
|
|
|
LEDGER_INS(SECRET_KEY_TO_PUBLIC_KEY, 0x30);
|
|
|
|
LEDGER_INS(GEN_KEY_DERIVATION, 0x32);
|
|
|
|
LEDGER_INS(DERIVATION_TO_SCALAR, 0x34);
|
|
|
|
LEDGER_INS(DERIVE_PUBLIC_KEY, 0x36);
|
|
|
|
LEDGER_INS(DERIVE_SECRET_KEY, 0x38);
|
|
|
|
LEDGER_INS(GEN_KEY_IMAGE, 0x3A);
|
|
|
|
LEDGER_INS(SECRET_KEY_ADD, 0x3C);
|
|
|
|
LEDGER_INS(SECRET_KEY_SUB, 0x3E);
|
|
|
|
LEDGER_INS(GENERATE_KEYPAIR, 0x40);
|
|
|
|
LEDGER_INS(SECRET_SCAL_MUL_KEY, 0x42);
|
|
|
|
LEDGER_INS(SECRET_SCAL_MUL_BASE, 0x44);
|
|
|
|
|
|
|
|
LEDGER_INS(DERIVE_SUBADDRESS_PUBLIC_KEY, 0x46);
|
|
|
|
LEDGER_INS(GET_SUBADDRESS, 0x48);
|
|
|
|
LEDGER_INS(GET_SUBADDRESS_SPEND_PUBLIC_KEY, 0x4A);
|
|
|
|
LEDGER_INS(GET_SUBADDRESS_SECRET_KEY, 0x4C);
|
|
|
|
|
|
|
|
LEDGER_INS(OPEN_TX, 0x70);
|
|
|
|
LEDGER_INS(SET_SIGNATURE_MODE, 0x72);
|
|
|
|
LEDGER_INS(GET_ADDITIONAL_KEY, 0x74);
|
2020-12-04 16:56:46 +01:00
|
|
|
LEDGER_INS(GET_TX_SECRET_KEY, 0x75);
|
2020-12-08 20:49:49 +01:00
|
|
|
LEDGER_INS(ENCRYPT_PAYMENT_ID, 0x76);
|
2020-11-28 00:35:10 +01:00
|
|
|
LEDGER_INS(GEN_COMMITMENT_MASK, 0x77);
|
|
|
|
LEDGER_INS(BLIND, 0x78);
|
|
|
|
LEDGER_INS(UNBLIND, 0x7A);
|
|
|
|
LEDGER_INS(GEN_TXOUT_KEYS, 0x7B);
|
|
|
|
LEDGER_INS(PREFIX_HASH, 0x7D);
|
|
|
|
LEDGER_INS(VALIDATE, 0x7C);
|
|
|
|
LEDGER_INS(CLSAG, 0x7F);
|
|
|
|
LEDGER_INS(CLOSE_TX, 0x80);
|
|
|
|
|
|
|
|
LEDGER_INS(GET_TX_PROOF, 0xA0);
|
2020-12-07 04:17:07 +01:00
|
|
|
LEDGER_INS(GEN_UNLOCK_SIGNATURE, 0xA2);
|
2021-02-12 05:19:30 +01:00
|
|
|
LEDGER_INS(GEN_ONS_SIGNATURE, 0xA3);
|
2020-12-07 04:21:46 +01:00
|
|
|
LEDGER_INS(GEN_KEY_IMAGE_SIGNATURE, 0xA4);
|
2020-11-28 00:35:10 +01:00
|
|
|
|
|
|
|
LEDGER_INS(GET_RESPONSE, 0xc0);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#define OPTION_MORE_DATA 0x80
|
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
// When we have to send a bunch of data to be keccak hashed we send in chunks of this size; we
|
|
|
|
// could go up to 254, but Keccak uses 136-byte chunks so it makes some sense to send at that
|
|
|
|
// size.
|
|
|
|
constexpr size_t KECCAK_HASH_CHUNK_SIZE = 136;
|
|
|
|
static_assert(KECCAK_HASH_CHUNK_SIZE <= 254, "Max keccak data chunk size exceeds the protocol limit");
|
|
|
|
|
2020-12-07 04:20:49 +01:00
|
|
|
constexpr size_t BLAKE2B_HASH_CHUNK_SIZE = 128;
|
|
|
|
static_assert(BLAKE2B_HASH_CHUNK_SIZE <= 254, "Max BLAKE2b data chunk size exceeds the protocol limit");
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2021-06-25 22:14:00 +02:00
|
|
|
device_ledger::device_ledger() : hw_device{std::make_unique<io::hid>(0x0101, 0x05, 64, 2000)} {
|
2020-11-28 03:59:45 +01:00
|
|
|
id = device_id++;
|
|
|
|
reset_buffer();
|
|
|
|
has_view_key = false;
|
|
|
|
tx_in_progress = false;
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} Created", id);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2021-06-25 22:14:00 +02:00
|
|
|
device_ledger::device_ledger(io::ledger_tcp&& tcp) : hw_device{std::make_unique<io::ledger_tcp>(std::move(tcp))} {
|
|
|
|
id = device_id++;
|
|
|
|
reset_buffer();
|
|
|
|
has_view_key = false;
|
|
|
|
tx_in_progress = false;
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} (tcp) created", id);
|
2021-06-25 22:14:00 +02:00
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
device_ledger::~device_ledger() {
|
2020-11-28 03:59:45 +01:00
|
|
|
release();
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} Destroyed", id);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
/* ======================================================================= */
|
|
|
|
/* LOCKER */
|
2020-11-27 03:38:57 +01:00
|
|
|
/* ======================================================================= */
|
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
//lock the device for a long sequence
|
2020-11-28 03:59:45 +01:00
|
|
|
void device_ledger::lock() {
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Ask for LOCKING for device {} in thread ", name);
|
2018-03-26 12:38:38 +02:00
|
|
|
device_locker.lock();
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} LOCKed", name);
|
2018-03-26 12:38:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//lock the device for a long sequence
|
2020-11-28 03:59:45 +01:00
|
|
|
bool device_ledger::try_lock() {
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Ask for LOCKING(try) for device {} in thread ", name);
|
2018-03-26 12:38:38 +02:00
|
|
|
bool r = device_locker.try_lock();
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {}{} LOCKed(try)", name, (r ? "" : " not"));
|
2018-03-26 12:38:38 +02:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
//unlock the device after a long sequence
|
|
|
|
void device_ledger::unlock() {
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Ask for UNLOCKING for device {} in thread ", name);
|
2018-03-26 12:38:38 +02:00
|
|
|
device_locker.unlock();
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} UNLOCKed", name);
|
2018-03-26 12:38:38 +02:00
|
|
|
}
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ======================================================================= */
|
2018-08-01 09:24:53 +02:00
|
|
|
/* IO */
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ======================================================================= */
|
2018-08-01 09:24:53 +02:00
|
|
|
|
2019-01-09 09:20:53 +01:00
|
|
|
#define IO_SW_DENY 0x6982
|
|
|
|
#define IO_SECRET_KEY 0x02
|
|
|
|
|
2018-08-01 09:24:53 +02:00
|
|
|
void device_ledger::logCMD() {
|
|
|
|
if (apdu_verbose) {
|
2020-11-28 00:35:10 +01:00
|
|
|
std::ostringstream cmd;
|
|
|
|
cmd << std::hex << std::setfill('0');
|
|
|
|
cmd << "v=0x" << std::setw(2) << +buffer_send[0];
|
|
|
|
cmd << " i=0x" << std::setw(2) << +buffer_send[1];
|
|
|
|
#ifndef NDEBUG
|
|
|
|
if (auto it = debug_ins_names.find(buffer_send[1]); it != debug_ins_names.end())
|
|
|
|
cmd << '[' << it->second << ']';
|
|
|
|
#endif
|
|
|
|
cmd << " p=(0x" << std::setw(2) << +buffer_send[2] << ",0x" << std::setw(2) << +buffer_send[3] << ')';
|
|
|
|
cmd << " sz=0x" << std::setw(2) << +buffer_send[4] << '[' << std::to_string(buffer_send[4]) << "] ";
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "CMD: {}{}", cmd.str(), oxenc::to_hex(buffer_send + 5, buffer_send + length_send));
|
2020-11-27 22:55:46 +01:00
|
|
|
last_cmd = std::chrono::steady_clock::now();
|
2018-08-01 09:24:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::logRESP() {
|
2020-11-27 03:38:57 +01:00
|
|
|
if (apdu_verbose)
|
2022-10-08 04:30:29 +02:00
|
|
|
log::debug(logcat, "RESP (+{}): {} {}", tools::friendly_duration(std::chrono::steady_clock::now() - last_cmd), oxenc::to_hex(std::string_view{reinterpret_cast<const char*>(&sw), sizeof(sw)}), oxenc::to_hex(buffer_recv, buffer_recv + length_recv));
|
2018-08-01 09:24:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) {
|
2018-06-20 11:40:09 +02:00
|
|
|
reset_buffer();
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[0] = PROTOCOL_VERSION;
|
|
|
|
buffer_send[1] = ins;
|
|
|
|
buffer_send[2] = p1;
|
|
|
|
buffer_send[3] = p2;
|
|
|
|
buffer_send[4] = 0x00;
|
2018-06-20 11:40:09 +02:00
|
|
|
return 5;
|
|
|
|
}
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-08-01 09:24:53 +02:00
|
|
|
int device_ledger::set_command_header_noopt(unsigned char ins, unsigned char p1, unsigned char p2) {
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header(ins, p1, p2);
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = 0; // options
|
|
|
|
buffer_send[4] = offset - 5;
|
2018-06-20 11:40:09 +02:00
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2018-08-01 09:24:53 +02:00
|
|
|
void device_ledger::send_simple(unsigned char ins, unsigned char p1) {
|
2020-11-28 03:59:45 +01:00
|
|
|
length_send = set_command_header_noopt(ins, p1);
|
|
|
|
bool wait = ins == INS_GET_KEY && p1 == IO_SECRET_KEY;
|
|
|
|
exchange(wait);
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::send_bytes(const void* buf, size_t size, int& offset) {
|
2020-12-08 20:49:49 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(offset + size <= BUFFER_SEND_SIZE, "send_bytes: out of bounds write");
|
2020-11-28 03:59:45 +01:00
|
|
|
std::memmove(buffer_send+offset, buf, size);
|
|
|
|
offset += size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::receive_bytes(void* dest, size_t size, int& offset) {
|
2020-12-08 20:49:49 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(offset + size <= BUFFER_RECV_SIZE, "receive_bytes: out of bounds read");
|
2020-11-28 03:59:45 +01:00
|
|
|
std::memmove(dest, buffer_recv+offset, size);
|
|
|
|
offset += size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::receive_bytes(void* dest, size_t size) {
|
|
|
|
int offset = 0;
|
|
|
|
receive_bytes(dest, size, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::send_u32(uint32_t x, int& offset) {
|
2022-05-17 17:59:30 +02:00
|
|
|
oxenc::host_to_big_inplace(x);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(&x, 4, offset);
|
|
|
|
}
|
|
|
|
|
2020-12-07 04:19:20 +01:00
|
|
|
void device_ledger::send_u16(uint16_t x, int& offset) {
|
2022-05-17 17:59:30 +02:00
|
|
|
oxenc::host_to_big_inplace(x);
|
2020-12-07 04:19:20 +01:00
|
|
|
send_bytes(&x, 2, offset);
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
uint32_t device_ledger::receive_u32(int& offset) {
|
|
|
|
uint32_t x;
|
|
|
|
receive_bytes(&x, 4, offset);
|
2022-05-17 17:59:30 +02:00
|
|
|
oxenc::big_to_host_inplace(x);
|
2020-11-28 03:59:45 +01:00
|
|
|
return x;
|
|
|
|
}
|
|
|
|
uint32_t device_ledger::receive_u32() {
|
|
|
|
int offset = 0;
|
|
|
|
return receive_u32(offset);
|
2018-06-20 11:40:09 +02:00
|
|
|
}
|
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
void device_ledger::send_secret(const unsigned char sec[32], int &offset) {
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "send_secret: {}", tx_in_progress);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(sec, 32, offset);
|
|
|
|
if (tx_in_progress) {
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(offset + 32 <= BUFFER_SEND_SIZE, "send_secret: out of bounds write (mac)");
|
|
|
|
hmac_map.find_mac((uint8_t*)sec, buffer_send+offset);
|
2019-09-25 14:31:14 +02:00
|
|
|
offset += 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::receive_secret(unsigned char sec[32], int &offset) {
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "receive_secret: {}", tx_in_progress);
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(sec, 32, offset);
|
|
|
|
if (tx_in_progress) {
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(offset + 32 <= BUFFER_RECV_SIZE, "receive_secret: out of bounds read (mac)");
|
|
|
|
hmac_map.add_mac((uint8_t*)sec, buffer_recv+offset);
|
2019-09-25 14:31:14 +02:00
|
|
|
offset += 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
void device_ledger::send_finish(int& offset) {
|
|
|
|
buffer_send[4] = offset-5;
|
|
|
|
length_send = offset;
|
|
|
|
offset = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int device_ledger::finish_and_exchange(int& offset, bool wait_on_input) {
|
|
|
|
send_finish(offset);
|
2020-11-29 23:27:34 +01:00
|
|
|
return exchange(wait_on_input);
|
2020-11-28 03:59:45 +01:00
|
|
|
}
|
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
bool device_ledger::reset() {
|
2019-03-07 23:34:53 +01:00
|
|
|
reset_buffer();
|
|
|
|
int offset = set_command_header_noopt(INS_RESET);
|
2021-01-04 04:19:42 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(offset + OXEN_VERSION_STR.size() <= BUFFER_SEND_SIZE, "OXEN_VERSION_STR is too long");
|
|
|
|
send_bytes(OXEN_VERSION_STR.data(), OXEN_VERSION_STR.size(), offset);
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2019-03-07 23:34:53 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(length_recv>=3, "Communication error, less than three bytes received. Check your application version.");
|
2019-03-07 23:34:53 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
std::array<uint8_t, 3> device_version = {buffer_recv[0], buffer_recv[1], buffer_recv[2]};
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(device_version >= MINIMUM_APP_VERSION,
|
|
|
|
"Unsupported device application version: " << tools::join(".", device_version) <<
|
|
|
|
" At least " << tools::join(".", MINIMUM_APP_VERSION) << " is required.");
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2019-03-07 23:34:53 +01:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
unsigned int device_ledger::exchange(bool wait_on_input) {
|
2018-02-20 17:01:27 +01:00
|
|
|
logCMD();
|
|
|
|
|
2021-06-25 22:14:00 +02:00
|
|
|
length_recv = hw_device->exchange(buffer_send, length_send, buffer_recv, BUFFER_RECV_SIZE, wait_on_input);
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(length_recv >= 2, "Communication error, less than two bytes received");
|
2018-08-01 09:24:53 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
length_recv -= 2;
|
|
|
|
sw = (buffer_recv[length_recv] << 8) | buffer_recv[length_recv+1];
|
2018-12-11 10:20:21 +01:00
|
|
|
logRESP();
|
2018-08-01 09:24:53 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
// If we are waiting on input then we also want to be able to return a DENY
|
|
|
|
if (wait_on_input && sw == IO_SW_DENY)
|
|
|
|
return sw;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(sw == SW_OK,
|
|
|
|
"Wrong Device Status: " << "0x" << std::hex << sw << " (" << status_string(sw) << "), " <<
|
|
|
|
"EXPECTED 0x" << std::hex << SW_OK << " (" << status_string(SW_OK) << "), ");
|
2019-01-09 09:20:53 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
return sw;
|
2019-01-09 09:20:53 +01:00
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
void device_ledger::reset_buffer() {
|
2020-11-28 03:59:45 +01:00
|
|
|
length_send = 0;
|
|
|
|
std::memset(buffer_send, 0, BUFFER_SEND_SIZE);
|
|
|
|
length_recv = 0;
|
|
|
|
std::memset(buffer_recv, 0, BUFFER_RECV_SIZE);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ======================================================================= */
|
|
|
|
/* SETUP/TEARDOWN */
|
|
|
|
/* ======================================================================= */
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
bool device_ledger::set_name(std::string_view n) {
|
|
|
|
name = name;
|
2018-02-20 17:01:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
std::string device_ledger::get_name() const {
|
|
|
|
if (!connected())
|
|
|
|
return "<disconnected:" + name + ">";
|
|
|
|
return name;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2021-06-25 22:14:00 +02:00
|
|
|
void device_ledger::set_address(std::string_view addr) {
|
|
|
|
if (addr.empty() || !hw_device)
|
|
|
|
return;
|
|
|
|
auto* tcp = dynamic_cast<io::ledger_tcp*>(hw_device.get());
|
|
|
|
if (!tcp)
|
|
|
|
return;
|
|
|
|
if (auto pos = addr.rfind(':'); pos != addr.npos) {
|
|
|
|
tcp->port = addr.substr(pos + 1);
|
|
|
|
addr = addr.substr(0, pos);
|
|
|
|
}
|
|
|
|
tcp->host = addr;
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
bool device_ledger::init() {
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
debug_device = &get_device("default");
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-11-28 03:59:45 +01:00
|
|
|
release();
|
2021-06-25 22:14:00 +02:00
|
|
|
hw_device->init();
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Device {} HIDUSB inited", id);
|
2018-02-20 17:01:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
static const std::vector<io::hid_conn_params> known_devices {
|
2021-11-04 23:33:48 +01:00
|
|
|
// Nano S
|
|
|
|
{0x2c97, 0x1000, 0, 0xffa0}, {0x2c97, 0x1001, 0, 0xffa0}, {0x2c97, 0x1002, 0, 0xffa0}, {0x2c97, 0x1003, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1004, 0, 0xffa0}, {0x2c97, 0x1005, 0, 0xffa0}, {0x2c97, 0x1006, 0, 0xffa0}, {0x2c97, 0x1007, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1008, 0, 0xffa0}, {0x2c97, 0x1009, 0, 0xffa0}, {0x2c97, 0x100a, 0, 0xffa0}, {0x2c97, 0x100b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x100c, 0, 0xffa0}, {0x2c97, 0x100d, 0, 0xffa0}, {0x2c97, 0x100e, 0, 0xffa0}, {0x2c97, 0x100f, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1010, 0, 0xffa0}, {0x2c97, 0x1011, 0, 0xffa0}, {0x2c97, 0x1012, 0, 0xffa0}, {0x2c97, 0x1013, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1014, 0, 0xffa0}, {0x2c97, 0x1015, 0, 0xffa0}, {0x2c97, 0x1016, 0, 0xffa0}, {0x2c97, 0x1017, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1018, 0, 0xffa0}, {0x2c97, 0x1019, 0, 0xffa0}, {0x2c97, 0x101a, 0, 0xffa0}, {0x2c97, 0x101b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x101c, 0, 0xffa0}, {0x2c97, 0x101d, 0, 0xffa0}, {0x2c97, 0x101e, 0, 0xffa0}, {0x2c97, 0x101f, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x1005, 0, 0xffa0},
|
|
|
|
// Nano X
|
|
|
|
{0x2c97, 0x4000, 0, 0xffa0}, {0x2c97, 0x4001, 0, 0xffa0}, {0x2c97, 0x4002, 0, 0xffa0}, {0x2c97, 0x4003, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x4004, 0, 0xffa0}, {0x2c97, 0x4005, 0, 0xffa0}, {0x2c97, 0x4006, 0, 0xffa0}, {0x2c97, 0x4007, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x4008, 0, 0xffa0}, {0x2c97, 0x4009, 0, 0xffa0}, {0x2c97, 0x400a, 0, 0xffa0}, {0x2c97, 0x400b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x400c, 0, 0xffa0}, {0x2c97, 0x400d, 0, 0xffa0}, {0x2c97, 0x400e, 0, 0xffa0}, {0x2c97, 0x400f, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x4010, 0, 0xffa0}, {0x2c97, 0x4011, 0, 0xffa0}, {0x2c97, 0x4012, 0, 0xffa0}, {0x2c97, 0x4013, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x4014, 0, 0xffa0}, {0x2c97, 0x4015, 0, 0xffa0}, {0x2c97, 0x4016, 0, 0xffa0}, {0x2c97, 0x4017, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x4018, 0, 0xffa0}, {0x2c97, 0x4019, 0, 0xffa0}, {0x2c97, 0x401a, 0, 0xffa0}, {0x2c97, 0x401b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x401c, 0, 0xffa0}, {0x2c97, 0x401d, 0, 0xffa0}, {0x2c97, 0x401e, 0, 0xffa0}, {0x2c97, 0x401f, 0, 0xffa0},
|
2022-06-29 07:27:22 +02:00
|
|
|
// Nano S Plus
|
|
|
|
{0x2c97, 0x5000, 0, 0xffa0}, {0x2c97, 0x5001, 0, 0xffa0}, {0x2c97, 0x5002, 0, 0xffa0}, {0x2c97, 0x5003, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x5004, 0, 0xffa0}, {0x2c97, 0x5005, 0, 0xffa0}, {0x2c97, 0x5006, 0, 0xffa0}, {0x2c97, 0x5007, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x5008, 0, 0xffa0}, {0x2c97, 0x5009, 0, 0xffa0}, {0x2c97, 0x500a, 0, 0xffa0}, {0x2c97, 0x500b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x500c, 0, 0xffa0}, {0x2c97, 0x500d, 0, 0xffa0}, {0x2c97, 0x500e, 0, 0xffa0}, {0x2c97, 0x500f, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x5010, 0, 0xffa0}, {0x2c97, 0x5011, 0, 0xffa0}, {0x2c97, 0x5012, 0, 0xffa0}, {0x2c97, 0x5013, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x5014, 0, 0xffa0}, {0x2c97, 0x5015, 0, 0xffa0}, {0x2c97, 0x5016, 0, 0xffa0}, {0x2c97, 0x5017, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x5018, 0, 0xffa0}, {0x2c97, 0x5019, 0, 0xffa0}, {0x2c97, 0x501a, 0, 0xffa0}, {0x2c97, 0x501b, 0, 0xffa0},
|
|
|
|
{0x2c97, 0x501c, 0, 0xffa0}, {0x2c97, 0x501d, 0, 0xffa0}, {0x2c97, 0x501e, 0, 0xffa0}, {0x2c97, 0x501f, 0, 0xffa0},
|
2019-03-28 17:14:24 +01:00
|
|
|
};
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
bool device_ledger::connect() {
|
|
|
|
disconnect();
|
2021-06-25 22:14:00 +02:00
|
|
|
if (auto* hid_io = dynamic_cast<io::hid*>(hw_device.get()))
|
|
|
|
hid_io->connect(known_devices);
|
|
|
|
else if (auto* tcp = dynamic_cast<io::ledger_tcp*>(hw_device.get()))
|
|
|
|
tcp->connect();
|
|
|
|
else
|
|
|
|
throw std::logic_error{"Invalid ledger hardware configure"};
|
2020-11-28 03:59:45 +01:00
|
|
|
reset();
|
2020-07-12 04:36:07 +02:00
|
|
|
|
|
|
|
check_network_type();
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2018-02-20 17:01:27 +01:00
|
|
|
cryptonote::account_public_address pubkey;
|
2020-11-28 03:59:45 +01:00
|
|
|
get_public_address(pubkey);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
crypto::secret_key vkey;
|
|
|
|
crypto::secret_key skey;
|
2020-11-28 03:59:45 +01:00
|
|
|
get_secret_keys(vkey,skey);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-08-01 09:24:53 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
bool device_ledger::connected() const {
|
2021-06-25 22:14:00 +02:00
|
|
|
return hw_device->connected();
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::disconnect() {
|
2021-06-25 22:14:00 +02:00
|
|
|
hw_device->disconnect();
|
2018-08-01 09:24:53 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::release() {
|
2020-11-28 03:59:45 +01:00
|
|
|
disconnect();
|
2021-06-25 22:14:00 +02:00
|
|
|
hw_device->release();
|
2018-02-20 17:01:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-07-12 04:36:07 +02:00
|
|
|
static std::string nettype_string(cryptonote::network_type n) {
|
|
|
|
switch (n) {
|
|
|
|
case cryptonote::network_type::MAINNET: return "mainnet";
|
|
|
|
case cryptonote::network_type::TESTNET: return "testnet";
|
2020-11-20 22:44:55 +01:00
|
|
|
case cryptonote::network_type::DEVNET: return "devnet";
|
2020-07-12 04:36:07 +02:00
|
|
|
case cryptonote::network_type::FAKECHAIN: return "fakenet";
|
|
|
|
default: return "(unknown)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::check_network_type() {
|
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
|
|
|
send_simple(INS_GET_NETWORK);
|
|
|
|
|
|
|
|
std::string coin{reinterpret_cast<const char*>(buffer_recv), 4};
|
|
|
|
auto device_nettype = static_cast<cryptonote::network_type>(buffer_recv[4]);
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Ledger wallet is set to {} {}", coin, nettype_string(device_nettype));
|
2020-07-12 04:36:07 +02:00
|
|
|
if (coin != COIN_NETWORK)
|
|
|
|
throw std::runtime_error{"Invalid wallet app: expected " + std::string{COIN_NETWORK} + ", got " + coin};
|
|
|
|
if (device_nettype != nettype)
|
|
|
|
throw std::runtime_error{"Ledger wallet is set to the wrong network type: expected " + nettype_string(nettype)
|
|
|
|
+ " but the device is set to " + nettype_string(device_nettype)};
|
|
|
|
}
|
|
|
|
|
|
|
|
void device_ledger::set_network_type(cryptonote::network_type set_nettype) {
|
|
|
|
nettype = set_nettype;
|
|
|
|
}
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
bool device_ledger::set_mode(mode m) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-26 12:55:48 +02:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
switch(m) {
|
|
|
|
case mode::TRANSACTION_CREATE_REAL:
|
|
|
|
case mode::TRANSACTION_CREATE_FAKE:
|
|
|
|
{
|
|
|
|
int offset = set_command_header_noopt(INS_SET_SIGNATURE_MODE, 1);
|
|
|
|
buffer_send[offset++] = static_cast<unsigned char>(m);
|
2018-03-26 12:55:48 +02:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
finish_and_exchange(offset);
|
|
|
|
break;
|
|
|
|
}
|
2020-11-28 03:59:45 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
case mode::TRANSACTION_PARSE:
|
|
|
|
case mode::NONE:
|
|
|
|
break;
|
2018-03-26 12:55:48 +02:00
|
|
|
}
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "Switch to mode: {}", +static_cast<unsigned char>(m));
|
2021-06-25 17:07:57 +02:00
|
|
|
return device::set_mode(m);
|
2018-03-26 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
/* ======================================================================= */
|
|
|
|
/* WALLET & ADDRESS */
|
|
|
|
/* ======================================================================= */
|
|
|
|
|
2020-07-12 04:36:07 +02:00
|
|
|
bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
send_simple(INS_GET_KEY, 1);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
int offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(pubkey.m_view_public_key.data(), 32, offset);
|
|
|
|
receive_bytes(pubkey.m_spend_public_key.data(), 32, offset);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-12-08 20:49:49 +01:00
|
|
|
bool device_ledger::get_secret_keys(crypto::secret_key& vkey, crypto::secret_key& skey) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-05 14:46:15 +01:00
|
|
|
|
2018-03-26 12:55:48 +02:00
|
|
|
//secret key are represented as fake key on the wallet side
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
memcpy(vkey.data(), dummy_view_key, 32);
|
|
|
|
memcpy(skey.data(), dummy_spend_key, 32);
|
2018-03-05 14:46:15 +01:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
//spcialkey, normal conf handled in decrypt
|
2018-06-20 11:40:09 +02:00
|
|
|
send_simple(INS_GET_KEY, 0x02);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-12-08 20:49:49 +01:00
|
|
|
//View key is retrieved, if allowed, to speed up blockchain parsing
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(viewkey.data(), 32);
|
2020-11-28 03:59:45 +01:00
|
|
|
has_view_key = !is_fake_view_key(viewkey);
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "{}", (has_view_key ? "Have view key" : "Have no view key"));
|
2020-11-27 03:38:57 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
2019-10-01 17:28:23 +02:00
|
|
|
send_simple(INS_GET_KEY, 0x04);
|
2020-11-28 03:59:45 +01:00
|
|
|
int offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(dbg_viewkey.data(), 32, offset);
|
|
|
|
receive_bytes(dbg_spendkey.data(), 32, offset);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-03-26 12:38:38 +02:00
|
|
|
|
2018-03-26 12:55:48 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-12-08 20:49:49 +01:00
|
|
|
bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key, uint64_t kdf_rounds) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2018-02-20 17:01:27 +01:00
|
|
|
crypto::chacha_key key_x;
|
2021-06-25 17:07:57 +02:00
|
|
|
debug_device->generate_chacha_key(decrypt(keys), key_x, kdf_rounds);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
send_simple(INS_GET_CHACHA8_PREKEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
char prekey[200];
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(prekey, 200);
|
|
|
|
crypto::generate_chacha_key_prehashed(prekey, sizeof(prekey), key, kdf_rounds);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("generate_chacha_key_prehashed", "key", key_x.data(), key.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-06-22 02:17:04 +02:00
|
|
|
void device_ledger::display_address(const cryptonote::subaddress_index& index, const std::optional<crypto::hash8> &payment_id) {
|
2020-06-22 02:42:23 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2019-09-28 14:03:51 +02:00
|
|
|
|
|
|
|
int offset = set_command_header_noopt(INS_DISPLAY_ADDRESS, payment_id?1:0);
|
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(&index, sizeof(index), offset);
|
2019-09-28 14:03:51 +02:00
|
|
|
|
|
|
|
//payment ID
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(payment_id ? payment_id->data() : crypto::null<crypto::hash8>.data(), 8, offset);
|
2019-09-28 14:03:51 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Timeout/Error on display address.");
|
2019-09-28 14:03:51 +02:00
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ======================================================================= */
|
|
|
|
/* SUB ADDRESS */
|
|
|
|
/* ======================================================================= */
|
|
|
|
|
|
|
|
bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){
|
2020-11-27 03:38:57 +01:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::key_derivation derivation_x =
|
2021-06-25 17:07:57 +02:00
|
|
|
(mode_ == mode::TRANSACTION_PARSE && has_view_key) ? derivation : decrypt(derivation);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub.data(), 32);
|
|
|
|
log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message( "derive_subaddress_public_key: [[IN]] index ", std::to_string(output_index));
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::public_key derived_pub_x;
|
|
|
|
debug_device->derive_subaddress_public_key(pub, derivation_x, output_index, derived_pub_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
if (mode_ == mode::TRANSACTION_PARSE && has_view_key) {
|
2018-03-26 12:55:48 +02:00
|
|
|
//If we are in TRANSACTION_PARSE, the given derivation has been retrieved uncrypted (wihtout the help
|
|
|
|
//of the device), so continue that way.
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "derive_subaddress_public_key : PARSE mode with known viewkey");
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::derive_subaddress_public_key(pub, derivation, output_index, derived_pub);
|
2018-03-26 12:55:48 +02:00
|
|
|
} else {
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(pub.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//derivation
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(derivation.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
send_u32(output_index, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
//pub key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(derived_pub.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data(), derived_pub.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-05 06:24:48 +01:00
|
|
|
crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-26 12:38:38 +02:00
|
|
|
crypto::public_key D;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const cryptonote::account_keys keys_x = decrypt(keys);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::public_key D_x = debug_device->get_subaddress_spend_public_key(keys_x, index);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
if (index.is_zero()) {
|
|
|
|
D = keys.m_account_address.m_spend_public_key;
|
|
|
|
} else {
|
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
static_assert(sizeof(cryptonote::subaddress_index) == 8);
|
|
|
|
send_bytes(&index, sizeof(index), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(D.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("get_subaddress_spend_public_key", "D", D_x.data(), D.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return D;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
std::vector<crypto::public_key> device_ledger::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) {
|
|
|
|
std::vector<crypto::public_key> pkeys;
|
|
|
|
cryptonote::subaddress_index index{account, begin};
|
|
|
|
for (uint32_t idx = begin; idx < end; ++idx) {
|
2018-02-20 17:01:27 +01:00
|
|
|
index.minor = idx;
|
2020-11-28 03:59:45 +01:00
|
|
|
pkeys.push_back(get_subaddress_spend_public_key(keys, index));
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2018-03-05 06:24:48 +01:00
|
|
|
return pkeys;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-05 06:24:48 +01:00
|
|
|
cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-26 12:38:38 +02:00
|
|
|
cryptonote::account_public_address address;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const cryptonote::account_keys keys_x = decrypt(keys);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message( "get_subaddress: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
|
2020-11-28 03:59:45 +01:00
|
|
|
cryptonote::account_public_address address_x = debug_device->get_subaddress(keys_x, index);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
if (index.is_zero()) {
|
|
|
|
address = keys.m_account_address;
|
|
|
|
} else {
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_GET_SUBADDRESS);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
static_assert(sizeof(cryptonote::subaddress_index) == 8);
|
|
|
|
send_bytes(&index, sizeof(index), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(address.m_view_public_key.data(), 32, offset);
|
|
|
|
receive_bytes(address.m_spend_public_key.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return address;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-05 06:24:48 +01:00
|
|
|
crypto::secret_key device_ledger::get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-26 12:38:38 +02:00
|
|
|
crypto::secret_key sub_sec;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key sec_x = decrypt(sec);
|
2019-02-06 15:05:06 +01:00
|
|
|
log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data(), 32);
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::secret_key sub_sec_x = debug_device->get_subaddress_secret_key(sec_x, index);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
static_assert(sizeof(cryptonote::subaddress_index) == 8);
|
|
|
|
send_bytes(&index, sizeof(index), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(sub_sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
crypto::secret_key sub_sec_clear = decrypt(sub_sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("get_subaddress_secret_key", "sub_sec", sub_sec_x.data(), sub_sec_clear.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return sub_sec;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ======================================================================= */
|
|
|
|
/* DERIVATION & KEY */
|
|
|
|
/* ======================================================================= */
|
|
|
|
|
|
|
|
bool device_ledger::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-12-07 16:46:52 +01:00
|
|
|
int offset;
|
2018-03-26 12:38:38 +02:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
offset = set_command_header_noopt(INS_VERIFY_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(secret_key.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(public_key.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
offset = 0;
|
|
|
|
uint32_t verified = receive_u32(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
return verified == 1;
|
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
bool device_ledger::scalarmultKey(rct::key& aP, const rct::key &P, const rct::key &a) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const rct::key a_x = decrypt(a);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("scalarmultKey: [[IN]] P ", P.bytes, 32);
|
|
|
|
log_hexbuffer("scalarmultKey: [[IN]] a ", a_x.bytes, 32);
|
2018-03-05 14:46:15 +01:00
|
|
|
rct::key aP_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->scalarmultKey(aP_x, P, a_x);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("scalarmultKey: [[OUT]] aP", aP_x.bytes, 32);
|
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(P.bytes, 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
2020-11-28 03:59:45 +01:00
|
|
|
send_secret(a.bytes, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
//pub key
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(aP.bytes, 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("scalarmultKey", "mulkey", aP_x.bytes, aP.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::scalarmultBase(rct::key &aG, const rct::key &a) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const rct::key a_x = decrypt(a);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("scalarmultKey: [[IN]] a ", a_x.bytes, 32);
|
2018-03-05 14:46:15 +01:00
|
|
|
rct::key aG_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->scalarmultBase(aG_x, a_x);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("scalarmultKey: [[OUT]] aG", aG_x.bytes, 32);
|
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
2020-11-28 03:59:45 +01:00
|
|
|
send_secret(a.bytes, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
//pub key
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(aG.bytes, 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("scalarmultBase", "mulkey", aG_x.bytes, aG.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2019-09-25 14:31:14 +02:00
|
|
|
int offset;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key a_x = decrypt(a);
|
|
|
|
const crypto::secret_key b_x = decrypt(b);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("sc_secret_add: [[IN]] a ", a_x.data(), 32);
|
|
|
|
log_hexbuffer("sc_secret_add: [[IN]] b ", b_x.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
crypto::secret_key r_x;
|
2019-03-21 17:22:43 +01:00
|
|
|
rct::key aG_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->sc_secret_add(r_x, a_x, b_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("sc_secret_add: [[OUT]] aG", r_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(a.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(b.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
//sec key
|
|
|
|
offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(r.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
crypto::secret_key r_clear = decrypt(r);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("sc_secret_add", "r", r_x.data(), r_clear.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-05 06:24:48 +01:00
|
|
|
crypto::secret_key device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2019-09-25 14:31:14 +02:00
|
|
|
int offset;
|
2018-03-26 12:38:38 +02:00
|
|
|
if (recover) {
|
|
|
|
throw std::runtime_error("device generate key does not support recover");
|
|
|
|
}
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2018-02-20 17:01:27 +01:00
|
|
|
crypto::public_key pub_x;
|
|
|
|
crypto::secret_key sec_x;
|
2019-03-21 17:22:43 +01:00
|
|
|
crypto::secret_key recovery_key_x;
|
|
|
|
if (recover) {
|
2021-06-25 17:07:57 +02:00
|
|
|
recovery_key_x = decrypt(recovery_key);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_keys: [[IN]] pub", recovery_key_x.data(), 32);
|
2019-03-21 17:22:43 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
send_simple(INS_GENERATE_KEYPAIR);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
offset = 0;
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(pub.data(), 32, offset);
|
|
|
|
receive_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
crypto::secret_key sec_clear = decrypt(sec);
|
2018-02-20 17:01:27 +01:00
|
|
|
sec_x = sec_clear;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_keys: [[OUT]] pub", pub.data(), 32);
|
|
|
|
log_hexbuffer("generate_keys: [[OUT]] sec", sec_clear.data(), 32);
|
2019-03-21 17:22:43 +01:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
crypto::secret_key_to_public_key(sec_x,pub_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_keys", "pub", pub_x.data(), pub.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return sec;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-07-19 20:42:38 +02:00
|
|
|
crypto::key_derivation device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec) {
|
|
|
|
//TODO: replace entirely the bool return version of this
|
|
|
|
crypto::key_derivation d;
|
|
|
|
generate_key_derivation(pub, sec, d);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-03-26 12:55:48 +02:00
|
|
|
bool r = false;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub.data(), 32);
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key sec_x = (sec == rct::rct2sk(rct::I)) ? sec : decrypt(sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::key_derivation derivation_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->generate_key_derivation(pub, sec_x, derivation_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
if (mode_ == mode::TRANSACTION_PARSE && has_view_key) {
|
2020-12-08 20:49:49 +01:00
|
|
|
//A derivation is requested in PARSE mode and we have the view key,
|
|
|
|
//so do that without the device and return the derivation unencrypted.
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "generate_key_derivation : PARSE mode with known viewkey");
|
2018-03-26 12:55:48 +02:00
|
|
|
//Note derivation in PARSE mode can only happen with viewkey, so assert it!
|
|
|
|
assert(is_fake_view_key(sec));
|
2020-11-28 03:59:45 +01:00
|
|
|
r = crypto::generate_key_derivation(pub, viewkey, derivation);
|
2018-03-26 12:55:48 +02:00
|
|
|
} else {
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(pub.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
offset = 0;
|
2020-11-28 03:59:45 +01:00
|
|
|
//derivation data
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(derivation.data(), offset);
|
2019-09-25 14:31:14 +02:00
|
|
|
|
2018-03-26 12:55:48 +02:00
|
|
|
r = true;
|
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::key_derivation derivation_clear =
|
2021-06-25 17:07:57 +02:00
|
|
|
(mode_ == mode::TRANSACTION_PARSE && has_view_key) ? derivation : decrypt(derivation);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_key_derivation", "derivation", derivation_x.data(), derivation_clear.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:55:48 +02:00
|
|
|
return r;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-04-09 16:07:11 +02:00
|
|
|
bool device_ledger::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) {
|
2020-11-28 03:59:45 +01:00
|
|
|
const crypto::public_key *pkey = nullptr;
|
2020-11-27 03:38:57 +01:00
|
|
|
if (derivation == main_derivation) {
|
2018-04-09 16:07:11 +02:00
|
|
|
pkey = &tx_pub_key;
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "conceal derivation with main tx pub key");
|
2018-04-09 16:07:11 +02:00
|
|
|
} else {
|
2020-11-28 03:59:45 +01:00
|
|
|
for (size_t n = 0; n < additional_derivations.size(); ++n) {
|
|
|
|
if (derivation == additional_derivations[n]) {
|
2018-04-09 16:07:11 +02:00
|
|
|
pkey = &additional_tx_pub_keys[n];
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "conceal derivation with additionnal tx pub key");
|
2018-04-09 16:07:11 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(pkey, "Mismatched derivation on scan info");
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
return generate_key_derivation(*pkey, crypto::null<crypto::secret_key>, derivation);
|
2020-11-27 03:38:57 +01:00
|
|
|
}
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
bool device_ledger::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::key_derivation derivation_x = decrypt(derivation);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index));
|
|
|
|
crypto::ec_scalar res_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->derivation_to_scalar(derivation_x, output_index, res_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
|
2019-09-25 14:31:14 +02:00
|
|
|
//derivation
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(derivation.data(), offset);
|
2019-09-25 14:31:14 +02:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
send_u32(output_index, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
//derivation data
|
|
|
|
offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(res.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
crypto::ec_scalar res_clear = decrypt(res);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("derivation_to_scalar", "res", res_x.data(), res_clear.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::key_derivation derivation_x = decrypt(derivation);
|
|
|
|
const crypto::secret_key sec_x = decrypt(sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index));
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data(), 32);
|
2020-11-28 03:59:45 +01:00
|
|
|
crypto::secret_key derived_sec_x;
|
|
|
|
debug_device->derive_secret_key(derivation_x, output_index, sec_x, derived_sec_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//derivation
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(derivation.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
send_u32(output_index, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
offset = 0;
|
|
|
|
//sec key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(derived_sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
crypto::secret_key derived_sec_clear = decrypt(derived_sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("derive_secret_key", "derived_sec", derived_sec_x.data(), derived_sec_clear.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub){
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::key_derivation derivation_x = decrypt(derivation);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index));
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_public_key: [[IN]] pub ", pub.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::public_key derived_pub_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->derive_public_key(derivation_x, output_index, pub, derived_pub_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//derivation
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(derivation.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//index
|
2020-11-28 03:59:45 +01:00
|
|
|
send_u32(output_index, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(pub.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
//pub key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(derived_pub.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("derive_public_key", "derived_pub", derived_pub_x.data(), derived_pub.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key sec_x = decrypt(sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::public_key pub_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
bool rc = debug_device->secret_key_to_public_key(sec_x, pub_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data(), 32);
|
2018-03-05 14:46:15 +01:00
|
|
|
if (!rc){
|
2019-03-21 17:22:43 +01:00
|
|
|
log_message("FAIL secret_key_to_public_key", "secret_key rejected");
|
2018-03-05 14:46:15 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_SECRET_KEY_TO_PUBLIC_KEY);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
//pub key
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(pub.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("secret_key_to_public_key", "pub", pub_x.data(), pub.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image){
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key sec_x = decrypt(sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_key_image: [[IN]] pub ", pub.data(), 32);
|
|
|
|
log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::key_image image_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->generate_key_image(pub, sec_x, image_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE);
|
2018-02-20 17:01:27 +01:00
|
|
|
//pub
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(pub.data(), 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
//sec
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(sec.data(), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-12-08 20:49:49 +01:00
|
|
|
//key image
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(image.data(), 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_key_image", "image", image_x.data(), image.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-12-04 16:54:33 +01:00
|
|
|
bool device_ledger::generate_key_image_signature(const crypto::key_image& image, const crypto::public_key& pub, const crypto::secret_key& sec, crypto::signature& sig) {
|
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
|
|
|
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE_SIGNATURE);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(image.data(), 32, offset);
|
|
|
|
send_bytes(pub.data(), 32, offset);
|
|
|
|
send_secret(sec.data(), offset);
|
2020-12-04 16:54:33 +01:00
|
|
|
|
|
|
|
finish_and_exchange(offset);
|
|
|
|
|
|
|
|
receive_bytes(reinterpret_cast<char*>(&sig), 64);
|
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
// 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);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-12-04 16:54:33 +01:00
|
|
|
log_message("generate_key_image_signature: signature returned from device", good ? "passed" : "FAILED");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-12-07 04:17:07 +01:00
|
|
|
bool device_ledger::generate_unlock_signature(const crypto::public_key& pub, const crypto::secret_key& sec, crypto::signature& sig) {
|
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_unlock_signature: [[IN]] pub ", pub.data(), 32);
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key sec_x = decrypt(sec);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_unlock_signature: [[IN]] sec ", sec_x.data(), 32);
|
2020-12-07 04:17:07 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Ask for confirmation:
|
|
|
|
int offset = set_command_header_noopt(INS_GEN_UNLOCK_SIGNATURE);
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Unlock denied on device.");
|
|
|
|
|
|
|
|
// If we got permission then we can ask for the actual signature:
|
|
|
|
offset = set_command_header_noopt(INS_GEN_UNLOCK_SIGNATURE, 1);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(pub.data(), 32, offset);
|
|
|
|
send_secret(sec.data(), offset);
|
2020-12-07 04:17:07 +01:00
|
|
|
finish_and_exchange(offset);
|
|
|
|
|
|
|
|
receive_bytes(reinterpret_cast<char*>(&sig), 64);
|
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
// 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);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_unlock_signature: signature.c", sig.c(), 32);
|
|
|
|
log_hexbuffer("generate_unlock_signature: signature.r", sig.r(), 32);
|
2020-12-07 04:17:07 +01:00
|
|
|
log_message("generate_unlock_signature: signature returned from device", good ? "passed" : "FAILED");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-02-12 05:19:30 +01:00
|
|
|
bool device_ledger::generate_ons_signature(std::string_view sig_data, const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index, crypto::signature& sig) {
|
2020-12-07 04:20:49 +01:00
|
|
|
// Initialize (prompts the user):
|
2021-02-12 05:19:30 +01:00
|
|
|
int offset = set_command_header_noopt(INS_GEN_ONS_SIGNATURE);
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "ONS denied on device.");
|
2020-12-07 04:20:49 +01:00
|
|
|
|
2021-02-12 05:19:30 +01:00
|
|
|
// Send ons signature data to be hashed:
|
|
|
|
exchange_multipart_data(INS_GEN_ONS_SIGNATURE, 1, sig_data, BLAKE2B_HASH_CHUNK_SIZE);
|
2020-12-07 04:20:49 +01:00
|
|
|
|
|
|
|
// Send the subaddr indices and get the signature:
|
2021-02-12 05:19:30 +01:00
|
|
|
offset = set_command_header_noopt(INS_GEN_ONS_SIGNATURE, 2);
|
2020-12-07 04:20:49 +01:00
|
|
|
send_bytes(&index, sizeof(index), offset);
|
|
|
|
finish_and_exchange(offset);
|
|
|
|
|
|
|
|
receive_bytes(reinterpret_cast<char*>(&sig), 64);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
/* ======================================================================= */
|
|
|
|
/* TRANSACTION */
|
|
|
|
/* ======================================================================= */
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
void device_ledger::generate_tx_proof(const crypto::hash &prefix_hash,
|
2020-06-02 00:30:19 +02:00
|
|
|
const crypto::public_key &R, const crypto::public_key &A, const std::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
2019-03-21 17:22:43 +01:00
|
|
|
crypto::signature &sig) {
|
|
|
|
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2019-03-21 17:22:43 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2019-03-21 17:22:43 +01:00
|
|
|
const crypto::hash prefix_hash_x = prefix_hash;
|
|
|
|
const crypto::public_key R_x = R;
|
|
|
|
const crypto::public_key A_x = A;
|
2020-06-02 00:30:19 +02:00
|
|
|
const std::optional<crypto::public_key> B_x = B;
|
2019-03-21 17:22:43 +01:00
|
|
|
const crypto::public_key D_x = D;
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key r_x = decrypt(r);
|
2019-03-21 17:22:43 +01:00
|
|
|
crypto::signature sig_x;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
if (B_x)
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
|
|
|
|
2019-03-21 17:22:43 +01:00
|
|
|
|
|
|
|
int offset = set_command_header(INS_GET_TX_PROOF);
|
|
|
|
//options
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = B ? 0x01 : 0x00;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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
|
2020-11-28 03:59:45 +01:00
|
|
|
|
|
|
|
finish_and_exchange(offset);
|
|
|
|
|
|
|
|
offset = 0;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(sig.c(), 32, offset);
|
|
|
|
receive_bytes(sig.r(), 32, offset);
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("GENERATE_TX_PROOF: **c** ", sig.c(), 32);
|
|
|
|
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r(), 32);
|
2019-03-21 17:22:43 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "FAIL is normal if random is not fixed in proof");
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_tx_proof", "c", sig_x.c(), sig.c());
|
|
|
|
check32("generate_tx_proof", "r", sig_x.r(), sig.r());
|
2019-03-21 17:22:43 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2019-03-21 17:22:43 +01:00
|
|
|
}
|
|
|
|
|
2020-12-07 04:19:20 +01:00
|
|
|
bool device_ledger::open_tx(crypto::secret_key &tx_key, cryptonote::txversion txversion, cryptonote::txtype txtype) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker, *this);
|
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
key_map.clear();
|
2019-09-25 14:31:14 +02:00
|
|
|
hmac_map.clear();
|
2020-11-28 03:59:45 +01:00
|
|
|
tx_in_progress = true;
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header_noopt(INS_OPEN_TX, 0x01);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-12-07 04:19:20 +01:00
|
|
|
send_u16(static_cast<uint16_t>(txversion), offset);
|
|
|
|
send_u16(static_cast<uint16_t>(txtype), offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-09-25 14:31:14 +02:00
|
|
|
//skip R, receive: r, r_hmac, fake_a, a_hmac, fake_b, hmac_b
|
|
|
|
unsigned char tmp[32];
|
|
|
|
offset = 32;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(tx_key.data(), offset);
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_secret(tmp, offset);
|
|
|
|
receive_secret(tmp, offset);
|
2019-09-25 14:31:14 +02:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key r_x = decrypt(tx_key);
|
2020-11-28 03:59:45 +01:00
|
|
|
log_hexbuffer("open_tx: [[OUT]] R ", buffer_recv, 32);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("open_tx: [[OUT]] r ", r_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
// Sends data in chunks using the given ins/p1 values, with p2 set to a sequence
|
|
|
|
// 1->2->....->255->1->...->0 so that the hw device can make sure it didn't miss anything.
|
|
|
|
// (Note the wrapping goes 255->1, not 255->0, as 0 always indicates the last piece).
|
|
|
|
// Max chunk size is 254 bytes.
|
2020-11-28 03:59:45 +01:00
|
|
|
void device_ledger::exchange_multipart_data(uint8_t ins, uint8_t p1, std::string_view data, uint8_t chunk_size) {
|
2020-11-27 03:31:43 +01:00
|
|
|
assert(chunk_size <= 254);
|
|
|
|
size_t cnt = 0;
|
|
|
|
while (!data.empty()) {
|
|
|
|
auto piece = data.substr(0, chunk_size);
|
|
|
|
data.remove_prefix(piece.size());
|
|
|
|
if (data.empty())
|
|
|
|
cnt = 0; // Signals last piece
|
|
|
|
else
|
|
|
|
cnt = cnt == 255 ? 1 : cnt + 1;
|
|
|
|
|
|
|
|
int offset = set_command_header_noopt(ins, p1, cnt);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(piece.data(), piece.size(), offset);
|
|
|
|
finish_and_exchange(offset);
|
2020-11-27 03:31:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-03 22:56:55 +02:00
|
|
|
void device_ledger::get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx, crypto::hash& h) {
|
2020-06-22 02:42:23 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
2020-04-03 22:56:55 +02:00
|
|
|
crypto::hash h_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->get_transaction_prefix_hash(tx, h_x);
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "get_transaction_prefix_hash [[IN]] h_x/1 {}", h_x);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-07-20 04:29:01 +02:00
|
|
|
|
|
|
|
// As of protocol version 4, we send:
|
|
|
|
// - tx version
|
2021-02-12 05:19:30 +01:00
|
|
|
// - tx type (transfer, registration, stake, ons)
|
2020-07-20 04:29:01 +02:00
|
|
|
// - tx lock time (if the tx has multiple lock times this will be the largest one)
|
|
|
|
// We then wait for confirmation from the device, and if we get it we continue by sending the
|
2020-11-27 03:31:43 +01:00
|
|
|
// data in chunks. The last chunk will have a p2 subparameter of 0;
|
|
|
|
// otherwise the p2 subparameters are in order starting at 1 (and, if we wrap, we go from 255->1).
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2020-06-22 03:38:09 +02:00
|
|
|
std::string tx_prefix;
|
|
|
|
try {
|
|
|
|
tx_prefix = serialization::dump_binary(const_cast<cryptonote::transaction_prefix&>(tx));
|
|
|
|
} catch (const std::exception& e) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
auto err = "unable to serialize transaction prefix: "_format(e.what());
|
|
|
|
log::error(logcat, err);
|
|
|
|
throw std::runtime_error{err};
|
2020-06-22 03:38:09 +02:00
|
|
|
}
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
unsigned char* send = buffer_send + set_command_header_noopt(INS_PREFIX_HASH, 1);
|
2020-07-20 04:29:01 +02:00
|
|
|
|
|
|
|
// version as varint
|
|
|
|
tools::write_varint(send, static_cast<std::underlying_type_t<cryptonote::txversion>>(tx.version));
|
|
|
|
|
|
|
|
// transaction type as varint
|
|
|
|
tools::write_varint(send, static_cast<std::underlying_type_t<cryptonote::txtype>>(tx.type));
|
|
|
|
|
|
|
|
// Transactions can have multiple unlock times; find the longest one and send that
|
|
|
|
uint64_t max_unlock = 0;
|
|
|
|
for (size_t i = 0; i < tx.vout.size(); i++)
|
|
|
|
max_unlock = std::max(max_unlock, tx.get_unlock_time(i));
|
|
|
|
tools::write_varint(send, max_unlock);
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
length_send = send - buffer_send;
|
|
|
|
buffer_send[4] = length_send - 5;
|
|
|
|
exchange(true);
|
2020-04-03 22:56:55 +02:00
|
|
|
|
2020-07-20 04:29:01 +02:00
|
|
|
// hash the full prefix
|
2020-11-28 03:59:45 +01:00
|
|
|
exchange_multipart_data(INS_PREFIX_HASH, 2, tx_prefix, KECCAK_HASH_CHUNK_SIZE);
|
2020-07-20 04:29:01 +02:00
|
|
|
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(h.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check8("prefix_hash", "h", h_x.data(), h.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-04-03 22:56:55 +02:00
|
|
|
}
|
|
|
|
|
2018-03-05 06:24:48 +01:00
|
|
|
bool device_ledger::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key secret_key_x = decrypt(secret_key);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
crypto::hash8 payment_id_x = payment_id;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->encrypt_payment_id(payment_id_x, public_key, secret_key_x);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-12-08 20:49:49 +01:00
|
|
|
int offset = set_command_header_noopt(INS_ENCRYPT_PAYMENT_ID);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(public_key.data(), 32, offset); // pub
|
|
|
|
send_secret(secret_key.data(), offset); //sec
|
|
|
|
send_bytes(payment_id.data(), 8, offset); //id
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(payment_id.data(), 8);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check8("stealth", "payment_id", payment_id_x.data(), payment_id.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-26 00:49:42 +01:00
|
|
|
bool device_ledger::generate_output_ephemeral_keys(
|
|
|
|
const size_t tx_version,
|
|
|
|
bool& found_change,
|
|
|
|
const cryptonote::account_keys& sender_account_keys,
|
|
|
|
const crypto::public_key& txkey_pub,
|
|
|
|
const crypto::secret_key& tx_key,
|
|
|
|
const cryptonote::tx_destination_entry& dst_entr,
|
|
|
|
const std::optional<cryptonote::tx_destination_entry>& change_addr,
|
|
|
|
const size_t output_index,
|
|
|
|
const bool need_additional_txkeys,
|
|
|
|
const std::vector<crypto::secret_key>& additional_tx_keys,
|
|
|
|
std::vector<crypto::public_key>& additional_tx_public_keys,
|
|
|
|
std::vector<rct::key>& amount_keys,
|
|
|
|
crypto::public_key& out_eph_public_key) {
|
|
|
|
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
cryptonote::account_keys sender_account_keys_x = decrypt(sender_account_keys);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
std::memmove(sender_account_keys_x.m_view_secret_key.data(), dbg_viewkey.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
const crypto::secret_key tx_key_x = decrypt(tx_key);
|
2020-11-27 03:38:57 +01:00
|
|
|
|
|
|
|
std::vector<crypto::secret_key> additional_tx_keys_x;
|
|
|
|
for (const auto& k: additional_tx_keys) {
|
2021-06-25 17:07:57 +02:00
|
|
|
additional_tx_keys_x.push_back(decrypt(k));
|
2018-12-11 10:20:21 +01:00
|
|
|
}
|
2019-03-21 17:22:43 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
log_message("generate_output_ephemeral_keys: [[IN]] tx_version", std::to_string(tx_version));
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
//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);
|
2019-03-21 17:22:43 +01:00
|
|
|
if (change_addr) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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);
|
2019-03-21 17:22:43 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
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) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data(), 32);
|
2019-03-21 17:22:43 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
std::vector<crypto::public_key> additional_tx_public_keys_x;
|
|
|
|
std::vector<rct::key> amount_keys_x;
|
|
|
|
crypto::public_key out_eph_public_key_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
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);
|
2020-11-27 03:38:57 +01:00
|
|
|
if(need_additional_txkeys) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data(), 32);
|
2019-03-21 17:22:43 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] amount_keys ", amount_keys_x.back().bytes, 32);
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data(), 32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(tx_version > 1, "TX version not supported"<<tx_version);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
// make additional tx pubkey if necessary
|
|
|
|
cryptonote::keypair additional_txkey;
|
|
|
|
if (need_additional_txkeys) {
|
|
|
|
additional_txkey.sec = additional_tx_keys[output_index];
|
|
|
|
}
|
|
|
|
|
2021-01-04 01:09:45 +01:00
|
|
|
bool &is_change = found_change; // NOTE(oxen): Alias our param into theirs so we don't have to change much code.
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2019-02-25 07:28:33 +01:00
|
|
|
if (change_addr && dst_entr == *change_addr && !is_change)
|
2019-07-01 02:10:03 +02:00
|
|
|
is_change = true; // sending change to yourself; derivation = a*R
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
int offset = set_command_header_noopt(INS_GEN_TXOUT_KEYS);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_u32(tx_version, offset); //tx_version
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
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
|
2020-11-28 03:59:45 +01:00
|
|
|
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
|
2019-03-21 17:22:43 +01:00
|
|
|
//additional_tx_key
|
2020-11-28 02:32:10 +01:00
|
|
|
if (need_additional_txkeys)
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_secret(additional_txkey.sec.data(), offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
offset = 0;
|
2020-11-28 03:59:45 +01:00
|
|
|
unsigned int recv_len = length_recv;
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
//if (tx_version > 1)
|
2018-12-11 10:20:21 +01:00
|
|
|
{
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
|
2018-12-11 10:20:21 +01:00
|
|
|
crypto::secret_key scalar1;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_secret(scalar1.data(), offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
amount_keys.push_back(rct::sk2rct(scalar1));
|
|
|
|
recv_len -= 32;
|
|
|
|
}
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(out_eph_public_key.data(), 32, offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
recv_len -= 32;
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
if (need_additional_txkeys)
|
|
|
|
{
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(recv_len>=32, "Not enough data from device");
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(additional_txkey.pub.data(), 32, offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
additional_tx_public_keys.push_back(additional_txkey.pub);
|
|
|
|
recv_len -= 32;
|
|
|
|
}
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
// add ABPkeys
|
2020-11-28 03:59:45 +01:00
|
|
|
add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, is_change,
|
|
|
|
need_additional_txkeys, output_index,
|
|
|
|
amount_keys.back(), out_eph_public_key);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
rct::key amount_back = decrypt(amount_keys.back());
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("generate_output_ephemeral_keys: clear amount_key", amount_back.bytes, 32);
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("generate_output_ephemeral_keys", "amount_key", amount_keys_x.back().bytes, amount_back.bytes);
|
2018-12-11 10:20:21 +01:00
|
|
|
if (need_additional_txkeys) {
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data(), additional_tx_public_keys.back().data());
|
2018-12-11 10:20:21 +01:00
|
|
|
}
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data(), out_eph_public_key.data());
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change,
|
|
|
|
const bool need_additional, const size_t real_output_index,
|
|
|
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) {
|
|
|
|
key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, is_change, need_additional, real_output_index, rct::pk2rct(out_eph_public_key), amount_key));
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
rct::key device_ledger::genCommitmentMask(const rct::key &AKout) {
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
rct::key mask_x = debug_device->genCommitmentMask(decrypt(AKout));
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-12-11 10:20:21 +01:00
|
|
|
|
|
|
|
rct::key mask;
|
|
|
|
int offset = set_command_header_noopt(INS_GEN_COMMITMENT_MASK);
|
|
|
|
// AKout
|
2020-11-28 03:59:45 +01:00
|
|
|
send_secret(AKout.bytes, offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(mask.bytes, 32);
|
2018-12-11 10:20:21 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("genCommitmentMask", "mask", mask_x.bytes, mask.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
|
|
|
|
2018-12-11 10:20:21 +01:00
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
bool device_ledger::ecdhEncode(rct::ecdhTuple& unmasked, const rct::key& AKout, bool short_amount) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const rct::key AKout_x = decrypt(AKout);
|
2018-02-20 17:01:27 +01:00
|
|
|
rct::ecdhTuple unmasked_x = unmasked;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->ecdhEncode(unmasked_x, AKout_x, short_amount);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-02-08 16:11:51 +01:00
|
|
|
int offset = set_command_header(INS_BLIND);
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = short_amount ? 0x02 : 0x00; //options
|
|
|
|
send_secret(AKout.bytes, offset); // AKout
|
|
|
|
send_bytes(unmasked.mask.bytes, 32, offset); //mask k
|
|
|
|
send_bytes(unmasked.amount.bytes, 32, offset); //value v
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
offset = 0;
|
|
|
|
receive_bytes(unmasked.amount.bytes, 32, offset);
|
|
|
|
receive_bytes(unmasked.mask.bytes, 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "ecdhEncode: Akout: {}", AKout_x);
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("ecdhEncode", "amount", unmasked_x.amount.bytes, unmasked.amount.bytes);
|
|
|
|
check32("ecdhEncode", "mask", unmasked_x.mask.bytes, unmasked.mask.bytes);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
log_hexbuffer("Blind AKV input", &buffer_recv[64], 3*32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
bool device_ledger::ecdhDecode(rct::ecdhTuple& masked, const rct::key& AKout, bool short_amount) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const rct::key AKout_x = decrypt(AKout);
|
2018-02-20 17:01:27 +01:00
|
|
|
rct::ecdhTuple masked_x = masked;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->ecdhDecode(masked_x, AKout_x, short_amount);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-02-08 16:11:51 +01:00
|
|
|
int offset = set_command_header(INS_UNBLIND);
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = short_amount ? 0x02 : 0x00; //options
|
|
|
|
send_secret(AKout.bytes, offset); // AKout
|
|
|
|
send_bytes(masked.mask.bytes, 32, offset); //mask k
|
|
|
|
send_bytes(masked.amount.bytes, 32, offset); //value v
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
offset = 0;
|
|
|
|
receive_bytes(masked.amount.bytes, 32, offset);
|
|
|
|
receive_bytes(masked.mask.bytes, 32, offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2022-09-23 01:27:12 +02:00
|
|
|
log::debug(logcat, "ecdhEncode: Akout: {}", AKout_x);
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("ecdhDecode", "amount", masked_x.amount.bytes, masked.amount.bytes);
|
|
|
|
check32("ecdhDecode", "mask", masked_x.mask.bytes, masked.mask.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
bool device_ledger::clsag_prehash(const std::string &data, size_t inputs_size, size_t outputs_size,
|
2018-02-20 17:01:27 +01:00
|
|
|
const rct::keyV &hashes, const rct::ctkeyV &outPk,
|
|
|
|
rct::key &prehash) {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2018-02-20 17:01:27 +01:00
|
|
|
rct::key prehash_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->clsag_prehash(data, inputs_size, outputs_size, hashes, outPk, prehash_x);
|
2018-02-20 17:01:27 +01:00
|
|
|
if (inputs_size) {
|
2020-11-20 22:50:21 +01:00
|
|
|
log_message("clsag_prehash", (std::string("inputs_size not null: ") + std::to_string(inputs_size)).c_str());
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2020-11-28 03:59:45 +01:00
|
|
|
key_map.log();
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
// ====== u8 type, varint txnfee ======
|
2018-06-20 11:40:09 +02:00
|
|
|
int offset = set_command_header(INS_VALIDATE, 0x01, 0x01);
|
2018-02-20 17:01:27 +01:00
|
|
|
//options
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = (inputs_size == 0) ? 0x00 : OPTION_MORE_DATA;
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = data[0];
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
// txnfee
|
|
|
|
size_t data_offset = 1;
|
|
|
|
while (data[data_offset] & 0x80)
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = data[data_offset++];
|
|
|
|
buffer_send[offset++] = data[data_offset++];
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-01-09 09:20:53 +01:00
|
|
|
// check fee user input
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Fee denied on device.");
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-23 23:25:01 +01:00
|
|
|
auto type = static_cast<rct::RCTType>(data[0]);
|
2020-12-08 20:49:49 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(type == rct::RCTType::CLSAG, "non-CLSAG generation not supported");
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
// ====== Aout, Bout, AKout, C, v, k ======
|
2020-11-27 03:31:43 +01:00
|
|
|
size_t kv_offset = data_offset;
|
|
|
|
size_t C_offset = kv_offset + 8 * outputs_size;
|
|
|
|
for (size_t i = 0; i < outputs_size; i++) {
|
2018-02-20 17:01:27 +01:00
|
|
|
ABPkeys outKeys;
|
|
|
|
bool found;
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
found = key_map.find(outPk[i].dest, outKeys);
|
2018-02-20 17:01:27 +01:00
|
|
|
if (!found) {
|
2020-11-27 03:38:57 +01:00
|
|
|
log_hexbuffer("Pout not found", outPk[i].dest.bytes, 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(found, "Pout not found");
|
|
|
|
}
|
2018-06-20 11:40:09 +02:00
|
|
|
offset = set_command_header(INS_VALIDATE, 0x02, i+1);
|
2020-12-08 20:49:49 +01:00
|
|
|
// options
|
|
|
|
buffer_send[offset++] = (i < outputs_size-1 ? OPTION_MORE_DATA : 0) | 0x02;
|
2020-11-28 03:59:45 +01:00
|
|
|
|
|
|
|
buffer_send[offset++] = outKeys.is_subaddress; //is_subaddress
|
|
|
|
buffer_send[offset++] = outKeys.is_change_address; //is_change_address
|
|
|
|
send_bytes(outKeys.Aout.bytes, 32, offset); //Aout
|
|
|
|
send_bytes(outKeys.Bout.bytes, 32, offset); //Bout
|
|
|
|
send_secret(outKeys.AKout.bytes, offset); //AKout
|
|
|
|
send_bytes(&data[C_offset], 32, offset); //C
|
2018-02-20 17:01:27 +01:00
|
|
|
C_offset += 32;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(crypto::null<crypto::hash>.data(), 32, offset); // k
|
2020-12-08 20:49:49 +01:00
|
|
|
send_bytes(&data[kv_offset], 8, offset); // v
|
|
|
|
kv_offset += 8;
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
send_bytes(crypto::null<crypto::hash>.data(), 24, offset); // v padding
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2019-01-09 09:20:53 +01:00
|
|
|
// check transaction user input
|
2020-11-28 03:59:45 +01:00
|
|
|
CHECK_AND_ASSERT_THROW_MES(finish_and_exchange(offset, true) == SW_OK, "Transaction denied on device.");
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2020-11-28 03:59:45 +01:00
|
|
|
log_hexbuffer("Prehash AKV input", &buffer_recv[64], 3*32);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ====== C[], message, proof======
|
|
|
|
C_offset = kv_offset;
|
2020-11-27 03:31:43 +01:00
|
|
|
for (size_t i = 0; i < outputs_size; i++) {
|
2018-06-20 11:40:09 +02:00
|
|
|
offset = set_command_header(INS_VALIDATE, 0x03, i+1);
|
2020-11-28 03:59:45 +01:00
|
|
|
buffer_send[offset++] = 0x80; //options
|
|
|
|
send_bytes(&data[C_offset], 32, offset); //C
|
2018-02-20 17:01:27 +01:00
|
|
|
C_offset += 32;
|
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
offset = set_command_header_noopt(INS_VALIDATE, 0x03, outputs_size+1);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_bytes(hashes[0].bytes, 32, offset); //message
|
|
|
|
send_bytes(hashes[2].bytes, 32, offset); //proof
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(prehash.bytes, 32);
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("clsag_prehash", "prehash", prehash_x.bytes, prehash.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2018-02-20 17:01:27 +01:00
|
|
|
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 17:11:51 +02:00
|
|
|
bool device_ledger::clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) {
|
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
const rct::key p_x = decrypt(p);
|
2020-03-31 17:11:51 +02:00
|
|
|
rct::key I_x;
|
|
|
|
rct::key D_x;
|
|
|
|
rct::key a_x;
|
|
|
|
rct::key aG_x;
|
|
|
|
rct::key aH_x;
|
2020-11-27 03:38:57 +01:00
|
|
|
hw::get_device("default").clsag_prepare(p_x, z, I_x, D_x, H, a_x, aG_x, aH_x);
|
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
rct::skpkGen(a,aG); // aG = a*G
|
|
|
|
rct::scalarmultKey(aH,H,a); // aH = a*H
|
|
|
|
rct::scalarmultKey(I,H,p); // I = p*H
|
|
|
|
rct::scalarmultKey(D,H,z); // D = z*H
|
|
|
|
*/
|
2020-11-27 03:31:43 +01:00
|
|
|
int offset = set_command_header_noopt(INS_CLSAG, 1);
|
2020-11-28 03:59:45 +01:00
|
|
|
send_secret(p.bytes, offset); //p
|
|
|
|
send_bytes(z.bytes, 32, offset); //z
|
|
|
|
send_bytes(H.bytes, 32, offset); //H
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
offset = 0;
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_secret(a.bytes, offset); //a
|
|
|
|
receive_bytes(aG.bytes, 32, offset); //aG
|
|
|
|
receive_bytes(aH.bytes, 32, offset); //aH
|
|
|
|
receive_bytes(I.bytes, 32, offset); //I = pH
|
|
|
|
receive_bytes(D.bytes, 32, offset); //D = zH
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("clsag_prepare", "I", I_x.bytes, I.bytes);
|
|
|
|
check32("clsag_prepare", "D", D_x.bytes, D.bytes);
|
|
|
|
check32("clsag_prepare", "a", a_x.bytes, a.bytes);
|
|
|
|
check32("clsag_prepare", "aG", aG_x.bytes, aG.bytes);
|
|
|
|
check32("clsag_prepare", "aH", aH_x.bytes, aH.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
bool device_ledger::clsag_hash(const rct::keyV &keydata, rct::key &hash) {
|
2020-03-31 17:11:51 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
rct::key hash_x;
|
2020-11-28 03:59:45 +01:00
|
|
|
debug_device->clsag_hash(keydata, hash_x);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-27 03:31:43 +01:00
|
|
|
std::string_view data{reinterpret_cast<const char*>(keydata.data()), sizeof(rct::key)*keydata.size()};
|
2020-11-28 03:59:45 +01:00
|
|
|
exchange_multipart_data(INS_CLSAG, 2, data, KECCAK_HASH_CHUNK_SIZE);
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
//c/hash
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(hash.bytes, 32);
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("clsag_hash", "hash", hash_x.bytes, hash.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool device_ledger::clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) {
|
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
|
|
|
rct::key s_x;
|
2021-06-25 17:07:57 +02:00
|
|
|
debug_device->clsag_sign(c, decrypt(a), decrypt(p), z, mu_P, mu_C, s_x);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
rct::key s0_p_mu_P;
|
|
|
|
sc_mul(s0_p_mu_P.bytes,mu_P.bytes,p.bytes);
|
|
|
|
rct::key s0_add_z_mu_C;
|
|
|
|
sc_muladd(s0_add_z_mu_C.bytes,mu_C.bytes,z.bytes,s0_p_mu_P.bytes);
|
|
|
|
sc_mulsub(s.bytes,c.bytes,s0_add_z_mu_C.bytes,a.bytes);
|
|
|
|
*/
|
|
|
|
|
2020-12-07 04:22:00 +01:00
|
|
|
int offset = set_command_header_noopt(INS_CLSAG, 3);
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
send_secret(a.bytes, offset); //a
|
|
|
|
send_secret(p.bytes, offset); //p
|
|
|
|
send_bytes(z.bytes, 32, offset); //z
|
|
|
|
send_bytes(mu_P.bytes, 32, offset); //mu_P
|
|
|
|
send_bytes(mu_C.bytes, 32, offset); //mu_C
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
finish_and_exchange(offset);
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-28 03:59:45 +01:00
|
|
|
receive_bytes(s.bytes, 32); //s
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2020-11-27 03:38:57 +01:00
|
|
|
#ifdef DEBUG_HWDEVICE
|
2021-06-25 17:07:57 +02:00
|
|
|
check32("clsag_sign", "s", s_x.bytes, s.bytes);
|
2020-11-27 03:38:57 +01:00
|
|
|
#endif
|
2020-03-31 17:11:51 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-12-14 16:47:46 +01:00
|
|
|
bool device_ledger::update_staking_tx_secret_key(crypto::secret_key& key) {
|
2020-12-04 16:56:46 +01:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
|
|
|
|
|
|
|
// This will fail if this isn't an open stake tx.
|
|
|
|
send_simple(INS_GET_TX_SECRET_KEY);
|
2020-12-14 16:47:46 +01:00
|
|
|
// The ledger provides us with the (unencrypted) tx secret key if we're allowed to have it
|
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::hash::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.
2022-10-15 03:22:44 +02:00
|
|
|
receive_bytes(key.data(), 32);
|
2020-12-04 16:56:46 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2020-03-31 17:11:51 +02:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
bool device_ledger::close_tx() {
|
C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.
- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.
- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.
- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.
- switched from mapbox::variant to std::variant
- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).
- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition. boost::lock() won't compile in C++17 mode when given
locks of different types.
- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.
- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`. This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work. This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.
- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates. So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.
- LNS validation gained a couple minor validation checks in the process:
- slightly tightened the requirement on lokinet addresses to require
that the last character of the mapped address is 'y' or 'o' (the
last base32z char holds only one significant bit).
- In parse_owner_to_generic_owner made sure that the owner value has
the correct size (otherwise we could up end not filling or
overfilling the pubkey buffer).
- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-05-13 20:12:49 +02:00
|
|
|
auto locks = tools::unique_locks(device_locker, command_locker);
|
2018-06-20 11:40:09 +02:00
|
|
|
send_simple(INS_CLOSE_TX);
|
2019-09-25 14:31:14 +02:00
|
|
|
key_map.clear();
|
|
|
|
hmac_map.clear();
|
2020-11-28 03:59:45 +01:00
|
|
|
tx_in_progress = false;
|
|
|
|
unlock();
|
2018-03-26 12:38:38 +02:00
|
|
|
return true;
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------- */
|
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
void register_all(std::map<std::string, std::unique_ptr<device>>& registry) {
|
|
|
|
registry.emplace("Ledger", std::make_unique<device_ledger>());
|
2021-06-25 22:14:00 +02:00
|
|
|
registry.emplace("LedgerTCP", std::make_unique<device_ledger>(io::ledger_tcp{}));
|
2018-02-20 17:01:27 +01:00
|
|
|
}
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2018-02-20 17:01:27 +01:00
|
|
|
#else //WITH_DEVICE_LEDGER
|
2020-11-27 03:38:57 +01:00
|
|
|
|
2021-06-25 17:07:57 +02:00
|
|
|
void register_all(std::map<std::string, std::unique_ptr<device>> &) {}
|
2018-02-20 17:01:27 +01:00
|
|
|
|
|
|
|
#endif //WITH_DEVICE_LEDGER
|
|
|
|
|
|
|
|
}
|
|
|
|
|