diff --git a/src/carrot_core/address_utils.cpp b/src/carrot_core/address_utils.cpp index 18bbfd964..09a2bfe81 100644 --- a/src/carrot_core/address_utils.cpp +++ b/src/carrot_core/address_utils.cpp @@ -82,20 +82,4 @@ void make_carrot_address_spend_pubkey(const crypto::public_key &spend_pubkey, rct::pk2rct(spend_pubkey), rct::sk2rct(subaddress_scalar))); } //------------------------------------------------------------------------------------------------------------------- -void make_carrot_address(const crypto::public_key &spend_pubkey, - const crypto::secret_key &s_generate_address, - const std::uint32_t j_major, - const std::uint32_t j_minor, - const crypto::secret_key &k_view, - crypto::public_key &address_spend_pubkey_out) -{ - // K^j_s = k^j_subscal * K_s - crypto::public_key address_spend_pubkey; - make_carrot_address_spend_pubkey(spend_pubkey, s_generate_address, j_major, j_minor, address_spend_pubkey); - - // K^j_v = k_v * K^j_s - address_spend_pubkey_out = rct::rct2pk(rct::scalarmultKey( - rct::pk2rct(address_spend_pubkey), rct::sk2rct(k_view))); -} -//------------------------------------------------------------------------------------------------------------------- } //namespace carrot diff --git a/src/carrot_core/address_utils.h b/src/carrot_core/address_utils.h index 0ecbf850c..4f66725bf 100644 --- a/src/carrot_core/address_utils.h +++ b/src/carrot_core/address_utils.h @@ -92,22 +92,4 @@ void make_carrot_address_spend_pubkey(const crypto::public_key &spend_pubkey, const std::uint32_t j_minor, crypto::public_key &address_spend_pubkey_out); -/** -* brief: make_carrot_address - (K^j_s, K^j_v) -* K^j_s = k^j_subscal * K_s -* K^j_v = k_v K^j_s -* param: spend_pubkey - K_s = k_gi G + k_ps U -* param: s_generate_address - s_ga -* param: j_major - -* param: j_minor - -* param: k_view - k_v -* outparam: address_spend_pubkey_out - K^j_s -*/ -void make_carrot_address(const crypto::public_key &spend_pubkey, - const crypto::secret_key &s_generate_address, - const std::uint32_t j_major, - const std::uint32_t j_minor, - const crypto::secret_key &k_view, - crypto::public_key &address_spend_pubkey_out); - } //namespace carrot diff --git a/src/carrot_core/device.h b/src/carrot_core/device.h new file mode 100644 index 000000000..09eec74fe --- /dev/null +++ b/src/carrot_core/device.h @@ -0,0 +1,161 @@ +// Copyright (c) 2022, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +//! @file Abstract interfaces for performing scanning without revealing account keys + +#pragma once + +//local headers +#include "core_types.h" +#include "crypto/crypto.h" +#include "crypto/x25519.h" + +//third party headers + +//standard headers +#include +#include +#include + +//forward declarations + + +/** + * These device interfaces were written primarily to be as lean as possible, for ease of the + * implementor, so long as account keys don't leak. As such, the interfaces do not shield + * sender-receiver secrets, and thus temporary access to this device interface can expose + * transaction content permanently in a provable manner. The device interface currently used in + * Monero (hw::device) also exposes transaction content, which can be saved permanently, but it + * wouldn't necessarily be provable. Thus, in the case of a breach, the original user has some + * plausible deniability with (hw::device), which cannot be said of the interfaces in this file. + * It's not impossible to make carrot scanning happen completely on-device, but it is significantly + * more involved. + */ + +namespace carrot +{ +/** + * brief: base exception type for reporting carrot device errors. + * note: devices should only throw this exception or derived classes + */ +struct device_error: public std::runtime_error +{ + /** + * param: dev_make - e.g. "Trezor", "Ledger" + * param: dev_model - e.g. "Model T", "Nano X" + * param: func_called - verbatim device interface method name, e.g. "view_key_8_scalar_mult_x25519" + * param: msg - arbitrary error message + * param: code - arbitrary error code + */ + device_error(std::string &&dev_make, + std::string &&dev_model, + std::string &&func_called, + std::string &&msg, + const int code) + : std::runtime_error(make_formatted_message(dev_make, dev_model, func_called, msg, code)), + dev_make(dev_make), dev_model(dev_model), func_called(func_called), msg(msg), code(code) + {} + + static std::string make_formatted_message(const std::string &dev_make, + const std::string &dev_model, + const std::string &func_called, + const std::string &msg, + const int code) + { + char buf[384]; + snprintf(buf, sizeof(buf), + "%s %s device error (%d), at %s(): %s", + code, dev_make, dev_model, func_called, msg); + return {buf}; + } + + const std::string dev_make; + const std::string dev_model; + const std::string func_called; + const std::string msg; + const int code; +}; + +struct view_incoming_key_device +{ + /** + * brief: view_key_scalar_mult_ed25519 - do an Ed25519 scalar mult against the incoming view key + * param: P - Ed25519 base point + * outparam: kvP = k_v P + * return: true on success, false on failure (e.g. unable to decompress point) + */ + virtual bool view_key_scalar_mult_ed25519(const crypto::public_key &P, + crypto::public_key &kvP) const = 0; + + /** + * brief: view_key_8_scalar_mult_x25519 - do an X25519 scalar mult and cofactor clear against the incoming view key + * param: D - X25519 base point + * outparam: kv8D = 8 k_v D + * return: true on success, false on failure (e.g. unable to decompress point) + */ + virtual bool view_key_8_scalar_mult_x25519(const crypto::x25519_pubkey &D, + crypto::public_key &kv8D) const = 0; + + /** + * brief: make_janus_anchor_special - make a janus anchor for "special" enotes + * param: enote_ephemeral_pubkey - D_e + * param: input_context - input_context + * param: account_spend_pubkey - K_s + * outparam: anchor_special_out - anchor_sp = anchor_sp = H_16(D_e, input_context, Ko, k_v, K_s) + */ + virtual void make_janus_anchor_special(const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const input_context_t &input_context, + const crypto::public_key &onetime_address, + const crypto::public_key &account_spend_pubkey, + janus_anchor_t &anchor_special_out) const = 0; +}; + +struct view_balance_secret_device +{ + /** + * brief: make_internal_view_tag - make an internal view tag, given non-secret data + * param: input_context - input_context + * param: onetime_address - Ko + * outparam: view_tag_out - vt = H_3(s_vb || input_context || Ko) + */ + virtual void make_internal_view_tag(const input_context_t &input_context, + const crypto::public_key &onetime_address, + view_tag_t &view_tag_out) const = 0; + + /** + * brief: make_internal_sender_receiver_secret - make internal sender-receiver secret, given non-secret data + * param: enote_ephemeral_pubkey - D_e + * param: input_context - input_context + * outparam: s_sender_receiver_out - s_sr = s^ctx_sr = H_32(s_sr, D_e, input_context) + */ + virtual void make_internal_sender_receiver_secret(const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const input_context_t &input_context, + crypto::hash &s_sender_receiver_out) const = 0; +}; + +} //namespace carrot