mirror of
https://github.com/monero-project/monero.git
synced 2025-01-28 18:56:31 +02:00
remove x25519 wrapper header
This commit is contained in:
parent
f85d3cb5c2
commit
5f5981c4df
@ -48,6 +48,7 @@ target_link_libraries(carrot_core
|
||||
PUBLIC
|
||||
cncrypto
|
||||
epee
|
||||
mx25519_static
|
||||
ringct
|
||||
seraphis_crypto
|
||||
PRIVATE
|
||||
|
@ -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_t> 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,
|
||||
|
@ -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_t> 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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -31,6 +31,10 @@
|
||||
|
||||
//local headers
|
||||
#include "crypto/crypto.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "crypto/crypto-ops.h"
|
||||
}
|
||||
|
||||
//third party headers
|
||||
#include <cstring>
|
||||
@ -118,4 +122,16 @@ input_context_t gen_input_context()
|
||||
return crypto::rand<input_context_t>();
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -46,6 +46,7 @@ extern "C"
|
||||
//third party headers
|
||||
|
||||
//standard headers
|
||||
#include <mutex>
|
||||
|
||||
#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<const mx25519_privkey*>(&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<const mx25519_privkey*>(&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<const mx25519_privkey*>(&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
|
||||
|
@ -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
|
||||
|
@ -98,7 +98,7 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
const rct::xmr_amount remaining_change,
|
||||
const bool have_payment_type_selfsend,
|
||||
const crypto::public_key &change_address_spend_pubkey,
|
||||
const crypto::x25519_pubkey &other_enote_ephemeral_pubkey)
|
||||
const mx25519_pubkey &other_enote_ephemeral_pubkey)
|
||||
{
|
||||
const std::optional<AdditionalOutputType> additional_output_type = get_additional_output_type(
|
||||
num_outgoing,
|
||||
@ -131,7 +131,7 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
.destination_address_spend_pubkey = change_address_spend_pubkey,
|
||||
.amount = remaining_change,
|
||||
.enote_type = CarrotEnoteType::CHANGE,
|
||||
.enote_ephemeral_pubkey = crypto::x25519_pubkey_gen()
|
||||
.enote_ephemeral_pubkey = gen_x25519_pubkey()
|
||||
};
|
||||
case AdditionalOutputType::DUMMY:
|
||||
return CarrotPaymentProposalV1{
|
||||
@ -245,7 +245,7 @@ void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&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,
|
||||
|
@ -85,7 +85,7 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
const rct::xmr_amount remaining_change,
|
||||
const bool have_payment_type_selfsend,
|
||||
const crypto::public_key &change_address_spend_pubkey,
|
||||
const crypto::x25519_pubkey &other_enote_ephemeral_pubkey);
|
||||
const mx25519_pubkey &other_enote_ephemeral_pubkey);
|
||||
/**
|
||||
* brief: get_output_enote_proposals - convert a *finalized* set of payment proposals into output enote proposals
|
||||
* param: normal_payment_proposals -
|
||||
|
@ -77,8 +77,8 @@ static crypto::secret_key get_enote_ephemeral_privkey(const CarrotPaymentProposa
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void get_normal_proposal_ecdh_parts(const CarrotPaymentProposalV1 &proposal,
|
||||
const input_context_t &input_context,
|
||||
crypto::x25519_pubkey &enote_ephemeral_pubkey_out,
|
||||
crypto::x25519_pubkey &s_sender_receiver_unctx_out)
|
||||
mx25519_pubkey &enote_ephemeral_pubkey_out,
|
||||
mx25519_pubkey &s_sender_receiver_unctx_out)
|
||||
{
|
||||
// 1. d_e = H_n(anchor_norm, input_context, K^j_s, K^j_v, pid))
|
||||
const crypto::secret_key enote_ephemeral_privkey = get_enote_ephemeral_privkey(proposal, input_context);
|
||||
@ -98,7 +98,7 @@ static void get_output_proposal_parts(const crypto::hash &s_sender_receiver,
|
||||
const payment_id_t payment_id,
|
||||
const rct::xmr_amount amount,
|
||||
const CarrotEnoteType enote_type,
|
||||
const crypto::x25519_pubkey &enote_ephemeral_pubkey,
|
||||
const mx25519_pubkey &enote_ephemeral_pubkey,
|
||||
const input_context_t &input_context,
|
||||
const bool coinbase_amount_commitment,
|
||||
crypto::secret_key &amount_blinding_factor_out,
|
||||
@ -136,12 +136,12 @@ static void get_output_proposal_parts(const crypto::hash &s_sender_receiver,
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void get_external_output_proposal_parts(const crypto::x25519_pubkey &s_sender_receiver_unctx,
|
||||
static void get_external_output_proposal_parts(const mx25519_pubkey &s_sender_receiver_unctx,
|
||||
const crypto::public_key &destination_spend_pubkey,
|
||||
const payment_id_t payment_id,
|
||||
const rct::xmr_amount amount,
|
||||
const CarrotEnoteType enote_type,
|
||||
const crypto::x25519_pubkey &enote_ephemeral_pubkey,
|
||||
const mx25519_pubkey &enote_ephemeral_pubkey,
|
||||
const input_context_t &input_context,
|
||||
const bool coinbase_amount_commitment,
|
||||
crypto::hash &s_sender_receiver_out,
|
||||
@ -190,8 +190,8 @@ bool operator==(const CarrotPaymentProposalSelfSendV1 &a, const CarrotPaymentPro
|
||||
return a.destination_address_spend_pubkey == b.destination_address_spend_pubkey &&
|
||||
a.amount == b.amount &&
|
||||
a.enote_type == b.enote_type &&
|
||||
a.enote_ephemeral_pubkey == b.enote_ephemeral_pubkey &&
|
||||
a.internal_message == b.internal_message;
|
||||
a.internal_message == b.internal_message &&
|
||||
0 == memcmp(&a.enote_ephemeral_pubkey, &b.enote_ephemeral_pubkey, sizeof(mx25519_pubkey));
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
bool operator<(const RCTOutputEnoteProposal &a, const RCTOutputEnoteProposal &b)
|
||||
@ -199,13 +199,13 @@ bool operator<(const RCTOutputEnoteProposal &a, const RCTOutputEnoteProposal &b)
|
||||
return memcmp(&a.enote.onetime_address, &b.enote.onetime_address, sizeof(crypto::public_key)) < 0;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
// d_e = H_n(anchor_norm, input_context, K^j_s, K^j_v, pid))
|
||||
const crypto::secret_key enote_ephemeral_privkey{get_enote_ephemeral_privkey(proposal, input_context)};
|
||||
|
||||
crypto::x25519_pubkey enote_ephemeral_pubkey;
|
||||
mx25519_pubkey enote_ephemeral_pubkey;
|
||||
if (proposal.destination.is_subaddress)
|
||||
// D_e = d_e ConvertPointE(K^j_s)
|
||||
make_carrot_enote_ephemeral_pubkey_subaddress(enote_ephemeral_privkey,
|
||||
@ -236,7 +236,7 @@ void get_coinbase_output_proposal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
make_carrot_input_context_coinbase(block_index, input_context);
|
||||
|
||||
// 3. make D_e and do external ECDH
|
||||
crypto::x25519_pubkey s_sender_receiver_unctx; auto dhe_wiper = auto_wiper(s_sender_receiver_unctx);
|
||||
mx25519_pubkey s_sender_receiver_unctx; auto dhe_wiper = auto_wiper(s_sender_receiver_unctx);
|
||||
get_normal_proposal_ecdh_parts(proposal,
|
||||
input_context,
|
||||
output_enote_out.enote_ephemeral_pubkey,
|
||||
@ -288,7 +288,7 @@ void get_output_proposal_normal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
make_carrot_input_context(tx_first_key_image, input_context);
|
||||
|
||||
// 3. make D_e and do external ECDH
|
||||
crypto::x25519_pubkey s_sender_receiver_unctx; auto dhe_wiper = auto_wiper(s_sender_receiver_unctx);
|
||||
mx25519_pubkey s_sender_receiver_unctx; auto dhe_wiper = auto_wiper(s_sender_receiver_unctx);
|
||||
get_normal_proposal_ecdh_parts(proposal,
|
||||
input_context,
|
||||
output_enote_out.enote.enote_ephemeral_pubkey,
|
||||
@ -337,7 +337,7 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
make_carrot_input_context(tx_first_key_image, input_context);
|
||||
|
||||
// 3. s_sr = k_v D_e
|
||||
crypto::x25519_pubkey s_sender_receiver_unctx;
|
||||
mx25519_pubkey s_sender_receiver_unctx;
|
||||
CHECK_AND_ASSERT_THROW_MES(k_view_dev.view_key_scalar_mult_x25519(proposal.enote_ephemeral_pubkey,
|
||||
s_sender_receiver_unctx),
|
||||
"get output proposal special v1: HW device failed to perform ECDH with ephemeral pubkey");
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
//local headers
|
||||
#include "carrot_enote_types.h"
|
||||
#include "crypto/x25519.h"
|
||||
#include "destination.h"
|
||||
#include "device.h"
|
||||
#include "ringct/rctTypes.h"
|
||||
@ -77,7 +76,7 @@ struct CarrotPaymentProposalSelfSendV1 final
|
||||
/// enote_type
|
||||
CarrotEnoteType enote_type;
|
||||
/// enote ephemeral pubkey: xr G
|
||||
crypto::x25519_pubkey enote_ephemeral_pubkey;
|
||||
mx25519_pubkey enote_ephemeral_pubkey;
|
||||
/// anchor: arbitrary, pre-encrypted message for _internal_ selfsends
|
||||
std::optional<janus_anchor_t> 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
|
||||
|
@ -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}
|
||||
|
@ -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 <vector>
|
||||
|
||||
#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<const mx25519_privkey*>(&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<const mx25519_privkey*>(&scalar), &pubkey);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void x25519_invmul_key(std::vector<ec_scalar> 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<mx25519_privkey*>(&inverted_xkey),
|
||||
reinterpret_cast<const mx25519_privkey*>(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
|
@ -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 <vector>
|
||||
|
||||
//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<ec_scalar> 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<const unsigned char&>(point); }
|
||||
|
||||
/// upgrade x25519 keys
|
||||
CRYPTO_MAKE_HASHABLE(x25519_pubkey)
|
@ -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);
|
||||
|
@ -43,8 +43,10 @@ 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] = {
|
||||
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,
|
||||
@ -75,7 +77,7 @@ using namespace carrot;
|
||||
{{ 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<CarrotEnoteV1> &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<CarrotEnoteV1> &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<const mx25519_privkey*>(&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<rct::xmr_amount>(),
|
||||
.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<rct::xmr_amount>(),
|
||||
.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<rct::xmr_amount>(),
|
||||
.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<rct::xmr_amount>(),
|
||||
.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);
|
||||
|
@ -104,7 +104,7 @@ static void unittest_legacy_scan_enote_set(const std::vector<CarrotEnoteV1> &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);
|
||||
|
@ -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<typename T> void *addressof(T &t) { return &t; }
|
||||
template<> void *addressof(crypto::secret_key &k) { return addressof(unwrap(unwrap(k))); }
|
||||
|
||||
template<typename T>
|
||||
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,6 +549,10 @@ TEST(Crypto, ConvertPointE_Base)
|
||||
|
||||
TEST(Crypto, ConvertPointE_PreserveScalarMultBase)
|
||||
{
|
||||
const std::vector<const mx25519_impl*> available_impls = get_available_mx25519_impls();
|
||||
|
||||
for (const mx25519_impl *impl : available_impls)
|
||||
{
|
||||
// *clamped* private key a
|
||||
const crypto::secret_key a = rct::rct2sk(rct::skGen());
|
||||
rct::key a_key;
|
||||
@ -560,21 +562,26 @@ TEST(Crypto, ConvertPointE_PreserveScalarMultBase)
|
||||
const rct::key P_edward = rct::scalarmultBase(a_key);
|
||||
|
||||
// P_mont = a B
|
||||
crypto::x25519_pubkey P_mont;
|
||||
crypto::x25519_scmul_base(a, P_mont);
|
||||
mx25519_pubkey P_mont;
|
||||
mx25519_scmul_base(impl, &P_mont, reinterpret_cast<const mx25519_privkey*>(&a));
|
||||
|
||||
// P_mont' = ConvertPointE(P_ed)
|
||||
crypto::x25519_pubkey P_mont_converted;
|
||||
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 std::vector<const mx25519_impl*> available_impls = get_available_mx25519_impls();
|
||||
|
||||
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));
|
||||
@ -589,15 +596,16 @@ TEST(Crypto, ConvertPointE_PreserveScalarMultBase_gep3)
|
||||
ASSERT_NE(Z_bytes, rct::I); // check Z != 1
|
||||
|
||||
// P_mont = a B
|
||||
crypto::x25519_pubkey P_mont;
|
||||
crypto::x25519_scmul_base(a, P_mont);
|
||||
mx25519_pubkey P_mont;
|
||||
mx25519_scmul_base(impl, &P_mont, reinterpret_cast<const mx25519_privkey*>(&a));
|
||||
|
||||
// P_mont' = ConvertPointE(P_ed)
|
||||
crypto::x25519_pubkey P_mont_converted;
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user