mirror of
https://github.com/monero-project/monero.git
synced 2025-01-24 23:06:39 -05:00
delay selfsend proposal ephemeral pubkey dependencies
This commit is contained in:
parent
43178fddc5
commit
81317b36cd
@ -46,11 +46,11 @@ namespace carrot
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
std::optional<AdditionalOutputType> get_additional_output_type(const size_t num_outgoing,
|
||||
const size_t num_selfsend,
|
||||
const bool remaining_change,
|
||||
const bool need_change_output,
|
||||
const bool have_payment_type_selfsend)
|
||||
{
|
||||
const size_t num_outputs = num_outgoing + num_selfsend;
|
||||
const bool already_completed = num_outputs >= 2 && num_selfsend >= 1 && !remaining_change;
|
||||
const bool already_completed = num_outputs >= 2 && num_selfsend >= 1 && !need_change_output;
|
||||
if (num_outputs == 0)
|
||||
{
|
||||
ASSERT_MES_AND_THROW("get additional output type: set contains 0 outputs");
|
||||
@ -65,11 +65,11 @@ std::optional<AdditionalOutputType> get_additional_output_type(const size_t num_
|
||||
{
|
||||
return AdditionalOutputType::CHANGE_SHARED;
|
||||
}
|
||||
else if (!remaining_change)
|
||||
else if (!need_change_output)
|
||||
{
|
||||
return AdditionalOutputType::DUMMY;
|
||||
}
|
||||
else // num_selfsend == 1 && remaining_change
|
||||
else // num_selfsend == 1 && need_change_output
|
||||
{
|
||||
if (have_payment_type_selfsend)
|
||||
{
|
||||
@ -95,15 +95,14 @@ std::optional<AdditionalOutputType> get_additional_output_type(const size_t num_
|
||||
tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1> get_additional_output_proposal(
|
||||
const size_t num_outgoing,
|
||||
const size_t num_selfsend,
|
||||
const rct::xmr_amount remaining_change,
|
||||
const rct::xmr_amount needed_change_amount,
|
||||
const bool have_payment_type_selfsend,
|
||||
const crypto::public_key &change_address_spend_pubkey,
|
||||
const mx25519_pubkey &other_enote_ephemeral_pubkey)
|
||||
const crypto::public_key &change_address_spend_pubkey)
|
||||
{
|
||||
const std::optional<AdditionalOutputType> additional_output_type = get_additional_output_type(
|
||||
num_outgoing,
|
||||
num_selfsend,
|
||||
remaining_change,
|
||||
needed_change_amount,
|
||||
have_payment_type_selfsend
|
||||
);
|
||||
|
||||
@ -115,23 +114,23 @@ tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1
|
||||
case AdditionalOutputType::PAYMENT_SHARED:
|
||||
return CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = change_address_spend_pubkey,
|
||||
.amount = remaining_change,
|
||||
.amount = needed_change_amount,
|
||||
.enote_type = CarrotEnoteType::PAYMENT,
|
||||
.enote_ephemeral_pubkey = other_enote_ephemeral_pubkey
|
||||
.enote_ephemeral_pubkey = std::nullopt
|
||||
};
|
||||
case AdditionalOutputType::CHANGE_SHARED:
|
||||
return CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = change_address_spend_pubkey,
|
||||
.amount = remaining_change,
|
||||
.amount = needed_change_amount,
|
||||
.enote_type = CarrotEnoteType::CHANGE,
|
||||
.enote_ephemeral_pubkey = other_enote_ephemeral_pubkey
|
||||
.enote_ephemeral_pubkey = std::nullopt
|
||||
};
|
||||
case AdditionalOutputType::CHANGE_UNIQUE:
|
||||
return CarrotPaymentProposalSelfSendV1{
|
||||
.destination_address_spend_pubkey = change_address_spend_pubkey,
|
||||
.amount = remaining_change,
|
||||
.amount = needed_change_amount,
|
||||
.enote_type = CarrotEnoteType::CHANGE,
|
||||
.enote_ephemeral_pubkey = gen_x25519_pubkey()
|
||||
.enote_ephemeral_pubkey = std::nullopt
|
||||
};
|
||||
case AdditionalOutputType::DUMMY:
|
||||
return CarrotPaymentProposalV1{
|
||||
@ -218,11 +217,17 @@ void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_pa
|
||||
// construct selfsend enotes, preferring internal enotes over special enotes when possible
|
||||
for (const CarrotPaymentProposalSelfSendV1 &selfsend_payment_proposal : selfsend_payment_proposals)
|
||||
{
|
||||
const std::optional<mx25519_pubkey> other_enote_ephemeral_pubkey =
|
||||
(num_proposals == 2 && output_enote_proposals_out.size())
|
||||
? output_enote_proposals_out.at(0).enote.enote_ephemeral_pubkey
|
||||
: std::optional<mx25519_pubkey>{};
|
||||
|
||||
if (s_view_balance_dev != nullptr)
|
||||
{
|
||||
get_output_proposal_internal_v1(selfsend_payment_proposal,
|
||||
*s_view_balance_dev,
|
||||
tx_first_key_image,
|
||||
other_enote_ephemeral_pubkey,
|
||||
tools::add_element(output_enote_proposals_out));
|
||||
}
|
||||
else if (k_view_dev != nullptr)
|
||||
@ -231,6 +236,7 @@ void get_output_enote_proposals(std::vector<CarrotPaymentProposalV1> &&normal_pa
|
||||
*k_view_dev,
|
||||
account_spend_pubkey,
|
||||
tx_first_key_image,
|
||||
other_enote_ephemeral_pubkey,
|
||||
tools::add_element(output_enote_proposals_out));
|
||||
}
|
||||
else // neither k_v nor s_vb device passed
|
||||
|
@ -59,33 +59,31 @@ enum class AdditionalOutputType
|
||||
* brief: get_additional_output_type - get the type of the additional enote needed to finalize an output set
|
||||
* param: num_outgoing - number of outgoing transfers
|
||||
* param: num_selfsend - number of selfsend transfers
|
||||
* param: remaining_change - whether there is any leftover change needed to be included
|
||||
* param: need_change_output - whether an additional change output needs to be included for balance
|
||||
* param: have_payment_type_selfsend - true if the enote set has a selfsend enote with enote_type="payment"
|
||||
* return: AdditionalOutputType if need an additional enote, else std::nullopt
|
||||
* throw: std::runtime_error if the output set is in a state where it cannot be finalized
|
||||
*/
|
||||
std::optional<AdditionalOutputType> get_additional_output_type(const size_t num_outgoing,
|
||||
const size_t num_selfsend,
|
||||
const bool remaining_change,
|
||||
const bool need_change_output,
|
||||
const bool have_payment_type_selfsend);
|
||||
/**
|
||||
* brief: get_additional_output_proposal - get an additional output proposal to complete an output set
|
||||
* param: num_outgoing - number of outgoing transfers
|
||||
* param: num_selfsend - number of selfsend transfers
|
||||
* param: remaining_change - the amount of leftover change needed to be included
|
||||
* param: needed_change_amount - the amount of leftover change needed to be included
|
||||
* param: have_payment_type_selfsend - true if the enote set has a selfsend enote with enote_type="payment"
|
||||
* param: change_address_spend_pubkey - K^j_s of our change address
|
||||
* param: other_enote_ephemeral_pubkey - D^other_e
|
||||
* return: an output proposal if need an additional enote, else none
|
||||
* throw: std::runtime_error if the output set is in a state where it cannot be finalized
|
||||
*/
|
||||
tools::optional_variant<CarrotPaymentProposalV1, CarrotPaymentProposalSelfSendV1> get_additional_output_proposal(
|
||||
const size_t num_outgoing,
|
||||
const size_t num_selfsend,
|
||||
const rct::xmr_amount remaining_change,
|
||||
const rct::xmr_amount needed_change_amount,
|
||||
const bool have_payment_type_selfsend,
|
||||
const crypto::public_key &change_address_spend_pubkey,
|
||||
const mx25519_pubkey &other_enote_ephemeral_pubkey);
|
||||
const crypto::public_key &change_address_spend_pubkey);
|
||||
/**
|
||||
* brief: get_output_enote_proposals - convert a *finalized* set of payment proposals into output enote proposals
|
||||
* param: normal_payment_proposals -
|
||||
|
@ -59,29 +59,56 @@ static auto auto_wiper(T &obj)
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static crypto::secret_key get_enote_ephemeral_privkey(const CarrotPaymentProposalV1 &proposal,
|
||||
static crypto::secret_key get_enote_ephemeral_privkey(const janus_anchor_t randomness,
|
||||
const CarrotDestinationV1 &destination,
|
||||
const input_context_t &input_context)
|
||||
{
|
||||
// d_e = H_n(anchor_norm, input_context, K^j_s, K^j_v, pid))
|
||||
crypto::secret_key enote_ephemeral_privkey;
|
||||
make_carrot_enote_ephemeral_privkey(proposal.randomness,
|
||||
make_carrot_enote_ephemeral_privkey(randomness,
|
||||
input_context,
|
||||
proposal.destination.address_spend_pubkey,
|
||||
proposal.destination.address_view_pubkey,
|
||||
proposal.destination.payment_id,
|
||||
destination.address_spend_pubkey,
|
||||
destination.address_view_pubkey,
|
||||
destination.payment_id,
|
||||
enote_ephemeral_privkey);
|
||||
|
||||
return enote_ephemeral_privkey;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static mx25519_pubkey get_enote_ephemeral_pubkey(const janus_anchor_t randomness,
|
||||
const CarrotDestinationV1 &destination,
|
||||
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(randomness,
|
||||
destination,
|
||||
input_context)};
|
||||
|
||||
mx25519_pubkey enote_ephemeral_pubkey;
|
||||
if (destination.is_subaddress)
|
||||
// D_e = d_e ConvertPointE(K^j_s)
|
||||
make_carrot_enote_ephemeral_pubkey_subaddress(enote_ephemeral_privkey,
|
||||
destination.address_spend_pubkey,
|
||||
enote_ephemeral_pubkey);
|
||||
else
|
||||
// D_e = d_e B
|
||||
make_carrot_enote_ephemeral_pubkey_cryptonote(enote_ephemeral_privkey,
|
||||
enote_ephemeral_pubkey);
|
||||
|
||||
return enote_ephemeral_pubkey;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
static void get_normal_proposal_ecdh_parts(const CarrotPaymentProposalV1 &proposal,
|
||||
const input_context_t &input_context,
|
||||
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);
|
||||
const crypto::secret_key enote_ephemeral_privkey = get_enote_ephemeral_privkey(proposal.randomness,
|
||||
proposal.destination,
|
||||
input_context);
|
||||
|
||||
// 2. make D_e
|
||||
enote_ephemeral_pubkey_out = get_enote_ephemeral_pubkey(proposal, input_context);
|
||||
@ -202,21 +229,7 @@ bool operator<(const RCTOutputEnoteProposal &a, const RCTOutputEnoteProposal &b)
|
||||
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)};
|
||||
|
||||
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,
|
||||
proposal.destination.address_spend_pubkey,
|
||||
enote_ephemeral_pubkey);
|
||||
else
|
||||
// D_e = d_e B
|
||||
make_carrot_enote_ephemeral_pubkey_cryptonote(enote_ephemeral_privkey,
|
||||
enote_ephemeral_pubkey);
|
||||
|
||||
return enote_ephemeral_pubkey;
|
||||
return get_enote_ephemeral_pubkey(proposal.randomness, proposal.destination, input_context);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
void get_coinbase_output_proposal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
@ -326,6 +339,7 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
const view_incoming_key_device &k_view_dev,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
const std::optional<mx25519_pubkey> &other_enote_ephemeral_pubkey,
|
||||
RCTOutputEnoteProposal &output_enote_out)
|
||||
{
|
||||
// 1. sanity checks
|
||||
@ -336,13 +350,22 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
input_context_t input_context;
|
||||
make_carrot_input_context(tx_first_key_image, input_context);
|
||||
|
||||
// 3. s_sr = k_v D_e
|
||||
mx25519_pubkey s_sender_receiver_unctx;
|
||||
CHECK_AND_ASSERT_THROW_MES(k_view_dev.view_key_scalar_mult_x25519(proposal.enote_ephemeral_pubkey,
|
||||
// 3. D_e
|
||||
const bool mismatched_enote_ephemeral_pubkeys = proposal.enote_ephemeral_pubkey &&
|
||||
other_enote_ephemeral_pubkey &&
|
||||
memcmp(&*proposal.enote_ephemeral_pubkey, &*other_enote_ephemeral_pubkey, sizeof(mx25519_pubkey));
|
||||
CHECK_AND_ASSERT_THROW_MES(!mismatched_enote_ephemeral_pubkeys,
|
||||
"get output proposal special v1: mismatched enote ephemeral pubkeys provided");
|
||||
const mx25519_pubkey enote_ephemeral_pubkey = proposal.enote_ephemeral_pubkey.value_or(
|
||||
other_enote_ephemeral_pubkey.value_or(gen_x25519_pubkey()));
|
||||
|
||||
// 4. s_sr = k_v D_e
|
||||
mx25519_pubkey s_sender_receiver_unctx; auto ecdh_wiper = auto_wiper(s_sender_receiver_unctx);
|
||||
CHECK_AND_ASSERT_THROW_MES(k_view_dev.view_key_scalar_mult_x25519(enote_ephemeral_pubkey,
|
||||
s_sender_receiver_unctx),
|
||||
"get output proposal special v1: HW device failed to perform ECDH with ephemeral pubkey");
|
||||
|
||||
// 4. build the output enote address pieces
|
||||
// 5. build the output enote address pieces
|
||||
crypto::hash s_sender_receiver; auto q_wiper = auto_wiper(s_sender_receiver);
|
||||
encrypted_payment_id_t dummy_encrypted_payment_id;
|
||||
get_external_output_proposal_parts(s_sender_receiver_unctx,
|
||||
@ -350,7 +373,7 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
null_payment_id,
|
||||
proposal.amount,
|
||||
proposal.enote_type,
|
||||
proposal.enote_ephemeral_pubkey,
|
||||
enote_ephemeral_pubkey,
|
||||
input_context,
|
||||
false, // coinbase_amount_commitment
|
||||
s_sender_receiver,
|
||||
@ -361,21 +384,21 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
dummy_encrypted_payment_id,
|
||||
output_enote_out.enote.view_tag);
|
||||
|
||||
// 5. make special janus anchor: anchor_sp = H_16(D_e, input_context, Ko, k_v, K_s)
|
||||
// 6. make special janus anchor: anchor_sp = H_16(D_e, input_context, Ko, k_v, K_s)
|
||||
janus_anchor_t janus_anchor_special;
|
||||
k_view_dev.make_janus_anchor_special(proposal.enote_ephemeral_pubkey,
|
||||
k_view_dev.make_janus_anchor_special(enote_ephemeral_pubkey,
|
||||
input_context,
|
||||
output_enote_out.enote.onetime_address,
|
||||
account_spend_pubkey,
|
||||
janus_anchor_special);
|
||||
|
||||
// 6. encrypt special anchor: anchor_enc = anchor XOR m_anchor
|
||||
// 7. encrypt special anchor: anchor_enc = anchor XOR m_anchor
|
||||
output_enote_out.enote.anchor_enc = encrypt_carrot_anchor(janus_anchor_special,
|
||||
s_sender_receiver,
|
||||
output_enote_out.enote.onetime_address);
|
||||
|
||||
// 7. save the enote ephemeral pubkey, first tx key image, and amount
|
||||
output_enote_out.enote.enote_ephemeral_pubkey = proposal.enote_ephemeral_pubkey;
|
||||
// 8. save the enote ephemeral pubkey, first tx key image, and amount
|
||||
output_enote_out.enote.enote_ephemeral_pubkey = enote_ephemeral_pubkey;
|
||||
output_enote_out.enote.tx_first_key_image = tx_first_key_image;
|
||||
output_enote_out.amount = proposal.amount;
|
||||
}
|
||||
@ -383,6 +406,7 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
void get_output_proposal_internal_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||
const view_balance_secret_device &s_view_balance_dev,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
const std::optional<mx25519_pubkey> &other_enote_ephemeral_pubkey,
|
||||
RCTOutputEnoteProposal &output_enote_out)
|
||||
{
|
||||
// 1. sanity checks
|
||||
@ -392,20 +416,29 @@ void get_output_proposal_internal_v1(const CarrotPaymentProposalSelfSendV1 &prop
|
||||
input_context_t input_context;
|
||||
make_carrot_input_context(tx_first_key_image, input_context);
|
||||
|
||||
// 3. s^ctx_sr = H_32(s_vb, D_e, input_context)
|
||||
// 3. D_e
|
||||
const bool mismatched_enote_ephemeral_pubkeys = proposal.enote_ephemeral_pubkey &&
|
||||
other_enote_ephemeral_pubkey &&
|
||||
memcmp(&*proposal.enote_ephemeral_pubkey, &*other_enote_ephemeral_pubkey, sizeof(mx25519_pubkey));
|
||||
CHECK_AND_ASSERT_THROW_MES(!mismatched_enote_ephemeral_pubkeys,
|
||||
"get output proposal internal v1: mismatched enote ephemeral pubkeys provided");
|
||||
const mx25519_pubkey enote_ephemeral_pubkey = proposal.enote_ephemeral_pubkey.value_or(
|
||||
other_enote_ephemeral_pubkey.value_or(gen_x25519_pubkey()));
|
||||
|
||||
// 4. s^ctx_sr = H_32(s_vb, D_e, input_context)
|
||||
crypto::hash s_sender_receiver; auto q_wiper = auto_wiper(s_sender_receiver);
|
||||
s_view_balance_dev.make_internal_sender_receiver_secret(proposal.enote_ephemeral_pubkey,
|
||||
s_view_balance_dev.make_internal_sender_receiver_secret(enote_ephemeral_pubkey,
|
||||
input_context,
|
||||
s_sender_receiver);
|
||||
|
||||
// 4. build the output enote address pieces
|
||||
// 5. build the output enote address pieces
|
||||
encrypted_payment_id_t dummy_encrypted_payment_id;
|
||||
get_output_proposal_parts(s_sender_receiver,
|
||||
proposal.destination_address_spend_pubkey,
|
||||
null_payment_id,
|
||||
proposal.amount,
|
||||
proposal.enote_type,
|
||||
proposal.enote_ephemeral_pubkey,
|
||||
enote_ephemeral_pubkey,
|
||||
input_context,
|
||||
false, // coinbase_amount_commitment
|
||||
output_enote_out.amount_blinding_factor,
|
||||
@ -414,21 +447,21 @@ void get_output_proposal_internal_v1(const CarrotPaymentProposalSelfSendV1 &prop
|
||||
output_enote_out.enote.amount_enc,
|
||||
dummy_encrypted_payment_id);
|
||||
|
||||
// 5. vt = H_3(s_vb || input_context || Ko)
|
||||
// 6. vt = H_3(s_vb || input_context || Ko)
|
||||
s_view_balance_dev.make_internal_view_tag(input_context,
|
||||
output_enote_out.enote.onetime_address,
|
||||
output_enote_out.enote.view_tag);
|
||||
|
||||
// 6. anchor = given message OR 0s, if not available
|
||||
// 7. anchor = given message OR 0s, if not available
|
||||
const janus_anchor_t anchor = proposal.internal_message.value_or(janus_anchor_t{});
|
||||
|
||||
// 7. encrypt anchor: anchor_enc = anchor XOR m_anchor
|
||||
// 8. encrypt anchor: anchor_enc = anchor XOR m_anchor
|
||||
output_enote_out.enote.anchor_enc = encrypt_carrot_anchor(anchor,
|
||||
s_sender_receiver,
|
||||
output_enote_out.enote.onetime_address);
|
||||
|
||||
// 8. save the enote ephemeral pubkey, first tx key image, and amount
|
||||
output_enote_out.enote.enote_ephemeral_pubkey = proposal.enote_ephemeral_pubkey;
|
||||
// 9. save the enote ephemeral pubkey, first tx key image, and amount
|
||||
output_enote_out.enote.enote_ephemeral_pubkey = enote_ephemeral_pubkey;
|
||||
output_enote_out.enote.tx_first_key_image = tx_first_key_image;
|
||||
output_enote_out.amount = proposal.amount;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "destination.h"
|
||||
#include "device.h"
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "common/variant.h"
|
||||
|
||||
//third party headers
|
||||
|
||||
@ -75,8 +76,8 @@ struct CarrotPaymentProposalSelfSendV1 final
|
||||
|
||||
/// enote_type
|
||||
CarrotEnoteType enote_type;
|
||||
/// enote ephemeral pubkey: xr G
|
||||
mx25519_pubkey enote_ephemeral_pubkey;
|
||||
/// enote ephemeral pubkey: D_e
|
||||
std::optional<mx25519_pubkey> enote_ephemeral_pubkey;
|
||||
/// anchor: arbitrary, pre-encrypted message for _internal_ selfsends
|
||||
std::optional<janus_anchor_t> internal_message;
|
||||
};
|
||||
@ -133,12 +134,14 @@ void get_output_proposal_normal_v1(const CarrotPaymentProposalV1 &proposal,
|
||||
* param: k_view_dev -
|
||||
* param: account_spend_pubkey -
|
||||
* param: tx_first_key_image -
|
||||
* param: other_enote_ephemeral_pubkey -
|
||||
* outparam: output_enote_out -
|
||||
*/
|
||||
void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||
const view_incoming_key_device &k_view_dev,
|
||||
const crypto::public_key &account_spend_pubkey,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
const std::optional<mx25519_pubkey> &other_enote_ephemeral_pubkey,
|
||||
RCTOutputEnoteProposal &output_enote_out);
|
||||
/**
|
||||
* brief: get_output_proposal_internal_v1 - convert the carrot proposal to an output proposal (internal)
|
||||
@ -146,12 +149,13 @@ void get_output_proposal_special_v1(const CarrotPaymentProposalSelfSendV1 &propo
|
||||
* param: s_view_balance_dev -
|
||||
* param: account_spend_pubkey -
|
||||
* param: tx_first_key_image -
|
||||
* param: other_enote_ephemeral_pubkey -
|
||||
* outparam: output_enote_out -
|
||||
* outparam: partial_memo_out -
|
||||
*/
|
||||
void get_output_proposal_internal_v1(const CarrotPaymentProposalSelfSendV1 &proposal,
|
||||
const view_balance_secret_device &s_view_balance_dev,
|
||||
const crypto::key_image &tx_first_key_image,
|
||||
const std::optional<mx25519_pubkey> &other_enote_ephemeral_pubkey,
|
||||
RCTOutputEnoteProposal &output_enote_out);
|
||||
/**
|
||||
* brief: gen_jamtis_payment_proposal_v1 - generate a random proposal
|
||||
|
@ -543,6 +543,7 @@ TEST(carrot_core, main_address_special_scan_completeness)
|
||||
keys.k_view_dev,
|
||||
keys.account_spend_pubkey,
|
||||
tx_first_key_image,
|
||||
std::nullopt,
|
||||
enote_proposal);
|
||||
|
||||
ASSERT_EQ(proposal.amount, enote_proposal.amount);
|
||||
@ -627,6 +628,7 @@ TEST(carrot_core, subaddress_special_scan_completeness)
|
||||
keys.k_view_dev,
|
||||
keys.account_spend_pubkey,
|
||||
tx_first_key_image,
|
||||
std::nullopt,
|
||||
enote_proposal);
|
||||
|
||||
ASSERT_EQ(proposal.amount, enote_proposal.amount);
|
||||
@ -716,6 +718,7 @@ TEST(carrot_core, main_address_internal_scan_completeness)
|
||||
get_output_proposal_internal_v1(proposal,
|
||||
keys.s_view_balance_dev,
|
||||
tx_first_key_image,
|
||||
std::nullopt,
|
||||
enote_proposal);
|
||||
|
||||
ASSERT_EQ(proposal.amount, enote_proposal.amount);
|
||||
@ -792,6 +795,7 @@ TEST(carrot_core, subaddress_internal_scan_completeness)
|
||||
get_output_proposal_internal_v1(proposal,
|
||||
keys.s_view_balance_dev,
|
||||
tx_first_key_image,
|
||||
std::nullopt,
|
||||
enote_proposal);
|
||||
|
||||
ASSERT_EQ(proposal.amount, enote_proposal.amount);
|
||||
|
Loading…
Reference in New Issue
Block a user