Skip to content

Commit ab9ebed

Browse files
committed
carrot+fcmp: order rerandomized outputs for SA/L proofs
And transfer small amount in k_anonymity test so FCMP++ can handle the amount with limited # of inputs.
1 parent 4f4b1af commit ab9ebed

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

src/wallet/tx_builder.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "carrot_impl/tx_builder_outputs.h"
4141
#include "carrot_impl/format_utils.h"
4242
#include "carrot_impl/input_selection.h"
43+
#include "common/apply_permutation.h"
4344
#include "common/container_helpers.h"
4445
#include "common/perf_timer.h"
4546
#include "common/threadpool.h"
@@ -817,10 +818,6 @@ std::unordered_map<crypto::key_image, fcmp_pp::FcmpPpSalProof> sign_carrot_trans
817818
CHECK_AND_ASSERT_THROW_MES(rerandomized_outputs.size() == n_inputs,
818819
__func__ << ": wrong size for rerandomized_outputs");
819820

820-
std::unordered_map<crypto::key_image, fcmp_pp::FcmpPpSalProof> sal_proofs_by_ki;
821-
822-
const auto best_transfer_by_ota = collect_non_burned_transfers_by_onetime_address(transfers);
823-
824821
//! @TODO: carrot hierarchy
825822
const carrot::cryptonote_hierarchy_address_device_ram_borrowed addr_dev(
826823
acc_keys.m_account_address.m_spend_public_key,
@@ -839,6 +836,7 @@ std::unordered_map<crypto::key_image, fcmp_pp::FcmpPpSalProof> sign_carrot_trans
839836
key_image_dev,
840837
signable_tx_hash);
841838

839+
std::unordered_map<crypto::key_image, fcmp_pp::FcmpPpSalProof> sal_proofs_by_ki;
842840
for (size_t input_idx = 0; input_idx < n_inputs; ++input_idx)
843841
{
844842
//! @TODO: spend device
@@ -941,7 +939,7 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
941939
__func__ << ": cannot find transfer by onetime address");
942940
const size_t transfer_idx = ota_it->second;
943941
CHECK_AND_ASSERT_THROW_MES(transfer_idx < transfers.size(),
944-
"finalize_all_proofs_from_transfer_details: transfer index out of range");
942+
__func__ << ": transfer index out of range");
945943
const wallet2_basic::transfer_details &td = transfers.at(transfer_idx);
946944
const fcmp_pp::curve_trees::OutputPair input_pair = td.get_output_pair();
947945
input_onetime_addresses.push_back(input_pair.output_pubkey);
@@ -1057,11 +1055,15 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
10571055
//! @TODO: parallelize jobs
10581056
std::vector<fcmp_pp::FcmpPpSalProof> sal_proofs(n_inputs);
10591057
tpool.submit(&pre_membership_waiter,
1060-
[&tx_proposal, &sorted_input_key_images, &rerandomized_outputs, &transfers, &acc_keys, &sal_proofs](){
1058+
[&tx_proposal, &sorted_input_key_images, &rerandomized_outputs, &transfers, &acc_keys, &sal_proofs, &key_image_order]() {
1059+
// hacky: permutate tx proposal input proposals in key image order
1060+
carrot::CarrotTransactionProposalV1 tx_proposal_sorted_ins = tx_proposal;
1061+
tools::apply_permutation(key_image_order, tx_proposal_sorted_ins.input_proposals);
1062+
10611063
PERF_TIMER(sign_carrot_transaction_proposal_from_transfer_details);
10621064
std::unordered_map<crypto::key_image, fcmp_pp::FcmpPpSalProof> sal_proofs_by_ki =
10631065
sign_carrot_transaction_proposal_from_transfer_details(
1064-
tx_proposal, rerandomized_outputs, transfers, acc_keys);
1066+
tx_proposal_sorted_ins, rerandomized_outputs, transfers, acc_keys);
10651067

10661068
CHECK_AND_ASSERT_THROW_MES(sal_proofs.size() == sorted_input_key_images.size(),
10671069
__func__ << ": bad SA/L result buffer size");

tests/functional_tests/k_anonymity.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ def transfer_around(self):
162162

163163
print("Creating transfers b/t wallets")
164164

165+
max_n_inputs = 8
166+
165167
num_successful_transfers = 0
166168
fee_margin = 0.05 # 5%
167169
for sender in range(N):
@@ -175,6 +177,15 @@ def transfer_around(self):
175177
break
176178
imperfect_starting_balance = unlocked_balance * (N - 1) / (N - 1 - j) * (1 - fee_margin)
177179
transfer_amount = int(imperfect_starting_balance / (N - 1))
180+
181+
# Limit transfer amount to sum of max_n_inputs-1 random unlocked input candidates,
182+
# so that FCMP++ txs can always pay the target sum
183+
incoming_transfers = self.wallet[sender].get_transfers(out=False, pending=False, pool=False)['in']
184+
unlocked_incoming_transfers = list(filter(lambda e: not e.locked, incoming_transfers))
185+
random.shuffle(unlocked_incoming_transfers)
186+
random_unlocked_subset_sum = sum(e.amount for e in unlocked_incoming_transfers[:(max_n_inputs-1)])
187+
transfer_amount = min(transfer_amount, random_unlocked_subset_sum)
188+
178189
assert transfer_amount < unlocked_balance
179190
dst = {'address': pub_addrs[receiver], 'amount': transfer_amount}
180191
res = self.wallet[sender].transfer([dst], get_tx_metadata = True)

0 commit comments

Comments
 (0)