interim checkin - working RCT Carrot TX
This commit is contained in:
@@ -252,7 +252,8 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_pre_car
|
||||
.amount = amount,
|
||||
.amount_blinding_factor = amount_blinding_factor,
|
||||
.asset_type = enote.asset_type,
|
||||
.main_tx_pubkey_index = main_deriv_idx
|
||||
.main_tx_pubkey_index = main_deriv_idx,
|
||||
.is_carrot = false
|
||||
};
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
@@ -278,7 +279,19 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
|
||||
res.asset_type = enote.asset_type;
|
||||
res.amount_blinding_factor = rct::I;
|
||||
res.main_tx_pubkey_index = 0;
|
||||
res.is_carrot = true;
|
||||
|
||||
/*
|
||||
LOG_ERROR("wallet scanning values:" << std::endl <<
|
||||
" height : " << std::to_string(enote.block_index) << std::endl <<
|
||||
" Ko : " << epee::string_tools::pod_to_hex(enote.onetime_address) << std::endl <<
|
||||
" C_a : " << epee::string_tools::pod_to_hex(rct::commit(res.amount, res.amount_blinding_factor)) << std::endl <<
|
||||
" D_e : " << epee::string_tools::pod_to_hex(enote.enote_ephemeral_pubkey) << std::endl <<
|
||||
" s_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver_unctx.data) << std::endl <<
|
||||
" k^o_g : " << epee::string_tools::pod_to_hex(res.sender_extension_g.data) << std::endl <<
|
||||
" k^o_t : " << epee::string_tools::pod_to_hex(res.sender_extension_t.data) << std::endl <<
|
||||
" K^j_s : " << epee::string_tools::pod_to_hex(res.address_spend_pubkey) << std::endl);
|
||||
*/
|
||||
return res;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
@@ -322,6 +335,7 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
|
||||
res.amount_blinding_factor = rct::sk2rct(amount_blinding_factor_sk);
|
||||
res.main_tx_pubkey_index = 0;
|
||||
res.asset_type = enote.asset_type;
|
||||
res.is_carrot = true;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -375,6 +389,7 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
|
||||
res.amount_blinding_factor = rct::sk2rct(amount_blinding_factor_sk);
|
||||
res.main_tx_pubkey_index = 0;
|
||||
res.asset_type = enote.asset_type;
|
||||
res.is_carrot = true;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -864,7 +879,7 @@ bool is_long_payment_id(const crypto::hash &pid)
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
std::optional<crypto::key_image> try_derive_enote_key_image(
|
||||
const enote_view_incoming_scan_info_t &enote_scan_info,
|
||||
const cryptonote::account_keys &acc)
|
||||
const carrot::carrot_and_legacy_account &acc)
|
||||
{
|
||||
if (!enote_scan_info.subaddr_index)
|
||||
return std::nullopt;
|
||||
@@ -872,20 +887,19 @@ std::optional<crypto::key_image> try_derive_enote_key_image(
|
||||
// k^j_subext
|
||||
rct::key subaddress_extension;
|
||||
if (enote_scan_info.subaddr_index->index.is_subaddress())
|
||||
{
|
||||
{
|
||||
const cryptonote::subaddress_index subaddr_index_cn{enote_scan_info.subaddr_index->index.major,
|
||||
enote_scan_info.subaddr_index->index.minor};
|
||||
subaddress_extension = rct::sk2rct(
|
||||
acc.get_device().get_subaddress_secret_key(acc.m_view_secret_key, subaddr_index_cn));
|
||||
}
|
||||
enote_scan_info.subaddr_index->index.minor};
|
||||
subaddress_extension = rct::sk2rct(acc.get_keys().get_device().get_subaddress_secret_key(acc.get_keys().m_view_secret_key, subaddr_index_cn));
|
||||
}
|
||||
else // !subaddr_index_cn.is_zero()
|
||||
{
|
||||
{
|
||||
subaddress_extension = rct::Z;
|
||||
}
|
||||
}
|
||||
|
||||
// O = K^j_s + k^g_o G + k^t_o T
|
||||
rct::key onetime_address = rct::scalarmultKey(rct::pk2rct(crypto::get_T()),
|
||||
rct::sk2rct(enote_scan_info.sender_extension_t));
|
||||
rct::sk2rct(enote_scan_info.sender_extension_t));
|
||||
rct::addKeys1(onetime_address, rct::sk2rct(enote_scan_info.sender_extension_g), onetime_address);
|
||||
rct::addKeys(onetime_address, onetime_address, rct::pk2rct(enote_scan_info.address_spend_pubkey));
|
||||
|
||||
@@ -896,11 +910,19 @@ std::optional<crypto::key_image> try_derive_enote_key_image(
|
||||
//! @TODO: HW devices
|
||||
// x = k_s + k^j_subext + k^g_o
|
||||
rct::key x;
|
||||
sc_add(x.bytes,
|
||||
to_bytes(acc.m_spend_secret_key),
|
||||
to_bytes(enote_scan_info.sender_extension_g));
|
||||
sc_add(x.bytes, x.bytes, subaddress_extension.bytes);
|
||||
if (enote_scan_info.is_carrot) {
|
||||
|
||||
return acc.derive_key_image(enote_scan_info.address_spend_pubkey,
|
||||
enote_scan_info.sender_extension_g,
|
||||
enote_scan_info.sender_extension_t,
|
||||
rct::rct2pk(onetime_address));
|
||||
} else {
|
||||
sc_add(x.bytes,
|
||||
to_bytes(acc.get_keys().m_spend_secret_key),
|
||||
to_bytes(enote_scan_info.sender_extension_g));
|
||||
sc_add(x.bytes, x.bytes, subaddress_extension.bytes);
|
||||
}
|
||||
|
||||
// L = x I = (k_s + k^j_subext + k^g_o) Hp(O)
|
||||
return rct::rct2ki(rct::scalarmultKey(rct::pt2rct(ki_generator), x));
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
//local headers
|
||||
#include "carrot_core/carrot_enote_types.h"
|
||||
#include "carrot_core/device.h"
|
||||
#include "carrot_impl/account.h"
|
||||
#include "carrot_impl/subaddress_index.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "cryptonote_basic/account.h"
|
||||
@@ -75,6 +76,8 @@ struct enote_view_incoming_scan_info_t
|
||||
|
||||
// the cold signing code used to have a bug which added multiple main tx pubkeys to extra
|
||||
std::size_t main_tx_pubkey_index;
|
||||
|
||||
bool is_carrot;
|
||||
};
|
||||
|
||||
struct PreCarrotEnote
|
||||
@@ -141,6 +144,6 @@ bool is_long_payment_id(const crypto::hash &pid);
|
||||
|
||||
std::optional<crypto::key_image> try_derive_enote_key_image(
|
||||
const enote_view_incoming_scan_info_t &enote_scan_info,
|
||||
const cryptonote::account_keys &acc);
|
||||
const carrot::carrot_and_legacy_account &acc);
|
||||
} //namespace wallet
|
||||
} //namespace tools
|
||||
|
||||
@@ -91,6 +91,7 @@ static bool is_transfer_usable_for_input_selection(const wallet2::transfer_detai
|
||||
&& (from_subaddresses.empty() || from_subaddresses.count(td.m_subaddr_index.minor) == 1)
|
||||
&& td.amount() >= ignore_below
|
||||
&& td.amount() <= ignore_above
|
||||
&& td.asset_type == "SAL1"
|
||||
;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
@@ -173,11 +174,17 @@ static crypto::public_key find_change_address_spend_pubkey(
|
||||
CHECK_AND_ASSERT_THROW_MES(change_it != subaddress_map.cend(),
|
||||
"find_change_address_spend_pubkey: missing change address (index "
|
||||
<< subaddr_account << ",0) in subaddress map");
|
||||
// HERE BE DRAGONS!!!
|
||||
// SRCG: Disabling the following check is necessary to allow return_payments to work...
|
||||
// ...but if we can find an alternative to using the subaddress_map, we should!
|
||||
/*
|
||||
const auto change_it_2 = std::find_if(std::next(change_it), subaddress_map.cend(),
|
||||
[subaddr_account](const auto &p) { return p.second.major == subaddr_account && p.second.minor == 0; });
|
||||
CHECK_AND_ASSERT_THROW_MES(change_it_2 == subaddress_map.cend(),
|
||||
"find_change_address_spend_pubkey: provided subaddress map is malformed!!! At least two spend pubkeys map to "
|
||||
"index " << subaddr_account << ",0 in the subaddress map!");
|
||||
*/
|
||||
// LAND AHOY!!!
|
||||
return change_it->first;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
@@ -410,14 +417,14 @@ std::vector<carrot::CarrotTransactionProposalV1> make_carrot_transaction_proposa
|
||||
const auto subaddress_map = w.get_subaddress_map_ref();
|
||||
|
||||
std::vector<carrot::CarrotTransactionProposalV1> tx_proposals;
|
||||
tx_proposals.reserve(dsts.size() / (FCMP_PLUS_PLUS_MAX_OUTPUTS - 1) + 1);
|
||||
tx_proposals.reserve(dsts.size() / (carrot::CARROT_MAX_TX_OUTPUTS - 1) + 1);
|
||||
|
||||
const crypto::public_key change_address_spend_pubkey
|
||||
= find_change_address_spend_pubkey(subaddress_map, subaddr_account);
|
||||
|
||||
while (!dsts.empty())
|
||||
{
|
||||
const std::size_t num_dsts_to_complete = std::min<std::size_t>(dsts.size(), FCMP_PLUS_PLUS_MAX_OUTPUTS - 1);
|
||||
const std::size_t num_dsts_to_complete = std::min<std::size_t>(dsts.size(), carrot::CARROT_MAX_TX_OUTPUTS - 1);
|
||||
|
||||
// build payment proposals and subtractable info from last `num_dsts_to_complete` dsts
|
||||
std::vector<carrot::CarrotPaymentProposalV1> normal_payment_proposals;
|
||||
@@ -847,10 +854,11 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
|
||||
ctkey.mask = sources[i].mask;
|
||||
if (sources[i].carrot) {
|
||||
|
||||
const std::vector<crypto::public_key> v_pubkeys{sources[i].real_out_tx_key};
|
||||
const epee::span<const crypto::public_key> main_tx_ephemeral_pubkeys =
|
||||
epee::to_span(std::vector<crypto::public_key>{sources[i].real_out_tx_key});
|
||||
epee::to_span(v_pubkeys);
|
||||
const epee::span<const crypto::public_key> additional_tx_ephemeral_pubkeys =
|
||||
epee::to_span(sources[i].real_out_additional_tx_keys);
|
||||
epee::to_span(sources[i].real_out_additional_tx_keys);
|
||||
|
||||
// 2. perform ECDH derivations
|
||||
std::vector<crypto::key_derivation> main_derivations;
|
||||
@@ -917,8 +925,28 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
|
||||
nominal_janus_anchor_out
|
||||
);
|
||||
|
||||
/*
|
||||
LOG_ERROR("tx_builder values:" << std::endl <<
|
||||
" Ko : " << epee::string_tools::pod_to_hex(sources[i].outputs[sources[i].real_output].second.dest) << std::endl <<
|
||||
" C_a : " << epee::string_tools::pod_to_hex(sources[i].outputs[sources[i].real_output].second.mask) << std::endl <<
|
||||
" D_e : " << epee::string_tools::pod_to_hex(sources[i].real_out_tx_key) << std::endl <<
|
||||
" s_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver_unctx.data) << std::endl <<
|
||||
" s^ctx_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver.data) << std::endl <<
|
||||
" k^o_g : " << epee::string_tools::pod_to_hex(sender_extension_g_out.data) << std::endl <<
|
||||
" k^o_t : " << epee::string_tools::pod_to_hex(sender_extension_t_out.data) << std::endl <<
|
||||
" K^j_s : " << epee::string_tools::pod_to_hex(sources[i].address_spend_pubkey) << std::endl);
|
||||
*/
|
||||
|
||||
bool r = w.get_account().can_open_fcmp_onetime_address(
|
||||
sources[i].address_spend_pubkey,
|
||||
sender_extension_g_out,
|
||||
sender_extension_t_out,
|
||||
rct::rct2pk(sources[i].outputs[sources[i].real_output].second.dest)
|
||||
);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error,
|
||||
"Failed to open onetime address");
|
||||
crypto::secret_key x, y;
|
||||
bool r = w.get_account().try_searching_for_opening_for_onetime_address(
|
||||
r = w.get_account().try_searching_for_opening_for_onetime_address(
|
||||
sources[i].address_spend_pubkey,
|
||||
sender_extension_g_out,
|
||||
sender_extension_t_out,
|
||||
@@ -926,7 +954,7 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
|
||||
y
|
||||
);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error,
|
||||
"Failed to search for opening for onetime address");
|
||||
"Failed to obtain openings for onetime address");
|
||||
ctkey.x = rct::sk2rct(x);
|
||||
ctkey.y = rct::sk2rct(y);
|
||||
} else {
|
||||
|
||||
@@ -2426,7 +2426,7 @@ void wallet2::scan_key_image(const wallet::enote_view_incoming_scan_info_t &enot
|
||||
}
|
||||
}
|
||||
|
||||
ki_out = wallet::try_derive_enote_key_image(enote_scan_info, m_account.get_keys());
|
||||
ki_out = wallet::try_derive_enote_key_image(enote_scan_info, m_account);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::process_new_transaction(
|
||||
|
||||
Reference in New Issue
Block a user