Skip to content

Commit

Permalink
Randomize JoinSplits in z_sendmany
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Oct 18, 2016
1 parent 7f0aa74 commit 2eeb6be
Showing 1 changed file with 48 additions and 6 deletions.
54 changes: 48 additions & 6 deletions src/wallet/asyncrpcoperation_sendmany.cpp
Expand Up @@ -29,6 +29,22 @@

using namespace libzcash;

int find_output(Object obj, int n) {
Value outputMapValue = find_value(obj, "outputmap");
if (outputMapValue.type() != array_type) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation");
}

Array outputMap = outputMapValue.get_array();
for (size_t i = 0; i < outputMap.size(); i++) {
if (outputMap[i] == n) {
return i;
}
}

return -1;
}

AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
std::string fromAddress,
std::vector<SendManyRecipient> tOutputs,
Expand Down Expand Up @@ -372,6 +388,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
*/
Object obj;
CAmount jsChange = 0; // this is updated after each joinsplit
int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0
bool minersFeeProcessed = false;

if (t_outputs_total > 0) {
Expand Down Expand Up @@ -429,6 +446,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {
}

obj = perform_joinsplit(info, outPoints);

if (jsChange > 0) {
changeOutputIndex = find_output(obj, 1);
}
}
}

Expand All @@ -442,9 +463,6 @@ bool AsyncRPCOperation_sendmany::main_impl() {
// Keep track of treestate within this transaction
boost::unordered_map<uint256, ZCIncrementalMerkleTree, CCoinsKeyHasher> intermediates;
std::vector<uint256> previousCommitments;

// NOTE: Randomization of input and output order could break this in future
const int changeOutputIndex = 1;

while (zOutputsDeque.size() > 0) {
AsyncJoinSplitInfo info;
Expand Down Expand Up @@ -645,6 +663,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {
}

obj = perform_joinsplit(info, witnesses, jsAnchor);

if (jsChange > 0) {
changeOutputIndex = find_output(obj, 1);
}
}
}

Expand Down Expand Up @@ -845,11 +867,20 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
);

// Generate the proof, this can take over a minute.
JSDescription jsdesc(*pzcashParams,
boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs
{info.vjsin[0], info.vjsin[1]};
boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs
{info.vjsout[0], info.vjsout[1]};
boost::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
boost::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
JSDescription jsdesc = JSDescription::Randomized(
*pzcashParams,
joinSplitPubKey_,
anchor,
{info.vjsin[0], info.vjsin[1]},
{info.vjsout[0], info.vjsout[1]},
inputs,
outputs,
inputMap,
outputMap,
info.vpub_old,
info.vpub_new,
!this->testmode);
Expand Down Expand Up @@ -910,10 +941,21 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
}

Array arrInputMap;
Array arrOutputMap;
for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) {
arrInputMap.push_back(inputMap[i]);
}
for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
arrOutputMap.push_back(outputMap[i]);
}

Object obj;
obj.push_back(Pair("encryptednote1", encryptedNote1));
obj.push_back(Pair("encryptednote2", encryptedNote2));
obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
obj.push_back(Pair("inputmap", arrInputMap));
obj.push_back(Pair("outputmap", arrOutputMap));
return obj;
}

Expand Down

0 comments on commit 2eeb6be

Please sign in to comment.