From 5f5981c4dfa7027b1c774c01d0317f2ba75b2d40 Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Thu, 9 Jan 2025 13:15:17 -0600 Subject: [PATCH] remove x25519 wrapper header --- src/carrot_core/CMakeLists.txt | 1 + src/carrot_core/carrot_enote_scan.cpp | 6 +- src/carrot_core/carrot_enote_scan.h | 6 +- src/carrot_core/carrot_enote_types.h | 6 +- src/carrot_core/core_types.cpp | 16 +++ src/carrot_core/core_types.h | 3 + src/carrot_core/device.h | 10 +- src/carrot_core/device_ram_borrowed.cpp | 8 +- src/carrot_core/device_ram_borrowed.h | 8 +- src/carrot_core/enote_utils.cpp | 54 +++++---- src/carrot_core/enote_utils.h | 18 +-- src/carrot_core/output_set_finalization.cpp | 6 +- src/carrot_core/output_set_finalization.h | 2 +- src/carrot_core/payment_proposal.cpp | 24 ++-- src/carrot_core/payment_proposal.h | 5 +- src/crypto/CMakeLists.txt | 4 +- src/crypto/x25519.cpp | 116 -------------------- src/crypto/x25519.h | 106 ------------------ tests/performance_tests/view_scan.h | 5 +- tests/unit_tests/carrot_core.cpp | 88 ++++++++------- tests/unit_tests/carrot_legacy.cpp | 2 +- tests/unit_tests/crypto.cpp | 90 ++++++++------- 22 files changed, 206 insertions(+), 378 deletions(-) delete mode 100644 src/crypto/x25519.cpp delete mode 100644 src/crypto/x25519.h diff --git a/src/carrot_core/CMakeLists.txt b/src/carrot_core/CMakeLists.txt index 299cc88b5..af816dbbb 100644 --- a/src/carrot_core/CMakeLists.txt +++ b/src/carrot_core/CMakeLists.txt @@ -48,6 +48,7 @@ target_link_libraries(carrot_core PUBLIC cncrypto epee + mx25519_static ringct seraphis_crypto PRIVATE diff --git a/src/carrot_core/carrot_enote_scan.cpp b/src/carrot_core/carrot_enote_scan.cpp index e1c3474ae..8b4549609 100644 --- a/src/carrot_core/carrot_enote_scan.cpp +++ b/src/carrot_core/carrot_enote_scan.cpp @@ -104,7 +104,7 @@ bool verify_carrot_janus_protection(const input_context_t &input_context, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, const crypto::public_key &nominal_address_spend_pubkey, - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const janus_anchor_t &nominal_anchor, payment_id_t &nominal_payment_id_inout) { @@ -159,7 +159,7 @@ bool verify_carrot_janus_protection(const input_context_t &input_context, } //------------------------------------------------------------------------------------------------------------------- bool try_scan_carrot_coinbase_enote(const CarrotCoinbaseEnoteV1 &enote, - const crypto::x25519_pubkey &s_sender_receiver_unctx, + const mx25519_pubkey &s_sender_receiver_unctx, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, crypto::secret_key &sender_extension_g_out, @@ -228,7 +228,7 @@ bool try_scan_carrot_coinbase_enote(const CarrotCoinbaseEnoteV1 &enote, //------------------------------------------------------------------------------------------------------------------- bool try_scan_carrot_enote_external(const CarrotEnoteV1 &enote, const std::optional encrypted_payment_id, - const crypto::x25519_pubkey &s_sender_receiver_unctx, + const mx25519_pubkey &s_sender_receiver_unctx, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, crypto::secret_key &sender_extension_g_out, diff --git a/src/carrot_core/carrot_enote_scan.h b/src/carrot_core/carrot_enote_scan.h index 1bc33bfaf..7bc160d23 100644 --- a/src/carrot_core/carrot_enote_scan.h +++ b/src/carrot_core/carrot_enote_scan.h @@ -49,12 +49,12 @@ bool verify_carrot_janus_protection(const input_context_t &input_context, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, const crypto::public_key &nominal_address_spend_pubkey, - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const janus_anchor_t &nominal_anchor, payment_id_t &nominal_payment_id_inout); bool try_scan_carrot_coinbase_enote(const CarrotCoinbaseEnoteV1 &enote, - const crypto::x25519_pubkey &s_sender_receiver_unctx, + const mx25519_pubkey &s_sender_receiver_unctx, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, crypto::secret_key &sender_extension_g_out, @@ -63,7 +63,7 @@ bool try_scan_carrot_coinbase_enote(const CarrotCoinbaseEnoteV1 &enote, bool try_scan_carrot_enote_external(const CarrotEnoteV1 &enote, const std::optional encrypted_payment_id, - const crypto::x25519_pubkey &s_sender_receiver_unctx, + const mx25519_pubkey &s_sender_receiver_unctx, const view_incoming_key_device &k_view_dev, const crypto::public_key &account_spend_pubkey, crypto::secret_key &sender_extension_g_out, diff --git a/src/carrot_core/carrot_enote_types.h b/src/carrot_core/carrot_enote_types.h index 3fbbf1f89..f91bdc65f 100644 --- a/src/carrot_core/carrot_enote_types.h +++ b/src/carrot_core/carrot_enote_types.h @@ -31,8 +31,8 @@ #pragma once //local headers -#include "crypto/x25519.h" #include "core_types.h" +#include "mx25519.h" #include "ringct/rctTypes.h" //third party headers @@ -66,7 +66,7 @@ struct CarrotEnoteV1 final /// view_tag view_tag_t view_tag; /// D_e - crypto::x25519_pubkey enote_ephemeral_pubkey; + mx25519_pubkey enote_ephemeral_pubkey; /// L_0 crypto::key_image tx_first_key_image; }; @@ -89,7 +89,7 @@ struct CarrotCoinbaseEnoteV1 final /// view_tag view_tag_t view_tag; /// D_e - crypto::x25519_pubkey enote_ephemeral_pubkey; + mx25519_pubkey enote_ephemeral_pubkey; /// block_index std::uint64_t block_index; }; diff --git a/src/carrot_core/core_types.cpp b/src/carrot_core/core_types.cpp index 2145f4dc8..137b6a952 100644 --- a/src/carrot_core/core_types.cpp +++ b/src/carrot_core/core_types.cpp @@ -31,6 +31,10 @@ //local headers #include "crypto/crypto.h" +extern "C" +{ +#include "crypto/crypto-ops.h" +} //third party headers #include @@ -118,4 +122,16 @@ input_context_t gen_input_context() return crypto::rand(); } //------------------------------------------------------------------------------------------------------------------- +mx25519_pubkey gen_x25519_pubkey() +{ + unsigned char sc64[64]; + crypto::rand(sizeof(sc64), sc64); + sc_reduce(sc64); + ge_p3 P; + ge_scalarmult_base(&P, sc64); + mx25519_pubkey P_x25519; + ge_p3_to_x25519(P_x25519.data, &P); + return P_x25519; +} +//------------------------------------------------------------------------------------------------------------------- } //namespace carrot diff --git a/src/carrot_core/core_types.h b/src/carrot_core/core_types.h index 8dc8a0e67..98b096201 100644 --- a/src/carrot_core/core_types.h +++ b/src/carrot_core/core_types.h @@ -31,6 +31,7 @@ #pragma once //local headers +#include "mx25519.h" //third party headers @@ -126,5 +127,7 @@ payment_id_t gen_payment_id(); view_tag_t gen_view_tag(); /// generate a random input context input_context_t gen_input_context(); +/// generate a random X25519 pubkey (unclamped) +mx25519_pubkey gen_x25519_pubkey(); } //namespace carrot diff --git a/src/carrot_core/device.h b/src/carrot_core/device.h index b64170a00..c095fe732 100644 --- a/src/carrot_core/device.h +++ b/src/carrot_core/device.h @@ -33,7 +33,7 @@ //local headers #include "core_types.h" #include "crypto/crypto.h" -#include "crypto/x25519.h" +#include "mx25519.h" //third party headers @@ -118,8 +118,8 @@ struct view_incoming_key_device * outparam: kvD = k_v D * return: true on success, false on failure (e.g. unable to decompress point) */ - virtual bool view_key_scalar_mult_x25519(const crypto::x25519_pubkey &D, - crypto::x25519_pubkey &kvD) const = 0; + virtual bool view_key_scalar_mult_x25519(const mx25519_pubkey &D, + mx25519_pubkey &kvD) const = 0; /** * brief: make_janus_anchor_special - make a janus anchor for "special" enotes @@ -128,7 +128,7 @@ struct view_incoming_key_device * 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, + virtual void make_janus_anchor_special(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, const crypto::public_key &onetime_address, const crypto::public_key &account_spend_pubkey, @@ -155,7 +155,7 @@ struct view_balance_secret_device * 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, + virtual void make_internal_sender_receiver_secret(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, crypto::hash &s_sender_receiver_out) const = 0; diff --git a/src/carrot_core/device_ram_borrowed.cpp b/src/carrot_core/device_ram_borrowed.cpp index 8a4f73118..f749f4587 100644 --- a/src/carrot_core/device_ram_borrowed.cpp +++ b/src/carrot_core/device_ram_borrowed.cpp @@ -48,14 +48,14 @@ bool view_incoming_key_ram_borrowed_device::view_key_scalar_mult_ed25519(const c return true; } //------------------------------------------------------------------------------------------------------------------- -bool view_incoming_key_ram_borrowed_device::view_key_scalar_mult_x25519(const crypto::x25519_pubkey &D, - crypto::x25519_pubkey &kvD) const +bool view_incoming_key_ram_borrowed_device::view_key_scalar_mult_x25519(const mx25519_pubkey &D, + mx25519_pubkey &kvD) const { return make_carrot_uncontextualized_shared_key_receiver(m_k_view_incoming, D, kvD); } //------------------------------------------------------------------------------------------------------------------- void view_incoming_key_ram_borrowed_device::make_janus_anchor_special( - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, const crypto::public_key &onetime_address, const crypto::public_key &account_spend_pubkey, @@ -77,7 +77,7 @@ void view_balance_secret_ram_borrowed_device::make_internal_view_tag(const input } //------------------------------------------------------------------------------------------------------------------- void view_balance_secret_ram_borrowed_device::make_internal_sender_receiver_secret( - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, crypto::hash &s_sender_receiver_out) const { diff --git a/src/carrot_core/device_ram_borrowed.h b/src/carrot_core/device_ram_borrowed.h index b25821955..d9337425e 100644 --- a/src/carrot_core/device_ram_borrowed.h +++ b/src/carrot_core/device_ram_borrowed.h @@ -52,10 +52,10 @@ public: bool view_key_scalar_mult_ed25519(const crypto::public_key &P, crypto::public_key &kvP) const override; - bool view_key_scalar_mult_x25519(const crypto::x25519_pubkey &D, - crypto::x25519_pubkey &kvD) const override; + bool view_key_scalar_mult_x25519(const mx25519_pubkey &D, + mx25519_pubkey &kvD) const override; - void make_janus_anchor_special(const crypto::x25519_pubkey &enote_ephemeral_pubkey, + void make_janus_anchor_special(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, const crypto::public_key &onetime_address, const crypto::public_key &account_spend_pubkey, @@ -75,7 +75,7 @@ public: const crypto::public_key &onetime_address, view_tag_t &view_tag_out) const override; - void make_internal_sender_receiver_secret(const crypto::x25519_pubkey &enote_ephemeral_pubkey, + void make_internal_sender_receiver_secret(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, crypto::hash &s_sender_receiver_out) const override; diff --git a/src/carrot_core/enote_utils.cpp b/src/carrot_core/enote_utils.cpp index e75898c4d..e8b3e3d13 100644 --- a/src/carrot_core/enote_utils.cpp +++ b/src/carrot_core/enote_utils.cpp @@ -46,6 +46,7 @@ extern "C" //third party headers //standard headers +#include #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "carrot" @@ -54,6 +55,17 @@ namespace carrot { //------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------- +static const mx25519_impl* get_mx25519_impl() +{ + static std::once_flag of; + static const mx25519_impl *impl; + std::call_once(of, [&](){ impl = mx25519_select_impl(MX25519_TYPE_AUTO); }); + if (impl == nullptr) + throw std::runtime_error("failed to obtain a mx25519 implementation"); + return impl; +} +//------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------- static encrypted_amount_t enc_amount(const rct::xmr_amount amount, const encrypted_amount_t &mask) { static_assert(sizeof(rct::xmr_amount) == sizeof(encrypted_amount_t), ""); @@ -91,19 +103,17 @@ void make_carrot_enote_ephemeral_privkey(const janus_anchor_t &anchor_norm, } //------------------------------------------------------------------------------------------------------------------- void make_carrot_enote_ephemeral_pubkey_cryptonote(const crypto::secret_key &enote_ephemeral_privkey, - crypto::x25519_pubkey &enote_ephemeral_pubkey_out) + mx25519_pubkey &enote_ephemeral_pubkey_out) { - // K_e = d_e G - ge_p3 D_e_in_ed25519; - ge_scalarmult_base(&D_e_in_ed25519, to_bytes(enote_ephemeral_privkey)); - - // D_e = ConvertPointE(K_e) - ge_p3_to_x25519(enote_ephemeral_pubkey_out.data, &D_e_in_ed25519); + // D_e = d_e G + mx25519_scmul_base(get_mx25519_impl(), + &enote_ephemeral_pubkey_out, + reinterpret_cast(&enote_ephemeral_privkey)); } //------------------------------------------------------------------------------------------------------------------- void make_carrot_enote_ephemeral_pubkey_subaddress(const crypto::secret_key &enote_ephemeral_privkey, const crypto::public_key &address_spend_pubkey, - crypto::x25519_pubkey &enote_ephemeral_pubkey_out) + mx25519_pubkey &enote_ephemeral_pubkey_out) { // deserialize K^j_s ge_p3 address_spend_pubkey_p3; @@ -118,18 +128,21 @@ void make_carrot_enote_ephemeral_pubkey_subaddress(const crypto::secret_key &eno } //------------------------------------------------------------------------------------------------------------------- bool make_carrot_uncontextualized_shared_key_receiver(const crypto::secret_key &k_view, - const crypto::x25519_pubkey &enote_ephemeral_pubkey, - crypto::x25519_pubkey &s_sender_receiver_unctx_out) + const mx25519_pubkey &enote_ephemeral_pubkey, + mx25519_pubkey &s_sender_receiver_unctx_out) { // s_sr = k_v D_e - crypto::x25519_scmul_key(k_view, enote_ephemeral_pubkey, s_sender_receiver_unctx_out); + mx25519_scmul_key(get_mx25519_impl(), + &s_sender_receiver_unctx_out, + reinterpret_cast(&k_view), + &enote_ephemeral_pubkey); return true; } //------------------------------------------------------------------------------------------------------------------- bool make_carrot_uncontextualized_shared_key_sender(const crypto::secret_key &enote_ephemeral_privkey, const crypto::public_key &address_view_pubkey, - crypto::x25519_pubkey &s_sender_receiver_unctx_out) + mx25519_pubkey &s_sender_receiver_unctx_out) { // if K^j_v not in prime order subgroup, then FAIL ge_p3 address_view_pubkey_p3; @@ -137,11 +150,14 @@ bool make_carrot_uncontextualized_shared_key_sender(const crypto::secret_key &en return false; // D^j_v = ConvertPointE(K^j_v) - crypto::x25519_pubkey address_view_pubkey_x25519; + mx25519_pubkey address_view_pubkey_x25519; ge_p3_to_x25519(address_view_pubkey_x25519.data, &address_view_pubkey_p3); // s_sr = d_e D^j_v - crypto::x25519_scmul_key(enote_ephemeral_privkey, address_view_pubkey_x25519, s_sender_receiver_unctx_out); + mx25519_scmul_key(get_mx25519_impl(), + &s_sender_receiver_unctx_out, + reinterpret_cast(&enote_ephemeral_privkey), + &address_view_pubkey_x25519); return true; } @@ -172,7 +188,7 @@ void make_carrot_input_context(const crypto::key_image &first_rct_key_image, inp } //------------------------------------------------------------------------------------------------------------------- void make_carrot_sender_receiver_secret(const unsigned char s_sender_receiver_unctx[32], - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, crypto::hash &s_sender_receiver_out) { @@ -347,7 +363,7 @@ payment_id_t decrypt_legacy_payment_id(const encrypted_payment_id_t encrypted_pa return encrypted_payment_id ^ mask; } //------------------------------------------------------------------------------------------------------------------- -void make_carrot_janus_anchor_special(const crypto::x25519_pubkey &enote_ephemeral_pubkey, +void make_carrot_janus_anchor_special(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, const crypto::public_key &onetime_address, const crypto::secret_key &k_view, @@ -455,7 +471,7 @@ bool verify_carrot_external_janus_protection(const janus_anchor_t &nominal_ancho const crypto::public_key &nominal_address_view_pubkey, const bool is_subaddress, const payment_id_t nominal_payment_id, - const crypto::x25519_pubkey &enote_ephemeral_pubkey) + const mx25519_pubkey &enote_ephemeral_pubkey) { // d_e' = H_n(anchor_norm, input_context, K^j_s, K^j_v, pid)) crypto::secret_key nominal_enote_ephemeral_privkey; @@ -467,7 +483,7 @@ bool verify_carrot_external_janus_protection(const janus_anchor_t &nominal_ancho nominal_enote_ephemeral_privkey); // recompute D_e' for d_e' and address type - crypto::x25519_pubkey nominal_enote_ephemeral_pubkey; + mx25519_pubkey nominal_enote_ephemeral_pubkey; if (is_subaddress) make_carrot_enote_ephemeral_pubkey_subaddress(nominal_enote_ephemeral_privkey, nominal_address_spend_pubkey, @@ -477,7 +493,7 @@ bool verify_carrot_external_janus_protection(const janus_anchor_t &nominal_ancho nominal_enote_ephemeral_pubkey); // D_e' ?= D_e - return nominal_enote_ephemeral_pubkey == enote_ephemeral_pubkey; + return 0 == memcmp(&nominal_enote_ephemeral_pubkey, &enote_ephemeral_pubkey, sizeof(mx25519_pubkey)); } //------------------------------------------------------------------------------------------------------------------- } //namespace carrot diff --git a/src/carrot_core/enote_utils.h b/src/carrot_core/enote_utils.h index 13b4d9c61..fb9747422 100644 --- a/src/carrot_core/enote_utils.h +++ b/src/carrot_core/enote_utils.h @@ -32,8 +32,8 @@ //local headers #include "crypto/crypto.h" -#include "crypto/x25519.h" #include "core_types.h" +#include "mx25519.h" #include "ringct/rctTypes.h" //third party headers @@ -68,7 +68,7 @@ void make_carrot_enote_ephemeral_privkey(const janus_anchor_t &anchor_norm, * outparam: enote_ephemeral_pubkey_out - D_e */ void make_carrot_enote_ephemeral_pubkey_cryptonote(const crypto::secret_key &enote_ephemeral_privkey, - crypto::x25519_pubkey &enote_ephemeral_pubkey_out); + mx25519_pubkey &enote_ephemeral_pubkey_out); /** * brief: make_carrot_enote_ephemeral_pubkey_subaddress - make enote ephemeral pubkey D_e for a subaddress * D_e = d_e ConvertPointE(K^j_s) @@ -78,7 +78,7 @@ void make_carrot_enote_ephemeral_pubkey_cryptonote(const crypto::secret_key &eno */ void make_carrot_enote_ephemeral_pubkey_subaddress(const crypto::secret_key &enote_ephemeral_privkey, const crypto::public_key &address_spend_pubkey, - crypto::x25519_pubkey &enote_ephemeral_pubkey_out); + mx25519_pubkey &enote_ephemeral_pubkey_out); /** * brief: make_carrot_uncontextualized_shared_key_receiver - perform the receiver-side ECDH exchange for Carrot enotes * s_sr = k_v D_e @@ -88,8 +88,8 @@ void make_carrot_enote_ephemeral_pubkey_subaddress(const crypto::secret_key &eno * return: true if successful, false if a failure occurred in point decompression */ bool make_carrot_uncontextualized_shared_key_receiver(const crypto::secret_key &k_view, - const crypto::x25519_pubkey &enote_ephemeral_pubkey, - crypto::x25519_pubkey &s_sender_receiver_unctx_out); + const mx25519_pubkey &enote_ephemeral_pubkey, + mx25519_pubkey &s_sender_receiver_unctx_out); /** * brief: make_carrot_uncontextualized_shared_key_sender - perform the sender-side ECDH exchange for Carrot enotes * s_sr = d_e ConvertPointE(K^j_v) @@ -100,7 +100,7 @@ bool make_carrot_uncontextualized_shared_key_receiver(const crypto::secret_key & */ bool make_carrot_uncontextualized_shared_key_sender(const crypto::secret_key &enote_ephemeral_privkey, const crypto::public_key &address_view_pubkey, - crypto::x25519_pubkey &s_sender_receiver_unctx_out); + mx25519_pubkey &s_sender_receiver_unctx_out); /** * brief: make_carrot_view_tag - used for optimized identification of enotes * vt = H_3(s_sr || input_context || Ko) @@ -137,7 +137,7 @@ void make_carrot_input_context(const crypto::key_image &first_rct_key_image, inp * - note: this is 'crypto::hash' instead of 'crypto::secret_key' for better performance in multithreaded environments */ void make_carrot_sender_receiver_secret(const unsigned char s_sender_receiver_unctx[32], - const crypto::x25519_pubkey &enote_ephemeral_pubkey, + const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, crypto::hash &s_sender_receiver_out); /** @@ -304,7 +304,7 @@ payment_id_t decrypt_legacy_payment_id(const encrypted_payment_id_t encrypted_pa * param: account_spend_pubkey - K_s * outparam: anchor_special_out - anchor_sp */ -void make_carrot_janus_anchor_special(const crypto::x25519_pubkey &enote_ephemeral_pubkey, +void make_carrot_janus_anchor_special(const mx25519_pubkey &enote_ephemeral_pubkey, const input_context_t &input_context, const crypto::public_key &onetime_address, const crypto::secret_key &k_view, @@ -388,5 +388,5 @@ bool verify_carrot_external_janus_protection(const janus_anchor_t &nominal_ancho const crypto::public_key &nominal_address_view_pubkey, const bool is_subaddress, const payment_id_t nominal_payment_id, - const crypto::x25519_pubkey &enote_ephemeral_pubkey); + const mx25519_pubkey &enote_ephemeral_pubkey); } //namespace carrot diff --git a/src/carrot_core/output_set_finalization.cpp b/src/carrot_core/output_set_finalization.cpp index 558096681..6a6019fdb 100644 --- a/src/carrot_core/output_set_finalization.cpp +++ b/src/carrot_core/output_set_finalization.cpp @@ -98,7 +98,7 @@ tools::optional_variant additional_output_type = get_additional_output_type( num_outgoing, @@ -131,7 +131,7 @@ tools::optional_variant &&normal_pa { return memcmp(&a.enote.enote_ephemeral_pubkey, &b.enote.enote_ephemeral_pubkey, - sizeof(crypto::x25519_pubkey)) < 0; + sizeof(mx25519_pubkey)) < 0; }; std::sort(output_enote_proposals_out.begin(), output_enote_proposals_out.end(), sort_by_ephemeral_pubkey); const bool has_unique_ephemeral_pubkeys = tools::is_sorted_and_unique(output_enote_proposals_out, diff --git a/src/carrot_core/output_set_finalization.h b/src/carrot_core/output_set_finalization.h index 94b5ea8d0..fd76b3155 100644 --- a/src/carrot_core/output_set_finalization.h +++ b/src/carrot_core/output_set_finalization.h @@ -85,7 +85,7 @@ tools::optional_variant internal_message; }; @@ -105,7 +104,7 @@ bool operator<(const RCTOutputEnoteProposal &a, const RCTOutputEnoteProposal &b) * param: input_context - * return: D_e */ -crypto::x25519_pubkey get_enote_ephemeral_pubkey(const CarrotPaymentProposalV1 &proposal, +mx25519_pubkey get_enote_ephemeral_pubkey(const CarrotPaymentProposalV1 &proposal, const input_context_t &input_context); /** * brief: get_coinbase_output_proposal_v1 - convert the carrot proposal to a coinbase output proposal diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 8a7542c42..0f8edecb5 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -50,8 +50,7 @@ set(crypto_sources slow-hash.c rx-slow-hash.c CryptonightR_JIT.c - tree-hash.c - x25519.cpp) + tree-hash.c) if(ARCH_ID STREQUAL "i386" OR ARCH_ID STREQUAL "x86_64" OR ARCH_ID STREQUAL "x86-64" OR ARCH_ID STREQUAL "amd64") list(APPEND crypto_sources CryptonightR_template.S) @@ -72,7 +71,6 @@ monero_add_library(cncrypto target_link_libraries(cncrypto PUBLIC epee - mx25519_static randomx ${Boost_SYSTEM_LIBRARY} ${sodium_LIBRARIES} diff --git a/src/crypto/x25519.cpp b/src/crypto/x25519.cpp deleted file mode 100644 index d380bf98f..000000000 --- a/src/crypto/x25519.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// 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. - -//paired header -#include "x25519.h" - -//local headers -#include "crypto/crypto.h" -extern "C" -{ -#include "mx25519.h" -} - -//third party headers - -//standard headers -#include - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "crypto" - -namespace crypto -{ - -/// File-scope data -static const ec_scalar X25519_EIGHT{ .data = { 8 } }; - -//------------------------------------------------------------------------------------------------------------------- -secret_key x25519_secret_key_gen() -{ - secret_key privkey; - do - { - crypto::rand(32, to_bytes(privkey)); - privkey.data[0] &= 255 - 7; - privkey.data[31] &= 127; - } while (privkey == secret_key{}); - - return privkey; -} -//------------------------------------------------------------------------------------------------------------------- -x25519_pubkey x25519_pubkey_gen() -{ - const secret_key privkey{x25519_secret_key_gen()}; - x25519_pubkey pubkey; - x25519_scmul_base(privkey, pubkey); - - return pubkey; -} -//------------------------------------------------------------------------------------------------------------------- -bool x25519_scalar_is_canonical(const ec_scalar &test_scalar) -{ - //todo: is this constant time? - return (test_scalar.data[0] & 7) == 0 && - (test_scalar.data[31] & 128) == 0; -} -//------------------------------------------------------------------------------------------------------------------- -void x25519_scmul_base(const ec_scalar &scalar, x25519_pubkey &result_out) -{ - static const mx25519_impl *impl{mx25519_select_impl(mx25519_type::MX25519_TYPE_AUTO)}; - mx25519_scmul_base(impl, &result_out, reinterpret_cast(&scalar)); -} -//------------------------------------------------------------------------------------------------------------------- -void x25519_scmul_key(const ec_scalar &scalar, const x25519_pubkey &pubkey, x25519_pubkey &result_out) -{ - static const mx25519_impl *impl{mx25519_select_impl(mx25519_type::MX25519_TYPE_AUTO)}; - mx25519_scmul_key(impl, &result_out, reinterpret_cast(&scalar), &pubkey); -} -//------------------------------------------------------------------------------------------------------------------- -void x25519_invmul_key(std::vector privkeys_to_invert, - const x25519_pubkey &initial_pubkey, - x25519_pubkey &result_out) -{ - // 1. (1/({privkey1 * privkey2 * ...})) - // note: mx25519_invkey() will error if the resulting X25519 scalar is >= 2^255, so we 'search' for a valid solution - crypto::secret_key inverted_xkey; - result_out = initial_pubkey; - - while (mx25519_invkey(reinterpret_cast(&inverted_xkey), - reinterpret_cast(privkeys_to_invert.data()), - privkeys_to_invert.size()) != 0) - { - privkeys_to_invert.emplace_back(X25519_EIGHT); //add 8 to keys to invert - x25519_scmul_key(X25519_EIGHT, result_out, result_out); //xK = 8 * xK - } - - // 2. (1/([8*8*...*8] * {privkey1 * privkey2 * ...})) * [8*8*...*8] * xK - x25519_scmul_key(inverted_xkey, result_out, result_out); -} -//------------------------------------------------------------------------------------------------------------------- -} //namespace crypto diff --git a/src/crypto/x25519.h b/src/crypto/x25519.h deleted file mode 100644 index 80bb8ec22..000000000 --- a/src/crypto/x25519.h +++ /dev/null @@ -1,106 +0,0 @@ -// 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. - -// Interface for an x25519 implementation (mx25519). - -#pragma once - -//local headers -#include "crypto.h" -#include "generic-ops.h" -#include "memwipe.h" -#include "mlocker.h" - -//third party headers - -//standard headers -#include - -//forward declarations - - -namespace crypto -{ - -extern "C" -{ -#include "mx25519.h" -} - -struct x25519_pubkey : public mx25519_pubkey -{ - x25519_pubkey() = default; - x25519_pubkey(const mx25519_pubkey &other) { *this = other; } - x25519_pubkey& operator=(const mx25519_pubkey &other) { memcpy(data, other.data, 32); return *this; } -}; - -/** -* brief: x25519_secret_key_gen - generate a random x25519 privkey -* return: random canonical x25519 privkey -*/ -secret_key x25519_secret_key_gen(); -/** -* brief: x25519_pubkey_gen - generate a random x25519 pubkey -* return: random x25519 pubkey -*/ -x25519_pubkey x25519_pubkey_gen(); -/** -* brief: x25519_scalar_is_canonical - check that an X25519 scalar is canonical -* - expect: 2^255 > scalar >= 8 (i.e. last bit and first three bits not set) -* result: true if input scalar is canonical -*/ -bool x25519_scalar_is_canonical(const ec_scalar &test_scalar); -/** -* brief: x25519_scmul_base - compute scalar * xG -* param: scalar - scalar to multiply -* result: scalar * xG -*/ -void x25519_scmul_base(const ec_scalar &scalar, x25519_pubkey &result_out); -/** -* brief: x25519_scmul_key - compute scalar * pubkey -* param: scalar - scalar to multiply -* param: pubkey - public key to multiple against -* result: scalar * pubkey -*/ -void x25519_scmul_key(const ec_scalar &scalar, const x25519_pubkey &pubkey, x25519_pubkey &result_out); -/** -* brief: x25519_invmul_key - compute (1/({privkey1 * privkey2 * ...})) * initial_pubkey -* param: privkeys_to_invert - {privkey1, privkey2, ...} -* param: initial_pubkey - base key for inversion -* result: (1/({privkey1 * privkey2 * ...})) * initial_pubkey -*/ -void x25519_invmul_key(std::vector privkeys_to_invert, - const x25519_pubkey &initial_pubkey, - x25519_pubkey &result_out); - -} //namespace crypto - -inline const unsigned char* to_bytes(const crypto::x25519_pubkey &point) { return &reinterpret_cast(point); } - -/// upgrade x25519 keys -CRYPTO_MAKE_HASHABLE(x25519_pubkey) diff --git a/tests/performance_tests/view_scan.h b/tests/performance_tests/view_scan.h index 8503f0fd7..1fc043979 100644 --- a/tests/performance_tests/view_scan.h +++ b/tests/performance_tests/view_scan.h @@ -33,7 +33,6 @@ #include "carrot_core/enote_utils.h" #include "carrot_core/payment_proposal.h" #include "crypto/crypto.h" -#include "crypto/x25519.h" #include "device/device.hpp" #include "performance_tests.h" #include "ringct/rctOps.h" @@ -222,7 +221,7 @@ public: m_encrypted_payment_id); m_enote = output_proposal.enote; - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; carrot::make_carrot_uncontextualized_shared_key_receiver(m_k_view_incoming, m_enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -266,7 +265,7 @@ public: bool test() { - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; carrot::make_carrot_uncontextualized_shared_key_receiver(m_k_view_incoming, m_enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); diff --git a/tests/unit_tests/carrot_core.cpp b/tests/unit_tests/carrot_core.cpp index f193503ae..ba72dba5e 100644 --- a/tests/unit_tests/carrot_core.cpp +++ b/tests/unit_tests/carrot_core.cpp @@ -43,39 +43,41 @@ using namespace carrot; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- +namespace +{ // https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c#L17 - static const crypto::x25519_pubkey x25519_small_order_points[7] = { - /* 0 (order 4) */ - {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +static const mx25519_pubkey x25519_small_order_points[7] = { + /* 0 (order 4) */ + {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}, - /* 1 (order 1) */ - {{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 1 (order 1) */ + {{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}, - /* 325606250916557431795983626356110631294008115727848805560023387167927233504 - (order 8) */ - {{ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + /* 325606250916557431795983626356110631294008115727848805560023387167927233504 + (order 8) */ + {{ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 }}, - /* 39382357235489614581723060781553021112529911719440698176882885853963445705823 - (order 8) */ - {{ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, + /* 39382357235489614581723060781553021112529911719440698176882885853963445705823 + (order 8) */ + {{ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 }}, - /* p-1 (order 2) */ - {{ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* p-1 (order 2) */ + {{ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }}, - /* p (=0, order 4) */ - {{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* p (=0, order 4) */ + {{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }}, - /* p+1 (=1, order 1) */ - {{ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* p+1 (=1, order 1) */ + {{ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }} - }; +}; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- struct mock_carrot_keys @@ -173,7 +175,7 @@ static void unittest_scan_enote_set(const std::vector &enotes, const CarrotEnoteV1 &enote = enotes.at(output_index); // s_sr = k_v D_e - crypto::x25519_pubkey s_sr; + mx25519_pubkey s_sr; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote.enote_ephemeral_pubkey, s_sr); unittest_carrot_scan_result_t scan_result{}; @@ -218,6 +220,11 @@ static void unittest_scan_enote_set(const std::vector &enotes, res.push_back(scan_result); } } +} // namespace +static inline bool operator==(const mx25519_pubkey &a, const mx25519_pubkey &b) +{ + return 0 == memcmp(&a, &b, sizeof(mx25519_pubkey)); +} //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- TEST(carrot_core, ECDH_cryptonote_completeness) @@ -227,13 +234,13 @@ TEST(carrot_core, ECDH_cryptonote_completeness) crypto::secret_key k_ephem = rct::rct2sk(rct::skGen()); ASSERT_NE(k_view, k_ephem); - crypto::x25519_pubkey enote_ephemeral_pubkey; + mx25519_pubkey enote_ephemeral_pubkey; make_carrot_enote_ephemeral_pubkey_cryptonote(k_ephem, enote_ephemeral_pubkey); - crypto::x25519_pubkey s_sr_sender; + mx25519_pubkey s_sr_sender; ASSERT_TRUE(make_carrot_uncontextualized_shared_key_sender(k_ephem, view_pubkey, s_sr_sender)); - crypto::x25519_pubkey s_sr_receiver; + mx25519_pubkey s_sr_receiver; ASSERT_TRUE(make_carrot_uncontextualized_shared_key_receiver(k_view, enote_ephemeral_pubkey, s_sr_receiver)); EXPECT_EQ(s_sr_sender, s_sr_receiver); @@ -247,13 +254,13 @@ TEST(carrot_core, ECDH_subaddress_completeness) crypto::secret_key k_ephem = rct::rct2sk(rct::skGen()); ASSERT_NE(k_view, k_ephem); - crypto::x25519_pubkey enote_ephemeral_pubkey; + mx25519_pubkey enote_ephemeral_pubkey; make_carrot_enote_ephemeral_pubkey_subaddress(k_ephem, spend_pubkey, enote_ephemeral_pubkey); - crypto::x25519_pubkey s_sr_sender; + mx25519_pubkey s_sr_sender; ASSERT_TRUE(make_carrot_uncontextualized_shared_key_sender(k_ephem, view_pubkey, s_sr_sender)); - crypto::x25519_pubkey s_sr_receiver; + mx25519_pubkey s_sr_receiver; ASSERT_TRUE(make_carrot_uncontextualized_shared_key_receiver(k_view, enote_ephemeral_pubkey, s_sr_receiver)); EXPECT_EQ(s_sr_sender, s_sr_receiver); @@ -261,15 +268,18 @@ TEST(carrot_core, ECDH_subaddress_completeness) //---------------------------------------------------------------------------------------------------------------------- TEST(carrot_core, ECDH_mx25519_convergence) { - const crypto::x25519_pubkey P = crypto::x25519_pubkey_gen(); + const mx25519_pubkey P = gen_x25519_pubkey(); const crypto::secret_key a = rct::rct2sk(rct::skGen()); + const mx25519_impl *impl = mx25519_select_impl(MX25519_TYPE_AUTO); + ASSERT_NE(nullptr, impl); + // do Q = a * P using mx25519 - crypto::x25519_pubkey Q_mx25519; - crypto::x25519_scmul_key(a, P, Q_mx25519); + mx25519_pubkey Q_mx25519; + mx25519_scmul_key(impl, &Q_mx25519, reinterpret_cast(&a), &P); // do Q = a * P using make_carrot_uncontextualized_shared_key_receiver() - crypto::x25519_pubkey Q_carrot; + mx25519_pubkey Q_carrot; ASSERT_TRUE(make_carrot_uncontextualized_shared_key_receiver(a, P, Q_carrot)); // check equal @@ -302,7 +312,7 @@ TEST(carrot_core, main_address_normal_scan_completeness) const rct::key recomputed_amount_commitment = rct::commit(enote_proposal.amount, rct::sk2rct(enote_proposal.amount_blinding_factor)); ASSERT_EQ(enote_proposal.enote.amount_commitment, recomputed_amount_commitment); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote_proposal.enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -379,7 +389,7 @@ TEST(carrot_core, subaddress_normal_scan_completeness) const rct::key recomputed_amount_commitment = rct::commit(enote_proposal.amount, rct::sk2rct(enote_proposal.amount_blinding_factor)); ASSERT_EQ(enote_proposal.enote.amount_commitment, recomputed_amount_commitment); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote_proposal.enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -464,7 +474,7 @@ TEST(carrot_core, integrated_address_normal_scan_completeness) const rct::key recomputed_amount_commitment = rct::commit(enote_proposal.amount, rct::sk2rct(enote_proposal.amount_blinding_factor)); ASSERT_EQ(enote_proposal.enote.amount_commitment, recomputed_amount_commitment); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote_proposal.enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -523,7 +533,7 @@ TEST(carrot_core, main_address_special_scan_completeness) .destination_address_spend_pubkey = keys.account_spend_pubkey, .amount = crypto::rand(), .enote_type = enote_type, - .enote_ephemeral_pubkey = crypto::x25519_pubkey_gen(), + .enote_ephemeral_pubkey = gen_x25519_pubkey(), }; const crypto::key_image tx_first_key_image = rct::rct2ki(rct::pkGen()); @@ -539,7 +549,7 @@ TEST(carrot_core, main_address_special_scan_completeness) const rct::key recomputed_amount_commitment = rct::commit(enote_proposal.amount, rct::sk2rct(enote_proposal.amount_blinding_factor)); ASSERT_EQ(enote_proposal.enote.amount_commitment, recomputed_amount_commitment); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote_proposal.enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -607,7 +617,7 @@ TEST(carrot_core, subaddress_special_scan_completeness) .destination_address_spend_pubkey = subaddress.address_spend_pubkey, .amount = crypto::rand(), .enote_type = enote_type, - .enote_ephemeral_pubkey = crypto::x25519_pubkey_gen(), + .enote_ephemeral_pubkey = gen_x25519_pubkey(), }; const crypto::key_image tx_first_key_image = rct::rct2ki(rct::pkGen()); @@ -623,7 +633,7 @@ TEST(carrot_core, subaddress_special_scan_completeness) const rct::key recomputed_amount_commitment = rct::commit(enote_proposal.amount, rct::sk2rct(enote_proposal.amount_blinding_factor)); ASSERT_EQ(enote_proposal.enote.amount_commitment, recomputed_amount_commitment); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote_proposal.enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); @@ -696,7 +706,7 @@ TEST(carrot_core, main_address_internal_scan_completeness) .destination_address_spend_pubkey = main_address.address_spend_pubkey, .amount = crypto::rand(), .enote_type = enote_type, - .enote_ephemeral_pubkey = crypto::x25519_pubkey_gen(), + .enote_ephemeral_pubkey = gen_x25519_pubkey(), .internal_message = gen_janus_anchor() }; @@ -772,7 +782,7 @@ TEST(carrot_core, subaddress_internal_scan_completeness) .destination_address_spend_pubkey = subaddress.address_spend_pubkey, .amount = crypto::rand(), .enote_type = enote_type, - .enote_ephemeral_pubkey = crypto::x25519_pubkey_gen(), + .enote_ephemeral_pubkey = gen_x25519_pubkey(), .internal_message = gen_janus_anchor() }; @@ -859,7 +869,7 @@ TEST(carrot_core, main_address_coinbase_scan_completeness) ASSERT_EQ(proposal.amount, enote.amount); - crypto::x25519_pubkey s_sender_receiver_unctx; + mx25519_pubkey s_sender_receiver_unctx; make_carrot_uncontextualized_shared_key_receiver(keys.k_view, enote.enote_ephemeral_pubkey, s_sender_receiver_unctx); diff --git a/tests/unit_tests/carrot_legacy.cpp b/tests/unit_tests/carrot_legacy.cpp index 629230b7a..d94d49fc9 100644 --- a/tests/unit_tests/carrot_legacy.cpp +++ b/tests/unit_tests/carrot_legacy.cpp @@ -104,7 +104,7 @@ static void unittest_legacy_scan_enote_set(const std::vector &eno const CarrotEnoteV1 &enote = enotes.at(output_index); // s_sr = k_v D_e - crypto::x25519_pubkey s_sr; + mx25519_pubkey s_sr; make_carrot_uncontextualized_shared_key_receiver(acb.get_keys().m_view_secret_key, enote.enote_ephemeral_pubkey, s_sr); diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp index 27c992a23..cb9cf0f39 100644 --- a/tests/unit_tests/crypto.cpp +++ b/tests/unit_tests/crypto.cpp @@ -35,12 +35,11 @@ extern "C" { #include "crypto/crypto-ops.h" -#include "mx25519.h" } -#include "crypto/x25519.h" #include "crypto/generators.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/merge_mining.h" +#include "mx25519.h" #include "ringct/rctOps.h" #include "ringct/rctTypes.h" #include "string_tools.h" @@ -59,7 +58,6 @@ namespace "6c7251d54154cfa92c173a0dd39c1f948b655970153799af2aeadc9ff1add0ea"; template void *addressof(T &t) { return &t; } - template<> void *addressof(crypto::secret_key &k) { return addressof(unwrap(unwrap(k))); } template bool is_formatted() @@ -414,10 +412,10 @@ TEST(Crypto, x25519_impl_scmul_key_convergence) dump_mx25519_impls(available_impls); - crypto::x25519_pubkey P_fixed; + mx25519_pubkey P_fixed; epee::string_tools::hex_to_pod("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a", P_fixed); - crypto::x25519_pubkey P_random; + mx25519_pubkey P_random; rct::key tmp = rct::pkGen(); edwards_bytes_to_x25519_vartime(P_random.data, tmp.bytes); @@ -541,9 +539,9 @@ TEST(Crypto, x25519_secret_key_8_scmul_base) TEST(Crypto, ConvertPointE_Base) { const crypto::public_key G = crypto::get_G(); - const crypto::x25519_pubkey B_expected = {{9}}; + const mx25519_pubkey B_expected = {{9}}; - crypto::x25519_pubkey B_actual; + mx25519_pubkey B_actual; edwards_bytes_to_x25519_vartime(B_actual.data, to_bytes(G)); EXPECT_EQ(B_expected, B_actual); @@ -551,53 +549,63 @@ TEST(Crypto, ConvertPointE_Base) TEST(Crypto, ConvertPointE_PreserveScalarMultBase) { - // *clamped* private key a - const crypto::secret_key a = rct::rct2sk(rct::skGen()); - rct::key a_key; - memcpy(&a_key, &a, sizeof(rct::key)); + const std::vector available_impls = get_available_mx25519_impls(); - // P_ed = a G - const rct::key P_edward = rct::scalarmultBase(a_key); + for (const mx25519_impl *impl : available_impls) + { + // *clamped* private key a + const crypto::secret_key a = rct::rct2sk(rct::skGen()); + rct::key a_key; + memcpy(&a_key, &a, sizeof(rct::key)); - // P_mont = a B - crypto::x25519_pubkey P_mont; - crypto::x25519_scmul_base(a, P_mont); + // P_ed = a G + const rct::key P_edward = rct::scalarmultBase(a_key); - // P_mont' = ConvertPointE(P_ed) - crypto::x25519_pubkey P_mont_converted; - edwards_bytes_to_x25519_vartime(P_mont_converted.data, P_edward.bytes); + // P_mont = a B + mx25519_pubkey P_mont; + mx25519_scmul_base(impl, &P_mont, reinterpret_cast(&a)); - // P_mont' ?= P_mont - EXPECT_EQ(P_mont_converted, P_mont); + // P_mont' = ConvertPointE(P_ed) + mx25519_pubkey P_mont_converted; + edwards_bytes_to_x25519_vartime(P_mont_converted.data, P_edward.bytes); + + // P_mont' ?= P_mont + EXPECT_EQ(P_mont_converted, P_mont); + } } TEST(Crypto, ConvertPointE_PreserveScalarMultBase_gep3) { // compared to ConvertPointE_PreserveScalarMultBase, this test will use Z != 1 (probably) - const crypto::secret_key a = rct::rct2sk(rct::skGen()); - rct::key a_key; - memcpy(&a_key, &a, sizeof(rct::key)); + const std::vector available_impls = get_available_mx25519_impls(); - // P_ed = a G - ge_p3 P_p3; - ge_scalarmult_base(&P_p3, to_bytes(a)); + for (const mx25519_impl *impl : available_impls) + { + const crypto::secret_key a = rct::rct2sk(rct::skGen()); + rct::key a_key; + memcpy(&a_key, &a, sizeof(rct::key)); - // check that Z != 1, otherwise this test is a dup of ConvertPointE_PreserveScalarMultBase - rct::key Z_bytes; - fe_tobytes(Z_bytes.bytes, P_p3.Z); - ASSERT_NE(Z_bytes, rct::I); // check Z != 1 + // P_ed = a G + ge_p3 P_p3; + ge_scalarmult_base(&P_p3, to_bytes(a)); - // P_mont = a B - crypto::x25519_pubkey P_mont; - crypto::x25519_scmul_base(a, P_mont); + // check that Z != 1, otherwise this test is a dup of ConvertPointE_PreserveScalarMultBase + rct::key Z_bytes; + fe_tobytes(Z_bytes.bytes, P_p3.Z); + ASSERT_NE(Z_bytes, rct::I); // check Z != 1 - // P_mont' = ConvertPointE(P_ed) - crypto::x25519_pubkey P_mont_converted; - ge_p3_to_x25519(P_mont_converted.data, &P_p3); + // P_mont = a B + mx25519_pubkey P_mont; + mx25519_scmul_base(impl, &P_mont, reinterpret_cast(&a)); - // P_mont' ?= P_mont - EXPECT_EQ(P_mont_converted, P_mont); + // P_mont' = ConvertPointE(P_ed) + mx25519_pubkey P_mont_converted; + ge_p3_to_x25519(P_mont_converted.data, &P_p3); + + // P_mont' ?= P_mont + EXPECT_EQ(P_mont_converted, P_mont); + } } TEST(Crypto, ConvertPointE_EraseSign) @@ -608,10 +616,10 @@ TEST(Crypto, ConvertPointE_EraseSign) rct::key negP; rct::subKeys(negP, rct::I, P); - crypto::x25519_pubkey P_mont; + mx25519_pubkey P_mont; edwards_bytes_to_x25519_vartime(P_mont.data, P.bytes); - crypto::x25519_pubkey negP_mont; + mx25519_pubkey negP_mont; edwards_bytes_to_x25519_vartime(negP_mont.data, negP.bytes); EXPECT_EQ(P_mont, negP_mont);