Skip to content

Commit 792c154

Browse files
committed
carrot+fcmp: test stateless hot/cold sign
1 parent a5b9c13 commit 792c154

File tree

4 files changed

+315
-28
lines changed

4 files changed

+315
-28
lines changed

src/wallet/hot_cold.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,37 @@ static std::vector<RerandomizationScalars> expand_rerandomization_scalars(const
336336
}
337337
//-------------------------------------------------------------------------------------------------------------------
338338
//-------------------------------------------------------------------------------------------------------------------
339+
static std::function<carrot::InputProposalV1(const crypto::public_key&)> extend_supplemental_input_proposals_fetcher(
340+
const std::function<carrot::InputProposalV1(const crypto::public_key&)> &supplemental_input_proposals,
341+
const UnsignedCarrotTransactionSetV1 &unsigned_txs,
342+
const carrot::cryptonote_hierarchy_address_device &addr_dev)
343+
{
344+
// fake key image device
345+
struct dummy_key_image_device: public carrot::key_image_device
346+
{
347+
crypto::key_image derive_key_image(const carrot::OutputOpeningHintVariant&) const final
348+
{ return {}; }
349+
};
350+
351+
// collect new in-set transfers by one-time address (w/o correct key images)
352+
std::unordered_map<crypto::public_key, carrot::InputProposalV1> inset_input_proposals;
353+
for (const exported_transfer_details_variant &etd : unsigned_txs.new_transfers)
354+
{
355+
const wallet2_basic::transfer_details td = import_cold_output(etd, addr_dev, dummy_key_image_device());
356+
inset_input_proposals.emplace(td.get_public_key(), make_sal_opening_hint_from_transfer_details(td));
357+
}
358+
359+
// try to find in-set first, then use backup supplemental callback
360+
return [&, inset_input_proposals](const crypto::public_key &ota) -> carrot::InputProposalV1
361+
{
362+
const auto inset_it = inset_input_proposals.find(ota);
363+
if (inset_it != inset_input_proposals.cend())
364+
return inset_it->second;
365+
return supplemental_input_proposals(ota);
366+
};
367+
}
368+
//-------------------------------------------------------------------------------------------------------------------
369+
//-------------------------------------------------------------------------------------------------------------------
339370
static crypto::hash ki2hash(const crypto::key_image &ki)
340371
{
341372
return carrot::raw_byte_convert<crypto::hash>(ki);
@@ -898,28 +929,8 @@ void expand_carrot_transaction_proposals(const UnsignedCarrotTransactionSetV1 &u
898929
tx_proposals_out.clear();
899930
tx_proposals_out.reserve(unsigned_txs.tx_proposals.size());
900931

901-
// fake key image device
902-
struct dummy_key_image_device: public carrot::key_image_device
903-
{
904-
crypto::key_image derive_key_image(const carrot::OutputOpeningHintVariant&) const final
905-
{ return {}; }
906-
};
907-
908-
// collect new in-set transfers by one-time address (w/o correct key images)
909-
std::unordered_map<crypto::public_key, carrot::InputProposalV1> inset_input_proposals;
910-
for (const exported_transfer_details_variant &etd : unsigned_txs.new_transfers)
911-
{
912-
const wallet2_basic::transfer_details td = import_cold_output(etd, addr_dev, dummy_key_image_device());
913-
inset_input_proposals.emplace(td.get_public_key(), make_sal_opening_hint_from_transfer_details(td));
914-
}
915-
916-
const auto supplemental_and_inset_input_proposals = [&](const crypto::public_key &ota) -> carrot::InputProposalV1
917-
{
918-
const auto inset_it = inset_input_proposals.find(ota);
919-
if (inset_it != inset_input_proposals.cend())
920-
return inset_it->second;
921-
return supplemental_input_proposals(ota);
922-
};
932+
const auto supplemental_and_inset_input_proposals = extend_supplemental_input_proposals_fetcher(
933+
supplemental_input_proposals, unsigned_txs, addr_dev);
923934

924935
for (const HotColdCarrotTransactionProposalV1 &cold_tx_proposal : unsigned_txs.tx_proposals)
925936
{
@@ -1304,6 +1315,10 @@ void sign_carrot_tx_set_v1(const UnsignedCarrotTransactionSetV1 &unsigned_txs,
13041315
const carrot::generate_image_key_ram_borrowed_device generate_image_dev(k_spend);
13051316
const carrot::key_image_device_composed key_image_dev(generate_image_dev, hybrid_addr_dev, nullptr, &addr_dev);
13061317

1318+
// fetcher of input proposals / opening hints which tries provided in-set first
1319+
const auto supplemental_and_inset_input_proposals = extend_supplemental_input_proposals_fetcher(
1320+
supplemental_opening_hints, unsigned_txs, addr_dev);
1321+
13071322
// for each hot/cold tx proposal...
13081323
for (const HotColdCarrotTransactionProposalV1 &tx_proposal : unsigned_txs.tx_proposals)
13091324
{
@@ -1312,7 +1327,7 @@ void sign_carrot_tx_set_v1(const UnsignedCarrotTransactionSetV1 &unsigned_txs,
13121327
std::vector<crypto::key_image> input_key_images;
13131328
std::vector<FcmpRerandomizedOutputCompressed> rerandomized_outputs;
13141329
expand_carrot_transaction_proposal_and_rerandomized_outputs(tx_proposal,
1315-
supplemental_opening_hints,
1330+
supplemental_and_inset_input_proposals,
13161331
addr_dev,
13171332
key_image_dev,
13181333
expanded_tx_proposal,

tests/unit_tests/tx_construction_helpers.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
358358
std::vector<stripped_down_tx_source_entry_t> &&stripped_sources,
359359
std::vector<cryptonote::tx_destination_entry> &destinations,
360360
const boost::optional<cryptonote::account_public_address> &change_addr,
361+
const crypto::hash &payment_id,
361362
const rct::xmr_amount fee,
362363
const uint8_t hf_version,
363364
const bool sweep_unmixable_override)
@@ -369,7 +370,7 @@ cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
369370
std::forward<std::vector<stripped_down_tx_source_entry_t>>(stripped_sources),
370371
destinations,
371372
change_addr,
372-
crypto::null_hash,
373+
payment_id,
373374
fee,
374375
hf_version,
375376
dummy_main_tx_privkey,
@@ -379,6 +380,7 @@ cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
379380
//----------------------------------------------------------------------------------------------------------------------
380381
cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
381382
std::vector<cryptonote::tx_destination_entry> &destinations,
383+
const crypto::hash &payment_id,
382384
const rct::xmr_amount fee,
383385
const uint8_t hf_version,
384386
const bool sweep_unmixable_override)
@@ -394,6 +396,20 @@ cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
394396
/*stripped_sources=*/{},
395397
destinations,
396398
/*change_addr*/boost::none,
399+
payment_id,
400+
fee,
401+
hf_version,
402+
sweep_unmixable_override);
403+
}
404+
//----------------------------------------------------------------------------------------------------------------------
405+
cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
406+
std::vector<cryptonote::tx_destination_entry> &destinations,
407+
const rct::xmr_amount fee,
408+
const uint8_t hf_version,
409+
const bool sweep_unmixable_override)
410+
{
411+
return construct_pre_carrot_tx_with_fake_inputs(destinations,
412+
crypto::null_hash,
397413
fee,
398414
hf_version,
399415
sweep_unmixable_override);

tests/unit_tests/tx_construction_helpers.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
9797
std::vector<stripped_down_tx_source_entry_t> &&stripped_sources,
9898
std::vector<cryptonote::tx_destination_entry> &destinations,
9999
const boost::optional<cryptonote::account_public_address> &change_addr,
100+
const crypto::hash &payment_id,
101+
const rct::xmr_amount fee,
102+
const uint8_t hf_version,
103+
const bool sweep_unmixable_override = false);
104+
//----------------------------------------------------------------------------------------------------------------------
105+
//----------------------------------------------------------------------------------------------------------------------
106+
cryptonote::transaction construct_pre_carrot_tx_with_fake_inputs(
107+
std::vector<cryptonote::tx_destination_entry> &destinations,
108+
const crypto::hash &payment_id,
100109
const rct::xmr_amount fee,
101110
const uint8_t hf_version,
102111
const bool sweep_unmixable_override = false);

0 commit comments

Comments
 (0)